42178 lines
3.3 MiB
42178 lines
3.3 MiB
(function webpackUniversalModuleDefinition(root, factory) {
|
||
if(typeof exports === 'object' && typeof module === 'object')
|
||
module.exports = factory();
|
||
else if(typeof define === 'function' && define.amd)
|
||
define("pdfAnnotate", [], factory);
|
||
else if(typeof exports === 'object')
|
||
exports["pdfAnnotate"] = factory();
|
||
else
|
||
root["pdfAnnotate"] = factory();
|
||
})(window, function() {
|
||
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].exports;
|
||
/******/ }
|
||
/******/ // Create a new module (and put it into the cache)
|
||
/******/ var module = installedModules[moduleId] = {
|
||
/******/ i: moduleId,
|
||
/******/ l: false,
|
||
/******/ exports: {}
|
||
/******/ };
|
||
/******/
|
||
/******/ // Execute the module function
|
||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||
/******/
|
||
/******/ // Flag the module as loaded
|
||
/******/ module.l = true;
|
||
/******/
|
||
/******/ // Return the exports of the module
|
||
/******/ return module.exports;
|
||
/******/ }
|
||
/******/
|
||
/******/
|
||
/******/ // expose the modules object (__webpack_modules__)
|
||
/******/ __webpack_require__.m = modules;
|
||
/******/
|
||
/******/ // expose the module cache
|
||
/******/ __webpack_require__.c = installedModules;
|
||
/******/
|
||
/******/ // define getter function for harmony exports
|
||
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||
/******/ if(!__webpack_require__.o(exports, name)) {
|
||
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
|
||
/******/ }
|
||
/******/ };
|
||
/******/
|
||
/******/ // define __esModule on exports
|
||
/******/ __webpack_require__.r = function(exports) {
|
||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||
/******/ }
|
||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||
/******/ };
|
||
/******/
|
||
/******/ // create a fake namespace object
|
||
/******/ // mode & 1: value is a module id, require it
|
||
/******/ // mode & 2: merge all properties of value into the ns
|
||
/******/ // mode & 4: return value when already ns object
|
||
/******/ // mode & 8|1: behave like require
|
||
/******/ __webpack_require__.t = function(value, mode) {
|
||
/******/ if(mode & 1) value = __webpack_require__(value);
|
||
/******/ if(mode & 8) return value;
|
||
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
|
||
/******/ var ns = Object.create(null);
|
||
/******/ __webpack_require__.r(ns);
|
||
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
|
||
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
|
||
/******/ return ns;
|
||
/******/ };
|
||
/******/
|
||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||
/******/ __webpack_require__.n = function(module) {
|
||
/******/ var getter = module && module.__esModule ?
|
||
/******/ function getDefault() { return module['default']; } :
|
||
/******/ function getModuleExports() { return module; };
|
||
/******/ __webpack_require__.d(getter, 'a', getter);
|
||
/******/ return getter;
|
||
/******/ };
|
||
/******/
|
||
/******/ // Object.prototype.hasOwnProperty.call
|
||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||
/******/
|
||
/******/ // __webpack_public_path__
|
||
/******/ __webpack_require__.p = "";
|
||
/******/
|
||
/******/
|
||
/******/ // Load entry module and return exports
|
||
/******/ return __webpack_require__(__webpack_require__.s = "./src/index.ts");
|
||
/******/ })
|
||
/************************************************************************/
|
||
/******/ ({
|
||
|
||
/***/ "./node_modules/asn1.js/lib/asn1.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/asn1.js/lib/asn1.js ***!
|
||
\******************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var asn1 = exports;
|
||
|
||
asn1.bignum = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js");
|
||
|
||
asn1.define = __webpack_require__(/*! ./asn1/api */ "./node_modules/asn1.js/lib/asn1/api.js").define;
|
||
asn1.base = __webpack_require__(/*! ./asn1/base */ "./node_modules/asn1.js/lib/asn1/base/index.js");
|
||
asn1.constants = __webpack_require__(/*! ./asn1/constants */ "./node_modules/asn1.js/lib/asn1/constants/index.js");
|
||
asn1.decoders = __webpack_require__(/*! ./asn1/decoders */ "./node_modules/asn1.js/lib/asn1/decoders/index.js");
|
||
asn1.encoders = __webpack_require__(/*! ./asn1/encoders */ "./node_modules/asn1.js/lib/asn1/encoders/index.js");
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/asn1.js/lib/asn1/api.js":
|
||
/*!**********************************************!*\
|
||
!*** ./node_modules/asn1.js/lib/asn1/api.js ***!
|
||
\**********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var asn1 = __webpack_require__(/*! ../asn1 */ "./node_modules/asn1.js/lib/asn1.js");
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
|
||
var api = exports;
|
||
|
||
api.define = function define(name, body) {
|
||
return new Entity(name, body);
|
||
};
|
||
|
||
function Entity(name, body) {
|
||
this.name = name;
|
||
this.body = body;
|
||
|
||
this.decoders = {};
|
||
this.encoders = {};
|
||
};
|
||
|
||
Entity.prototype._createNamed = function createNamed(base) {
|
||
var named;
|
||
try {
|
||
named = __webpack_require__(/*! vm */ "./node_modules/vm-browserify/index.js").runInThisContext(
|
||
'(function ' + this.name + '(entity) {\n' +
|
||
' this._initNamed(entity);\n' +
|
||
'})'
|
||
);
|
||
} catch (e) {
|
||
named = function (entity) {
|
||
this._initNamed(entity);
|
||
};
|
||
}
|
||
inherits(named, base);
|
||
named.prototype._initNamed = function initnamed(entity) {
|
||
base.call(this, entity);
|
||
};
|
||
|
||
return new named(this);
|
||
};
|
||
|
||
Entity.prototype._getDecoder = function _getDecoder(enc) {
|
||
enc = enc || 'der';
|
||
// Lazily create decoder
|
||
if (!this.decoders.hasOwnProperty(enc))
|
||
this.decoders[enc] = this._createNamed(asn1.decoders[enc]);
|
||
return this.decoders[enc];
|
||
};
|
||
|
||
Entity.prototype.decode = function decode(data, enc, options) {
|
||
return this._getDecoder(enc).decode(data, options);
|
||
};
|
||
|
||
Entity.prototype._getEncoder = function _getEncoder(enc) {
|
||
enc = enc || 'der';
|
||
// Lazily create encoder
|
||
if (!this.encoders.hasOwnProperty(enc))
|
||
this.encoders[enc] = this._createNamed(asn1.encoders[enc]);
|
||
return this.encoders[enc];
|
||
};
|
||
|
||
Entity.prototype.encode = function encode(data, enc, /* internal */ reporter) {
|
||
return this._getEncoder(enc).encode(data, reporter);
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/asn1.js/lib/asn1/base/buffer.js":
|
||
/*!******************************************************!*\
|
||
!*** ./node_modules/asn1.js/lib/asn1/base/buffer.js ***!
|
||
\******************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
var Reporter = __webpack_require__(/*! ../base */ "./node_modules/asn1.js/lib/asn1/base/index.js").Reporter;
|
||
var Buffer = __webpack_require__(/*! buffer */ "./node_modules/buffer/index.js").Buffer;
|
||
|
||
function DecoderBuffer(base, options) {
|
||
Reporter.call(this, options);
|
||
if (!Buffer.isBuffer(base)) {
|
||
this.error('Input not Buffer');
|
||
return;
|
||
}
|
||
|
||
this.base = base;
|
||
this.offset = 0;
|
||
this.length = base.length;
|
||
}
|
||
inherits(DecoderBuffer, Reporter);
|
||
exports.DecoderBuffer = DecoderBuffer;
|
||
|
||
DecoderBuffer.prototype.save = function save() {
|
||
return { offset: this.offset, reporter: Reporter.prototype.save.call(this) };
|
||
};
|
||
|
||
DecoderBuffer.prototype.restore = function restore(save) {
|
||
// Return skipped data
|
||
var res = new DecoderBuffer(this.base);
|
||
res.offset = save.offset;
|
||
res.length = this.offset;
|
||
|
||
this.offset = save.offset;
|
||
Reporter.prototype.restore.call(this, save.reporter);
|
||
|
||
return res;
|
||
};
|
||
|
||
DecoderBuffer.prototype.isEmpty = function isEmpty() {
|
||
return this.offset === this.length;
|
||
};
|
||
|
||
DecoderBuffer.prototype.readUInt8 = function readUInt8(fail) {
|
||
if (this.offset + 1 <= this.length)
|
||
return this.base.readUInt8(this.offset++, true);
|
||
else
|
||
return this.error(fail || 'DecoderBuffer overrun');
|
||
}
|
||
|
||
DecoderBuffer.prototype.skip = function skip(bytes, fail) {
|
||
if (!(this.offset + bytes <= this.length))
|
||
return this.error(fail || 'DecoderBuffer overrun');
|
||
|
||
var res = new DecoderBuffer(this.base);
|
||
|
||
// Share reporter state
|
||
res._reporterState = this._reporterState;
|
||
|
||
res.offset = this.offset;
|
||
res.length = this.offset + bytes;
|
||
this.offset += bytes;
|
||
return res;
|
||
}
|
||
|
||
DecoderBuffer.prototype.raw = function raw(save) {
|
||
return this.base.slice(save ? save.offset : this.offset, this.length);
|
||
}
|
||
|
||
function EncoderBuffer(value, reporter) {
|
||
if (Array.isArray(value)) {
|
||
this.length = 0;
|
||
this.value = value.map(function(item) {
|
||
if (!(item instanceof EncoderBuffer))
|
||
item = new EncoderBuffer(item, reporter);
|
||
this.length += item.length;
|
||
return item;
|
||
}, this);
|
||
} else if (typeof value === 'number') {
|
||
if (!(0 <= value && value <= 0xff))
|
||
return reporter.error('non-byte EncoderBuffer value');
|
||
this.value = value;
|
||
this.length = 1;
|
||
} else if (typeof value === 'string') {
|
||
this.value = value;
|
||
this.length = Buffer.byteLength(value);
|
||
} else if (Buffer.isBuffer(value)) {
|
||
this.value = value;
|
||
this.length = value.length;
|
||
} else {
|
||
return reporter.error('Unsupported type: ' + typeof value);
|
||
}
|
||
}
|
||
exports.EncoderBuffer = EncoderBuffer;
|
||
|
||
EncoderBuffer.prototype.join = function join(out, offset) {
|
||
if (!out)
|
||
out = new Buffer(this.length);
|
||
if (!offset)
|
||
offset = 0;
|
||
|
||
if (this.length === 0)
|
||
return out;
|
||
|
||
if (Array.isArray(this.value)) {
|
||
this.value.forEach(function(item) {
|
||
item.join(out, offset);
|
||
offset += item.length;
|
||
});
|
||
} else {
|
||
if (typeof this.value === 'number')
|
||
out[offset] = this.value;
|
||
else if (typeof this.value === 'string')
|
||
out.write(this.value, offset);
|
||
else if (Buffer.isBuffer(this.value))
|
||
this.value.copy(out, offset);
|
||
offset += this.length;
|
||
}
|
||
|
||
return out;
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/asn1.js/lib/asn1/base/index.js":
|
||
/*!*****************************************************!*\
|
||
!*** ./node_modules/asn1.js/lib/asn1/base/index.js ***!
|
||
\*****************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var base = exports;
|
||
|
||
base.Reporter = __webpack_require__(/*! ./reporter */ "./node_modules/asn1.js/lib/asn1/base/reporter.js").Reporter;
|
||
base.DecoderBuffer = __webpack_require__(/*! ./buffer */ "./node_modules/asn1.js/lib/asn1/base/buffer.js").DecoderBuffer;
|
||
base.EncoderBuffer = __webpack_require__(/*! ./buffer */ "./node_modules/asn1.js/lib/asn1/base/buffer.js").EncoderBuffer;
|
||
base.Node = __webpack_require__(/*! ./node */ "./node_modules/asn1.js/lib/asn1/base/node.js");
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/asn1.js/lib/asn1/base/node.js":
|
||
/*!****************************************************!*\
|
||
!*** ./node_modules/asn1.js/lib/asn1/base/node.js ***!
|
||
\****************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var Reporter = __webpack_require__(/*! ../base */ "./node_modules/asn1.js/lib/asn1/base/index.js").Reporter;
|
||
var EncoderBuffer = __webpack_require__(/*! ../base */ "./node_modules/asn1.js/lib/asn1/base/index.js").EncoderBuffer;
|
||
var DecoderBuffer = __webpack_require__(/*! ../base */ "./node_modules/asn1.js/lib/asn1/base/index.js").DecoderBuffer;
|
||
var assert = __webpack_require__(/*! minimalistic-assert */ "./node_modules/minimalistic-assert/index.js");
|
||
|
||
// Supported tags
|
||
var tags = [
|
||
'seq', 'seqof', 'set', 'setof', 'objid', 'bool',
|
||
'gentime', 'utctime', 'null_', 'enum', 'int', 'objDesc',
|
||
'bitstr', 'bmpstr', 'charstr', 'genstr', 'graphstr', 'ia5str', 'iso646str',
|
||
'numstr', 'octstr', 'printstr', 't61str', 'unistr', 'utf8str', 'videostr'
|
||
];
|
||
|
||
// Public methods list
|
||
var methods = [
|
||
'key', 'obj', 'use', 'optional', 'explicit', 'implicit', 'def', 'choice',
|
||
'any', 'contains'
|
||
].concat(tags);
|
||
|
||
// Overrided methods list
|
||
var overrided = [
|
||
'_peekTag', '_decodeTag', '_use',
|
||
'_decodeStr', '_decodeObjid', '_decodeTime',
|
||
'_decodeNull', '_decodeInt', '_decodeBool', '_decodeList',
|
||
|
||
'_encodeComposite', '_encodeStr', '_encodeObjid', '_encodeTime',
|
||
'_encodeNull', '_encodeInt', '_encodeBool'
|
||
];
|
||
|
||
function Node(enc, parent) {
|
||
var state = {};
|
||
this._baseState = state;
|
||
|
||
state.enc = enc;
|
||
|
||
state.parent = parent || null;
|
||
state.children = null;
|
||
|
||
// State
|
||
state.tag = null;
|
||
state.args = null;
|
||
state.reverseArgs = null;
|
||
state.choice = null;
|
||
state.optional = false;
|
||
state.any = false;
|
||
state.obj = false;
|
||
state.use = null;
|
||
state.useDecoder = null;
|
||
state.key = null;
|
||
state['default'] = null;
|
||
state.explicit = null;
|
||
state.implicit = null;
|
||
state.contains = null;
|
||
|
||
// Should create new instance on each method
|
||
if (!state.parent) {
|
||
state.children = [];
|
||
this._wrap();
|
||
}
|
||
}
|
||
module.exports = Node;
|
||
|
||
var stateProps = [
|
||
'enc', 'parent', 'children', 'tag', 'args', 'reverseArgs', 'choice',
|
||
'optional', 'any', 'obj', 'use', 'alteredUse', 'key', 'default', 'explicit',
|
||
'implicit', 'contains'
|
||
];
|
||
|
||
Node.prototype.clone = function clone() {
|
||
var state = this._baseState;
|
||
var cstate = {};
|
||
stateProps.forEach(function(prop) {
|
||
cstate[prop] = state[prop];
|
||
});
|
||
var res = new this.constructor(cstate.parent);
|
||
res._baseState = cstate;
|
||
return res;
|
||
};
|
||
|
||
Node.prototype._wrap = function wrap() {
|
||
var state = this._baseState;
|
||
methods.forEach(function(method) {
|
||
this[method] = function _wrappedMethod() {
|
||
var clone = new this.constructor(this);
|
||
state.children.push(clone);
|
||
return clone[method].apply(clone, arguments);
|
||
};
|
||
}, this);
|
||
};
|
||
|
||
Node.prototype._init = function init(body) {
|
||
var state = this._baseState;
|
||
|
||
assert(state.parent === null);
|
||
body.call(this);
|
||
|
||
// Filter children
|
||
state.children = state.children.filter(function(child) {
|
||
return child._baseState.parent === this;
|
||
}, this);
|
||
assert.equal(state.children.length, 1, 'Root node can have only one child');
|
||
};
|
||
|
||
Node.prototype._useArgs = function useArgs(args) {
|
||
var state = this._baseState;
|
||
|
||
// Filter children and args
|
||
var children = args.filter(function(arg) {
|
||
return arg instanceof this.constructor;
|
||
}, this);
|
||
args = args.filter(function(arg) {
|
||
return !(arg instanceof this.constructor);
|
||
}, this);
|
||
|
||
if (children.length !== 0) {
|
||
assert(state.children === null);
|
||
state.children = children;
|
||
|
||
// Replace parent to maintain backward link
|
||
children.forEach(function(child) {
|
||
child._baseState.parent = this;
|
||
}, this);
|
||
}
|
||
if (args.length !== 0) {
|
||
assert(state.args === null);
|
||
state.args = args;
|
||
state.reverseArgs = args.map(function(arg) {
|
||
if (typeof arg !== 'object' || arg.constructor !== Object)
|
||
return arg;
|
||
|
||
var res = {};
|
||
Object.keys(arg).forEach(function(key) {
|
||
if (key == (key | 0))
|
||
key |= 0;
|
||
var value = arg[key];
|
||
res[value] = key;
|
||
});
|
||
return res;
|
||
});
|
||
}
|
||
};
|
||
|
||
//
|
||
// Overrided methods
|
||
//
|
||
|
||
overrided.forEach(function(method) {
|
||
Node.prototype[method] = function _overrided() {
|
||
var state = this._baseState;
|
||
throw new Error(method + ' not implemented for encoding: ' + state.enc);
|
||
};
|
||
});
|
||
|
||
//
|
||
// Public methods
|
||
//
|
||
|
||
tags.forEach(function(tag) {
|
||
Node.prototype[tag] = function _tagMethod() {
|
||
var state = this._baseState;
|
||
var args = Array.prototype.slice.call(arguments);
|
||
|
||
assert(state.tag === null);
|
||
state.tag = tag;
|
||
|
||
this._useArgs(args);
|
||
|
||
return this;
|
||
};
|
||
});
|
||
|
||
Node.prototype.use = function use(item) {
|
||
assert(item);
|
||
var state = this._baseState;
|
||
|
||
assert(state.use === null);
|
||
state.use = item;
|
||
|
||
return this;
|
||
};
|
||
|
||
Node.prototype.optional = function optional() {
|
||
var state = this._baseState;
|
||
|
||
state.optional = true;
|
||
|
||
return this;
|
||
};
|
||
|
||
Node.prototype.def = function def(val) {
|
||
var state = this._baseState;
|
||
|
||
assert(state['default'] === null);
|
||
state['default'] = val;
|
||
state.optional = true;
|
||
|
||
return this;
|
||
};
|
||
|
||
Node.prototype.explicit = function explicit(num) {
|
||
var state = this._baseState;
|
||
|
||
assert(state.explicit === null && state.implicit === null);
|
||
state.explicit = num;
|
||
|
||
return this;
|
||
};
|
||
|
||
Node.prototype.implicit = function implicit(num) {
|
||
var state = this._baseState;
|
||
|
||
assert(state.explicit === null && state.implicit === null);
|
||
state.implicit = num;
|
||
|
||
return this;
|
||
};
|
||
|
||
Node.prototype.obj = function obj() {
|
||
var state = this._baseState;
|
||
var args = Array.prototype.slice.call(arguments);
|
||
|
||
state.obj = true;
|
||
|
||
if (args.length !== 0)
|
||
this._useArgs(args);
|
||
|
||
return this;
|
||
};
|
||
|
||
Node.prototype.key = function key(newKey) {
|
||
var state = this._baseState;
|
||
|
||
assert(state.key === null);
|
||
state.key = newKey;
|
||
|
||
return this;
|
||
};
|
||
|
||
Node.prototype.any = function any() {
|
||
var state = this._baseState;
|
||
|
||
state.any = true;
|
||
|
||
return this;
|
||
};
|
||
|
||
Node.prototype.choice = function choice(obj) {
|
||
var state = this._baseState;
|
||
|
||
assert(state.choice === null);
|
||
state.choice = obj;
|
||
this._useArgs(Object.keys(obj).map(function(key) {
|
||
return obj[key];
|
||
}));
|
||
|
||
return this;
|
||
};
|
||
|
||
Node.prototype.contains = function contains(item) {
|
||
var state = this._baseState;
|
||
|
||
assert(state.use === null);
|
||
state.contains = item;
|
||
|
||
return this;
|
||
};
|
||
|
||
//
|
||
// Decoding
|
||
//
|
||
|
||
Node.prototype._decode = function decode(input, options) {
|
||
var state = this._baseState;
|
||
|
||
// Decode root node
|
||
if (state.parent === null)
|
||
return input.wrapResult(state.children[0]._decode(input, options));
|
||
|
||
var result = state['default'];
|
||
var present = true;
|
||
|
||
var prevKey = null;
|
||
if (state.key !== null)
|
||
prevKey = input.enterKey(state.key);
|
||
|
||
// Check if tag is there
|
||
if (state.optional) {
|
||
var tag = null;
|
||
if (state.explicit !== null)
|
||
tag = state.explicit;
|
||
else if (state.implicit !== null)
|
||
tag = state.implicit;
|
||
else if (state.tag !== null)
|
||
tag = state.tag;
|
||
|
||
if (tag === null && !state.any) {
|
||
// Trial and Error
|
||
var save = input.save();
|
||
try {
|
||
if (state.choice === null)
|
||
this._decodeGeneric(state.tag, input, options);
|
||
else
|
||
this._decodeChoice(input, options);
|
||
present = true;
|
||
} catch (e) {
|
||
present = false;
|
||
}
|
||
input.restore(save);
|
||
} else {
|
||
present = this._peekTag(input, tag, state.any);
|
||
|
||
if (input.isError(present))
|
||
return present;
|
||
}
|
||
}
|
||
|
||
// Push object on stack
|
||
var prevObj;
|
||
if (state.obj && present)
|
||
prevObj = input.enterObject();
|
||
|
||
if (present) {
|
||
// Unwrap explicit values
|
||
if (state.explicit !== null) {
|
||
var explicit = this._decodeTag(input, state.explicit);
|
||
if (input.isError(explicit))
|
||
return explicit;
|
||
input = explicit;
|
||
}
|
||
|
||
var start = input.offset;
|
||
|
||
// Unwrap implicit and normal values
|
||
if (state.use === null && state.choice === null) {
|
||
if (state.any)
|
||
var save = input.save();
|
||
var body = this._decodeTag(
|
||
input,
|
||
state.implicit !== null ? state.implicit : state.tag,
|
||
state.any
|
||
);
|
||
if (input.isError(body))
|
||
return body;
|
||
|
||
if (state.any)
|
||
result = input.raw(save);
|
||
else
|
||
input = body;
|
||
}
|
||
|
||
if (options && options.track && state.tag !== null)
|
||
options.track(input.path(), start, input.length, 'tagged');
|
||
|
||
if (options && options.track && state.tag !== null)
|
||
options.track(input.path(), input.offset, input.length, 'content');
|
||
|
||
// Select proper method for tag
|
||
if (state.any)
|
||
result = result;
|
||
else if (state.choice === null)
|
||
result = this._decodeGeneric(state.tag, input, options);
|
||
else
|
||
result = this._decodeChoice(input, options);
|
||
|
||
if (input.isError(result))
|
||
return result;
|
||
|
||
// Decode children
|
||
if (!state.any && state.choice === null && state.children !== null) {
|
||
state.children.forEach(function decodeChildren(child) {
|
||
// NOTE: We are ignoring errors here, to let parser continue with other
|
||
// parts of encoded data
|
||
child._decode(input, options);
|
||
});
|
||
}
|
||
|
||
// Decode contained/encoded by schema, only in bit or octet strings
|
||
if (state.contains && (state.tag === 'octstr' || state.tag === 'bitstr')) {
|
||
var data = new DecoderBuffer(result);
|
||
result = this._getUse(state.contains, input._reporterState.obj)
|
||
._decode(data, options);
|
||
}
|
||
}
|
||
|
||
// Pop object
|
||
if (state.obj && present)
|
||
result = input.leaveObject(prevObj);
|
||
|
||
// Set key
|
||
if (state.key !== null && (result !== null || present === true))
|
||
input.leaveKey(prevKey, state.key, result);
|
||
else if (prevKey !== null)
|
||
input.exitKey(prevKey);
|
||
|
||
return result;
|
||
};
|
||
|
||
Node.prototype._decodeGeneric = function decodeGeneric(tag, input, options) {
|
||
var state = this._baseState;
|
||
|
||
if (tag === 'seq' || tag === 'set')
|
||
return null;
|
||
if (tag === 'seqof' || tag === 'setof')
|
||
return this._decodeList(input, tag, state.args[0], options);
|
||
else if (/str$/.test(tag))
|
||
return this._decodeStr(input, tag, options);
|
||
else if (tag === 'objid' && state.args)
|
||
return this._decodeObjid(input, state.args[0], state.args[1], options);
|
||
else if (tag === 'objid')
|
||
return this._decodeObjid(input, null, null, options);
|
||
else if (tag === 'gentime' || tag === 'utctime')
|
||
return this._decodeTime(input, tag, options);
|
||
else if (tag === 'null_')
|
||
return this._decodeNull(input, options);
|
||
else if (tag === 'bool')
|
||
return this._decodeBool(input, options);
|
||
else if (tag === 'objDesc')
|
||
return this._decodeStr(input, tag, options);
|
||
else if (tag === 'int' || tag === 'enum')
|
||
return this._decodeInt(input, state.args && state.args[0], options);
|
||
|
||
if (state.use !== null) {
|
||
return this._getUse(state.use, input._reporterState.obj)
|
||
._decode(input, options);
|
||
} else {
|
||
return input.error('unknown tag: ' + tag);
|
||
}
|
||
};
|
||
|
||
Node.prototype._getUse = function _getUse(entity, obj) {
|
||
|
||
var state = this._baseState;
|
||
// Create altered use decoder if implicit is set
|
||
state.useDecoder = this._use(entity, obj);
|
||
assert(state.useDecoder._baseState.parent === null);
|
||
state.useDecoder = state.useDecoder._baseState.children[0];
|
||
if (state.implicit !== state.useDecoder._baseState.implicit) {
|
||
state.useDecoder = state.useDecoder.clone();
|
||
state.useDecoder._baseState.implicit = state.implicit;
|
||
}
|
||
return state.useDecoder;
|
||
};
|
||
|
||
Node.prototype._decodeChoice = function decodeChoice(input, options) {
|
||
var state = this._baseState;
|
||
var result = null;
|
||
var match = false;
|
||
|
||
Object.keys(state.choice).some(function(key) {
|
||
var save = input.save();
|
||
var node = state.choice[key];
|
||
try {
|
||
var value = node._decode(input, options);
|
||
if (input.isError(value))
|
||
return false;
|
||
|
||
result = { type: key, value: value };
|
||
match = true;
|
||
} catch (e) {
|
||
input.restore(save);
|
||
return false;
|
||
}
|
||
return true;
|
||
}, this);
|
||
|
||
if (!match)
|
||
return input.error('Choice not matched');
|
||
|
||
return result;
|
||
};
|
||
|
||
//
|
||
// Encoding
|
||
//
|
||
|
||
Node.prototype._createEncoderBuffer = function createEncoderBuffer(data) {
|
||
return new EncoderBuffer(data, this.reporter);
|
||
};
|
||
|
||
Node.prototype._encode = function encode(data, reporter, parent) {
|
||
var state = this._baseState;
|
||
if (state['default'] !== null && state['default'] === data)
|
||
return;
|
||
|
||
var result = this._encodeValue(data, reporter, parent);
|
||
if (result === undefined)
|
||
return;
|
||
|
||
if (this._skipDefault(result, reporter, parent))
|
||
return;
|
||
|
||
return result;
|
||
};
|
||
|
||
Node.prototype._encodeValue = function encode(data, reporter, parent) {
|
||
var state = this._baseState;
|
||
|
||
// Decode root node
|
||
if (state.parent === null)
|
||
return state.children[0]._encode(data, reporter || new Reporter());
|
||
|
||
var result = null;
|
||
|
||
// Set reporter to share it with a child class
|
||
this.reporter = reporter;
|
||
|
||
// Check if data is there
|
||
if (state.optional && data === undefined) {
|
||
if (state['default'] !== null)
|
||
data = state['default']
|
||
else
|
||
return;
|
||
}
|
||
|
||
// Encode children first
|
||
var content = null;
|
||
var primitive = false;
|
||
if (state.any) {
|
||
// Anything that was given is translated to buffer
|
||
result = this._createEncoderBuffer(data);
|
||
} else if (state.choice) {
|
||
result = this._encodeChoice(data, reporter);
|
||
} else if (state.contains) {
|
||
content = this._getUse(state.contains, parent)._encode(data, reporter);
|
||
primitive = true;
|
||
} else if (state.children) {
|
||
content = state.children.map(function(child) {
|
||
if (child._baseState.tag === 'null_')
|
||
return child._encode(null, reporter, data);
|
||
|
||
if (child._baseState.key === null)
|
||
return reporter.error('Child should have a key');
|
||
var prevKey = reporter.enterKey(child._baseState.key);
|
||
|
||
if (typeof data !== 'object')
|
||
return reporter.error('Child expected, but input is not object');
|
||
|
||
var res = child._encode(data[child._baseState.key], reporter, data);
|
||
reporter.leaveKey(prevKey);
|
||
|
||
return res;
|
||
}, this).filter(function(child) {
|
||
return child;
|
||
});
|
||
content = this._createEncoderBuffer(content);
|
||
} else {
|
||
if (state.tag === 'seqof' || state.tag === 'setof') {
|
||
// TODO(indutny): this should be thrown on DSL level
|
||
if (!(state.args && state.args.length === 1))
|
||
return reporter.error('Too many args for : ' + state.tag);
|
||
|
||
if (!Array.isArray(data))
|
||
return reporter.error('seqof/setof, but data is not Array');
|
||
|
||
var child = this.clone();
|
||
child._baseState.implicit = null;
|
||
content = this._createEncoderBuffer(data.map(function(item) {
|
||
var state = this._baseState;
|
||
|
||
return this._getUse(state.args[0], data)._encode(item, reporter);
|
||
}, child));
|
||
} else if (state.use !== null) {
|
||
result = this._getUse(state.use, parent)._encode(data, reporter);
|
||
} else {
|
||
content = this._encodePrimitive(state.tag, data);
|
||
primitive = true;
|
||
}
|
||
}
|
||
|
||
// Encode data itself
|
||
var result;
|
||
if (!state.any && state.choice === null) {
|
||
var tag = state.implicit !== null ? state.implicit : state.tag;
|
||
var cls = state.implicit === null ? 'universal' : 'context';
|
||
|
||
if (tag === null) {
|
||
if (state.use === null)
|
||
reporter.error('Tag could be omitted only for .use()');
|
||
} else {
|
||
if (state.use === null)
|
||
result = this._encodeComposite(tag, primitive, cls, content);
|
||
}
|
||
}
|
||
|
||
// Wrap in explicit
|
||
if (state.explicit !== null)
|
||
result = this._encodeComposite(state.explicit, false, 'context', result);
|
||
|
||
return result;
|
||
};
|
||
|
||
Node.prototype._encodeChoice = function encodeChoice(data, reporter) {
|
||
var state = this._baseState;
|
||
|
||
var node = state.choice[data.type];
|
||
if (!node) {
|
||
assert(
|
||
false,
|
||
data.type + ' not found in ' +
|
||
JSON.stringify(Object.keys(state.choice)));
|
||
}
|
||
return node._encode(data.value, reporter);
|
||
};
|
||
|
||
Node.prototype._encodePrimitive = function encodePrimitive(tag, data) {
|
||
var state = this._baseState;
|
||
|
||
if (/str$/.test(tag))
|
||
return this._encodeStr(data, tag);
|
||
else if (tag === 'objid' && state.args)
|
||
return this._encodeObjid(data, state.reverseArgs[0], state.args[1]);
|
||
else if (tag === 'objid')
|
||
return this._encodeObjid(data, null, null);
|
||
else if (tag === 'gentime' || tag === 'utctime')
|
||
return this._encodeTime(data, tag);
|
||
else if (tag === 'null_')
|
||
return this._encodeNull();
|
||
else if (tag === 'int' || tag === 'enum')
|
||
return this._encodeInt(data, state.args && state.reverseArgs[0]);
|
||
else if (tag === 'bool')
|
||
return this._encodeBool(data);
|
||
else if (tag === 'objDesc')
|
||
return this._encodeStr(data, tag);
|
||
else
|
||
throw new Error('Unsupported tag: ' + tag);
|
||
};
|
||
|
||
Node.prototype._isNumstr = function isNumstr(str) {
|
||
return /^[0-9 ]*$/.test(str);
|
||
};
|
||
|
||
Node.prototype._isPrintstr = function isPrintstr(str) {
|
||
return /^[A-Za-z0-9 '\(\)\+,\-\.\/:=\?]*$/.test(str);
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/asn1.js/lib/asn1/base/reporter.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/asn1.js/lib/asn1/base/reporter.js ***!
|
||
\********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
|
||
function Reporter(options) {
|
||
this._reporterState = {
|
||
obj: null,
|
||
path: [],
|
||
options: options || {},
|
||
errors: []
|
||
};
|
||
}
|
||
exports.Reporter = Reporter;
|
||
|
||
Reporter.prototype.isError = function isError(obj) {
|
||
return obj instanceof ReporterError;
|
||
};
|
||
|
||
Reporter.prototype.save = function save() {
|
||
var state = this._reporterState;
|
||
|
||
return { obj: state.obj, pathLen: state.path.length };
|
||
};
|
||
|
||
Reporter.prototype.restore = function restore(data) {
|
||
var state = this._reporterState;
|
||
|
||
state.obj = data.obj;
|
||
state.path = state.path.slice(0, data.pathLen);
|
||
};
|
||
|
||
Reporter.prototype.enterKey = function enterKey(key) {
|
||
return this._reporterState.path.push(key);
|
||
};
|
||
|
||
Reporter.prototype.exitKey = function exitKey(index) {
|
||
var state = this._reporterState;
|
||
|
||
state.path = state.path.slice(0, index - 1);
|
||
};
|
||
|
||
Reporter.prototype.leaveKey = function leaveKey(index, key, value) {
|
||
var state = this._reporterState;
|
||
|
||
this.exitKey(index);
|
||
if (state.obj !== null)
|
||
state.obj[key] = value;
|
||
};
|
||
|
||
Reporter.prototype.path = function path() {
|
||
return this._reporterState.path.join('/');
|
||
};
|
||
|
||
Reporter.prototype.enterObject = function enterObject() {
|
||
var state = this._reporterState;
|
||
|
||
var prev = state.obj;
|
||
state.obj = {};
|
||
return prev;
|
||
};
|
||
|
||
Reporter.prototype.leaveObject = function leaveObject(prev) {
|
||
var state = this._reporterState;
|
||
|
||
var now = state.obj;
|
||
state.obj = prev;
|
||
return now;
|
||
};
|
||
|
||
Reporter.prototype.error = function error(msg) {
|
||
var err;
|
||
var state = this._reporterState;
|
||
|
||
var inherited = msg instanceof ReporterError;
|
||
if (inherited) {
|
||
err = msg;
|
||
} else {
|
||
err = new ReporterError(state.path.map(function(elem) {
|
||
return '[' + JSON.stringify(elem) + ']';
|
||
}).join(''), msg.message || msg, msg.stack);
|
||
}
|
||
|
||
if (!state.options.partial)
|
||
throw err;
|
||
|
||
if (!inherited)
|
||
state.errors.push(err);
|
||
|
||
return err;
|
||
};
|
||
|
||
Reporter.prototype.wrapResult = function wrapResult(result) {
|
||
var state = this._reporterState;
|
||
if (!state.options.partial)
|
||
return result;
|
||
|
||
return {
|
||
result: this.isError(result) ? null : result,
|
||
errors: state.errors
|
||
};
|
||
};
|
||
|
||
function ReporterError(path, msg) {
|
||
this.path = path;
|
||
this.rethrow(msg);
|
||
};
|
||
inherits(ReporterError, Error);
|
||
|
||
ReporterError.prototype.rethrow = function rethrow(msg) {
|
||
this.message = msg + ' at: ' + (this.path || '(shallow)');
|
||
if (Error.captureStackTrace)
|
||
Error.captureStackTrace(this, ReporterError);
|
||
|
||
if (!this.stack) {
|
||
try {
|
||
// IE only adds stack when thrown
|
||
throw new Error(this.message);
|
||
} catch (e) {
|
||
this.stack = e.stack;
|
||
}
|
||
}
|
||
return this;
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/asn1.js/lib/asn1/constants/der.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/asn1.js/lib/asn1/constants/der.js ***!
|
||
\********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var constants = __webpack_require__(/*! ../constants */ "./node_modules/asn1.js/lib/asn1/constants/index.js");
|
||
|
||
exports.tagClass = {
|
||
0: 'universal',
|
||
1: 'application',
|
||
2: 'context',
|
||
3: 'private'
|
||
};
|
||
exports.tagClassByName = constants._reverse(exports.tagClass);
|
||
|
||
exports.tag = {
|
||
0x00: 'end',
|
||
0x01: 'bool',
|
||
0x02: 'int',
|
||
0x03: 'bitstr',
|
||
0x04: 'octstr',
|
||
0x05: 'null_',
|
||
0x06: 'objid',
|
||
0x07: 'objDesc',
|
||
0x08: 'external',
|
||
0x09: 'real',
|
||
0x0a: 'enum',
|
||
0x0b: 'embed',
|
||
0x0c: 'utf8str',
|
||
0x0d: 'relativeOid',
|
||
0x10: 'seq',
|
||
0x11: 'set',
|
||
0x12: 'numstr',
|
||
0x13: 'printstr',
|
||
0x14: 't61str',
|
||
0x15: 'videostr',
|
||
0x16: 'ia5str',
|
||
0x17: 'utctime',
|
||
0x18: 'gentime',
|
||
0x19: 'graphstr',
|
||
0x1a: 'iso646str',
|
||
0x1b: 'genstr',
|
||
0x1c: 'unistr',
|
||
0x1d: 'charstr',
|
||
0x1e: 'bmpstr'
|
||
};
|
||
exports.tagByName = constants._reverse(exports.tag);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/asn1.js/lib/asn1/constants/index.js":
|
||
/*!**********************************************************!*\
|
||
!*** ./node_modules/asn1.js/lib/asn1/constants/index.js ***!
|
||
\**********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var constants = exports;
|
||
|
||
// Helper
|
||
constants._reverse = function reverse(map) {
|
||
var res = {};
|
||
|
||
Object.keys(map).forEach(function(key) {
|
||
// Convert key to integer if it is stringified
|
||
if ((key | 0) == key)
|
||
key = key | 0;
|
||
|
||
var value = map[key];
|
||
res[value] = key;
|
||
});
|
||
|
||
return res;
|
||
};
|
||
|
||
constants.der = __webpack_require__(/*! ./der */ "./node_modules/asn1.js/lib/asn1/constants/der.js");
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/asn1.js/lib/asn1/decoders/der.js":
|
||
/*!*******************************************************!*\
|
||
!*** ./node_modules/asn1.js/lib/asn1/decoders/der.js ***!
|
||
\*******************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
|
||
var asn1 = __webpack_require__(/*! ../../asn1 */ "./node_modules/asn1.js/lib/asn1.js");
|
||
var base = asn1.base;
|
||
var bignum = asn1.bignum;
|
||
|
||
// Import DER constants
|
||
var der = asn1.constants.der;
|
||
|
||
function DERDecoder(entity) {
|
||
this.enc = 'der';
|
||
this.name = entity.name;
|
||
this.entity = entity;
|
||
|
||
// Construct base tree
|
||
this.tree = new DERNode();
|
||
this.tree._init(entity.body);
|
||
};
|
||
module.exports = DERDecoder;
|
||
|
||
DERDecoder.prototype.decode = function decode(data, options) {
|
||
if (!(data instanceof base.DecoderBuffer))
|
||
data = new base.DecoderBuffer(data, options);
|
||
|
||
return this.tree._decode(data, options);
|
||
};
|
||
|
||
// Tree methods
|
||
|
||
function DERNode(parent) {
|
||
base.Node.call(this, 'der', parent);
|
||
}
|
||
inherits(DERNode, base.Node);
|
||
|
||
DERNode.prototype._peekTag = function peekTag(buffer, tag, any) {
|
||
if (buffer.isEmpty())
|
||
return false;
|
||
|
||
var state = buffer.save();
|
||
var decodedTag = derDecodeTag(buffer, 'Failed to peek tag: "' + tag + '"');
|
||
if (buffer.isError(decodedTag))
|
||
return decodedTag;
|
||
|
||
buffer.restore(state);
|
||
|
||
return decodedTag.tag === tag || decodedTag.tagStr === tag ||
|
||
(decodedTag.tagStr + 'of') === tag || any;
|
||
};
|
||
|
||
DERNode.prototype._decodeTag = function decodeTag(buffer, tag, any) {
|
||
var decodedTag = derDecodeTag(buffer,
|
||
'Failed to decode tag of "' + tag + '"');
|
||
if (buffer.isError(decodedTag))
|
||
return decodedTag;
|
||
|
||
var len = derDecodeLen(buffer,
|
||
decodedTag.primitive,
|
||
'Failed to get length of "' + tag + '"');
|
||
|
||
// Failure
|
||
if (buffer.isError(len))
|
||
return len;
|
||
|
||
if (!any &&
|
||
decodedTag.tag !== tag &&
|
||
decodedTag.tagStr !== tag &&
|
||
decodedTag.tagStr + 'of' !== tag) {
|
||
return buffer.error('Failed to match tag: "' + tag + '"');
|
||
}
|
||
|
||
if (decodedTag.primitive || len !== null)
|
||
return buffer.skip(len, 'Failed to match body of: "' + tag + '"');
|
||
|
||
// Indefinite length... find END tag
|
||
var state = buffer.save();
|
||
var res = this._skipUntilEnd(
|
||
buffer,
|
||
'Failed to skip indefinite length body: "' + this.tag + '"');
|
||
if (buffer.isError(res))
|
||
return res;
|
||
|
||
len = buffer.offset - state.offset;
|
||
buffer.restore(state);
|
||
return buffer.skip(len, 'Failed to match body of: "' + tag + '"');
|
||
};
|
||
|
||
DERNode.prototype._skipUntilEnd = function skipUntilEnd(buffer, fail) {
|
||
while (true) {
|
||
var tag = derDecodeTag(buffer, fail);
|
||
if (buffer.isError(tag))
|
||
return tag;
|
||
var len = derDecodeLen(buffer, tag.primitive, fail);
|
||
if (buffer.isError(len))
|
||
return len;
|
||
|
||
var res;
|
||
if (tag.primitive || len !== null)
|
||
res = buffer.skip(len)
|
||
else
|
||
res = this._skipUntilEnd(buffer, fail);
|
||
|
||
// Failure
|
||
if (buffer.isError(res))
|
||
return res;
|
||
|
||
if (tag.tagStr === 'end')
|
||
break;
|
||
}
|
||
};
|
||
|
||
DERNode.prototype._decodeList = function decodeList(buffer, tag, decoder,
|
||
options) {
|
||
var result = [];
|
||
while (!buffer.isEmpty()) {
|
||
var possibleEnd = this._peekTag(buffer, 'end');
|
||
if (buffer.isError(possibleEnd))
|
||
return possibleEnd;
|
||
|
||
var res = decoder.decode(buffer, 'der', options);
|
||
if (buffer.isError(res) && possibleEnd)
|
||
break;
|
||
result.push(res);
|
||
}
|
||
return result;
|
||
};
|
||
|
||
DERNode.prototype._decodeStr = function decodeStr(buffer, tag) {
|
||
if (tag === 'bitstr') {
|
||
var unused = buffer.readUInt8();
|
||
if (buffer.isError(unused))
|
||
return unused;
|
||
return { unused: unused, data: buffer.raw() };
|
||
} else if (tag === 'bmpstr') {
|
||
var raw = buffer.raw();
|
||
if (raw.length % 2 === 1)
|
||
return buffer.error('Decoding of string type: bmpstr length mismatch');
|
||
|
||
var str = '';
|
||
for (var i = 0; i < raw.length / 2; i++) {
|
||
str += String.fromCharCode(raw.readUInt16BE(i * 2));
|
||
}
|
||
return str;
|
||
} else if (tag === 'numstr') {
|
||
var numstr = buffer.raw().toString('ascii');
|
||
if (!this._isNumstr(numstr)) {
|
||
return buffer.error('Decoding of string type: ' +
|
||
'numstr unsupported characters');
|
||
}
|
||
return numstr;
|
||
} else if (tag === 'octstr') {
|
||
return buffer.raw();
|
||
} else if (tag === 'objDesc') {
|
||
return buffer.raw();
|
||
} else if (tag === 'printstr') {
|
||
var printstr = buffer.raw().toString('ascii');
|
||
if (!this._isPrintstr(printstr)) {
|
||
return buffer.error('Decoding of string type: ' +
|
||
'printstr unsupported characters');
|
||
}
|
||
return printstr;
|
||
} else if (/str$/.test(tag)) {
|
||
return buffer.raw().toString();
|
||
} else {
|
||
return buffer.error('Decoding of string type: ' + tag + ' unsupported');
|
||
}
|
||
};
|
||
|
||
DERNode.prototype._decodeObjid = function decodeObjid(buffer, values, relative) {
|
||
var result;
|
||
var identifiers = [];
|
||
var ident = 0;
|
||
while (!buffer.isEmpty()) {
|
||
var subident = buffer.readUInt8();
|
||
ident <<= 7;
|
||
ident |= subident & 0x7f;
|
||
if ((subident & 0x80) === 0) {
|
||
identifiers.push(ident);
|
||
ident = 0;
|
||
}
|
||
}
|
||
if (subident & 0x80)
|
||
identifiers.push(ident);
|
||
|
||
var first = (identifiers[0] / 40) | 0;
|
||
var second = identifiers[0] % 40;
|
||
|
||
if (relative)
|
||
result = identifiers;
|
||
else
|
||
result = [first, second].concat(identifiers.slice(1));
|
||
|
||
if (values) {
|
||
var tmp = values[result.join(' ')];
|
||
if (tmp === undefined)
|
||
tmp = values[result.join('.')];
|
||
if (tmp !== undefined)
|
||
result = tmp;
|
||
}
|
||
|
||
return result;
|
||
};
|
||
|
||
DERNode.prototype._decodeTime = function decodeTime(buffer, tag) {
|
||
var str = buffer.raw().toString();
|
||
if (tag === 'gentime') {
|
||
var year = str.slice(0, 4) | 0;
|
||
var mon = str.slice(4, 6) | 0;
|
||
var day = str.slice(6, 8) | 0;
|
||
var hour = str.slice(8, 10) | 0;
|
||
var min = str.slice(10, 12) | 0;
|
||
var sec = str.slice(12, 14) | 0;
|
||
} else if (tag === 'utctime') {
|
||
var year = str.slice(0, 2) | 0;
|
||
var mon = str.slice(2, 4) | 0;
|
||
var day = str.slice(4, 6) | 0;
|
||
var hour = str.slice(6, 8) | 0;
|
||
var min = str.slice(8, 10) | 0;
|
||
var sec = str.slice(10, 12) | 0;
|
||
if (year < 70)
|
||
year = 2000 + year;
|
||
else
|
||
year = 1900 + year;
|
||
} else {
|
||
return buffer.error('Decoding ' + tag + ' time is not supported yet');
|
||
}
|
||
|
||
return Date.UTC(year, mon - 1, day, hour, min, sec, 0);
|
||
};
|
||
|
||
DERNode.prototype._decodeNull = function decodeNull(buffer) {
|
||
return null;
|
||
};
|
||
|
||
DERNode.prototype._decodeBool = function decodeBool(buffer) {
|
||
var res = buffer.readUInt8();
|
||
if (buffer.isError(res))
|
||
return res;
|
||
else
|
||
return res !== 0;
|
||
};
|
||
|
||
DERNode.prototype._decodeInt = function decodeInt(buffer, values) {
|
||
// Bigint, return as it is (assume big endian)
|
||
var raw = buffer.raw();
|
||
var res = new bignum(raw);
|
||
|
||
if (values)
|
||
res = values[res.toString(10)] || res;
|
||
|
||
return res;
|
||
};
|
||
|
||
DERNode.prototype._use = function use(entity, obj) {
|
||
if (typeof entity === 'function')
|
||
entity = entity(obj);
|
||
return entity._getDecoder('der').tree;
|
||
};
|
||
|
||
// Utility methods
|
||
|
||
function derDecodeTag(buf, fail) {
|
||
var tag = buf.readUInt8(fail);
|
||
if (buf.isError(tag))
|
||
return tag;
|
||
|
||
var cls = der.tagClass[tag >> 6];
|
||
var primitive = (tag & 0x20) === 0;
|
||
|
||
// Multi-octet tag - load
|
||
if ((tag & 0x1f) === 0x1f) {
|
||
var oct = tag;
|
||
tag = 0;
|
||
while ((oct & 0x80) === 0x80) {
|
||
oct = buf.readUInt8(fail);
|
||
if (buf.isError(oct))
|
||
return oct;
|
||
|
||
tag <<= 7;
|
||
tag |= oct & 0x7f;
|
||
}
|
||
} else {
|
||
tag &= 0x1f;
|
||
}
|
||
var tagStr = der.tag[tag];
|
||
|
||
return {
|
||
cls: cls,
|
||
primitive: primitive,
|
||
tag: tag,
|
||
tagStr: tagStr
|
||
};
|
||
}
|
||
|
||
function derDecodeLen(buf, primitive, fail) {
|
||
var len = buf.readUInt8(fail);
|
||
if (buf.isError(len))
|
||
return len;
|
||
|
||
// Indefinite form
|
||
if (!primitive && len === 0x80)
|
||
return null;
|
||
|
||
// Definite form
|
||
if ((len & 0x80) === 0) {
|
||
// Short form
|
||
return len;
|
||
}
|
||
|
||
// Long form
|
||
var num = len & 0x7f;
|
||
if (num > 4)
|
||
return buf.error('length octect is too long');
|
||
|
||
len = 0;
|
||
for (var i = 0; i < num; i++) {
|
||
len <<= 8;
|
||
var j = buf.readUInt8(fail);
|
||
if (buf.isError(j))
|
||
return j;
|
||
len |= j;
|
||
}
|
||
|
||
return len;
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/asn1.js/lib/asn1/decoders/index.js":
|
||
/*!*********************************************************!*\
|
||
!*** ./node_modules/asn1.js/lib/asn1/decoders/index.js ***!
|
||
\*********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var decoders = exports;
|
||
|
||
decoders.der = __webpack_require__(/*! ./der */ "./node_modules/asn1.js/lib/asn1/decoders/der.js");
|
||
decoders.pem = __webpack_require__(/*! ./pem */ "./node_modules/asn1.js/lib/asn1/decoders/pem.js");
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/asn1.js/lib/asn1/decoders/pem.js":
|
||
/*!*******************************************************!*\
|
||
!*** ./node_modules/asn1.js/lib/asn1/decoders/pem.js ***!
|
||
\*******************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
var Buffer = __webpack_require__(/*! buffer */ "./node_modules/buffer/index.js").Buffer;
|
||
|
||
var DERDecoder = __webpack_require__(/*! ./der */ "./node_modules/asn1.js/lib/asn1/decoders/der.js");
|
||
|
||
function PEMDecoder(entity) {
|
||
DERDecoder.call(this, entity);
|
||
this.enc = 'pem';
|
||
};
|
||
inherits(PEMDecoder, DERDecoder);
|
||
module.exports = PEMDecoder;
|
||
|
||
PEMDecoder.prototype.decode = function decode(data, options) {
|
||
var lines = data.toString().split(/[\r\n]+/g);
|
||
|
||
var label = options.label.toUpperCase();
|
||
|
||
var re = /^-----(BEGIN|END) ([^-]+)-----$/;
|
||
var start = -1;
|
||
var end = -1;
|
||
for (var i = 0; i < lines.length; i++) {
|
||
var match = lines[i].match(re);
|
||
if (match === null)
|
||
continue;
|
||
|
||
if (match[2] !== label)
|
||
continue;
|
||
|
||
if (start === -1) {
|
||
if (match[1] !== 'BEGIN')
|
||
break;
|
||
start = i;
|
||
} else {
|
||
if (match[1] !== 'END')
|
||
break;
|
||
end = i;
|
||
break;
|
||
}
|
||
}
|
||
if (start === -1 || end === -1)
|
||
throw new Error('PEM section not found for: ' + label);
|
||
|
||
var base64 = lines.slice(start + 1, end).join('');
|
||
// Remove excessive symbols
|
||
base64.replace(/[^a-z0-9\+\/=]+/gi, '');
|
||
|
||
var input = new Buffer(base64, 'base64');
|
||
return DERDecoder.prototype.decode.call(this, input, options);
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/asn1.js/lib/asn1/encoders/der.js":
|
||
/*!*******************************************************!*\
|
||
!*** ./node_modules/asn1.js/lib/asn1/encoders/der.js ***!
|
||
\*******************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
var Buffer = __webpack_require__(/*! buffer */ "./node_modules/buffer/index.js").Buffer;
|
||
|
||
var asn1 = __webpack_require__(/*! ../../asn1 */ "./node_modules/asn1.js/lib/asn1.js");
|
||
var base = asn1.base;
|
||
|
||
// Import DER constants
|
||
var der = asn1.constants.der;
|
||
|
||
function DEREncoder(entity) {
|
||
this.enc = 'der';
|
||
this.name = entity.name;
|
||
this.entity = entity;
|
||
|
||
// Construct base tree
|
||
this.tree = new DERNode();
|
||
this.tree._init(entity.body);
|
||
};
|
||
module.exports = DEREncoder;
|
||
|
||
DEREncoder.prototype.encode = function encode(data, reporter) {
|
||
return this.tree._encode(data, reporter).join();
|
||
};
|
||
|
||
// Tree methods
|
||
|
||
function DERNode(parent) {
|
||
base.Node.call(this, 'der', parent);
|
||
}
|
||
inherits(DERNode, base.Node);
|
||
|
||
DERNode.prototype._encodeComposite = function encodeComposite(tag,
|
||
primitive,
|
||
cls,
|
||
content) {
|
||
var encodedTag = encodeTag(tag, primitive, cls, this.reporter);
|
||
|
||
// Short form
|
||
if (content.length < 0x80) {
|
||
var header = new Buffer(2);
|
||
header[0] = encodedTag;
|
||
header[1] = content.length;
|
||
return this._createEncoderBuffer([ header, content ]);
|
||
}
|
||
|
||
// Long form
|
||
// Count octets required to store length
|
||
var lenOctets = 1;
|
||
for (var i = content.length; i >= 0x100; i >>= 8)
|
||
lenOctets++;
|
||
|
||
var header = new Buffer(1 + 1 + lenOctets);
|
||
header[0] = encodedTag;
|
||
header[1] = 0x80 | lenOctets;
|
||
|
||
for (var i = 1 + lenOctets, j = content.length; j > 0; i--, j >>= 8)
|
||
header[i] = j & 0xff;
|
||
|
||
return this._createEncoderBuffer([ header, content ]);
|
||
};
|
||
|
||
DERNode.prototype._encodeStr = function encodeStr(str, tag) {
|
||
if (tag === 'bitstr') {
|
||
return this._createEncoderBuffer([ str.unused | 0, str.data ]);
|
||
} else if (tag === 'bmpstr') {
|
||
var buf = new Buffer(str.length * 2);
|
||
for (var i = 0; i < str.length; i++) {
|
||
buf.writeUInt16BE(str.charCodeAt(i), i * 2);
|
||
}
|
||
return this._createEncoderBuffer(buf);
|
||
} else if (tag === 'numstr') {
|
||
if (!this._isNumstr(str)) {
|
||
return this.reporter.error('Encoding of string type: numstr supports ' +
|
||
'only digits and space');
|
||
}
|
||
return this._createEncoderBuffer(str);
|
||
} else if (tag === 'printstr') {
|
||
if (!this._isPrintstr(str)) {
|
||
return this.reporter.error('Encoding of string type: printstr supports ' +
|
||
'only latin upper and lower case letters, ' +
|
||
'digits, space, apostrophe, left and rigth ' +
|
||
'parenthesis, plus sign, comma, hyphen, ' +
|
||
'dot, slash, colon, equal sign, ' +
|
||
'question mark');
|
||
}
|
||
return this._createEncoderBuffer(str);
|
||
} else if (/str$/.test(tag)) {
|
||
return this._createEncoderBuffer(str);
|
||
} else if (tag === 'objDesc') {
|
||
return this._createEncoderBuffer(str);
|
||
} else {
|
||
return this.reporter.error('Encoding of string type: ' + tag +
|
||
' unsupported');
|
||
}
|
||
};
|
||
|
||
DERNode.prototype._encodeObjid = function encodeObjid(id, values, relative) {
|
||
if (typeof id === 'string') {
|
||
if (!values)
|
||
return this.reporter.error('string objid given, but no values map found');
|
||
if (!values.hasOwnProperty(id))
|
||
return this.reporter.error('objid not found in values map');
|
||
id = values[id].split(/[\s\.]+/g);
|
||
for (var i = 0; i < id.length; i++)
|
||
id[i] |= 0;
|
||
} else if (Array.isArray(id)) {
|
||
id = id.slice();
|
||
for (var i = 0; i < id.length; i++)
|
||
id[i] |= 0;
|
||
}
|
||
|
||
if (!Array.isArray(id)) {
|
||
return this.reporter.error('objid() should be either array or string, ' +
|
||
'got: ' + JSON.stringify(id));
|
||
}
|
||
|
||
if (!relative) {
|
||
if (id[1] >= 40)
|
||
return this.reporter.error('Second objid identifier OOB');
|
||
id.splice(0, 2, id[0] * 40 + id[1]);
|
||
}
|
||
|
||
// Count number of octets
|
||
var size = 0;
|
||
for (var i = 0; i < id.length; i++) {
|
||
var ident = id[i];
|
||
for (size++; ident >= 0x80; ident >>= 7)
|
||
size++;
|
||
}
|
||
|
||
var objid = new Buffer(size);
|
||
var offset = objid.length - 1;
|
||
for (var i = id.length - 1; i >= 0; i--) {
|
||
var ident = id[i];
|
||
objid[offset--] = ident & 0x7f;
|
||
while ((ident >>= 7) > 0)
|
||
objid[offset--] = 0x80 | (ident & 0x7f);
|
||
}
|
||
|
||
return this._createEncoderBuffer(objid);
|
||
};
|
||
|
||
function two(num) {
|
||
if (num < 10)
|
||
return '0' + num;
|
||
else
|
||
return num;
|
||
}
|
||
|
||
DERNode.prototype._encodeTime = function encodeTime(time, tag) {
|
||
var str;
|
||
var date = new Date(time);
|
||
|
||
if (tag === 'gentime') {
|
||
str = [
|
||
two(date.getFullYear()),
|
||
two(date.getUTCMonth() + 1),
|
||
two(date.getUTCDate()),
|
||
two(date.getUTCHours()),
|
||
two(date.getUTCMinutes()),
|
||
two(date.getUTCSeconds()),
|
||
'Z'
|
||
].join('');
|
||
} else if (tag === 'utctime') {
|
||
str = [
|
||
two(date.getFullYear() % 100),
|
||
two(date.getUTCMonth() + 1),
|
||
two(date.getUTCDate()),
|
||
two(date.getUTCHours()),
|
||
two(date.getUTCMinutes()),
|
||
two(date.getUTCSeconds()),
|
||
'Z'
|
||
].join('');
|
||
} else {
|
||
this.reporter.error('Encoding ' + tag + ' time is not supported yet');
|
||
}
|
||
|
||
return this._encodeStr(str, 'octstr');
|
||
};
|
||
|
||
DERNode.prototype._encodeNull = function encodeNull() {
|
||
return this._createEncoderBuffer('');
|
||
};
|
||
|
||
DERNode.prototype._encodeInt = function encodeInt(num, values) {
|
||
if (typeof num === 'string') {
|
||
if (!values)
|
||
return this.reporter.error('String int or enum given, but no values map');
|
||
if (!values.hasOwnProperty(num)) {
|
||
return this.reporter.error('Values map doesn\'t contain: ' +
|
||
JSON.stringify(num));
|
||
}
|
||
num = values[num];
|
||
}
|
||
|
||
// Bignum, assume big endian
|
||
if (typeof num !== 'number' && !Buffer.isBuffer(num)) {
|
||
var numArray = num.toArray();
|
||
if (!num.sign && numArray[0] & 0x80) {
|
||
numArray.unshift(0);
|
||
}
|
||
num = new Buffer(numArray);
|
||
}
|
||
|
||
if (Buffer.isBuffer(num)) {
|
||
var size = num.length;
|
||
if (num.length === 0)
|
||
size++;
|
||
|
||
var out = new Buffer(size);
|
||
num.copy(out);
|
||
if (num.length === 0)
|
||
out[0] = 0
|
||
return this._createEncoderBuffer(out);
|
||
}
|
||
|
||
if (num < 0x80)
|
||
return this._createEncoderBuffer(num);
|
||
|
||
if (num < 0x100)
|
||
return this._createEncoderBuffer([0, num]);
|
||
|
||
var size = 1;
|
||
for (var i = num; i >= 0x100; i >>= 8)
|
||
size++;
|
||
|
||
var out = new Array(size);
|
||
for (var i = out.length - 1; i >= 0; i--) {
|
||
out[i] = num & 0xff;
|
||
num >>= 8;
|
||
}
|
||
if(out[0] & 0x80) {
|
||
out.unshift(0);
|
||
}
|
||
|
||
return this._createEncoderBuffer(new Buffer(out));
|
||
};
|
||
|
||
DERNode.prototype._encodeBool = function encodeBool(value) {
|
||
return this._createEncoderBuffer(value ? 0xff : 0);
|
||
};
|
||
|
||
DERNode.prototype._use = function use(entity, obj) {
|
||
if (typeof entity === 'function')
|
||
entity = entity(obj);
|
||
return entity._getEncoder('der').tree;
|
||
};
|
||
|
||
DERNode.prototype._skipDefault = function skipDefault(dataBuffer, reporter, parent) {
|
||
var state = this._baseState;
|
||
var i;
|
||
if (state['default'] === null)
|
||
return false;
|
||
|
||
var data = dataBuffer.join();
|
||
if (state.defaultBuffer === undefined)
|
||
state.defaultBuffer = this._encodeValue(state['default'], reporter, parent).join();
|
||
|
||
if (data.length !== state.defaultBuffer.length)
|
||
return false;
|
||
|
||
for (i=0; i < data.length; i++)
|
||
if (data[i] !== state.defaultBuffer[i])
|
||
return false;
|
||
|
||
return true;
|
||
};
|
||
|
||
// Utility methods
|
||
|
||
function encodeTag(tag, primitive, cls, reporter) {
|
||
var res;
|
||
|
||
if (tag === 'seqof')
|
||
tag = 'seq';
|
||
else if (tag === 'setof')
|
||
tag = 'set';
|
||
|
||
if (der.tagByName.hasOwnProperty(tag))
|
||
res = der.tagByName[tag];
|
||
else if (typeof tag === 'number' && (tag | 0) === tag)
|
||
res = tag;
|
||
else
|
||
return reporter.error('Unknown tag: ' + tag);
|
||
|
||
if (res >= 0x1f)
|
||
return reporter.error('Multi-octet tag encoding unsupported');
|
||
|
||
if (!primitive)
|
||
res |= 0x20;
|
||
|
||
res |= (der.tagClassByName[cls || 'universal'] << 6);
|
||
|
||
return res;
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/asn1.js/lib/asn1/encoders/index.js":
|
||
/*!*********************************************************!*\
|
||
!*** ./node_modules/asn1.js/lib/asn1/encoders/index.js ***!
|
||
\*********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var encoders = exports;
|
||
|
||
encoders.der = __webpack_require__(/*! ./der */ "./node_modules/asn1.js/lib/asn1/encoders/der.js");
|
||
encoders.pem = __webpack_require__(/*! ./pem */ "./node_modules/asn1.js/lib/asn1/encoders/pem.js");
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/asn1.js/lib/asn1/encoders/pem.js":
|
||
/*!*******************************************************!*\
|
||
!*** ./node_modules/asn1.js/lib/asn1/encoders/pem.js ***!
|
||
\*******************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
|
||
var DEREncoder = __webpack_require__(/*! ./der */ "./node_modules/asn1.js/lib/asn1/encoders/der.js");
|
||
|
||
function PEMEncoder(entity) {
|
||
DEREncoder.call(this, entity);
|
||
this.enc = 'pem';
|
||
};
|
||
inherits(PEMEncoder, DEREncoder);
|
||
module.exports = PEMEncoder;
|
||
|
||
PEMEncoder.prototype.encode = function encode(data, options) {
|
||
var buf = DEREncoder.prototype.encode.call(this, data);
|
||
|
||
var p = buf.toString('base64');
|
||
var out = [ '-----BEGIN ' + options.label + '-----' ];
|
||
for (var i = 0; i < p.length; i += 64)
|
||
out.push(p.slice(i, i + 64));
|
||
out.push('-----END ' + options.label + '-----');
|
||
return out.join('\n');
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/base64-js/index.js":
|
||
/*!*****************************************!*\
|
||
!*** ./node_modules/base64-js/index.js ***!
|
||
\*****************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
exports.byteLength = byteLength
|
||
exports.toByteArray = toByteArray
|
||
exports.fromByteArray = fromByteArray
|
||
|
||
var lookup = []
|
||
var revLookup = []
|
||
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
|
||
|
||
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||
for (var i = 0, len = code.length; i < len; ++i) {
|
||
lookup[i] = code[i]
|
||
revLookup[code.charCodeAt(i)] = i
|
||
}
|
||
|
||
// Support decoding URL-safe base64 strings, as Node.js does.
|
||
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
|
||
revLookup['-'.charCodeAt(0)] = 62
|
||
revLookup['_'.charCodeAt(0)] = 63
|
||
|
||
function getLens (b64) {
|
||
var len = b64.length
|
||
|
||
if (len % 4 > 0) {
|
||
throw new Error('Invalid string. Length must be a multiple of 4')
|
||
}
|
||
|
||
// Trim off extra bytes after placeholder bytes are found
|
||
// See: https://github.com/beatgammit/base64-js/issues/42
|
||
var validLen = b64.indexOf('=')
|
||
if (validLen === -1) validLen = len
|
||
|
||
var placeHoldersLen = validLen === len
|
||
? 0
|
||
: 4 - (validLen % 4)
|
||
|
||
return [validLen, placeHoldersLen]
|
||
}
|
||
|
||
// base64 is 4/3 + up to two characters of the original data
|
||
function byteLength (b64) {
|
||
var lens = getLens(b64)
|
||
var validLen = lens[0]
|
||
var placeHoldersLen = lens[1]
|
||
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
|
||
}
|
||
|
||
function _byteLength (b64, validLen, placeHoldersLen) {
|
||
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
|
||
}
|
||
|
||
function toByteArray (b64) {
|
||
var tmp
|
||
var lens = getLens(b64)
|
||
var validLen = lens[0]
|
||
var placeHoldersLen = lens[1]
|
||
|
||
var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
|
||
|
||
var curByte = 0
|
||
|
||
// if there are placeholders, only get up to the last complete 4 chars
|
||
var len = placeHoldersLen > 0
|
||
? validLen - 4
|
||
: validLen
|
||
|
||
var i
|
||
for (i = 0; i < len; i += 4) {
|
||
tmp =
|
||
(revLookup[b64.charCodeAt(i)] << 18) |
|
||
(revLookup[b64.charCodeAt(i + 1)] << 12) |
|
||
(revLookup[b64.charCodeAt(i + 2)] << 6) |
|
||
revLookup[b64.charCodeAt(i + 3)]
|
||
arr[curByte++] = (tmp >> 16) & 0xFF
|
||
arr[curByte++] = (tmp >> 8) & 0xFF
|
||
arr[curByte++] = tmp & 0xFF
|
||
}
|
||
|
||
if (placeHoldersLen === 2) {
|
||
tmp =
|
||
(revLookup[b64.charCodeAt(i)] << 2) |
|
||
(revLookup[b64.charCodeAt(i + 1)] >> 4)
|
||
arr[curByte++] = tmp & 0xFF
|
||
}
|
||
|
||
if (placeHoldersLen === 1) {
|
||
tmp =
|
||
(revLookup[b64.charCodeAt(i)] << 10) |
|
||
(revLookup[b64.charCodeAt(i + 1)] << 4) |
|
||
(revLookup[b64.charCodeAt(i + 2)] >> 2)
|
||
arr[curByte++] = (tmp >> 8) & 0xFF
|
||
arr[curByte++] = tmp & 0xFF
|
||
}
|
||
|
||
return arr
|
||
}
|
||
|
||
function tripletToBase64 (num) {
|
||
return lookup[num >> 18 & 0x3F] +
|
||
lookup[num >> 12 & 0x3F] +
|
||
lookup[num >> 6 & 0x3F] +
|
||
lookup[num & 0x3F]
|
||
}
|
||
|
||
function encodeChunk (uint8, start, end) {
|
||
var tmp
|
||
var output = []
|
||
for (var i = start; i < end; i += 3) {
|
||
tmp =
|
||
((uint8[i] << 16) & 0xFF0000) +
|
||
((uint8[i + 1] << 8) & 0xFF00) +
|
||
(uint8[i + 2] & 0xFF)
|
||
output.push(tripletToBase64(tmp))
|
||
}
|
||
return output.join('')
|
||
}
|
||
|
||
function fromByteArray (uint8) {
|
||
var tmp
|
||
var len = uint8.length
|
||
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
|
||
var parts = []
|
||
var maxChunkLength = 16383 // must be multiple of 3
|
||
|
||
// go through the array every three bytes, we'll deal with trailing stuff later
|
||
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
|
||
parts.push(encodeChunk(
|
||
uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)
|
||
))
|
||
}
|
||
|
||
// pad the end with zeros, but make sure to not forget the extra bytes
|
||
if (extraBytes === 1) {
|
||
tmp = uint8[len - 1]
|
||
parts.push(
|
||
lookup[tmp >> 2] +
|
||
lookup[(tmp << 4) & 0x3F] +
|
||
'=='
|
||
)
|
||
} else if (extraBytes === 2) {
|
||
tmp = (uint8[len - 2] << 8) + uint8[len - 1]
|
||
parts.push(
|
||
lookup[tmp >> 10] +
|
||
lookup[(tmp >> 4) & 0x3F] +
|
||
lookup[(tmp << 2) & 0x3F] +
|
||
'='
|
||
)
|
||
}
|
||
|
||
return parts.join('')
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/bn.js/lib/bn.js":
|
||
/*!**************************************!*\
|
||
!*** ./node_modules/bn.js/lib/bn.js ***!
|
||
\**************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(module) {(function (module, exports) {
|
||
'use strict';
|
||
|
||
// Utils
|
||
function assert (val, msg) {
|
||
if (!val) throw new Error(msg || 'Assertion failed');
|
||
}
|
||
|
||
// Could use `inherits` module, but don't want to move from single file
|
||
// architecture yet.
|
||
function inherits (ctor, superCtor) {
|
||
ctor.super_ = superCtor;
|
||
var TempCtor = function () {};
|
||
TempCtor.prototype = superCtor.prototype;
|
||
ctor.prototype = new TempCtor();
|
||
ctor.prototype.constructor = ctor;
|
||
}
|
||
|
||
// BN
|
||
|
||
function BN (number, base, endian) {
|
||
if (BN.isBN(number)) {
|
||
return number;
|
||
}
|
||
|
||
this.negative = 0;
|
||
this.words = null;
|
||
this.length = 0;
|
||
|
||
// Reduction context
|
||
this.red = null;
|
||
|
||
if (number !== null) {
|
||
if (base === 'le' || base === 'be') {
|
||
endian = base;
|
||
base = 10;
|
||
}
|
||
|
||
this._init(number || 0, base || 10, endian || 'be');
|
||
}
|
||
}
|
||
if (typeof module === 'object') {
|
||
module.exports = BN;
|
||
} else {
|
||
exports.BN = BN;
|
||
}
|
||
|
||
BN.BN = BN;
|
||
BN.wordSize = 26;
|
||
|
||
var Buffer;
|
||
try {
|
||
Buffer = __webpack_require__(/*! buffer */ 2).Buffer;
|
||
} catch (e) {
|
||
}
|
||
|
||
BN.isBN = function isBN (num) {
|
||
if (num instanceof BN) {
|
||
return true;
|
||
}
|
||
|
||
return num !== null && typeof num === 'object' &&
|
||
num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);
|
||
};
|
||
|
||
BN.max = function max (left, right) {
|
||
if (left.cmp(right) > 0) return left;
|
||
return right;
|
||
};
|
||
|
||
BN.min = function min (left, right) {
|
||
if (left.cmp(right) < 0) return left;
|
||
return right;
|
||
};
|
||
|
||
BN.prototype._init = function init (number, base, endian) {
|
||
if (typeof number === 'number') {
|
||
return this._initNumber(number, base, endian);
|
||
}
|
||
|
||
if (typeof number === 'object') {
|
||
return this._initArray(number, base, endian);
|
||
}
|
||
|
||
if (base === 'hex') {
|
||
base = 16;
|
||
}
|
||
assert(base === (base | 0) && base >= 2 && base <= 36);
|
||
|
||
number = number.toString().replace(/\s+/g, '');
|
||
var start = 0;
|
||
if (number[0] === '-') {
|
||
start++;
|
||
}
|
||
|
||
if (base === 16) {
|
||
this._parseHex(number, start);
|
||
} else {
|
||
this._parseBase(number, base, start);
|
||
}
|
||
|
||
if (number[0] === '-') {
|
||
this.negative = 1;
|
||
}
|
||
|
||
this.strip();
|
||
|
||
if (endian !== 'le') return;
|
||
|
||
this._initArray(this.toArray(), base, endian);
|
||
};
|
||
|
||
BN.prototype._initNumber = function _initNumber (number, base, endian) {
|
||
if (number < 0) {
|
||
this.negative = 1;
|
||
number = -number;
|
||
}
|
||
if (number < 0x4000000) {
|
||
this.words = [ number & 0x3ffffff ];
|
||
this.length = 1;
|
||
} else if (number < 0x10000000000000) {
|
||
this.words = [
|
||
number & 0x3ffffff,
|
||
(number / 0x4000000) & 0x3ffffff
|
||
];
|
||
this.length = 2;
|
||
} else {
|
||
assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
|
||
this.words = [
|
||
number & 0x3ffffff,
|
||
(number / 0x4000000) & 0x3ffffff,
|
||
1
|
||
];
|
||
this.length = 3;
|
||
}
|
||
|
||
if (endian !== 'le') return;
|
||
|
||
// Reverse the bytes
|
||
this._initArray(this.toArray(), base, endian);
|
||
};
|
||
|
||
BN.prototype._initArray = function _initArray (number, base, endian) {
|
||
// Perhaps a Uint8Array
|
||
assert(typeof number.length === 'number');
|
||
if (number.length <= 0) {
|
||
this.words = [ 0 ];
|
||
this.length = 1;
|
||
return this;
|
||
}
|
||
|
||
this.length = Math.ceil(number.length / 3);
|
||
this.words = new Array(this.length);
|
||
for (var i = 0; i < this.length; i++) {
|
||
this.words[i] = 0;
|
||
}
|
||
|
||
var j, w;
|
||
var off = 0;
|
||
if (endian === 'be') {
|
||
for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
|
||
w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
|
||
this.words[j] |= (w << off) & 0x3ffffff;
|
||
this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
|
||
off += 24;
|
||
if (off >= 26) {
|
||
off -= 26;
|
||
j++;
|
||
}
|
||
}
|
||
} else if (endian === 'le') {
|
||
for (i = 0, j = 0; i < number.length; i += 3) {
|
||
w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
|
||
this.words[j] |= (w << off) & 0x3ffffff;
|
||
this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
|
||
off += 24;
|
||
if (off >= 26) {
|
||
off -= 26;
|
||
j++;
|
||
}
|
||
}
|
||
}
|
||
return this.strip();
|
||
};
|
||
|
||
function parseHex (str, start, end) {
|
||
var r = 0;
|
||
var len = Math.min(str.length, end);
|
||
for (var i = start; i < len; i++) {
|
||
var c = str.charCodeAt(i) - 48;
|
||
|
||
r <<= 4;
|
||
|
||
// 'a' - 'f'
|
||
if (c >= 49 && c <= 54) {
|
||
r |= c - 49 + 0xa;
|
||
|
||
// 'A' - 'F'
|
||
} else if (c >= 17 && c <= 22) {
|
||
r |= c - 17 + 0xa;
|
||
|
||
// '0' - '9'
|
||
} else {
|
||
r |= c & 0xf;
|
||
}
|
||
}
|
||
return r;
|
||
}
|
||
|
||
BN.prototype._parseHex = function _parseHex (number, start) {
|
||
// Create possibly bigger array to ensure that it fits the number
|
||
this.length = Math.ceil((number.length - start) / 6);
|
||
this.words = new Array(this.length);
|
||
for (var i = 0; i < this.length; i++) {
|
||
this.words[i] = 0;
|
||
}
|
||
|
||
var j, w;
|
||
// Scan 24-bit chunks and add them to the number
|
||
var off = 0;
|
||
for (i = number.length - 6, j = 0; i >= start; i -= 6) {
|
||
w = parseHex(number, i, i + 6);
|
||
this.words[j] |= (w << off) & 0x3ffffff;
|
||
// NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb
|
||
this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
|
||
off += 24;
|
||
if (off >= 26) {
|
||
off -= 26;
|
||
j++;
|
||
}
|
||
}
|
||
if (i + 6 !== start) {
|
||
w = parseHex(number, start, i + 6);
|
||
this.words[j] |= (w << off) & 0x3ffffff;
|
||
this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
|
||
}
|
||
this.strip();
|
||
};
|
||
|
||
function parseBase (str, start, end, mul) {
|
||
var r = 0;
|
||
var len = Math.min(str.length, end);
|
||
for (var i = start; i < len; i++) {
|
||
var c = str.charCodeAt(i) - 48;
|
||
|
||
r *= mul;
|
||
|
||
// 'a'
|
||
if (c >= 49) {
|
||
r += c - 49 + 0xa;
|
||
|
||
// 'A'
|
||
} else if (c >= 17) {
|
||
r += c - 17 + 0xa;
|
||
|
||
// '0' - '9'
|
||
} else {
|
||
r += c;
|
||
}
|
||
}
|
||
return r;
|
||
}
|
||
|
||
BN.prototype._parseBase = function _parseBase (number, base, start) {
|
||
// Initialize as zero
|
||
this.words = [ 0 ];
|
||
this.length = 1;
|
||
|
||
// Find length of limb in base
|
||
for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) {
|
||
limbLen++;
|
||
}
|
||
limbLen--;
|
||
limbPow = (limbPow / base) | 0;
|
||
|
||
var total = number.length - start;
|
||
var mod = total % limbLen;
|
||
var end = Math.min(total, total - mod) + start;
|
||
|
||
var word = 0;
|
||
for (var i = start; i < end; i += limbLen) {
|
||
word = parseBase(number, i, i + limbLen, base);
|
||
|
||
this.imuln(limbPow);
|
||
if (this.words[0] + word < 0x4000000) {
|
||
this.words[0] += word;
|
||
} else {
|
||
this._iaddn(word);
|
||
}
|
||
}
|
||
|
||
if (mod !== 0) {
|
||
var pow = 1;
|
||
word = parseBase(number, i, number.length, base);
|
||
|
||
for (i = 0; i < mod; i++) {
|
||
pow *= base;
|
||
}
|
||
|
||
this.imuln(pow);
|
||
if (this.words[0] + word < 0x4000000) {
|
||
this.words[0] += word;
|
||
} else {
|
||
this._iaddn(word);
|
||
}
|
||
}
|
||
};
|
||
|
||
BN.prototype.copy = function copy (dest) {
|
||
dest.words = new Array(this.length);
|
||
for (var i = 0; i < this.length; i++) {
|
||
dest.words[i] = this.words[i];
|
||
}
|
||
dest.length = this.length;
|
||
dest.negative = this.negative;
|
||
dest.red = this.red;
|
||
};
|
||
|
||
BN.prototype.clone = function clone () {
|
||
var r = new BN(null);
|
||
this.copy(r);
|
||
return r;
|
||
};
|
||
|
||
BN.prototype._expand = function _expand (size) {
|
||
while (this.length < size) {
|
||
this.words[this.length++] = 0;
|
||
}
|
||
return this;
|
||
};
|
||
|
||
// Remove leading `0` from `this`
|
||
BN.prototype.strip = function strip () {
|
||
while (this.length > 1 && this.words[this.length - 1] === 0) {
|
||
this.length--;
|
||
}
|
||
return this._normSign();
|
||
};
|
||
|
||
BN.prototype._normSign = function _normSign () {
|
||
// -0 = 0
|
||
if (this.length === 1 && this.words[0] === 0) {
|
||
this.negative = 0;
|
||
}
|
||
return this;
|
||
};
|
||
|
||
BN.prototype.inspect = function inspect () {
|
||
return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
|
||
};
|
||
|
||
/*
|
||
|
||
var zeros = [];
|
||
var groupSizes = [];
|
||
var groupBases = [];
|
||
|
||
var s = '';
|
||
var i = -1;
|
||
while (++i < BN.wordSize) {
|
||
zeros[i] = s;
|
||
s += '0';
|
||
}
|
||
groupSizes[0] = 0;
|
||
groupSizes[1] = 0;
|
||
groupBases[0] = 0;
|
||
groupBases[1] = 0;
|
||
var base = 2 - 1;
|
||
while (++base < 36 + 1) {
|
||
var groupSize = 0;
|
||
var groupBase = 1;
|
||
while (groupBase < (1 << BN.wordSize) / base) {
|
||
groupBase *= base;
|
||
groupSize += 1;
|
||
}
|
||
groupSizes[base] = groupSize;
|
||
groupBases[base] = groupBase;
|
||
}
|
||
|
||
*/
|
||
|
||
var zeros = [
|
||
'',
|
||
'0',
|
||
'00',
|
||
'000',
|
||
'0000',
|
||
'00000',
|
||
'000000',
|
||
'0000000',
|
||
'00000000',
|
||
'000000000',
|
||
'0000000000',
|
||
'00000000000',
|
||
'000000000000',
|
||
'0000000000000',
|
||
'00000000000000',
|
||
'000000000000000',
|
||
'0000000000000000',
|
||
'00000000000000000',
|
||
'000000000000000000',
|
||
'0000000000000000000',
|
||
'00000000000000000000',
|
||
'000000000000000000000',
|
||
'0000000000000000000000',
|
||
'00000000000000000000000',
|
||
'000000000000000000000000',
|
||
'0000000000000000000000000'
|
||
];
|
||
|
||
var groupSizes = [
|
||
0, 0,
|
||
25, 16, 12, 11, 10, 9, 8,
|
||
8, 7, 7, 7, 7, 6, 6,
|
||
6, 6, 6, 6, 6, 5, 5,
|
||
5, 5, 5, 5, 5, 5, 5,
|
||
5, 5, 5, 5, 5, 5, 5
|
||
];
|
||
|
||
var groupBases = [
|
||
0, 0,
|
||
33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
|
||
43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
|
||
16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
|
||
6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
|
||
24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
|
||
];
|
||
|
||
BN.prototype.toString = function toString (base, padding) {
|
||
base = base || 10;
|
||
padding = padding | 0 || 1;
|
||
|
||
var out;
|
||
if (base === 16 || base === 'hex') {
|
||
out = '';
|
||
var off = 0;
|
||
var carry = 0;
|
||
for (var i = 0; i < this.length; i++) {
|
||
var w = this.words[i];
|
||
var word = (((w << off) | carry) & 0xffffff).toString(16);
|
||
carry = (w >>> (24 - off)) & 0xffffff;
|
||
if (carry !== 0 || i !== this.length - 1) {
|
||
out = zeros[6 - word.length] + word + out;
|
||
} else {
|
||
out = word + out;
|
||
}
|
||
off += 2;
|
||
if (off >= 26) {
|
||
off -= 26;
|
||
i--;
|
||
}
|
||
}
|
||
if (carry !== 0) {
|
||
out = carry.toString(16) + out;
|
||
}
|
||
while (out.length % padding !== 0) {
|
||
out = '0' + out;
|
||
}
|
||
if (this.negative !== 0) {
|
||
out = '-' + out;
|
||
}
|
||
return out;
|
||
}
|
||
|
||
if (base === (base | 0) && base >= 2 && base <= 36) {
|
||
// var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
|
||
var groupSize = groupSizes[base];
|
||
// var groupBase = Math.pow(base, groupSize);
|
||
var groupBase = groupBases[base];
|
||
out = '';
|
||
var c = this.clone();
|
||
c.negative = 0;
|
||
while (!c.isZero()) {
|
||
var r = c.modn(groupBase).toString(base);
|
||
c = c.idivn(groupBase);
|
||
|
||
if (!c.isZero()) {
|
||
out = zeros[groupSize - r.length] + r + out;
|
||
} else {
|
||
out = r + out;
|
||
}
|
||
}
|
||
if (this.isZero()) {
|
||
out = '0' + out;
|
||
}
|
||
while (out.length % padding !== 0) {
|
||
out = '0' + out;
|
||
}
|
||
if (this.negative !== 0) {
|
||
out = '-' + out;
|
||
}
|
||
return out;
|
||
}
|
||
|
||
assert(false, 'Base should be between 2 and 36');
|
||
};
|
||
|
||
BN.prototype.toNumber = function toNumber () {
|
||
var ret = this.words[0];
|
||
if (this.length === 2) {
|
||
ret += this.words[1] * 0x4000000;
|
||
} else if (this.length === 3 && this.words[2] === 0x01) {
|
||
// NOTE: at this stage it is known that the top bit is set
|
||
ret += 0x10000000000000 + (this.words[1] * 0x4000000);
|
||
} else if (this.length > 2) {
|
||
assert(false, 'Number can only safely store up to 53 bits');
|
||
}
|
||
return (this.negative !== 0) ? -ret : ret;
|
||
};
|
||
|
||
BN.prototype.toJSON = function toJSON () {
|
||
return this.toString(16);
|
||
};
|
||
|
||
BN.prototype.toBuffer = function toBuffer (endian, length) {
|
||
assert(typeof Buffer !== 'undefined');
|
||
return this.toArrayLike(Buffer, endian, length);
|
||
};
|
||
|
||
BN.prototype.toArray = function toArray (endian, length) {
|
||
return this.toArrayLike(Array, endian, length);
|
||
};
|
||
|
||
BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {
|
||
var byteLength = this.byteLength();
|
||
var reqLength = length || Math.max(1, byteLength);
|
||
assert(byteLength <= reqLength, 'byte array longer than desired length');
|
||
assert(reqLength > 0, 'Requested array length <= 0');
|
||
|
||
this.strip();
|
||
var littleEndian = endian === 'le';
|
||
var res = new ArrayType(reqLength);
|
||
|
||
var b, i;
|
||
var q = this.clone();
|
||
if (!littleEndian) {
|
||
// Assume big-endian
|
||
for (i = 0; i < reqLength - byteLength; i++) {
|
||
res[i] = 0;
|
||
}
|
||
|
||
for (i = 0; !q.isZero(); i++) {
|
||
b = q.andln(0xff);
|
||
q.iushrn(8);
|
||
|
||
res[reqLength - i - 1] = b;
|
||
}
|
||
} else {
|
||
for (i = 0; !q.isZero(); i++) {
|
||
b = q.andln(0xff);
|
||
q.iushrn(8);
|
||
|
||
res[i] = b;
|
||
}
|
||
|
||
for (; i < reqLength; i++) {
|
||
res[i] = 0;
|
||
}
|
||
}
|
||
|
||
return res;
|
||
};
|
||
|
||
if (Math.clz32) {
|
||
BN.prototype._countBits = function _countBits (w) {
|
||
return 32 - Math.clz32(w);
|
||
};
|
||
} else {
|
||
BN.prototype._countBits = function _countBits (w) {
|
||
var t = w;
|
||
var r = 0;
|
||
if (t >= 0x1000) {
|
||
r += 13;
|
||
t >>>= 13;
|
||
}
|
||
if (t >= 0x40) {
|
||
r += 7;
|
||
t >>>= 7;
|
||
}
|
||
if (t >= 0x8) {
|
||
r += 4;
|
||
t >>>= 4;
|
||
}
|
||
if (t >= 0x02) {
|
||
r += 2;
|
||
t >>>= 2;
|
||
}
|
||
return r + t;
|
||
};
|
||
}
|
||
|
||
BN.prototype._zeroBits = function _zeroBits (w) {
|
||
// Short-cut
|
||
if (w === 0) return 26;
|
||
|
||
var t = w;
|
||
var r = 0;
|
||
if ((t & 0x1fff) === 0) {
|
||
r += 13;
|
||
t >>>= 13;
|
||
}
|
||
if ((t & 0x7f) === 0) {
|
||
r += 7;
|
||
t >>>= 7;
|
||
}
|
||
if ((t & 0xf) === 0) {
|
||
r += 4;
|
||
t >>>= 4;
|
||
}
|
||
if ((t & 0x3) === 0) {
|
||
r += 2;
|
||
t >>>= 2;
|
||
}
|
||
if ((t & 0x1) === 0) {
|
||
r++;
|
||
}
|
||
return r;
|
||
};
|
||
|
||
// Return number of used bits in a BN
|
||
BN.prototype.bitLength = function bitLength () {
|
||
var w = this.words[this.length - 1];
|
||
var hi = this._countBits(w);
|
||
return (this.length - 1) * 26 + hi;
|
||
};
|
||
|
||
function toBitArray (num) {
|
||
var w = new Array(num.bitLength());
|
||
|
||
for (var bit = 0; bit < w.length; bit++) {
|
||
var off = (bit / 26) | 0;
|
||
var wbit = bit % 26;
|
||
|
||
w[bit] = (num.words[off] & (1 << wbit)) >>> wbit;
|
||
}
|
||
|
||
return w;
|
||
}
|
||
|
||
// Number of trailing zero bits
|
||
BN.prototype.zeroBits = function zeroBits () {
|
||
if (this.isZero()) return 0;
|
||
|
||
var r = 0;
|
||
for (var i = 0; i < this.length; i++) {
|
||
var b = this._zeroBits(this.words[i]);
|
||
r += b;
|
||
if (b !== 26) break;
|
||
}
|
||
return r;
|
||
};
|
||
|
||
BN.prototype.byteLength = function byteLength () {
|
||
return Math.ceil(this.bitLength() / 8);
|
||
};
|
||
|
||
BN.prototype.toTwos = function toTwos (width) {
|
||
if (this.negative !== 0) {
|
||
return this.abs().inotn(width).iaddn(1);
|
||
}
|
||
return this.clone();
|
||
};
|
||
|
||
BN.prototype.fromTwos = function fromTwos (width) {
|
||
if (this.testn(width - 1)) {
|
||
return this.notn(width).iaddn(1).ineg();
|
||
}
|
||
return this.clone();
|
||
};
|
||
|
||
BN.prototype.isNeg = function isNeg () {
|
||
return this.negative !== 0;
|
||
};
|
||
|
||
// Return negative clone of `this`
|
||
BN.prototype.neg = function neg () {
|
||
return this.clone().ineg();
|
||
};
|
||
|
||
BN.prototype.ineg = function ineg () {
|
||
if (!this.isZero()) {
|
||
this.negative ^= 1;
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
// Or `num` with `this` in-place
|
||
BN.prototype.iuor = function iuor (num) {
|
||
while (this.length < num.length) {
|
||
this.words[this.length++] = 0;
|
||
}
|
||
|
||
for (var i = 0; i < num.length; i++) {
|
||
this.words[i] = this.words[i] | num.words[i];
|
||
}
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype.ior = function ior (num) {
|
||
assert((this.negative | num.negative) === 0);
|
||
return this.iuor(num);
|
||
};
|
||
|
||
// Or `num` with `this`
|
||
BN.prototype.or = function or (num) {
|
||
if (this.length > num.length) return this.clone().ior(num);
|
||
return num.clone().ior(this);
|
||
};
|
||
|
||
BN.prototype.uor = function uor (num) {
|
||
if (this.length > num.length) return this.clone().iuor(num);
|
||
return num.clone().iuor(this);
|
||
};
|
||
|
||
// And `num` with `this` in-place
|
||
BN.prototype.iuand = function iuand (num) {
|
||
// b = min-length(num, this)
|
||
var b;
|
||
if (this.length > num.length) {
|
||
b = num;
|
||
} else {
|
||
b = this;
|
||
}
|
||
|
||
for (var i = 0; i < b.length; i++) {
|
||
this.words[i] = this.words[i] & num.words[i];
|
||
}
|
||
|
||
this.length = b.length;
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype.iand = function iand (num) {
|
||
assert((this.negative | num.negative) === 0);
|
||
return this.iuand(num);
|
||
};
|
||
|
||
// And `num` with `this`
|
||
BN.prototype.and = function and (num) {
|
||
if (this.length > num.length) return this.clone().iand(num);
|
||
return num.clone().iand(this);
|
||
};
|
||
|
||
BN.prototype.uand = function uand (num) {
|
||
if (this.length > num.length) return this.clone().iuand(num);
|
||
return num.clone().iuand(this);
|
||
};
|
||
|
||
// Xor `num` with `this` in-place
|
||
BN.prototype.iuxor = function iuxor (num) {
|
||
// a.length > b.length
|
||
var a;
|
||
var b;
|
||
if (this.length > num.length) {
|
||
a = this;
|
||
b = num;
|
||
} else {
|
||
a = num;
|
||
b = this;
|
||
}
|
||
|
||
for (var i = 0; i < b.length; i++) {
|
||
this.words[i] = a.words[i] ^ b.words[i];
|
||
}
|
||
|
||
if (this !== a) {
|
||
for (; i < a.length; i++) {
|
||
this.words[i] = a.words[i];
|
||
}
|
||
}
|
||
|
||
this.length = a.length;
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype.ixor = function ixor (num) {
|
||
assert((this.negative | num.negative) === 0);
|
||
return this.iuxor(num);
|
||
};
|
||
|
||
// Xor `num` with `this`
|
||
BN.prototype.xor = function xor (num) {
|
||
if (this.length > num.length) return this.clone().ixor(num);
|
||
return num.clone().ixor(this);
|
||
};
|
||
|
||
BN.prototype.uxor = function uxor (num) {
|
||
if (this.length > num.length) return this.clone().iuxor(num);
|
||
return num.clone().iuxor(this);
|
||
};
|
||
|
||
// Not ``this`` with ``width`` bitwidth
|
||
BN.prototype.inotn = function inotn (width) {
|
||
assert(typeof width === 'number' && width >= 0);
|
||
|
||
var bytesNeeded = Math.ceil(width / 26) | 0;
|
||
var bitsLeft = width % 26;
|
||
|
||
// Extend the buffer with leading zeroes
|
||
this._expand(bytesNeeded);
|
||
|
||
if (bitsLeft > 0) {
|
||
bytesNeeded--;
|
||
}
|
||
|
||
// Handle complete words
|
||
for (var i = 0; i < bytesNeeded; i++) {
|
||
this.words[i] = ~this.words[i] & 0x3ffffff;
|
||
}
|
||
|
||
// Handle the residue
|
||
if (bitsLeft > 0) {
|
||
this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft));
|
||
}
|
||
|
||
// And remove leading zeroes
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype.notn = function notn (width) {
|
||
return this.clone().inotn(width);
|
||
};
|
||
|
||
// Set `bit` of `this`
|
||
BN.prototype.setn = function setn (bit, val) {
|
||
assert(typeof bit === 'number' && bit >= 0);
|
||
|
||
var off = (bit / 26) | 0;
|
||
var wbit = bit % 26;
|
||
|
||
this._expand(off + 1);
|
||
|
||
if (val) {
|
||
this.words[off] = this.words[off] | (1 << wbit);
|
||
} else {
|
||
this.words[off] = this.words[off] & ~(1 << wbit);
|
||
}
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
// Add `num` to `this` in-place
|
||
BN.prototype.iadd = function iadd (num) {
|
||
var r;
|
||
|
||
// negative + positive
|
||
if (this.negative !== 0 && num.negative === 0) {
|
||
this.negative = 0;
|
||
r = this.isub(num);
|
||
this.negative ^= 1;
|
||
return this._normSign();
|
||
|
||
// positive + negative
|
||
} else if (this.negative === 0 && num.negative !== 0) {
|
||
num.negative = 0;
|
||
r = this.isub(num);
|
||
num.negative = 1;
|
||
return r._normSign();
|
||
}
|
||
|
||
// a.length > b.length
|
||
var a, b;
|
||
if (this.length > num.length) {
|
||
a = this;
|
||
b = num;
|
||
} else {
|
||
a = num;
|
||
b = this;
|
||
}
|
||
|
||
var carry = 0;
|
||
for (var i = 0; i < b.length; i++) {
|
||
r = (a.words[i] | 0) + (b.words[i] | 0) + carry;
|
||
this.words[i] = r & 0x3ffffff;
|
||
carry = r >>> 26;
|
||
}
|
||
for (; carry !== 0 && i < a.length; i++) {
|
||
r = (a.words[i] | 0) + carry;
|
||
this.words[i] = r & 0x3ffffff;
|
||
carry = r >>> 26;
|
||
}
|
||
|
||
this.length = a.length;
|
||
if (carry !== 0) {
|
||
this.words[this.length] = carry;
|
||
this.length++;
|
||
// Copy the rest of the words
|
||
} else if (a !== this) {
|
||
for (; i < a.length; i++) {
|
||
this.words[i] = a.words[i];
|
||
}
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
// Add `num` to `this`
|
||
BN.prototype.add = function add (num) {
|
||
var res;
|
||
if (num.negative !== 0 && this.negative === 0) {
|
||
num.negative = 0;
|
||
res = this.sub(num);
|
||
num.negative ^= 1;
|
||
return res;
|
||
} else if (num.negative === 0 && this.negative !== 0) {
|
||
this.negative = 0;
|
||
res = num.sub(this);
|
||
this.negative = 1;
|
||
return res;
|
||
}
|
||
|
||
if (this.length > num.length) return this.clone().iadd(num);
|
||
|
||
return num.clone().iadd(this);
|
||
};
|
||
|
||
// Subtract `num` from `this` in-place
|
||
BN.prototype.isub = function isub (num) {
|
||
// this - (-num) = this + num
|
||
if (num.negative !== 0) {
|
||
num.negative = 0;
|
||
var r = this.iadd(num);
|
||
num.negative = 1;
|
||
return r._normSign();
|
||
|
||
// -this - num = -(this + num)
|
||
} else if (this.negative !== 0) {
|
||
this.negative = 0;
|
||
this.iadd(num);
|
||
this.negative = 1;
|
||
return this._normSign();
|
||
}
|
||
|
||
// At this point both numbers are positive
|
||
var cmp = this.cmp(num);
|
||
|
||
// Optimization - zeroify
|
||
if (cmp === 0) {
|
||
this.negative = 0;
|
||
this.length = 1;
|
||
this.words[0] = 0;
|
||
return this;
|
||
}
|
||
|
||
// a > b
|
||
var a, b;
|
||
if (cmp > 0) {
|
||
a = this;
|
||
b = num;
|
||
} else {
|
||
a = num;
|
||
b = this;
|
||
}
|
||
|
||
var carry = 0;
|
||
for (var i = 0; i < b.length; i++) {
|
||
r = (a.words[i] | 0) - (b.words[i] | 0) + carry;
|
||
carry = r >> 26;
|
||
this.words[i] = r & 0x3ffffff;
|
||
}
|
||
for (; carry !== 0 && i < a.length; i++) {
|
||
r = (a.words[i] | 0) + carry;
|
||
carry = r >> 26;
|
||
this.words[i] = r & 0x3ffffff;
|
||
}
|
||
|
||
// Copy rest of the words
|
||
if (carry === 0 && i < a.length && a !== this) {
|
||
for (; i < a.length; i++) {
|
||
this.words[i] = a.words[i];
|
||
}
|
||
}
|
||
|
||
this.length = Math.max(this.length, i);
|
||
|
||
if (a !== this) {
|
||
this.negative = 1;
|
||
}
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
// Subtract `num` from `this`
|
||
BN.prototype.sub = function sub (num) {
|
||
return this.clone().isub(num);
|
||
};
|
||
|
||
function smallMulTo (self, num, out) {
|
||
out.negative = num.negative ^ self.negative;
|
||
var len = (self.length + num.length) | 0;
|
||
out.length = len;
|
||
len = (len - 1) | 0;
|
||
|
||
// Peel one iteration (compiler can't do it, because of code complexity)
|
||
var a = self.words[0] | 0;
|
||
var b = num.words[0] | 0;
|
||
var r = a * b;
|
||
|
||
var lo = r & 0x3ffffff;
|
||
var carry = (r / 0x4000000) | 0;
|
||
out.words[0] = lo;
|
||
|
||
for (var k = 1; k < len; k++) {
|
||
// Sum all words with the same `i + j = k` and accumulate `ncarry`,
|
||
// note that ncarry could be >= 0x3ffffff
|
||
var ncarry = carry >>> 26;
|
||
var rword = carry & 0x3ffffff;
|
||
var maxJ = Math.min(k, num.length - 1);
|
||
for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
|
||
var i = (k - j) | 0;
|
||
a = self.words[i] | 0;
|
||
b = num.words[j] | 0;
|
||
r = a * b + rword;
|
||
ncarry += (r / 0x4000000) | 0;
|
||
rword = r & 0x3ffffff;
|
||
}
|
||
out.words[k] = rword | 0;
|
||
carry = ncarry | 0;
|
||
}
|
||
if (carry !== 0) {
|
||
out.words[k] = carry | 0;
|
||
} else {
|
||
out.length--;
|
||
}
|
||
|
||
return out.strip();
|
||
}
|
||
|
||
// TODO(indutny): it may be reasonable to omit it for users who don't need
|
||
// to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit
|
||
// multiplication (like elliptic secp256k1).
|
||
var comb10MulTo = function comb10MulTo (self, num, out) {
|
||
var a = self.words;
|
||
var b = num.words;
|
||
var o = out.words;
|
||
var c = 0;
|
||
var lo;
|
||
var mid;
|
||
var hi;
|
||
var a0 = a[0] | 0;
|
||
var al0 = a0 & 0x1fff;
|
||
var ah0 = a0 >>> 13;
|
||
var a1 = a[1] | 0;
|
||
var al1 = a1 & 0x1fff;
|
||
var ah1 = a1 >>> 13;
|
||
var a2 = a[2] | 0;
|
||
var al2 = a2 & 0x1fff;
|
||
var ah2 = a2 >>> 13;
|
||
var a3 = a[3] | 0;
|
||
var al3 = a3 & 0x1fff;
|
||
var ah3 = a3 >>> 13;
|
||
var a4 = a[4] | 0;
|
||
var al4 = a4 & 0x1fff;
|
||
var ah4 = a4 >>> 13;
|
||
var a5 = a[5] | 0;
|
||
var al5 = a5 & 0x1fff;
|
||
var ah5 = a5 >>> 13;
|
||
var a6 = a[6] | 0;
|
||
var al6 = a6 & 0x1fff;
|
||
var ah6 = a6 >>> 13;
|
||
var a7 = a[7] | 0;
|
||
var al7 = a7 & 0x1fff;
|
||
var ah7 = a7 >>> 13;
|
||
var a8 = a[8] | 0;
|
||
var al8 = a8 & 0x1fff;
|
||
var ah8 = a8 >>> 13;
|
||
var a9 = a[9] | 0;
|
||
var al9 = a9 & 0x1fff;
|
||
var ah9 = a9 >>> 13;
|
||
var b0 = b[0] | 0;
|
||
var bl0 = b0 & 0x1fff;
|
||
var bh0 = b0 >>> 13;
|
||
var b1 = b[1] | 0;
|
||
var bl1 = b1 & 0x1fff;
|
||
var bh1 = b1 >>> 13;
|
||
var b2 = b[2] | 0;
|
||
var bl2 = b2 & 0x1fff;
|
||
var bh2 = b2 >>> 13;
|
||
var b3 = b[3] | 0;
|
||
var bl3 = b3 & 0x1fff;
|
||
var bh3 = b3 >>> 13;
|
||
var b4 = b[4] | 0;
|
||
var bl4 = b4 & 0x1fff;
|
||
var bh4 = b4 >>> 13;
|
||
var b5 = b[5] | 0;
|
||
var bl5 = b5 & 0x1fff;
|
||
var bh5 = b5 >>> 13;
|
||
var b6 = b[6] | 0;
|
||
var bl6 = b6 & 0x1fff;
|
||
var bh6 = b6 >>> 13;
|
||
var b7 = b[7] | 0;
|
||
var bl7 = b7 & 0x1fff;
|
||
var bh7 = b7 >>> 13;
|
||
var b8 = b[8] | 0;
|
||
var bl8 = b8 & 0x1fff;
|
||
var bh8 = b8 >>> 13;
|
||
var b9 = b[9] | 0;
|
||
var bl9 = b9 & 0x1fff;
|
||
var bh9 = b9 >>> 13;
|
||
|
||
out.negative = self.negative ^ num.negative;
|
||
out.length = 19;
|
||
/* k = 0 */
|
||
lo = Math.imul(al0, bl0);
|
||
mid = Math.imul(al0, bh0);
|
||
mid = (mid + Math.imul(ah0, bl0)) | 0;
|
||
hi = Math.imul(ah0, bh0);
|
||
var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0;
|
||
w0 &= 0x3ffffff;
|
||
/* k = 1 */
|
||
lo = Math.imul(al1, bl0);
|
||
mid = Math.imul(al1, bh0);
|
||
mid = (mid + Math.imul(ah1, bl0)) | 0;
|
||
hi = Math.imul(ah1, bh0);
|
||
lo = (lo + Math.imul(al0, bl1)) | 0;
|
||
mid = (mid + Math.imul(al0, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh1)) | 0;
|
||
var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0;
|
||
w1 &= 0x3ffffff;
|
||
/* k = 2 */
|
||
lo = Math.imul(al2, bl0);
|
||
mid = Math.imul(al2, bh0);
|
||
mid = (mid + Math.imul(ah2, bl0)) | 0;
|
||
hi = Math.imul(ah2, bh0);
|
||
lo = (lo + Math.imul(al1, bl1)) | 0;
|
||
mid = (mid + Math.imul(al1, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh1)) | 0;
|
||
lo = (lo + Math.imul(al0, bl2)) | 0;
|
||
mid = (mid + Math.imul(al0, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh2)) | 0;
|
||
var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0;
|
||
w2 &= 0x3ffffff;
|
||
/* k = 3 */
|
||
lo = Math.imul(al3, bl0);
|
||
mid = Math.imul(al3, bh0);
|
||
mid = (mid + Math.imul(ah3, bl0)) | 0;
|
||
hi = Math.imul(ah3, bh0);
|
||
lo = (lo + Math.imul(al2, bl1)) | 0;
|
||
mid = (mid + Math.imul(al2, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh1)) | 0;
|
||
lo = (lo + Math.imul(al1, bl2)) | 0;
|
||
mid = (mid + Math.imul(al1, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh2)) | 0;
|
||
lo = (lo + Math.imul(al0, bl3)) | 0;
|
||
mid = (mid + Math.imul(al0, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh3)) | 0;
|
||
var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0;
|
||
w3 &= 0x3ffffff;
|
||
/* k = 4 */
|
||
lo = Math.imul(al4, bl0);
|
||
mid = Math.imul(al4, bh0);
|
||
mid = (mid + Math.imul(ah4, bl0)) | 0;
|
||
hi = Math.imul(ah4, bh0);
|
||
lo = (lo + Math.imul(al3, bl1)) | 0;
|
||
mid = (mid + Math.imul(al3, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh1)) | 0;
|
||
lo = (lo + Math.imul(al2, bl2)) | 0;
|
||
mid = (mid + Math.imul(al2, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh2)) | 0;
|
||
lo = (lo + Math.imul(al1, bl3)) | 0;
|
||
mid = (mid + Math.imul(al1, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh3)) | 0;
|
||
lo = (lo + Math.imul(al0, bl4)) | 0;
|
||
mid = (mid + Math.imul(al0, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh4)) | 0;
|
||
var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0;
|
||
w4 &= 0x3ffffff;
|
||
/* k = 5 */
|
||
lo = Math.imul(al5, bl0);
|
||
mid = Math.imul(al5, bh0);
|
||
mid = (mid + Math.imul(ah5, bl0)) | 0;
|
||
hi = Math.imul(ah5, bh0);
|
||
lo = (lo + Math.imul(al4, bl1)) | 0;
|
||
mid = (mid + Math.imul(al4, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh1)) | 0;
|
||
lo = (lo + Math.imul(al3, bl2)) | 0;
|
||
mid = (mid + Math.imul(al3, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh2)) | 0;
|
||
lo = (lo + Math.imul(al2, bl3)) | 0;
|
||
mid = (mid + Math.imul(al2, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh3)) | 0;
|
||
lo = (lo + Math.imul(al1, bl4)) | 0;
|
||
mid = (mid + Math.imul(al1, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh4)) | 0;
|
||
lo = (lo + Math.imul(al0, bl5)) | 0;
|
||
mid = (mid + Math.imul(al0, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh5)) | 0;
|
||
var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0;
|
||
w5 &= 0x3ffffff;
|
||
/* k = 6 */
|
||
lo = Math.imul(al6, bl0);
|
||
mid = Math.imul(al6, bh0);
|
||
mid = (mid + Math.imul(ah6, bl0)) | 0;
|
||
hi = Math.imul(ah6, bh0);
|
||
lo = (lo + Math.imul(al5, bl1)) | 0;
|
||
mid = (mid + Math.imul(al5, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh1)) | 0;
|
||
lo = (lo + Math.imul(al4, bl2)) | 0;
|
||
mid = (mid + Math.imul(al4, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh2)) | 0;
|
||
lo = (lo + Math.imul(al3, bl3)) | 0;
|
||
mid = (mid + Math.imul(al3, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh3)) | 0;
|
||
lo = (lo + Math.imul(al2, bl4)) | 0;
|
||
mid = (mid + Math.imul(al2, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh4)) | 0;
|
||
lo = (lo + Math.imul(al1, bl5)) | 0;
|
||
mid = (mid + Math.imul(al1, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh5)) | 0;
|
||
lo = (lo + Math.imul(al0, bl6)) | 0;
|
||
mid = (mid + Math.imul(al0, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh6)) | 0;
|
||
var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0;
|
||
w6 &= 0x3ffffff;
|
||
/* k = 7 */
|
||
lo = Math.imul(al7, bl0);
|
||
mid = Math.imul(al7, bh0);
|
||
mid = (mid + Math.imul(ah7, bl0)) | 0;
|
||
hi = Math.imul(ah7, bh0);
|
||
lo = (lo + Math.imul(al6, bl1)) | 0;
|
||
mid = (mid + Math.imul(al6, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh1)) | 0;
|
||
lo = (lo + Math.imul(al5, bl2)) | 0;
|
||
mid = (mid + Math.imul(al5, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh2)) | 0;
|
||
lo = (lo + Math.imul(al4, bl3)) | 0;
|
||
mid = (mid + Math.imul(al4, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh3)) | 0;
|
||
lo = (lo + Math.imul(al3, bl4)) | 0;
|
||
mid = (mid + Math.imul(al3, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh4)) | 0;
|
||
lo = (lo + Math.imul(al2, bl5)) | 0;
|
||
mid = (mid + Math.imul(al2, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh5)) | 0;
|
||
lo = (lo + Math.imul(al1, bl6)) | 0;
|
||
mid = (mid + Math.imul(al1, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh6)) | 0;
|
||
lo = (lo + Math.imul(al0, bl7)) | 0;
|
||
mid = (mid + Math.imul(al0, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh7)) | 0;
|
||
var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0;
|
||
w7 &= 0x3ffffff;
|
||
/* k = 8 */
|
||
lo = Math.imul(al8, bl0);
|
||
mid = Math.imul(al8, bh0);
|
||
mid = (mid + Math.imul(ah8, bl0)) | 0;
|
||
hi = Math.imul(ah8, bh0);
|
||
lo = (lo + Math.imul(al7, bl1)) | 0;
|
||
mid = (mid + Math.imul(al7, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh1)) | 0;
|
||
lo = (lo + Math.imul(al6, bl2)) | 0;
|
||
mid = (mid + Math.imul(al6, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh2)) | 0;
|
||
lo = (lo + Math.imul(al5, bl3)) | 0;
|
||
mid = (mid + Math.imul(al5, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh3)) | 0;
|
||
lo = (lo + Math.imul(al4, bl4)) | 0;
|
||
mid = (mid + Math.imul(al4, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh4)) | 0;
|
||
lo = (lo + Math.imul(al3, bl5)) | 0;
|
||
mid = (mid + Math.imul(al3, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh5)) | 0;
|
||
lo = (lo + Math.imul(al2, bl6)) | 0;
|
||
mid = (mid + Math.imul(al2, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh6)) | 0;
|
||
lo = (lo + Math.imul(al1, bl7)) | 0;
|
||
mid = (mid + Math.imul(al1, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh7)) | 0;
|
||
lo = (lo + Math.imul(al0, bl8)) | 0;
|
||
mid = (mid + Math.imul(al0, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh8)) | 0;
|
||
var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0;
|
||
w8 &= 0x3ffffff;
|
||
/* k = 9 */
|
||
lo = Math.imul(al9, bl0);
|
||
mid = Math.imul(al9, bh0);
|
||
mid = (mid + Math.imul(ah9, bl0)) | 0;
|
||
hi = Math.imul(ah9, bh0);
|
||
lo = (lo + Math.imul(al8, bl1)) | 0;
|
||
mid = (mid + Math.imul(al8, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh1)) | 0;
|
||
lo = (lo + Math.imul(al7, bl2)) | 0;
|
||
mid = (mid + Math.imul(al7, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh2)) | 0;
|
||
lo = (lo + Math.imul(al6, bl3)) | 0;
|
||
mid = (mid + Math.imul(al6, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh3)) | 0;
|
||
lo = (lo + Math.imul(al5, bl4)) | 0;
|
||
mid = (mid + Math.imul(al5, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh4)) | 0;
|
||
lo = (lo + Math.imul(al4, bl5)) | 0;
|
||
mid = (mid + Math.imul(al4, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh5)) | 0;
|
||
lo = (lo + Math.imul(al3, bl6)) | 0;
|
||
mid = (mid + Math.imul(al3, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh6)) | 0;
|
||
lo = (lo + Math.imul(al2, bl7)) | 0;
|
||
mid = (mid + Math.imul(al2, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh7)) | 0;
|
||
lo = (lo + Math.imul(al1, bl8)) | 0;
|
||
mid = (mid + Math.imul(al1, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh8)) | 0;
|
||
lo = (lo + Math.imul(al0, bl9)) | 0;
|
||
mid = (mid + Math.imul(al0, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh9)) | 0;
|
||
var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0;
|
||
w9 &= 0x3ffffff;
|
||
/* k = 10 */
|
||
lo = Math.imul(al9, bl1);
|
||
mid = Math.imul(al9, bh1);
|
||
mid = (mid + Math.imul(ah9, bl1)) | 0;
|
||
hi = Math.imul(ah9, bh1);
|
||
lo = (lo + Math.imul(al8, bl2)) | 0;
|
||
mid = (mid + Math.imul(al8, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh2)) | 0;
|
||
lo = (lo + Math.imul(al7, bl3)) | 0;
|
||
mid = (mid + Math.imul(al7, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh3)) | 0;
|
||
lo = (lo + Math.imul(al6, bl4)) | 0;
|
||
mid = (mid + Math.imul(al6, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh4)) | 0;
|
||
lo = (lo + Math.imul(al5, bl5)) | 0;
|
||
mid = (mid + Math.imul(al5, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh5)) | 0;
|
||
lo = (lo + Math.imul(al4, bl6)) | 0;
|
||
mid = (mid + Math.imul(al4, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh6)) | 0;
|
||
lo = (lo + Math.imul(al3, bl7)) | 0;
|
||
mid = (mid + Math.imul(al3, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh7)) | 0;
|
||
lo = (lo + Math.imul(al2, bl8)) | 0;
|
||
mid = (mid + Math.imul(al2, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh8)) | 0;
|
||
lo = (lo + Math.imul(al1, bl9)) | 0;
|
||
mid = (mid + Math.imul(al1, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh9)) | 0;
|
||
var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0;
|
||
w10 &= 0x3ffffff;
|
||
/* k = 11 */
|
||
lo = Math.imul(al9, bl2);
|
||
mid = Math.imul(al9, bh2);
|
||
mid = (mid + Math.imul(ah9, bl2)) | 0;
|
||
hi = Math.imul(ah9, bh2);
|
||
lo = (lo + Math.imul(al8, bl3)) | 0;
|
||
mid = (mid + Math.imul(al8, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh3)) | 0;
|
||
lo = (lo + Math.imul(al7, bl4)) | 0;
|
||
mid = (mid + Math.imul(al7, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh4)) | 0;
|
||
lo = (lo + Math.imul(al6, bl5)) | 0;
|
||
mid = (mid + Math.imul(al6, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh5)) | 0;
|
||
lo = (lo + Math.imul(al5, bl6)) | 0;
|
||
mid = (mid + Math.imul(al5, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh6)) | 0;
|
||
lo = (lo + Math.imul(al4, bl7)) | 0;
|
||
mid = (mid + Math.imul(al4, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh7)) | 0;
|
||
lo = (lo + Math.imul(al3, bl8)) | 0;
|
||
mid = (mid + Math.imul(al3, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh8)) | 0;
|
||
lo = (lo + Math.imul(al2, bl9)) | 0;
|
||
mid = (mid + Math.imul(al2, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh9)) | 0;
|
||
var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0;
|
||
w11 &= 0x3ffffff;
|
||
/* k = 12 */
|
||
lo = Math.imul(al9, bl3);
|
||
mid = Math.imul(al9, bh3);
|
||
mid = (mid + Math.imul(ah9, bl3)) | 0;
|
||
hi = Math.imul(ah9, bh3);
|
||
lo = (lo + Math.imul(al8, bl4)) | 0;
|
||
mid = (mid + Math.imul(al8, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh4)) | 0;
|
||
lo = (lo + Math.imul(al7, bl5)) | 0;
|
||
mid = (mid + Math.imul(al7, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh5)) | 0;
|
||
lo = (lo + Math.imul(al6, bl6)) | 0;
|
||
mid = (mid + Math.imul(al6, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh6)) | 0;
|
||
lo = (lo + Math.imul(al5, bl7)) | 0;
|
||
mid = (mid + Math.imul(al5, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh7)) | 0;
|
||
lo = (lo + Math.imul(al4, bl8)) | 0;
|
||
mid = (mid + Math.imul(al4, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh8)) | 0;
|
||
lo = (lo + Math.imul(al3, bl9)) | 0;
|
||
mid = (mid + Math.imul(al3, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh9)) | 0;
|
||
var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0;
|
||
w12 &= 0x3ffffff;
|
||
/* k = 13 */
|
||
lo = Math.imul(al9, bl4);
|
||
mid = Math.imul(al9, bh4);
|
||
mid = (mid + Math.imul(ah9, bl4)) | 0;
|
||
hi = Math.imul(ah9, bh4);
|
||
lo = (lo + Math.imul(al8, bl5)) | 0;
|
||
mid = (mid + Math.imul(al8, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh5)) | 0;
|
||
lo = (lo + Math.imul(al7, bl6)) | 0;
|
||
mid = (mid + Math.imul(al7, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh6)) | 0;
|
||
lo = (lo + Math.imul(al6, bl7)) | 0;
|
||
mid = (mid + Math.imul(al6, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh7)) | 0;
|
||
lo = (lo + Math.imul(al5, bl8)) | 0;
|
||
mid = (mid + Math.imul(al5, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh8)) | 0;
|
||
lo = (lo + Math.imul(al4, bl9)) | 0;
|
||
mid = (mid + Math.imul(al4, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh9)) | 0;
|
||
var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0;
|
||
w13 &= 0x3ffffff;
|
||
/* k = 14 */
|
||
lo = Math.imul(al9, bl5);
|
||
mid = Math.imul(al9, bh5);
|
||
mid = (mid + Math.imul(ah9, bl5)) | 0;
|
||
hi = Math.imul(ah9, bh5);
|
||
lo = (lo + Math.imul(al8, bl6)) | 0;
|
||
mid = (mid + Math.imul(al8, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh6)) | 0;
|
||
lo = (lo + Math.imul(al7, bl7)) | 0;
|
||
mid = (mid + Math.imul(al7, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh7)) | 0;
|
||
lo = (lo + Math.imul(al6, bl8)) | 0;
|
||
mid = (mid + Math.imul(al6, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh8)) | 0;
|
||
lo = (lo + Math.imul(al5, bl9)) | 0;
|
||
mid = (mid + Math.imul(al5, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh9)) | 0;
|
||
var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0;
|
||
w14 &= 0x3ffffff;
|
||
/* k = 15 */
|
||
lo = Math.imul(al9, bl6);
|
||
mid = Math.imul(al9, bh6);
|
||
mid = (mid + Math.imul(ah9, bl6)) | 0;
|
||
hi = Math.imul(ah9, bh6);
|
||
lo = (lo + Math.imul(al8, bl7)) | 0;
|
||
mid = (mid + Math.imul(al8, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh7)) | 0;
|
||
lo = (lo + Math.imul(al7, bl8)) | 0;
|
||
mid = (mid + Math.imul(al7, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh8)) | 0;
|
||
lo = (lo + Math.imul(al6, bl9)) | 0;
|
||
mid = (mid + Math.imul(al6, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh9)) | 0;
|
||
var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0;
|
||
w15 &= 0x3ffffff;
|
||
/* k = 16 */
|
||
lo = Math.imul(al9, bl7);
|
||
mid = Math.imul(al9, bh7);
|
||
mid = (mid + Math.imul(ah9, bl7)) | 0;
|
||
hi = Math.imul(ah9, bh7);
|
||
lo = (lo + Math.imul(al8, bl8)) | 0;
|
||
mid = (mid + Math.imul(al8, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh8)) | 0;
|
||
lo = (lo + Math.imul(al7, bl9)) | 0;
|
||
mid = (mid + Math.imul(al7, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh9)) | 0;
|
||
var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0;
|
||
w16 &= 0x3ffffff;
|
||
/* k = 17 */
|
||
lo = Math.imul(al9, bl8);
|
||
mid = Math.imul(al9, bh8);
|
||
mid = (mid + Math.imul(ah9, bl8)) | 0;
|
||
hi = Math.imul(ah9, bh8);
|
||
lo = (lo + Math.imul(al8, bl9)) | 0;
|
||
mid = (mid + Math.imul(al8, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh9)) | 0;
|
||
var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0;
|
||
w17 &= 0x3ffffff;
|
||
/* k = 18 */
|
||
lo = Math.imul(al9, bl9);
|
||
mid = Math.imul(al9, bh9);
|
||
mid = (mid + Math.imul(ah9, bl9)) | 0;
|
||
hi = Math.imul(ah9, bh9);
|
||
var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0;
|
||
w18 &= 0x3ffffff;
|
||
o[0] = w0;
|
||
o[1] = w1;
|
||
o[2] = w2;
|
||
o[3] = w3;
|
||
o[4] = w4;
|
||
o[5] = w5;
|
||
o[6] = w6;
|
||
o[7] = w7;
|
||
o[8] = w8;
|
||
o[9] = w9;
|
||
o[10] = w10;
|
||
o[11] = w11;
|
||
o[12] = w12;
|
||
o[13] = w13;
|
||
o[14] = w14;
|
||
o[15] = w15;
|
||
o[16] = w16;
|
||
o[17] = w17;
|
||
o[18] = w18;
|
||
if (c !== 0) {
|
||
o[19] = c;
|
||
out.length++;
|
||
}
|
||
return out;
|
||
};
|
||
|
||
// Polyfill comb
|
||
if (!Math.imul) {
|
||
comb10MulTo = smallMulTo;
|
||
}
|
||
|
||
function bigMulTo (self, num, out) {
|
||
out.negative = num.negative ^ self.negative;
|
||
out.length = self.length + num.length;
|
||
|
||
var carry = 0;
|
||
var hncarry = 0;
|
||
for (var k = 0; k < out.length - 1; k++) {
|
||
// Sum all words with the same `i + j = k` and accumulate `ncarry`,
|
||
// note that ncarry could be >= 0x3ffffff
|
||
var ncarry = hncarry;
|
||
hncarry = 0;
|
||
var rword = carry & 0x3ffffff;
|
||
var maxJ = Math.min(k, num.length - 1);
|
||
for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
|
||
var i = k - j;
|
||
var a = self.words[i] | 0;
|
||
var b = num.words[j] | 0;
|
||
var r = a * b;
|
||
|
||
var lo = r & 0x3ffffff;
|
||
ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
|
||
lo = (lo + rword) | 0;
|
||
rword = lo & 0x3ffffff;
|
||
ncarry = (ncarry + (lo >>> 26)) | 0;
|
||
|
||
hncarry += ncarry >>> 26;
|
||
ncarry &= 0x3ffffff;
|
||
}
|
||
out.words[k] = rword;
|
||
carry = ncarry;
|
||
ncarry = hncarry;
|
||
}
|
||
if (carry !== 0) {
|
||
out.words[k] = carry;
|
||
} else {
|
||
out.length--;
|
||
}
|
||
|
||
return out.strip();
|
||
}
|
||
|
||
function jumboMulTo (self, num, out) {
|
||
var fftm = new FFTM();
|
||
return fftm.mulp(self, num, out);
|
||
}
|
||
|
||
BN.prototype.mulTo = function mulTo (num, out) {
|
||
var res;
|
||
var len = this.length + num.length;
|
||
if (this.length === 10 && num.length === 10) {
|
||
res = comb10MulTo(this, num, out);
|
||
} else if (len < 63) {
|
||
res = smallMulTo(this, num, out);
|
||
} else if (len < 1024) {
|
||
res = bigMulTo(this, num, out);
|
||
} else {
|
||
res = jumboMulTo(this, num, out);
|
||
}
|
||
|
||
return res;
|
||
};
|
||
|
||
// Cooley-Tukey algorithm for FFT
|
||
// slightly revisited to rely on looping instead of recursion
|
||
|
||
function FFTM (x, y) {
|
||
this.x = x;
|
||
this.y = y;
|
||
}
|
||
|
||
FFTM.prototype.makeRBT = function makeRBT (N) {
|
||
var t = new Array(N);
|
||
var l = BN.prototype._countBits(N) - 1;
|
||
for (var i = 0; i < N; i++) {
|
||
t[i] = this.revBin(i, l, N);
|
||
}
|
||
|
||
return t;
|
||
};
|
||
|
||
// Returns binary-reversed representation of `x`
|
||
FFTM.prototype.revBin = function revBin (x, l, N) {
|
||
if (x === 0 || x === N - 1) return x;
|
||
|
||
var rb = 0;
|
||
for (var i = 0; i < l; i++) {
|
||
rb |= (x & 1) << (l - i - 1);
|
||
x >>= 1;
|
||
}
|
||
|
||
return rb;
|
||
};
|
||
|
||
// Performs "tweedling" phase, therefore 'emulating'
|
||
// behaviour of the recursive algorithm
|
||
FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) {
|
||
for (var i = 0; i < N; i++) {
|
||
rtws[i] = rws[rbt[i]];
|
||
itws[i] = iws[rbt[i]];
|
||
}
|
||
};
|
||
|
||
FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) {
|
||
this.permute(rbt, rws, iws, rtws, itws, N);
|
||
|
||
for (var s = 1; s < N; s <<= 1) {
|
||
var l = s << 1;
|
||
|
||
var rtwdf = Math.cos(2 * Math.PI / l);
|
||
var itwdf = Math.sin(2 * Math.PI / l);
|
||
|
||
for (var p = 0; p < N; p += l) {
|
||
var rtwdf_ = rtwdf;
|
||
var itwdf_ = itwdf;
|
||
|
||
for (var j = 0; j < s; j++) {
|
||
var re = rtws[p + j];
|
||
var ie = itws[p + j];
|
||
|
||
var ro = rtws[p + j + s];
|
||
var io = itws[p + j + s];
|
||
|
||
var rx = rtwdf_ * ro - itwdf_ * io;
|
||
|
||
io = rtwdf_ * io + itwdf_ * ro;
|
||
ro = rx;
|
||
|
||
rtws[p + j] = re + ro;
|
||
itws[p + j] = ie + io;
|
||
|
||
rtws[p + j + s] = re - ro;
|
||
itws[p + j + s] = ie - io;
|
||
|
||
/* jshint maxdepth : false */
|
||
if (j !== l) {
|
||
rx = rtwdf * rtwdf_ - itwdf * itwdf_;
|
||
|
||
itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_;
|
||
rtwdf_ = rx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
FFTM.prototype.guessLen13b = function guessLen13b (n, m) {
|
||
var N = Math.max(m, n) | 1;
|
||
var odd = N & 1;
|
||
var i = 0;
|
||
for (N = N / 2 | 0; N; N = N >>> 1) {
|
||
i++;
|
||
}
|
||
|
||
return 1 << i + 1 + odd;
|
||
};
|
||
|
||
FFTM.prototype.conjugate = function conjugate (rws, iws, N) {
|
||
if (N <= 1) return;
|
||
|
||
for (var i = 0; i < N / 2; i++) {
|
||
var t = rws[i];
|
||
|
||
rws[i] = rws[N - i - 1];
|
||
rws[N - i - 1] = t;
|
||
|
||
t = iws[i];
|
||
|
||
iws[i] = -iws[N - i - 1];
|
||
iws[N - i - 1] = -t;
|
||
}
|
||
};
|
||
|
||
FFTM.prototype.normalize13b = function normalize13b (ws, N) {
|
||
var carry = 0;
|
||
for (var i = 0; i < N / 2; i++) {
|
||
var w = Math.round(ws[2 * i + 1] / N) * 0x2000 +
|
||
Math.round(ws[2 * i] / N) +
|
||
carry;
|
||
|
||
ws[i] = w & 0x3ffffff;
|
||
|
||
if (w < 0x4000000) {
|
||
carry = 0;
|
||
} else {
|
||
carry = w / 0x4000000 | 0;
|
||
}
|
||
}
|
||
|
||
return ws;
|
||
};
|
||
|
||
FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) {
|
||
var carry = 0;
|
||
for (var i = 0; i < len; i++) {
|
||
carry = carry + (ws[i] | 0);
|
||
|
||
rws[2 * i] = carry & 0x1fff; carry = carry >>> 13;
|
||
rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13;
|
||
}
|
||
|
||
// Pad with zeroes
|
||
for (i = 2 * len; i < N; ++i) {
|
||
rws[i] = 0;
|
||
}
|
||
|
||
assert(carry === 0);
|
||
assert((carry & ~0x1fff) === 0);
|
||
};
|
||
|
||
FFTM.prototype.stub = function stub (N) {
|
||
var ph = new Array(N);
|
||
for (var i = 0; i < N; i++) {
|
||
ph[i] = 0;
|
||
}
|
||
|
||
return ph;
|
||
};
|
||
|
||
FFTM.prototype.mulp = function mulp (x, y, out) {
|
||
var N = 2 * this.guessLen13b(x.length, y.length);
|
||
|
||
var rbt = this.makeRBT(N);
|
||
|
||
var _ = this.stub(N);
|
||
|
||
var rws = new Array(N);
|
||
var rwst = new Array(N);
|
||
var iwst = new Array(N);
|
||
|
||
var nrws = new Array(N);
|
||
var nrwst = new Array(N);
|
||
var niwst = new Array(N);
|
||
|
||
var rmws = out.words;
|
||
rmws.length = N;
|
||
|
||
this.convert13b(x.words, x.length, rws, N);
|
||
this.convert13b(y.words, y.length, nrws, N);
|
||
|
||
this.transform(rws, _, rwst, iwst, N, rbt);
|
||
this.transform(nrws, _, nrwst, niwst, N, rbt);
|
||
|
||
for (var i = 0; i < N; i++) {
|
||
var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i];
|
||
iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i];
|
||
rwst[i] = rx;
|
||
}
|
||
|
||
this.conjugate(rwst, iwst, N);
|
||
this.transform(rwst, iwst, rmws, _, N, rbt);
|
||
this.conjugate(rmws, _, N);
|
||
this.normalize13b(rmws, N);
|
||
|
||
out.negative = x.negative ^ y.negative;
|
||
out.length = x.length + y.length;
|
||
return out.strip();
|
||
};
|
||
|
||
// Multiply `this` by `num`
|
||
BN.prototype.mul = function mul (num) {
|
||
var out = new BN(null);
|
||
out.words = new Array(this.length + num.length);
|
||
return this.mulTo(num, out);
|
||
};
|
||
|
||
// Multiply employing FFT
|
||
BN.prototype.mulf = function mulf (num) {
|
||
var out = new BN(null);
|
||
out.words = new Array(this.length + num.length);
|
||
return jumboMulTo(this, num, out);
|
||
};
|
||
|
||
// In-place Multiplication
|
||
BN.prototype.imul = function imul (num) {
|
||
return this.clone().mulTo(num, this);
|
||
};
|
||
|
||
BN.prototype.imuln = function imuln (num) {
|
||
assert(typeof num === 'number');
|
||
assert(num < 0x4000000);
|
||
|
||
// Carry
|
||
var carry = 0;
|
||
for (var i = 0; i < this.length; i++) {
|
||
var w = (this.words[i] | 0) * num;
|
||
var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);
|
||
carry >>= 26;
|
||
carry += (w / 0x4000000) | 0;
|
||
// NOTE: lo is 27bit maximum
|
||
carry += lo >>> 26;
|
||
this.words[i] = lo & 0x3ffffff;
|
||
}
|
||
|
||
if (carry !== 0) {
|
||
this.words[i] = carry;
|
||
this.length++;
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
BN.prototype.muln = function muln (num) {
|
||
return this.clone().imuln(num);
|
||
};
|
||
|
||
// `this` * `this`
|
||
BN.prototype.sqr = function sqr () {
|
||
return this.mul(this);
|
||
};
|
||
|
||
// `this` * `this` in-place
|
||
BN.prototype.isqr = function isqr () {
|
||
return this.imul(this.clone());
|
||
};
|
||
|
||
// Math.pow(`this`, `num`)
|
||
BN.prototype.pow = function pow (num) {
|
||
var w = toBitArray(num);
|
||
if (w.length === 0) return new BN(1);
|
||
|
||
// Skip leading zeroes
|
||
var res = this;
|
||
for (var i = 0; i < w.length; i++, res = res.sqr()) {
|
||
if (w[i] !== 0) break;
|
||
}
|
||
|
||
if (++i < w.length) {
|
||
for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) {
|
||
if (w[i] === 0) continue;
|
||
|
||
res = res.mul(q);
|
||
}
|
||
}
|
||
|
||
return res;
|
||
};
|
||
|
||
// Shift-left in-place
|
||
BN.prototype.iushln = function iushln (bits) {
|
||
assert(typeof bits === 'number' && bits >= 0);
|
||
var r = bits % 26;
|
||
var s = (bits - r) / 26;
|
||
var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
|
||
var i;
|
||
|
||
if (r !== 0) {
|
||
var carry = 0;
|
||
|
||
for (i = 0; i < this.length; i++) {
|
||
var newCarry = this.words[i] & carryMask;
|
||
var c = ((this.words[i] | 0) - newCarry) << r;
|
||
this.words[i] = c | carry;
|
||
carry = newCarry >>> (26 - r);
|
||
}
|
||
|
||
if (carry) {
|
||
this.words[i] = carry;
|
||
this.length++;
|
||
}
|
||
}
|
||
|
||
if (s !== 0) {
|
||
for (i = this.length - 1; i >= 0; i--) {
|
||
this.words[i + s] = this.words[i];
|
||
}
|
||
|
||
for (i = 0; i < s; i++) {
|
||
this.words[i] = 0;
|
||
}
|
||
|
||
this.length += s;
|
||
}
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype.ishln = function ishln (bits) {
|
||
// TODO(indutny): implement me
|
||
assert(this.negative === 0);
|
||
return this.iushln(bits);
|
||
};
|
||
|
||
// Shift-right in-place
|
||
// NOTE: `hint` is a lowest bit before trailing zeroes
|
||
// NOTE: if `extended` is present - it will be filled with destroyed bits
|
||
BN.prototype.iushrn = function iushrn (bits, hint, extended) {
|
||
assert(typeof bits === 'number' && bits >= 0);
|
||
var h;
|
||
if (hint) {
|
||
h = (hint - (hint % 26)) / 26;
|
||
} else {
|
||
h = 0;
|
||
}
|
||
|
||
var r = bits % 26;
|
||
var s = Math.min((bits - r) / 26, this.length);
|
||
var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
|
||
var maskedWords = extended;
|
||
|
||
h -= s;
|
||
h = Math.max(0, h);
|
||
|
||
// Extended mode, copy masked part
|
||
if (maskedWords) {
|
||
for (var i = 0; i < s; i++) {
|
||
maskedWords.words[i] = this.words[i];
|
||
}
|
||
maskedWords.length = s;
|
||
}
|
||
|
||
if (s === 0) {
|
||
// No-op, we should not move anything at all
|
||
} else if (this.length > s) {
|
||
this.length -= s;
|
||
for (i = 0; i < this.length; i++) {
|
||
this.words[i] = this.words[i + s];
|
||
}
|
||
} else {
|
||
this.words[0] = 0;
|
||
this.length = 1;
|
||
}
|
||
|
||
var carry = 0;
|
||
for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
|
||
var word = this.words[i] | 0;
|
||
this.words[i] = (carry << (26 - r)) | (word >>> r);
|
||
carry = word & mask;
|
||
}
|
||
|
||
// Push carried bits as a mask
|
||
if (maskedWords && carry !== 0) {
|
||
maskedWords.words[maskedWords.length++] = carry;
|
||
}
|
||
|
||
if (this.length === 0) {
|
||
this.words[0] = 0;
|
||
this.length = 1;
|
||
}
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype.ishrn = function ishrn (bits, hint, extended) {
|
||
// TODO(indutny): implement me
|
||
assert(this.negative === 0);
|
||
return this.iushrn(bits, hint, extended);
|
||
};
|
||
|
||
// Shift-left
|
||
BN.prototype.shln = function shln (bits) {
|
||
return this.clone().ishln(bits);
|
||
};
|
||
|
||
BN.prototype.ushln = function ushln (bits) {
|
||
return this.clone().iushln(bits);
|
||
};
|
||
|
||
// Shift-right
|
||
BN.prototype.shrn = function shrn (bits) {
|
||
return this.clone().ishrn(bits);
|
||
};
|
||
|
||
BN.prototype.ushrn = function ushrn (bits) {
|
||
return this.clone().iushrn(bits);
|
||
};
|
||
|
||
// Test if n bit is set
|
||
BN.prototype.testn = function testn (bit) {
|
||
assert(typeof bit === 'number' && bit >= 0);
|
||
var r = bit % 26;
|
||
var s = (bit - r) / 26;
|
||
var q = 1 << r;
|
||
|
||
// Fast case: bit is much higher than all existing words
|
||
if (this.length <= s) return false;
|
||
|
||
// Check bit and return
|
||
var w = this.words[s];
|
||
|
||
return !!(w & q);
|
||
};
|
||
|
||
// Return only lowers bits of number (in-place)
|
||
BN.prototype.imaskn = function imaskn (bits) {
|
||
assert(typeof bits === 'number' && bits >= 0);
|
||
var r = bits % 26;
|
||
var s = (bits - r) / 26;
|
||
|
||
assert(this.negative === 0, 'imaskn works only with positive numbers');
|
||
|
||
if (this.length <= s) {
|
||
return this;
|
||
}
|
||
|
||
if (r !== 0) {
|
||
s++;
|
||
}
|
||
this.length = Math.min(s, this.length);
|
||
|
||
if (r !== 0) {
|
||
var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
|
||
this.words[this.length - 1] &= mask;
|
||
}
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
// Return only lowers bits of number
|
||
BN.prototype.maskn = function maskn (bits) {
|
||
return this.clone().imaskn(bits);
|
||
};
|
||
|
||
// Add plain number `num` to `this`
|
||
BN.prototype.iaddn = function iaddn (num) {
|
||
assert(typeof num === 'number');
|
||
assert(num < 0x4000000);
|
||
if (num < 0) return this.isubn(-num);
|
||
|
||
// Possible sign change
|
||
if (this.negative !== 0) {
|
||
if (this.length === 1 && (this.words[0] | 0) < num) {
|
||
this.words[0] = num - (this.words[0] | 0);
|
||
this.negative = 0;
|
||
return this;
|
||
}
|
||
|
||
this.negative = 0;
|
||
this.isubn(num);
|
||
this.negative = 1;
|
||
return this;
|
||
}
|
||
|
||
// Add without checks
|
||
return this._iaddn(num);
|
||
};
|
||
|
||
BN.prototype._iaddn = function _iaddn (num) {
|
||
this.words[0] += num;
|
||
|
||
// Carry
|
||
for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {
|
||
this.words[i] -= 0x4000000;
|
||
if (i === this.length - 1) {
|
||
this.words[i + 1] = 1;
|
||
} else {
|
||
this.words[i + 1]++;
|
||
}
|
||
}
|
||
this.length = Math.max(this.length, i + 1);
|
||
|
||
return this;
|
||
};
|
||
|
||
// Subtract plain number `num` from `this`
|
||
BN.prototype.isubn = function isubn (num) {
|
||
assert(typeof num === 'number');
|
||
assert(num < 0x4000000);
|
||
if (num < 0) return this.iaddn(-num);
|
||
|
||
if (this.negative !== 0) {
|
||
this.negative = 0;
|
||
this.iaddn(num);
|
||
this.negative = 1;
|
||
return this;
|
||
}
|
||
|
||
this.words[0] -= num;
|
||
|
||
if (this.length === 1 && this.words[0] < 0) {
|
||
this.words[0] = -this.words[0];
|
||
this.negative = 1;
|
||
} else {
|
||
// Carry
|
||
for (var i = 0; i < this.length && this.words[i] < 0; i++) {
|
||
this.words[i] += 0x4000000;
|
||
this.words[i + 1] -= 1;
|
||
}
|
||
}
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype.addn = function addn (num) {
|
||
return this.clone().iaddn(num);
|
||
};
|
||
|
||
BN.prototype.subn = function subn (num) {
|
||
return this.clone().isubn(num);
|
||
};
|
||
|
||
BN.prototype.iabs = function iabs () {
|
||
this.negative = 0;
|
||
|
||
return this;
|
||
};
|
||
|
||
BN.prototype.abs = function abs () {
|
||
return this.clone().iabs();
|
||
};
|
||
|
||
BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) {
|
||
var len = num.length + shift;
|
||
var i;
|
||
|
||
this._expand(len);
|
||
|
||
var w;
|
||
var carry = 0;
|
||
for (i = 0; i < num.length; i++) {
|
||
w = (this.words[i + shift] | 0) + carry;
|
||
var right = (num.words[i] | 0) * mul;
|
||
w -= right & 0x3ffffff;
|
||
carry = (w >> 26) - ((right / 0x4000000) | 0);
|
||
this.words[i + shift] = w & 0x3ffffff;
|
||
}
|
||
for (; i < this.length - shift; i++) {
|
||
w = (this.words[i + shift] | 0) + carry;
|
||
carry = w >> 26;
|
||
this.words[i + shift] = w & 0x3ffffff;
|
||
}
|
||
|
||
if (carry === 0) return this.strip();
|
||
|
||
// Subtraction overflow
|
||
assert(carry === -1);
|
||
carry = 0;
|
||
for (i = 0; i < this.length; i++) {
|
||
w = -(this.words[i] | 0) + carry;
|
||
carry = w >> 26;
|
||
this.words[i] = w & 0x3ffffff;
|
||
}
|
||
this.negative = 1;
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype._wordDiv = function _wordDiv (num, mode) {
|
||
var shift = this.length - num.length;
|
||
|
||
var a = this.clone();
|
||
var b = num;
|
||
|
||
// Normalize
|
||
var bhi = b.words[b.length - 1] | 0;
|
||
var bhiBits = this._countBits(bhi);
|
||
shift = 26 - bhiBits;
|
||
if (shift !== 0) {
|
||
b = b.ushln(shift);
|
||
a.iushln(shift);
|
||
bhi = b.words[b.length - 1] | 0;
|
||
}
|
||
|
||
// Initialize quotient
|
||
var m = a.length - b.length;
|
||
var q;
|
||
|
||
if (mode !== 'mod') {
|
||
q = new BN(null);
|
||
q.length = m + 1;
|
||
q.words = new Array(q.length);
|
||
for (var i = 0; i < q.length; i++) {
|
||
q.words[i] = 0;
|
||
}
|
||
}
|
||
|
||
var diff = a.clone()._ishlnsubmul(b, 1, m);
|
||
if (diff.negative === 0) {
|
||
a = diff;
|
||
if (q) {
|
||
q.words[m] = 1;
|
||
}
|
||
}
|
||
|
||
for (var j = m - 1; j >= 0; j--) {
|
||
var qj = (a.words[b.length + j] | 0) * 0x4000000 +
|
||
(a.words[b.length + j - 1] | 0);
|
||
|
||
// NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
|
||
// (0x7ffffff)
|
||
qj = Math.min((qj / bhi) | 0, 0x3ffffff);
|
||
|
||
a._ishlnsubmul(b, qj, j);
|
||
while (a.negative !== 0) {
|
||
qj--;
|
||
a.negative = 0;
|
||
a._ishlnsubmul(b, 1, j);
|
||
if (!a.isZero()) {
|
||
a.negative ^= 1;
|
||
}
|
||
}
|
||
if (q) {
|
||
q.words[j] = qj;
|
||
}
|
||
}
|
||
if (q) {
|
||
q.strip();
|
||
}
|
||
a.strip();
|
||
|
||
// Denormalize
|
||
if (mode !== 'div' && shift !== 0) {
|
||
a.iushrn(shift);
|
||
}
|
||
|
||
return {
|
||
div: q || null,
|
||
mod: a
|
||
};
|
||
};
|
||
|
||
// NOTE: 1) `mode` can be set to `mod` to request mod only,
|
||
// to `div` to request div only, or be absent to
|
||
// request both div & mod
|
||
// 2) `positive` is true if unsigned mod is requested
|
||
BN.prototype.divmod = function divmod (num, mode, positive) {
|
||
assert(!num.isZero());
|
||
|
||
if (this.isZero()) {
|
||
return {
|
||
div: new BN(0),
|
||
mod: new BN(0)
|
||
};
|
||
}
|
||
|
||
var div, mod, res;
|
||
if (this.negative !== 0 && num.negative === 0) {
|
||
res = this.neg().divmod(num, mode);
|
||
|
||
if (mode !== 'mod') {
|
||
div = res.div.neg();
|
||
}
|
||
|
||
if (mode !== 'div') {
|
||
mod = res.mod.neg();
|
||
if (positive && mod.negative !== 0) {
|
||
mod.iadd(num);
|
||
}
|
||
}
|
||
|
||
return {
|
||
div: div,
|
||
mod: mod
|
||
};
|
||
}
|
||
|
||
if (this.negative === 0 && num.negative !== 0) {
|
||
res = this.divmod(num.neg(), mode);
|
||
|
||
if (mode !== 'mod') {
|
||
div = res.div.neg();
|
||
}
|
||
|
||
return {
|
||
div: div,
|
||
mod: res.mod
|
||
};
|
||
}
|
||
|
||
if ((this.negative & num.negative) !== 0) {
|
||
res = this.neg().divmod(num.neg(), mode);
|
||
|
||
if (mode !== 'div') {
|
||
mod = res.mod.neg();
|
||
if (positive && mod.negative !== 0) {
|
||
mod.isub(num);
|
||
}
|
||
}
|
||
|
||
return {
|
||
div: res.div,
|
||
mod: mod
|
||
};
|
||
}
|
||
|
||
// Both numbers are positive at this point
|
||
|
||
// Strip both numbers to approximate shift value
|
||
if (num.length > this.length || this.cmp(num) < 0) {
|
||
return {
|
||
div: new BN(0),
|
||
mod: this
|
||
};
|
||
}
|
||
|
||
// Very short reduction
|
||
if (num.length === 1) {
|
||
if (mode === 'div') {
|
||
return {
|
||
div: this.divn(num.words[0]),
|
||
mod: null
|
||
};
|
||
}
|
||
|
||
if (mode === 'mod') {
|
||
return {
|
||
div: null,
|
||
mod: new BN(this.modn(num.words[0]))
|
||
};
|
||
}
|
||
|
||
return {
|
||
div: this.divn(num.words[0]),
|
||
mod: new BN(this.modn(num.words[0]))
|
||
};
|
||
}
|
||
|
||
return this._wordDiv(num, mode);
|
||
};
|
||
|
||
// Find `this` / `num`
|
||
BN.prototype.div = function div (num) {
|
||
return this.divmod(num, 'div', false).div;
|
||
};
|
||
|
||
// Find `this` % `num`
|
||
BN.prototype.mod = function mod (num) {
|
||
return this.divmod(num, 'mod', false).mod;
|
||
};
|
||
|
||
BN.prototype.umod = function umod (num) {
|
||
return this.divmod(num, 'mod', true).mod;
|
||
};
|
||
|
||
// Find Round(`this` / `num`)
|
||
BN.prototype.divRound = function divRound (num) {
|
||
var dm = this.divmod(num);
|
||
|
||
// Fast case - exact division
|
||
if (dm.mod.isZero()) return dm.div;
|
||
|
||
var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod;
|
||
|
||
var half = num.ushrn(1);
|
||
var r2 = num.andln(1);
|
||
var cmp = mod.cmp(half);
|
||
|
||
// Round down
|
||
if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div;
|
||
|
||
// Round up
|
||
return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);
|
||
};
|
||
|
||
BN.prototype.modn = function modn (num) {
|
||
assert(num <= 0x3ffffff);
|
||
var p = (1 << 26) % num;
|
||
|
||
var acc = 0;
|
||
for (var i = this.length - 1; i >= 0; i--) {
|
||
acc = (p * acc + (this.words[i] | 0)) % num;
|
||
}
|
||
|
||
return acc;
|
||
};
|
||
|
||
// In-place division by number
|
||
BN.prototype.idivn = function idivn (num) {
|
||
assert(num <= 0x3ffffff);
|
||
|
||
var carry = 0;
|
||
for (var i = this.length - 1; i >= 0; i--) {
|
||
var w = (this.words[i] | 0) + carry * 0x4000000;
|
||
this.words[i] = (w / num) | 0;
|
||
carry = w % num;
|
||
}
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype.divn = function divn (num) {
|
||
return this.clone().idivn(num);
|
||
};
|
||
|
||
BN.prototype.egcd = function egcd (p) {
|
||
assert(p.negative === 0);
|
||
assert(!p.isZero());
|
||
|
||
var x = this;
|
||
var y = p.clone();
|
||
|
||
if (x.negative !== 0) {
|
||
x = x.umod(p);
|
||
} else {
|
||
x = x.clone();
|
||
}
|
||
|
||
// A * x + B * y = x
|
||
var A = new BN(1);
|
||
var B = new BN(0);
|
||
|
||
// C * x + D * y = y
|
||
var C = new BN(0);
|
||
var D = new BN(1);
|
||
|
||
var g = 0;
|
||
|
||
while (x.isEven() && y.isEven()) {
|
||
x.iushrn(1);
|
||
y.iushrn(1);
|
||
++g;
|
||
}
|
||
|
||
var yp = y.clone();
|
||
var xp = x.clone();
|
||
|
||
while (!x.isZero()) {
|
||
for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
|
||
if (i > 0) {
|
||
x.iushrn(i);
|
||
while (i-- > 0) {
|
||
if (A.isOdd() || B.isOdd()) {
|
||
A.iadd(yp);
|
||
B.isub(xp);
|
||
}
|
||
|
||
A.iushrn(1);
|
||
B.iushrn(1);
|
||
}
|
||
}
|
||
|
||
for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
|
||
if (j > 0) {
|
||
y.iushrn(j);
|
||
while (j-- > 0) {
|
||
if (C.isOdd() || D.isOdd()) {
|
||
C.iadd(yp);
|
||
D.isub(xp);
|
||
}
|
||
|
||
C.iushrn(1);
|
||
D.iushrn(1);
|
||
}
|
||
}
|
||
|
||
if (x.cmp(y) >= 0) {
|
||
x.isub(y);
|
||
A.isub(C);
|
||
B.isub(D);
|
||
} else {
|
||
y.isub(x);
|
||
C.isub(A);
|
||
D.isub(B);
|
||
}
|
||
}
|
||
|
||
return {
|
||
a: C,
|
||
b: D,
|
||
gcd: y.iushln(g)
|
||
};
|
||
};
|
||
|
||
// This is reduced incarnation of the binary EEA
|
||
// above, designated to invert members of the
|
||
// _prime_ fields F(p) at a maximal speed
|
||
BN.prototype._invmp = function _invmp (p) {
|
||
assert(p.negative === 0);
|
||
assert(!p.isZero());
|
||
|
||
var a = this;
|
||
var b = p.clone();
|
||
|
||
if (a.negative !== 0) {
|
||
a = a.umod(p);
|
||
} else {
|
||
a = a.clone();
|
||
}
|
||
|
||
var x1 = new BN(1);
|
||
var x2 = new BN(0);
|
||
|
||
var delta = b.clone();
|
||
|
||
while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {
|
||
for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
|
||
if (i > 0) {
|
||
a.iushrn(i);
|
||
while (i-- > 0) {
|
||
if (x1.isOdd()) {
|
||
x1.iadd(delta);
|
||
}
|
||
|
||
x1.iushrn(1);
|
||
}
|
||
}
|
||
|
||
for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
|
||
if (j > 0) {
|
||
b.iushrn(j);
|
||
while (j-- > 0) {
|
||
if (x2.isOdd()) {
|
||
x2.iadd(delta);
|
||
}
|
||
|
||
x2.iushrn(1);
|
||
}
|
||
}
|
||
|
||
if (a.cmp(b) >= 0) {
|
||
a.isub(b);
|
||
x1.isub(x2);
|
||
} else {
|
||
b.isub(a);
|
||
x2.isub(x1);
|
||
}
|
||
}
|
||
|
||
var res;
|
||
if (a.cmpn(1) === 0) {
|
||
res = x1;
|
||
} else {
|
||
res = x2;
|
||
}
|
||
|
||
if (res.cmpn(0) < 0) {
|
||
res.iadd(p);
|
||
}
|
||
|
||
return res;
|
||
};
|
||
|
||
BN.prototype.gcd = function gcd (num) {
|
||
if (this.isZero()) return num.abs();
|
||
if (num.isZero()) return this.abs();
|
||
|
||
var a = this.clone();
|
||
var b = num.clone();
|
||
a.negative = 0;
|
||
b.negative = 0;
|
||
|
||
// Remove common factor of two
|
||
for (var shift = 0; a.isEven() && b.isEven(); shift++) {
|
||
a.iushrn(1);
|
||
b.iushrn(1);
|
||
}
|
||
|
||
do {
|
||
while (a.isEven()) {
|
||
a.iushrn(1);
|
||
}
|
||
while (b.isEven()) {
|
||
b.iushrn(1);
|
||
}
|
||
|
||
var r = a.cmp(b);
|
||
if (r < 0) {
|
||
// Swap `a` and `b` to make `a` always bigger than `b`
|
||
var t = a;
|
||
a = b;
|
||
b = t;
|
||
} else if (r === 0 || b.cmpn(1) === 0) {
|
||
break;
|
||
}
|
||
|
||
a.isub(b);
|
||
} while (true);
|
||
|
||
return b.iushln(shift);
|
||
};
|
||
|
||
// Invert number in the field F(num)
|
||
BN.prototype.invm = function invm (num) {
|
||
return this.egcd(num).a.umod(num);
|
||
};
|
||
|
||
BN.prototype.isEven = function isEven () {
|
||
return (this.words[0] & 1) === 0;
|
||
};
|
||
|
||
BN.prototype.isOdd = function isOdd () {
|
||
return (this.words[0] & 1) === 1;
|
||
};
|
||
|
||
// And first word and num
|
||
BN.prototype.andln = function andln (num) {
|
||
return this.words[0] & num;
|
||
};
|
||
|
||
// Increment at the bit position in-line
|
||
BN.prototype.bincn = function bincn (bit) {
|
||
assert(typeof bit === 'number');
|
||
var r = bit % 26;
|
||
var s = (bit - r) / 26;
|
||
var q = 1 << r;
|
||
|
||
// Fast case: bit is much higher than all existing words
|
||
if (this.length <= s) {
|
||
this._expand(s + 1);
|
||
this.words[s] |= q;
|
||
return this;
|
||
}
|
||
|
||
// Add bit and propagate, if needed
|
||
var carry = q;
|
||
for (var i = s; carry !== 0 && i < this.length; i++) {
|
||
var w = this.words[i] | 0;
|
||
w += carry;
|
||
carry = w >>> 26;
|
||
w &= 0x3ffffff;
|
||
this.words[i] = w;
|
||
}
|
||
if (carry !== 0) {
|
||
this.words[i] = carry;
|
||
this.length++;
|
||
}
|
||
return this;
|
||
};
|
||
|
||
BN.prototype.isZero = function isZero () {
|
||
return this.length === 1 && this.words[0] === 0;
|
||
};
|
||
|
||
BN.prototype.cmpn = function cmpn (num) {
|
||
var negative = num < 0;
|
||
|
||
if (this.negative !== 0 && !negative) return -1;
|
||
if (this.negative === 0 && negative) return 1;
|
||
|
||
this.strip();
|
||
|
||
var res;
|
||
if (this.length > 1) {
|
||
res = 1;
|
||
} else {
|
||
if (negative) {
|
||
num = -num;
|
||
}
|
||
|
||
assert(num <= 0x3ffffff, 'Number is too big');
|
||
|
||
var w = this.words[0] | 0;
|
||
res = w === num ? 0 : w < num ? -1 : 1;
|
||
}
|
||
if (this.negative !== 0) return -res | 0;
|
||
return res;
|
||
};
|
||
|
||
// Compare two numbers and return:
|
||
// 1 - if `this` > `num`
|
||
// 0 - if `this` == `num`
|
||
// -1 - if `this` < `num`
|
||
BN.prototype.cmp = function cmp (num) {
|
||
if (this.negative !== 0 && num.negative === 0) return -1;
|
||
if (this.negative === 0 && num.negative !== 0) return 1;
|
||
|
||
var res = this.ucmp(num);
|
||
if (this.negative !== 0) return -res | 0;
|
||
return res;
|
||
};
|
||
|
||
// Unsigned comparison
|
||
BN.prototype.ucmp = function ucmp (num) {
|
||
// At this point both numbers have the same sign
|
||
if (this.length > num.length) return 1;
|
||
if (this.length < num.length) return -1;
|
||
|
||
var res = 0;
|
||
for (var i = this.length - 1; i >= 0; i--) {
|
||
var a = this.words[i] | 0;
|
||
var b = num.words[i] | 0;
|
||
|
||
if (a === b) continue;
|
||
if (a < b) {
|
||
res = -1;
|
||
} else if (a > b) {
|
||
res = 1;
|
||
}
|
||
break;
|
||
}
|
||
return res;
|
||
};
|
||
|
||
BN.prototype.gtn = function gtn (num) {
|
||
return this.cmpn(num) === 1;
|
||
};
|
||
|
||
BN.prototype.gt = function gt (num) {
|
||
return this.cmp(num) === 1;
|
||
};
|
||
|
||
BN.prototype.gten = function gten (num) {
|
||
return this.cmpn(num) >= 0;
|
||
};
|
||
|
||
BN.prototype.gte = function gte (num) {
|
||
return this.cmp(num) >= 0;
|
||
};
|
||
|
||
BN.prototype.ltn = function ltn (num) {
|
||
return this.cmpn(num) === -1;
|
||
};
|
||
|
||
BN.prototype.lt = function lt (num) {
|
||
return this.cmp(num) === -1;
|
||
};
|
||
|
||
BN.prototype.lten = function lten (num) {
|
||
return this.cmpn(num) <= 0;
|
||
};
|
||
|
||
BN.prototype.lte = function lte (num) {
|
||
return this.cmp(num) <= 0;
|
||
};
|
||
|
||
BN.prototype.eqn = function eqn (num) {
|
||
return this.cmpn(num) === 0;
|
||
};
|
||
|
||
BN.prototype.eq = function eq (num) {
|
||
return this.cmp(num) === 0;
|
||
};
|
||
|
||
//
|
||
// A reduce context, could be using montgomery or something better, depending
|
||
// on the `m` itself.
|
||
//
|
||
BN.red = function red (num) {
|
||
return new Red(num);
|
||
};
|
||
|
||
BN.prototype.toRed = function toRed (ctx) {
|
||
assert(!this.red, 'Already a number in reduction context');
|
||
assert(this.negative === 0, 'red works only with positives');
|
||
return ctx.convertTo(this)._forceRed(ctx);
|
||
};
|
||
|
||
BN.prototype.fromRed = function fromRed () {
|
||
assert(this.red, 'fromRed works only with numbers in reduction context');
|
||
return this.red.convertFrom(this);
|
||
};
|
||
|
||
BN.prototype._forceRed = function _forceRed (ctx) {
|
||
this.red = ctx;
|
||
return this;
|
||
};
|
||
|
||
BN.prototype.forceRed = function forceRed (ctx) {
|
||
assert(!this.red, 'Already a number in reduction context');
|
||
return this._forceRed(ctx);
|
||
};
|
||
|
||
BN.prototype.redAdd = function redAdd (num) {
|
||
assert(this.red, 'redAdd works only with red numbers');
|
||
return this.red.add(this, num);
|
||
};
|
||
|
||
BN.prototype.redIAdd = function redIAdd (num) {
|
||
assert(this.red, 'redIAdd works only with red numbers');
|
||
return this.red.iadd(this, num);
|
||
};
|
||
|
||
BN.prototype.redSub = function redSub (num) {
|
||
assert(this.red, 'redSub works only with red numbers');
|
||
return this.red.sub(this, num);
|
||
};
|
||
|
||
BN.prototype.redISub = function redISub (num) {
|
||
assert(this.red, 'redISub works only with red numbers');
|
||
return this.red.isub(this, num);
|
||
};
|
||
|
||
BN.prototype.redShl = function redShl (num) {
|
||
assert(this.red, 'redShl works only with red numbers');
|
||
return this.red.shl(this, num);
|
||
};
|
||
|
||
BN.prototype.redMul = function redMul (num) {
|
||
assert(this.red, 'redMul works only with red numbers');
|
||
this.red._verify2(this, num);
|
||
return this.red.mul(this, num);
|
||
};
|
||
|
||
BN.prototype.redIMul = function redIMul (num) {
|
||
assert(this.red, 'redMul works only with red numbers');
|
||
this.red._verify2(this, num);
|
||
return this.red.imul(this, num);
|
||
};
|
||
|
||
BN.prototype.redSqr = function redSqr () {
|
||
assert(this.red, 'redSqr works only with red numbers');
|
||
this.red._verify1(this);
|
||
return this.red.sqr(this);
|
||
};
|
||
|
||
BN.prototype.redISqr = function redISqr () {
|
||
assert(this.red, 'redISqr works only with red numbers');
|
||
this.red._verify1(this);
|
||
return this.red.isqr(this);
|
||
};
|
||
|
||
// Square root over p
|
||
BN.prototype.redSqrt = function redSqrt () {
|
||
assert(this.red, 'redSqrt works only with red numbers');
|
||
this.red._verify1(this);
|
||
return this.red.sqrt(this);
|
||
};
|
||
|
||
BN.prototype.redInvm = function redInvm () {
|
||
assert(this.red, 'redInvm works only with red numbers');
|
||
this.red._verify1(this);
|
||
return this.red.invm(this);
|
||
};
|
||
|
||
// Return negative clone of `this` % `red modulo`
|
||
BN.prototype.redNeg = function redNeg () {
|
||
assert(this.red, 'redNeg works only with red numbers');
|
||
this.red._verify1(this);
|
||
return this.red.neg(this);
|
||
};
|
||
|
||
BN.prototype.redPow = function redPow (num) {
|
||
assert(this.red && !num.red, 'redPow(normalNum)');
|
||
this.red._verify1(this);
|
||
return this.red.pow(this, num);
|
||
};
|
||
|
||
// Prime numbers with efficient reduction
|
||
var primes = {
|
||
k256: null,
|
||
p224: null,
|
||
p192: null,
|
||
p25519: null
|
||
};
|
||
|
||
// Pseudo-Mersenne prime
|
||
function MPrime (name, p) {
|
||
// P = 2 ^ N - K
|
||
this.name = name;
|
||
this.p = new BN(p, 16);
|
||
this.n = this.p.bitLength();
|
||
this.k = new BN(1).iushln(this.n).isub(this.p);
|
||
|
||
this.tmp = this._tmp();
|
||
}
|
||
|
||
MPrime.prototype._tmp = function _tmp () {
|
||
var tmp = new BN(null);
|
||
tmp.words = new Array(Math.ceil(this.n / 13));
|
||
return tmp;
|
||
};
|
||
|
||
MPrime.prototype.ireduce = function ireduce (num) {
|
||
// Assumes that `num` is less than `P^2`
|
||
// num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
|
||
var r = num;
|
||
var rlen;
|
||
|
||
do {
|
||
this.split(r, this.tmp);
|
||
r = this.imulK(r);
|
||
r = r.iadd(this.tmp);
|
||
rlen = r.bitLength();
|
||
} while (rlen > this.n);
|
||
|
||
var cmp = rlen < this.n ? -1 : r.ucmp(this.p);
|
||
if (cmp === 0) {
|
||
r.words[0] = 0;
|
||
r.length = 1;
|
||
} else if (cmp > 0) {
|
||
r.isub(this.p);
|
||
} else {
|
||
r.strip();
|
||
}
|
||
|
||
return r;
|
||
};
|
||
|
||
MPrime.prototype.split = function split (input, out) {
|
||
input.iushrn(this.n, 0, out);
|
||
};
|
||
|
||
MPrime.prototype.imulK = function imulK (num) {
|
||
return num.imul(this.k);
|
||
};
|
||
|
||
function K256 () {
|
||
MPrime.call(
|
||
this,
|
||
'k256',
|
||
'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
|
||
}
|
||
inherits(K256, MPrime);
|
||
|
||
K256.prototype.split = function split (input, output) {
|
||
// 256 = 9 * 26 + 22
|
||
var mask = 0x3fffff;
|
||
|
||
var outLen = Math.min(input.length, 9);
|
||
for (var i = 0; i < outLen; i++) {
|
||
output.words[i] = input.words[i];
|
||
}
|
||
output.length = outLen;
|
||
|
||
if (input.length <= 9) {
|
||
input.words[0] = 0;
|
||
input.length = 1;
|
||
return;
|
||
}
|
||
|
||
// Shift by 9 limbs
|
||
var prev = input.words[9];
|
||
output.words[output.length++] = prev & mask;
|
||
|
||
for (i = 10; i < input.length; i++) {
|
||
var next = input.words[i] | 0;
|
||
input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);
|
||
prev = next;
|
||
}
|
||
prev >>>= 22;
|
||
input.words[i - 10] = prev;
|
||
if (prev === 0 && input.length > 10) {
|
||
input.length -= 10;
|
||
} else {
|
||
input.length -= 9;
|
||
}
|
||
};
|
||
|
||
K256.prototype.imulK = function imulK (num) {
|
||
// K = 0x1000003d1 = [ 0x40, 0x3d1 ]
|
||
num.words[num.length] = 0;
|
||
num.words[num.length + 1] = 0;
|
||
num.length += 2;
|
||
|
||
// bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
|
||
var lo = 0;
|
||
for (var i = 0; i < num.length; i++) {
|
||
var w = num.words[i] | 0;
|
||
lo += w * 0x3d1;
|
||
num.words[i] = lo & 0x3ffffff;
|
||
lo = w * 0x40 + ((lo / 0x4000000) | 0);
|
||
}
|
||
|
||
// Fast length reduction
|
||
if (num.words[num.length - 1] === 0) {
|
||
num.length--;
|
||
if (num.words[num.length - 1] === 0) {
|
||
num.length--;
|
||
}
|
||
}
|
||
return num;
|
||
};
|
||
|
||
function P224 () {
|
||
MPrime.call(
|
||
this,
|
||
'p224',
|
||
'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
|
||
}
|
||
inherits(P224, MPrime);
|
||
|
||
function P192 () {
|
||
MPrime.call(
|
||
this,
|
||
'p192',
|
||
'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
|
||
}
|
||
inherits(P192, MPrime);
|
||
|
||
function P25519 () {
|
||
// 2 ^ 255 - 19
|
||
MPrime.call(
|
||
this,
|
||
'25519',
|
||
'7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
|
||
}
|
||
inherits(P25519, MPrime);
|
||
|
||
P25519.prototype.imulK = function imulK (num) {
|
||
// K = 0x13
|
||
var carry = 0;
|
||
for (var i = 0; i < num.length; i++) {
|
||
var hi = (num.words[i] | 0) * 0x13 + carry;
|
||
var lo = hi & 0x3ffffff;
|
||
hi >>>= 26;
|
||
|
||
num.words[i] = lo;
|
||
carry = hi;
|
||
}
|
||
if (carry !== 0) {
|
||
num.words[num.length++] = carry;
|
||
}
|
||
return num;
|
||
};
|
||
|
||
// Exported mostly for testing purposes, use plain name instead
|
||
BN._prime = function prime (name) {
|
||
// Cached version of prime
|
||
if (primes[name]) return primes[name];
|
||
|
||
var prime;
|
||
if (name === 'k256') {
|
||
prime = new K256();
|
||
} else if (name === 'p224') {
|
||
prime = new P224();
|
||
} else if (name === 'p192') {
|
||
prime = new P192();
|
||
} else if (name === 'p25519') {
|
||
prime = new P25519();
|
||
} else {
|
||
throw new Error('Unknown prime ' + name);
|
||
}
|
||
primes[name] = prime;
|
||
|
||
return prime;
|
||
};
|
||
|
||
//
|
||
// Base reduction engine
|
||
//
|
||
function Red (m) {
|
||
if (typeof m === 'string') {
|
||
var prime = BN._prime(m);
|
||
this.m = prime.p;
|
||
this.prime = prime;
|
||
} else {
|
||
assert(m.gtn(1), 'modulus must be greater than 1');
|
||
this.m = m;
|
||
this.prime = null;
|
||
}
|
||
}
|
||
|
||
Red.prototype._verify1 = function _verify1 (a) {
|
||
assert(a.negative === 0, 'red works only with positives');
|
||
assert(a.red, 'red works only with red numbers');
|
||
};
|
||
|
||
Red.prototype._verify2 = function _verify2 (a, b) {
|
||
assert((a.negative | b.negative) === 0, 'red works only with positives');
|
||
assert(a.red && a.red === b.red,
|
||
'red works only with red numbers');
|
||
};
|
||
|
||
Red.prototype.imod = function imod (a) {
|
||
if (this.prime) return this.prime.ireduce(a)._forceRed(this);
|
||
return a.umod(this.m)._forceRed(this);
|
||
};
|
||
|
||
Red.prototype.neg = function neg (a) {
|
||
if (a.isZero()) {
|
||
return a.clone();
|
||
}
|
||
|
||
return this.m.sub(a)._forceRed(this);
|
||
};
|
||
|
||
Red.prototype.add = function add (a, b) {
|
||
this._verify2(a, b);
|
||
|
||
var res = a.add(b);
|
||
if (res.cmp(this.m) >= 0) {
|
||
res.isub(this.m);
|
||
}
|
||
return res._forceRed(this);
|
||
};
|
||
|
||
Red.prototype.iadd = function iadd (a, b) {
|
||
this._verify2(a, b);
|
||
|
||
var res = a.iadd(b);
|
||
if (res.cmp(this.m) >= 0) {
|
||
res.isub(this.m);
|
||
}
|
||
return res;
|
||
};
|
||
|
||
Red.prototype.sub = function sub (a, b) {
|
||
this._verify2(a, b);
|
||
|
||
var res = a.sub(b);
|
||
if (res.cmpn(0) < 0) {
|
||
res.iadd(this.m);
|
||
}
|
||
return res._forceRed(this);
|
||
};
|
||
|
||
Red.prototype.isub = function isub (a, b) {
|
||
this._verify2(a, b);
|
||
|
||
var res = a.isub(b);
|
||
if (res.cmpn(0) < 0) {
|
||
res.iadd(this.m);
|
||
}
|
||
return res;
|
||
};
|
||
|
||
Red.prototype.shl = function shl (a, num) {
|
||
this._verify1(a);
|
||
return this.imod(a.ushln(num));
|
||
};
|
||
|
||
Red.prototype.imul = function imul (a, b) {
|
||
this._verify2(a, b);
|
||
return this.imod(a.imul(b));
|
||
};
|
||
|
||
Red.prototype.mul = function mul (a, b) {
|
||
this._verify2(a, b);
|
||
return this.imod(a.mul(b));
|
||
};
|
||
|
||
Red.prototype.isqr = function isqr (a) {
|
||
return this.imul(a, a.clone());
|
||
};
|
||
|
||
Red.prototype.sqr = function sqr (a) {
|
||
return this.mul(a, a);
|
||
};
|
||
|
||
Red.prototype.sqrt = function sqrt (a) {
|
||
if (a.isZero()) return a.clone();
|
||
|
||
var mod3 = this.m.andln(3);
|
||
assert(mod3 % 2 === 1);
|
||
|
||
// Fast case
|
||
if (mod3 === 3) {
|
||
var pow = this.m.add(new BN(1)).iushrn(2);
|
||
return this.pow(a, pow);
|
||
}
|
||
|
||
// Tonelli-Shanks algorithm (Totally unoptimized and slow)
|
||
//
|
||
// Find Q and S, that Q * 2 ^ S = (P - 1)
|
||
var q = this.m.subn(1);
|
||
var s = 0;
|
||
while (!q.isZero() && q.andln(1) === 0) {
|
||
s++;
|
||
q.iushrn(1);
|
||
}
|
||
assert(!q.isZero());
|
||
|
||
var one = new BN(1).toRed(this);
|
||
var nOne = one.redNeg();
|
||
|
||
// Find quadratic non-residue
|
||
// NOTE: Max is such because of generalized Riemann hypothesis.
|
||
var lpow = this.m.subn(1).iushrn(1);
|
||
var z = this.m.bitLength();
|
||
z = new BN(2 * z * z).toRed(this);
|
||
|
||
while (this.pow(z, lpow).cmp(nOne) !== 0) {
|
||
z.redIAdd(nOne);
|
||
}
|
||
|
||
var c = this.pow(z, q);
|
||
var r = this.pow(a, q.addn(1).iushrn(1));
|
||
var t = this.pow(a, q);
|
||
var m = s;
|
||
while (t.cmp(one) !== 0) {
|
||
var tmp = t;
|
||
for (var i = 0; tmp.cmp(one) !== 0; i++) {
|
||
tmp = tmp.redSqr();
|
||
}
|
||
assert(i < m);
|
||
var b = this.pow(c, new BN(1).iushln(m - i - 1));
|
||
|
||
r = r.redMul(b);
|
||
c = b.redSqr();
|
||
t = t.redMul(c);
|
||
m = i;
|
||
}
|
||
|
||
return r;
|
||
};
|
||
|
||
Red.prototype.invm = function invm (a) {
|
||
var inv = a._invmp(this.m);
|
||
if (inv.negative !== 0) {
|
||
inv.negative = 0;
|
||
return this.imod(inv).redNeg();
|
||
} else {
|
||
return this.imod(inv);
|
||
}
|
||
};
|
||
|
||
Red.prototype.pow = function pow (a, num) {
|
||
if (num.isZero()) return new BN(1).toRed(this);
|
||
if (num.cmpn(1) === 0) return a.clone();
|
||
|
||
var windowSize = 4;
|
||
var wnd = new Array(1 << windowSize);
|
||
wnd[0] = new BN(1).toRed(this);
|
||
wnd[1] = a;
|
||
for (var i = 2; i < wnd.length; i++) {
|
||
wnd[i] = this.mul(wnd[i - 1], a);
|
||
}
|
||
|
||
var res = wnd[0];
|
||
var current = 0;
|
||
var currentLen = 0;
|
||
var start = num.bitLength() % 26;
|
||
if (start === 0) {
|
||
start = 26;
|
||
}
|
||
|
||
for (i = num.length - 1; i >= 0; i--) {
|
||
var word = num.words[i];
|
||
for (var j = start - 1; j >= 0; j--) {
|
||
var bit = (word >> j) & 1;
|
||
if (res !== wnd[0]) {
|
||
res = this.sqr(res);
|
||
}
|
||
|
||
if (bit === 0 && current === 0) {
|
||
currentLen = 0;
|
||
continue;
|
||
}
|
||
|
||
current <<= 1;
|
||
current |= bit;
|
||
currentLen++;
|
||
if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue;
|
||
|
||
res = this.mul(res, wnd[current]);
|
||
currentLen = 0;
|
||
current = 0;
|
||
}
|
||
start = 26;
|
||
}
|
||
|
||
return res;
|
||
};
|
||
|
||
Red.prototype.convertTo = function convertTo (num) {
|
||
var r = num.umod(this.m);
|
||
|
||
return r === num ? r.clone() : r;
|
||
};
|
||
|
||
Red.prototype.convertFrom = function convertFrom (num) {
|
||
var res = num.clone();
|
||
res.red = null;
|
||
return res;
|
||
};
|
||
|
||
//
|
||
// Montgomery method engine
|
||
//
|
||
|
||
BN.mont = function mont (num) {
|
||
return new Mont(num);
|
||
};
|
||
|
||
function Mont (m) {
|
||
Red.call(this, m);
|
||
|
||
this.shift = this.m.bitLength();
|
||
if (this.shift % 26 !== 0) {
|
||
this.shift += 26 - (this.shift % 26);
|
||
}
|
||
|
||
this.r = new BN(1).iushln(this.shift);
|
||
this.r2 = this.imod(this.r.sqr());
|
||
this.rinv = this.r._invmp(this.m);
|
||
|
||
this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);
|
||
this.minv = this.minv.umod(this.r);
|
||
this.minv = this.r.sub(this.minv);
|
||
}
|
||
inherits(Mont, Red);
|
||
|
||
Mont.prototype.convertTo = function convertTo (num) {
|
||
return this.imod(num.ushln(this.shift));
|
||
};
|
||
|
||
Mont.prototype.convertFrom = function convertFrom (num) {
|
||
var r = this.imod(num.mul(this.rinv));
|
||
r.red = null;
|
||
return r;
|
||
};
|
||
|
||
Mont.prototype.imul = function imul (a, b) {
|
||
if (a.isZero() || b.isZero()) {
|
||
a.words[0] = 0;
|
||
a.length = 1;
|
||
return a;
|
||
}
|
||
|
||
var t = a.imul(b);
|
||
var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
|
||
var u = t.isub(c).iushrn(this.shift);
|
||
var res = u;
|
||
|
||
if (u.cmp(this.m) >= 0) {
|
||
res = u.isub(this.m);
|
||
} else if (u.cmpn(0) < 0) {
|
||
res = u.iadd(this.m);
|
||
}
|
||
|
||
return res._forceRed(this);
|
||
};
|
||
|
||
Mont.prototype.mul = function mul (a, b) {
|
||
if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this);
|
||
|
||
var t = a.mul(b);
|
||
var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
|
||
var u = t.isub(c).iushrn(this.shift);
|
||
var res = u;
|
||
if (u.cmp(this.m) >= 0) {
|
||
res = u.isub(this.m);
|
||
} else if (u.cmpn(0) < 0) {
|
||
res = u.iadd(this.m);
|
||
}
|
||
|
||
return res._forceRed(this);
|
||
};
|
||
|
||
Mont.prototype.invm = function invm (a) {
|
||
// (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
|
||
var res = this.imod(a._invmp(this.m).mul(this.r2));
|
||
return res._forceRed(this);
|
||
};
|
||
})( false || module, this);
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/module.js */ "./node_modules/webpack/buildin/module.js")(module)))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/brorand/index.js":
|
||
/*!***************************************!*\
|
||
!*** ./node_modules/brorand/index.js ***!
|
||
\***************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var r;
|
||
|
||
module.exports = function rand(len) {
|
||
if (!r)
|
||
r = new Rand(null);
|
||
|
||
return r.generate(len);
|
||
};
|
||
|
||
function Rand(rand) {
|
||
this.rand = rand;
|
||
}
|
||
module.exports.Rand = Rand;
|
||
|
||
Rand.prototype.generate = function generate(len) {
|
||
return this._rand(len);
|
||
};
|
||
|
||
// Emulate crypto API using randy
|
||
Rand.prototype._rand = function _rand(n) {
|
||
if (this.rand.getBytes)
|
||
return this.rand.getBytes(n);
|
||
|
||
var res = new Uint8Array(n);
|
||
for (var i = 0; i < res.length; i++)
|
||
res[i] = this.rand.getByte();
|
||
return res;
|
||
};
|
||
|
||
if (typeof self === 'object') {
|
||
if (self.crypto && self.crypto.getRandomValues) {
|
||
// Modern browsers
|
||
Rand.prototype._rand = function _rand(n) {
|
||
var arr = new Uint8Array(n);
|
||
self.crypto.getRandomValues(arr);
|
||
return arr;
|
||
};
|
||
} else if (self.msCrypto && self.msCrypto.getRandomValues) {
|
||
// IE
|
||
Rand.prototype._rand = function _rand(n) {
|
||
var arr = new Uint8Array(n);
|
||
self.msCrypto.getRandomValues(arr);
|
||
return arr;
|
||
};
|
||
|
||
// Safari's WebWorkers do not have `crypto`
|
||
} else if (typeof window === 'object') {
|
||
// Old junk
|
||
Rand.prototype._rand = function() {
|
||
throw new Error('Not implemented yet');
|
||
};
|
||
}
|
||
} else {
|
||
// Node.js or Web worker with no crypto support
|
||
try {
|
||
var crypto = __webpack_require__(/*! crypto */ 3);
|
||
if (typeof crypto.randomBytes !== 'function')
|
||
throw new Error('Not supported');
|
||
|
||
Rand.prototype._rand = function _rand(n) {
|
||
return crypto.randomBytes(n);
|
||
};
|
||
} catch (e) {
|
||
}
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-aes/aes.js":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/browserify-aes/aes.js ***!
|
||
\********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
// based on the aes implimentation in triple sec
|
||
// https://github.com/keybase/triplesec
|
||
// which is in turn based on the one from crypto-js
|
||
// https://code.google.com/p/crypto-js/
|
||
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
function asUInt32Array (buf) {
|
||
if (!Buffer.isBuffer(buf)) buf = Buffer.from(buf)
|
||
|
||
var len = (buf.length / 4) | 0
|
||
var out = new Array(len)
|
||
|
||
for (var i = 0; i < len; i++) {
|
||
out[i] = buf.readUInt32BE(i * 4)
|
||
}
|
||
|
||
return out
|
||
}
|
||
|
||
function scrubVec (v) {
|
||
for (var i = 0; i < v.length; v++) {
|
||
v[i] = 0
|
||
}
|
||
}
|
||
|
||
function cryptBlock (M, keySchedule, SUB_MIX, SBOX, nRounds) {
|
||
var SUB_MIX0 = SUB_MIX[0]
|
||
var SUB_MIX1 = SUB_MIX[1]
|
||
var SUB_MIX2 = SUB_MIX[2]
|
||
var SUB_MIX3 = SUB_MIX[3]
|
||
|
||
var s0 = M[0] ^ keySchedule[0]
|
||
var s1 = M[1] ^ keySchedule[1]
|
||
var s2 = M[2] ^ keySchedule[2]
|
||
var s3 = M[3] ^ keySchedule[3]
|
||
var t0, t1, t2, t3
|
||
var ksRow = 4
|
||
|
||
for (var round = 1; round < nRounds; round++) {
|
||
t0 = SUB_MIX0[s0 >>> 24] ^ SUB_MIX1[(s1 >>> 16) & 0xff] ^ SUB_MIX2[(s2 >>> 8) & 0xff] ^ SUB_MIX3[s3 & 0xff] ^ keySchedule[ksRow++]
|
||
t1 = SUB_MIX0[s1 >>> 24] ^ SUB_MIX1[(s2 >>> 16) & 0xff] ^ SUB_MIX2[(s3 >>> 8) & 0xff] ^ SUB_MIX3[s0 & 0xff] ^ keySchedule[ksRow++]
|
||
t2 = SUB_MIX0[s2 >>> 24] ^ SUB_MIX1[(s3 >>> 16) & 0xff] ^ SUB_MIX2[(s0 >>> 8) & 0xff] ^ SUB_MIX3[s1 & 0xff] ^ keySchedule[ksRow++]
|
||
t3 = SUB_MIX0[s3 >>> 24] ^ SUB_MIX1[(s0 >>> 16) & 0xff] ^ SUB_MIX2[(s1 >>> 8) & 0xff] ^ SUB_MIX3[s2 & 0xff] ^ keySchedule[ksRow++]
|
||
s0 = t0
|
||
s1 = t1
|
||
s2 = t2
|
||
s3 = t3
|
||
}
|
||
|
||
t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++]
|
||
t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++]
|
||
t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++]
|
||
t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++]
|
||
t0 = t0 >>> 0
|
||
t1 = t1 >>> 0
|
||
t2 = t2 >>> 0
|
||
t3 = t3 >>> 0
|
||
|
||
return [t0, t1, t2, t3]
|
||
}
|
||
|
||
// AES constants
|
||
var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]
|
||
var G = (function () {
|
||
// Compute double table
|
||
var d = new Array(256)
|
||
for (var j = 0; j < 256; j++) {
|
||
if (j < 128) {
|
||
d[j] = j << 1
|
||
} else {
|
||
d[j] = (j << 1) ^ 0x11b
|
||
}
|
||
}
|
||
|
||
var SBOX = []
|
||
var INV_SBOX = []
|
||
var SUB_MIX = [[], [], [], []]
|
||
var INV_SUB_MIX = [[], [], [], []]
|
||
|
||
// Walk GF(2^8)
|
||
var x = 0
|
||
var xi = 0
|
||
for (var i = 0; i < 256; ++i) {
|
||
// Compute sbox
|
||
var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4)
|
||
sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63
|
||
SBOX[x] = sx
|
||
INV_SBOX[sx] = x
|
||
|
||
// Compute multiplication
|
||
var x2 = d[x]
|
||
var x4 = d[x2]
|
||
var x8 = d[x4]
|
||
|
||
// Compute sub bytes, mix columns tables
|
||
var t = (d[sx] * 0x101) ^ (sx * 0x1010100)
|
||
SUB_MIX[0][x] = (t << 24) | (t >>> 8)
|
||
SUB_MIX[1][x] = (t << 16) | (t >>> 16)
|
||
SUB_MIX[2][x] = (t << 8) | (t >>> 24)
|
||
SUB_MIX[3][x] = t
|
||
|
||
// Compute inv sub bytes, inv mix columns tables
|
||
t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100)
|
||
INV_SUB_MIX[0][sx] = (t << 24) | (t >>> 8)
|
||
INV_SUB_MIX[1][sx] = (t << 16) | (t >>> 16)
|
||
INV_SUB_MIX[2][sx] = (t << 8) | (t >>> 24)
|
||
INV_SUB_MIX[3][sx] = t
|
||
|
||
if (x === 0) {
|
||
x = xi = 1
|
||
} else {
|
||
x = x2 ^ d[d[d[x8 ^ x2]]]
|
||
xi ^= d[d[xi]]
|
||
}
|
||
}
|
||
|
||
return {
|
||
SBOX: SBOX,
|
||
INV_SBOX: INV_SBOX,
|
||
SUB_MIX: SUB_MIX,
|
||
INV_SUB_MIX: INV_SUB_MIX
|
||
}
|
||
})()
|
||
|
||
function AES (key) {
|
||
this._key = asUInt32Array(key)
|
||
this._reset()
|
||
}
|
||
|
||
AES.blockSize = 4 * 4
|
||
AES.keySize = 256 / 8
|
||
AES.prototype.blockSize = AES.blockSize
|
||
AES.prototype.keySize = AES.keySize
|
||
AES.prototype._reset = function () {
|
||
var keyWords = this._key
|
||
var keySize = keyWords.length
|
||
var nRounds = keySize + 6
|
||
var ksRows = (nRounds + 1) * 4
|
||
|
||
var keySchedule = []
|
||
for (var k = 0; k < keySize; k++) {
|
||
keySchedule[k] = keyWords[k]
|
||
}
|
||
|
||
for (k = keySize; k < ksRows; k++) {
|
||
var t = keySchedule[k - 1]
|
||
|
||
if (k % keySize === 0) {
|
||
t = (t << 8) | (t >>> 24)
|
||
t =
|
||
(G.SBOX[t >>> 24] << 24) |
|
||
(G.SBOX[(t >>> 16) & 0xff] << 16) |
|
||
(G.SBOX[(t >>> 8) & 0xff] << 8) |
|
||
(G.SBOX[t & 0xff])
|
||
|
||
t ^= RCON[(k / keySize) | 0] << 24
|
||
} else if (keySize > 6 && k % keySize === 4) {
|
||
t =
|
||
(G.SBOX[t >>> 24] << 24) |
|
||
(G.SBOX[(t >>> 16) & 0xff] << 16) |
|
||
(G.SBOX[(t >>> 8) & 0xff] << 8) |
|
||
(G.SBOX[t & 0xff])
|
||
}
|
||
|
||
keySchedule[k] = keySchedule[k - keySize] ^ t
|
||
}
|
||
|
||
var invKeySchedule = []
|
||
for (var ik = 0; ik < ksRows; ik++) {
|
||
var ksR = ksRows - ik
|
||
var tt = keySchedule[ksR - (ik % 4 ? 0 : 4)]
|
||
|
||
if (ik < 4 || ksR <= 4) {
|
||
invKeySchedule[ik] = tt
|
||
} else {
|
||
invKeySchedule[ik] =
|
||
G.INV_SUB_MIX[0][G.SBOX[tt >>> 24]] ^
|
||
G.INV_SUB_MIX[1][G.SBOX[(tt >>> 16) & 0xff]] ^
|
||
G.INV_SUB_MIX[2][G.SBOX[(tt >>> 8) & 0xff]] ^
|
||
G.INV_SUB_MIX[3][G.SBOX[tt & 0xff]]
|
||
}
|
||
}
|
||
|
||
this._nRounds = nRounds
|
||
this._keySchedule = keySchedule
|
||
this._invKeySchedule = invKeySchedule
|
||
}
|
||
|
||
AES.prototype.encryptBlockRaw = function (M) {
|
||
M = asUInt32Array(M)
|
||
return cryptBlock(M, this._keySchedule, G.SUB_MIX, G.SBOX, this._nRounds)
|
||
}
|
||
|
||
AES.prototype.encryptBlock = function (M) {
|
||
var out = this.encryptBlockRaw(M)
|
||
var buf = Buffer.allocUnsafe(16)
|
||
buf.writeUInt32BE(out[0], 0)
|
||
buf.writeUInt32BE(out[1], 4)
|
||
buf.writeUInt32BE(out[2], 8)
|
||
buf.writeUInt32BE(out[3], 12)
|
||
return buf
|
||
}
|
||
|
||
AES.prototype.decryptBlock = function (M) {
|
||
M = asUInt32Array(M)
|
||
|
||
// swap
|
||
var m1 = M[1]
|
||
M[1] = M[3]
|
||
M[3] = m1
|
||
|
||
var out = cryptBlock(M, this._invKeySchedule, G.INV_SUB_MIX, G.INV_SBOX, this._nRounds)
|
||
var buf = Buffer.allocUnsafe(16)
|
||
buf.writeUInt32BE(out[0], 0)
|
||
buf.writeUInt32BE(out[3], 4)
|
||
buf.writeUInt32BE(out[2], 8)
|
||
buf.writeUInt32BE(out[1], 12)
|
||
return buf
|
||
}
|
||
|
||
AES.prototype.scrub = function () {
|
||
scrubVec(this._keySchedule)
|
||
scrubVec(this._invKeySchedule)
|
||
scrubVec(this._key)
|
||
}
|
||
|
||
module.exports.AES = AES
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-aes/authCipher.js":
|
||
/*!***************************************************!*\
|
||
!*** ./node_modules/browserify-aes/authCipher.js ***!
|
||
\***************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var aes = __webpack_require__(/*! ./aes */ "./node_modules/browserify-aes/aes.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
var Transform = __webpack_require__(/*! cipher-base */ "./node_modules/cipher-base/index.js")
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
var GHASH = __webpack_require__(/*! ./ghash */ "./node_modules/browserify-aes/ghash.js")
|
||
var xor = __webpack_require__(/*! buffer-xor */ "./node_modules/buffer-xor/index.js")
|
||
var incr32 = __webpack_require__(/*! ./incr32 */ "./node_modules/browserify-aes/incr32.js")
|
||
|
||
function xorTest (a, b) {
|
||
var out = 0
|
||
if (a.length !== b.length) out++
|
||
|
||
var len = Math.min(a.length, b.length)
|
||
for (var i = 0; i < len; ++i) {
|
||
out += (a[i] ^ b[i])
|
||
}
|
||
|
||
return out
|
||
}
|
||
|
||
function calcIv (self, iv, ck) {
|
||
if (iv.length === 12) {
|
||
self._finID = Buffer.concat([iv, Buffer.from([0, 0, 0, 1])])
|
||
return Buffer.concat([iv, Buffer.from([0, 0, 0, 2])])
|
||
}
|
||
var ghash = new GHASH(ck)
|
||
var len = iv.length
|
||
var toPad = len % 16
|
||
ghash.update(iv)
|
||
if (toPad) {
|
||
toPad = 16 - toPad
|
||
ghash.update(Buffer.alloc(toPad, 0))
|
||
}
|
||
ghash.update(Buffer.alloc(8, 0))
|
||
var ivBits = len * 8
|
||
var tail = Buffer.alloc(8)
|
||
tail.writeUIntBE(ivBits, 0, 8)
|
||
ghash.update(tail)
|
||
self._finID = ghash.state
|
||
var out = Buffer.from(self._finID)
|
||
incr32(out)
|
||
return out
|
||
}
|
||
function StreamCipher (mode, key, iv, decrypt) {
|
||
Transform.call(this)
|
||
|
||
var h = Buffer.alloc(4, 0)
|
||
|
||
this._cipher = new aes.AES(key)
|
||
var ck = this._cipher.encryptBlock(h)
|
||
this._ghash = new GHASH(ck)
|
||
iv = calcIv(this, iv, ck)
|
||
|
||
this._prev = Buffer.from(iv)
|
||
this._cache = Buffer.allocUnsafe(0)
|
||
this._secCache = Buffer.allocUnsafe(0)
|
||
this._decrypt = decrypt
|
||
this._alen = 0
|
||
this._len = 0
|
||
this._mode = mode
|
||
|
||
this._authTag = null
|
||
this._called = false
|
||
}
|
||
|
||
inherits(StreamCipher, Transform)
|
||
|
||
StreamCipher.prototype._update = function (chunk) {
|
||
if (!this._called && this._alen) {
|
||
var rump = 16 - (this._alen % 16)
|
||
if (rump < 16) {
|
||
rump = Buffer.alloc(rump, 0)
|
||
this._ghash.update(rump)
|
||
}
|
||
}
|
||
|
||
this._called = true
|
||
var out = this._mode.encrypt(this, chunk)
|
||
if (this._decrypt) {
|
||
this._ghash.update(chunk)
|
||
} else {
|
||
this._ghash.update(out)
|
||
}
|
||
this._len += chunk.length
|
||
return out
|
||
}
|
||
|
||
StreamCipher.prototype._final = function () {
|
||
if (this._decrypt && !this._authTag) throw new Error('Unsupported state or unable to authenticate data')
|
||
|
||
var tag = xor(this._ghash.final(this._alen * 8, this._len * 8), this._cipher.encryptBlock(this._finID))
|
||
if (this._decrypt && xorTest(tag, this._authTag)) throw new Error('Unsupported state or unable to authenticate data')
|
||
|
||
this._authTag = tag
|
||
this._cipher.scrub()
|
||
}
|
||
|
||
StreamCipher.prototype.getAuthTag = function getAuthTag () {
|
||
if (this._decrypt || !Buffer.isBuffer(this._authTag)) throw new Error('Attempting to get auth tag in unsupported state')
|
||
|
||
return this._authTag
|
||
}
|
||
|
||
StreamCipher.prototype.setAuthTag = function setAuthTag (tag) {
|
||
if (!this._decrypt) throw new Error('Attempting to set auth tag in unsupported state')
|
||
|
||
this._authTag = tag
|
||
}
|
||
|
||
StreamCipher.prototype.setAAD = function setAAD (buf) {
|
||
if (this._called) throw new Error('Attempting to set AAD in unsupported state')
|
||
|
||
this._ghash.update(buf)
|
||
this._alen += buf.length
|
||
}
|
||
|
||
module.exports = StreamCipher
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-aes/browser.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/browserify-aes/browser.js ***!
|
||
\************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var ciphers = __webpack_require__(/*! ./encrypter */ "./node_modules/browserify-aes/encrypter.js")
|
||
var deciphers = __webpack_require__(/*! ./decrypter */ "./node_modules/browserify-aes/decrypter.js")
|
||
var modes = __webpack_require__(/*! ./modes/list.json */ "./node_modules/browserify-aes/modes/list.json")
|
||
|
||
function getCiphers () {
|
||
return Object.keys(modes)
|
||
}
|
||
|
||
exports.createCipher = exports.Cipher = ciphers.createCipher
|
||
exports.createCipheriv = exports.Cipheriv = ciphers.createCipheriv
|
||
exports.createDecipher = exports.Decipher = deciphers.createDecipher
|
||
exports.createDecipheriv = exports.Decipheriv = deciphers.createDecipheriv
|
||
exports.listCiphers = exports.getCiphers = getCiphers
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-aes/decrypter.js":
|
||
/*!**************************************************!*\
|
||
!*** ./node_modules/browserify-aes/decrypter.js ***!
|
||
\**************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var AuthCipher = __webpack_require__(/*! ./authCipher */ "./node_modules/browserify-aes/authCipher.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
var MODES = __webpack_require__(/*! ./modes */ "./node_modules/browserify-aes/modes/index.js")
|
||
var StreamCipher = __webpack_require__(/*! ./streamCipher */ "./node_modules/browserify-aes/streamCipher.js")
|
||
var Transform = __webpack_require__(/*! cipher-base */ "./node_modules/cipher-base/index.js")
|
||
var aes = __webpack_require__(/*! ./aes */ "./node_modules/browserify-aes/aes.js")
|
||
var ebtk = __webpack_require__(/*! evp_bytestokey */ "./node_modules/evp_bytestokey/index.js")
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
|
||
function Decipher (mode, key, iv) {
|
||
Transform.call(this)
|
||
|
||
this._cache = new Splitter()
|
||
this._last = void 0
|
||
this._cipher = new aes.AES(key)
|
||
this._prev = Buffer.from(iv)
|
||
this._mode = mode
|
||
this._autopadding = true
|
||
}
|
||
|
||
inherits(Decipher, Transform)
|
||
|
||
Decipher.prototype._update = function (data) {
|
||
this._cache.add(data)
|
||
var chunk
|
||
var thing
|
||
var out = []
|
||
while ((chunk = this._cache.get(this._autopadding))) {
|
||
thing = this._mode.decrypt(this, chunk)
|
||
out.push(thing)
|
||
}
|
||
return Buffer.concat(out)
|
||
}
|
||
|
||
Decipher.prototype._final = function () {
|
||
var chunk = this._cache.flush()
|
||
if (this._autopadding) {
|
||
return unpad(this._mode.decrypt(this, chunk))
|
||
} else if (chunk) {
|
||
throw new Error('data not multiple of block length')
|
||
}
|
||
}
|
||
|
||
Decipher.prototype.setAutoPadding = function (setTo) {
|
||
this._autopadding = !!setTo
|
||
return this
|
||
}
|
||
|
||
function Splitter () {
|
||
this.cache = Buffer.allocUnsafe(0)
|
||
}
|
||
|
||
Splitter.prototype.add = function (data) {
|
||
this.cache = Buffer.concat([this.cache, data])
|
||
}
|
||
|
||
Splitter.prototype.get = function (autoPadding) {
|
||
var out
|
||
if (autoPadding) {
|
||
if (this.cache.length > 16) {
|
||
out = this.cache.slice(0, 16)
|
||
this.cache = this.cache.slice(16)
|
||
return out
|
||
}
|
||
} else {
|
||
if (this.cache.length >= 16) {
|
||
out = this.cache.slice(0, 16)
|
||
this.cache = this.cache.slice(16)
|
||
return out
|
||
}
|
||
}
|
||
|
||
return null
|
||
}
|
||
|
||
Splitter.prototype.flush = function () {
|
||
if (this.cache.length) return this.cache
|
||
}
|
||
|
||
function unpad (last) {
|
||
var padded = last[15]
|
||
if (padded < 1 || padded > 16) {
|
||
throw new Error('unable to decrypt data')
|
||
}
|
||
var i = -1
|
||
while (++i < padded) {
|
||
if (last[(i + (16 - padded))] !== padded) {
|
||
throw new Error('unable to decrypt data')
|
||
}
|
||
}
|
||
if (padded === 16) return
|
||
|
||
return last.slice(0, 16 - padded)
|
||
}
|
||
|
||
function createDecipheriv (suite, password, iv) {
|
||
var config = MODES[suite.toLowerCase()]
|
||
if (!config) throw new TypeError('invalid suite type')
|
||
|
||
if (typeof iv === 'string') iv = Buffer.from(iv)
|
||
if (config.mode !== 'GCM' && iv.length !== config.iv) throw new TypeError('invalid iv length ' + iv.length)
|
||
|
||
if (typeof password === 'string') password = Buffer.from(password)
|
||
if (password.length !== config.key / 8) throw new TypeError('invalid key length ' + password.length)
|
||
|
||
if (config.type === 'stream') {
|
||
return new StreamCipher(config.module, password, iv, true)
|
||
} else if (config.type === 'auth') {
|
||
return new AuthCipher(config.module, password, iv, true)
|
||
}
|
||
|
||
return new Decipher(config.module, password, iv)
|
||
}
|
||
|
||
function createDecipher (suite, password) {
|
||
var config = MODES[suite.toLowerCase()]
|
||
if (!config) throw new TypeError('invalid suite type')
|
||
|
||
var keys = ebtk(password, false, config.key, config.iv)
|
||
return createDecipheriv(suite, keys.key, keys.iv)
|
||
}
|
||
|
||
exports.createDecipher = createDecipher
|
||
exports.createDecipheriv = createDecipheriv
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-aes/encrypter.js":
|
||
/*!**************************************************!*\
|
||
!*** ./node_modules/browserify-aes/encrypter.js ***!
|
||
\**************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var MODES = __webpack_require__(/*! ./modes */ "./node_modules/browserify-aes/modes/index.js")
|
||
var AuthCipher = __webpack_require__(/*! ./authCipher */ "./node_modules/browserify-aes/authCipher.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
var StreamCipher = __webpack_require__(/*! ./streamCipher */ "./node_modules/browserify-aes/streamCipher.js")
|
||
var Transform = __webpack_require__(/*! cipher-base */ "./node_modules/cipher-base/index.js")
|
||
var aes = __webpack_require__(/*! ./aes */ "./node_modules/browserify-aes/aes.js")
|
||
var ebtk = __webpack_require__(/*! evp_bytestokey */ "./node_modules/evp_bytestokey/index.js")
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
|
||
function Cipher (mode, key, iv) {
|
||
Transform.call(this)
|
||
|
||
this._cache = new Splitter()
|
||
this._cipher = new aes.AES(key)
|
||
this._prev = Buffer.from(iv)
|
||
this._mode = mode
|
||
this._autopadding = true
|
||
}
|
||
|
||
inherits(Cipher, Transform)
|
||
|
||
Cipher.prototype._update = function (data) {
|
||
this._cache.add(data)
|
||
var chunk
|
||
var thing
|
||
var out = []
|
||
|
||
while ((chunk = this._cache.get())) {
|
||
thing = this._mode.encrypt(this, chunk)
|
||
out.push(thing)
|
||
}
|
||
|
||
return Buffer.concat(out)
|
||
}
|
||
|
||
var PADDING = Buffer.alloc(16, 0x10)
|
||
|
||
Cipher.prototype._final = function () {
|
||
var chunk = this._cache.flush()
|
||
if (this._autopadding) {
|
||
chunk = this._mode.encrypt(this, chunk)
|
||
this._cipher.scrub()
|
||
return chunk
|
||
}
|
||
|
||
if (!chunk.equals(PADDING)) {
|
||
this._cipher.scrub()
|
||
throw new Error('data not multiple of block length')
|
||
}
|
||
}
|
||
|
||
Cipher.prototype.setAutoPadding = function (setTo) {
|
||
this._autopadding = !!setTo
|
||
return this
|
||
}
|
||
|
||
function Splitter () {
|
||
this.cache = Buffer.allocUnsafe(0)
|
||
}
|
||
|
||
Splitter.prototype.add = function (data) {
|
||
this.cache = Buffer.concat([this.cache, data])
|
||
}
|
||
|
||
Splitter.prototype.get = function () {
|
||
if (this.cache.length > 15) {
|
||
var out = this.cache.slice(0, 16)
|
||
this.cache = this.cache.slice(16)
|
||
return out
|
||
}
|
||
return null
|
||
}
|
||
|
||
Splitter.prototype.flush = function () {
|
||
var len = 16 - this.cache.length
|
||
var padBuff = Buffer.allocUnsafe(len)
|
||
|
||
var i = -1
|
||
while (++i < len) {
|
||
padBuff.writeUInt8(len, i)
|
||
}
|
||
|
||
return Buffer.concat([this.cache, padBuff])
|
||
}
|
||
|
||
function createCipheriv (suite, password, iv) {
|
||
var config = MODES[suite.toLowerCase()]
|
||
if (!config) throw new TypeError('invalid suite type')
|
||
|
||
if (typeof password === 'string') password = Buffer.from(password)
|
||
if (password.length !== config.key / 8) throw new TypeError('invalid key length ' + password.length)
|
||
|
||
if (typeof iv === 'string') iv = Buffer.from(iv)
|
||
if (config.mode !== 'GCM' && iv.length !== config.iv) throw new TypeError('invalid iv length ' + iv.length)
|
||
|
||
if (config.type === 'stream') {
|
||
return new StreamCipher(config.module, password, iv)
|
||
} else if (config.type === 'auth') {
|
||
return new AuthCipher(config.module, password, iv)
|
||
}
|
||
|
||
return new Cipher(config.module, password, iv)
|
||
}
|
||
|
||
function createCipher (suite, password) {
|
||
var config = MODES[suite.toLowerCase()]
|
||
if (!config) throw new TypeError('invalid suite type')
|
||
|
||
var keys = ebtk(password, false, config.key, config.iv)
|
||
return createCipheriv(suite, keys.key, keys.iv)
|
||
}
|
||
|
||
exports.createCipheriv = createCipheriv
|
||
exports.createCipher = createCipher
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-aes/ghash.js":
|
||
/*!**********************************************!*\
|
||
!*** ./node_modules/browserify-aes/ghash.js ***!
|
||
\**********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
var ZEROES = Buffer.alloc(16, 0)
|
||
|
||
function toArray (buf) {
|
||
return [
|
||
buf.readUInt32BE(0),
|
||
buf.readUInt32BE(4),
|
||
buf.readUInt32BE(8),
|
||
buf.readUInt32BE(12)
|
||
]
|
||
}
|
||
|
||
function fromArray (out) {
|
||
var buf = Buffer.allocUnsafe(16)
|
||
buf.writeUInt32BE(out[0] >>> 0, 0)
|
||
buf.writeUInt32BE(out[1] >>> 0, 4)
|
||
buf.writeUInt32BE(out[2] >>> 0, 8)
|
||
buf.writeUInt32BE(out[3] >>> 0, 12)
|
||
return buf
|
||
}
|
||
|
||
function GHASH (key) {
|
||
this.h = key
|
||
this.state = Buffer.alloc(16, 0)
|
||
this.cache = Buffer.allocUnsafe(0)
|
||
}
|
||
|
||
// from http://bitwiseshiftleft.github.io/sjcl/doc/symbols/src/core_gcm.js.html
|
||
// by Juho Vähä-Herttua
|
||
GHASH.prototype.ghash = function (block) {
|
||
var i = -1
|
||
while (++i < block.length) {
|
||
this.state[i] ^= block[i]
|
||
}
|
||
this._multiply()
|
||
}
|
||
|
||
GHASH.prototype._multiply = function () {
|
||
var Vi = toArray(this.h)
|
||
var Zi = [0, 0, 0, 0]
|
||
var j, xi, lsbVi
|
||
var i = -1
|
||
while (++i < 128) {
|
||
xi = (this.state[~~(i / 8)] & (1 << (7 - (i % 8)))) !== 0
|
||
if (xi) {
|
||
// Z_i+1 = Z_i ^ V_i
|
||
Zi[0] ^= Vi[0]
|
||
Zi[1] ^= Vi[1]
|
||
Zi[2] ^= Vi[2]
|
||
Zi[3] ^= Vi[3]
|
||
}
|
||
|
||
// Store the value of LSB(V_i)
|
||
lsbVi = (Vi[3] & 1) !== 0
|
||
|
||
// V_i+1 = V_i >> 1
|
||
for (j = 3; j > 0; j--) {
|
||
Vi[j] = (Vi[j] >>> 1) | ((Vi[j - 1] & 1) << 31)
|
||
}
|
||
Vi[0] = Vi[0] >>> 1
|
||
|
||
// If LSB(V_i) is 1, V_i+1 = (V_i >> 1) ^ R
|
||
if (lsbVi) {
|
||
Vi[0] = Vi[0] ^ (0xe1 << 24)
|
||
}
|
||
}
|
||
this.state = fromArray(Zi)
|
||
}
|
||
|
||
GHASH.prototype.update = function (buf) {
|
||
this.cache = Buffer.concat([this.cache, buf])
|
||
var chunk
|
||
while (this.cache.length >= 16) {
|
||
chunk = this.cache.slice(0, 16)
|
||
this.cache = this.cache.slice(16)
|
||
this.ghash(chunk)
|
||
}
|
||
}
|
||
|
||
GHASH.prototype.final = function (abl, bl) {
|
||
if (this.cache.length) {
|
||
this.ghash(Buffer.concat([this.cache, ZEROES], 16))
|
||
}
|
||
|
||
this.ghash(fromArray([0, abl, 0, bl]))
|
||
return this.state
|
||
}
|
||
|
||
module.exports = GHASH
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-aes/incr32.js":
|
||
/*!***********************************************!*\
|
||
!*** ./node_modules/browserify-aes/incr32.js ***!
|
||
\***********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
function incr32 (iv) {
|
||
var len = iv.length
|
||
var item
|
||
while (len--) {
|
||
item = iv.readUInt8(len)
|
||
if (item === 255) {
|
||
iv.writeUInt8(0, len)
|
||
} else {
|
||
item++
|
||
iv.writeUInt8(item, len)
|
||
break
|
||
}
|
||
}
|
||
}
|
||
module.exports = incr32
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-aes/modes/cbc.js":
|
||
/*!**************************************************!*\
|
||
!*** ./node_modules/browserify-aes/modes/cbc.js ***!
|
||
\**************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var xor = __webpack_require__(/*! buffer-xor */ "./node_modules/buffer-xor/index.js")
|
||
|
||
exports.encrypt = function (self, block) {
|
||
var data = xor(block, self._prev)
|
||
|
||
self._prev = self._cipher.encryptBlock(data)
|
||
return self._prev
|
||
}
|
||
|
||
exports.decrypt = function (self, block) {
|
||
var pad = self._prev
|
||
|
||
self._prev = block
|
||
var out = self._cipher.decryptBlock(block)
|
||
|
||
return xor(out, pad)
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-aes/modes/cfb.js":
|
||
/*!**************************************************!*\
|
||
!*** ./node_modules/browserify-aes/modes/cfb.js ***!
|
||
\**************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
var xor = __webpack_require__(/*! buffer-xor */ "./node_modules/buffer-xor/index.js")
|
||
|
||
function encryptStart (self, data, decrypt) {
|
||
var len = data.length
|
||
var out = xor(data, self._cache)
|
||
self._cache = self._cache.slice(len)
|
||
self._prev = Buffer.concat([self._prev, decrypt ? data : out])
|
||
return out
|
||
}
|
||
|
||
exports.encrypt = function (self, data, decrypt) {
|
||
var out = Buffer.allocUnsafe(0)
|
||
var len
|
||
|
||
while (data.length) {
|
||
if (self._cache.length === 0) {
|
||
self._cache = self._cipher.encryptBlock(self._prev)
|
||
self._prev = Buffer.allocUnsafe(0)
|
||
}
|
||
|
||
if (self._cache.length <= data.length) {
|
||
len = self._cache.length
|
||
out = Buffer.concat([out, encryptStart(self, data.slice(0, len), decrypt)])
|
||
data = data.slice(len)
|
||
} else {
|
||
out = Buffer.concat([out, encryptStart(self, data, decrypt)])
|
||
break
|
||
}
|
||
}
|
||
|
||
return out
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-aes/modes/cfb1.js":
|
||
/*!***************************************************!*\
|
||
!*** ./node_modules/browserify-aes/modes/cfb1.js ***!
|
||
\***************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
function encryptByte (self, byteParam, decrypt) {
|
||
var pad
|
||
var i = -1
|
||
var len = 8
|
||
var out = 0
|
||
var bit, value
|
||
while (++i < len) {
|
||
pad = self._cipher.encryptBlock(self._prev)
|
||
bit = (byteParam & (1 << (7 - i))) ? 0x80 : 0
|
||
value = pad[0] ^ bit
|
||
out += ((value & 0x80) >> (i % 8))
|
||
self._prev = shiftIn(self._prev, decrypt ? bit : value)
|
||
}
|
||
return out
|
||
}
|
||
|
||
function shiftIn (buffer, value) {
|
||
var len = buffer.length
|
||
var i = -1
|
||
var out = Buffer.allocUnsafe(buffer.length)
|
||
buffer = Buffer.concat([buffer, Buffer.from([value])])
|
||
|
||
while (++i < len) {
|
||
out[i] = buffer[i] << 1 | buffer[i + 1] >> (7)
|
||
}
|
||
|
||
return out
|
||
}
|
||
|
||
exports.encrypt = function (self, chunk, decrypt) {
|
||
var len = chunk.length
|
||
var out = Buffer.allocUnsafe(len)
|
||
var i = -1
|
||
|
||
while (++i < len) {
|
||
out[i] = encryptByte(self, chunk[i], decrypt)
|
||
}
|
||
|
||
return out
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-aes/modes/cfb8.js":
|
||
/*!***************************************************!*\
|
||
!*** ./node_modules/browserify-aes/modes/cfb8.js ***!
|
||
\***************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
function encryptByte (self, byteParam, decrypt) {
|
||
var pad = self._cipher.encryptBlock(self._prev)
|
||
var out = pad[0] ^ byteParam
|
||
|
||
self._prev = Buffer.concat([
|
||
self._prev.slice(1),
|
||
Buffer.from([decrypt ? byteParam : out])
|
||
])
|
||
|
||
return out
|
||
}
|
||
|
||
exports.encrypt = function (self, chunk, decrypt) {
|
||
var len = chunk.length
|
||
var out = Buffer.allocUnsafe(len)
|
||
var i = -1
|
||
|
||
while (++i < len) {
|
||
out[i] = encryptByte(self, chunk[i], decrypt)
|
||
}
|
||
|
||
return out
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-aes/modes/ctr.js":
|
||
/*!**************************************************!*\
|
||
!*** ./node_modules/browserify-aes/modes/ctr.js ***!
|
||
\**************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var xor = __webpack_require__(/*! buffer-xor */ "./node_modules/buffer-xor/index.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
var incr32 = __webpack_require__(/*! ../incr32 */ "./node_modules/browserify-aes/incr32.js")
|
||
|
||
function getBlock (self) {
|
||
var out = self._cipher.encryptBlockRaw(self._prev)
|
||
incr32(self._prev)
|
||
return out
|
||
}
|
||
|
||
var blockSize = 16
|
||
exports.encrypt = function (self, chunk) {
|
||
var chunkNum = Math.ceil(chunk.length / blockSize)
|
||
var start = self._cache.length
|
||
self._cache = Buffer.concat([
|
||
self._cache,
|
||
Buffer.allocUnsafe(chunkNum * blockSize)
|
||
])
|
||
for (var i = 0; i < chunkNum; i++) {
|
||
var out = getBlock(self)
|
||
var offset = start + i * blockSize
|
||
self._cache.writeUInt32BE(out[0], offset + 0)
|
||
self._cache.writeUInt32BE(out[1], offset + 4)
|
||
self._cache.writeUInt32BE(out[2], offset + 8)
|
||
self._cache.writeUInt32BE(out[3], offset + 12)
|
||
}
|
||
var pad = self._cache.slice(0, chunk.length)
|
||
self._cache = self._cache.slice(chunk.length)
|
||
return xor(chunk, pad)
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-aes/modes/ecb.js":
|
||
/*!**************************************************!*\
|
||
!*** ./node_modules/browserify-aes/modes/ecb.js ***!
|
||
\**************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
exports.encrypt = function (self, block) {
|
||
return self._cipher.encryptBlock(block)
|
||
}
|
||
|
||
exports.decrypt = function (self, block) {
|
||
return self._cipher.decryptBlock(block)
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-aes/modes/index.js":
|
||
/*!****************************************************!*\
|
||
!*** ./node_modules/browserify-aes/modes/index.js ***!
|
||
\****************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var modeModules = {
|
||
ECB: __webpack_require__(/*! ./ecb */ "./node_modules/browserify-aes/modes/ecb.js"),
|
||
CBC: __webpack_require__(/*! ./cbc */ "./node_modules/browserify-aes/modes/cbc.js"),
|
||
CFB: __webpack_require__(/*! ./cfb */ "./node_modules/browserify-aes/modes/cfb.js"),
|
||
CFB8: __webpack_require__(/*! ./cfb8 */ "./node_modules/browserify-aes/modes/cfb8.js"),
|
||
CFB1: __webpack_require__(/*! ./cfb1 */ "./node_modules/browserify-aes/modes/cfb1.js"),
|
||
OFB: __webpack_require__(/*! ./ofb */ "./node_modules/browserify-aes/modes/ofb.js"),
|
||
CTR: __webpack_require__(/*! ./ctr */ "./node_modules/browserify-aes/modes/ctr.js"),
|
||
GCM: __webpack_require__(/*! ./ctr */ "./node_modules/browserify-aes/modes/ctr.js")
|
||
}
|
||
|
||
var modes = __webpack_require__(/*! ./list.json */ "./node_modules/browserify-aes/modes/list.json")
|
||
|
||
for (var key in modes) {
|
||
modes[key].module = modeModules[modes[key].mode]
|
||
}
|
||
|
||
module.exports = modes
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-aes/modes/list.json":
|
||
/*!*****************************************************!*\
|
||
!*** ./node_modules/browserify-aes/modes/list.json ***!
|
||
\*****************************************************/
|
||
/*! exports provided: aes-128-ecb, aes-192-ecb, aes-256-ecb, aes-128-cbc, aes-192-cbc, aes-256-cbc, aes128, aes192, aes256, aes-128-cfb, aes-192-cfb, aes-256-cfb, aes-128-cfb8, aes-192-cfb8, aes-256-cfb8, aes-128-cfb1, aes-192-cfb1, aes-256-cfb1, aes-128-ofb, aes-192-ofb, aes-256-ofb, aes-128-ctr, aes-192-ctr, aes-256-ctr, aes-128-gcm, aes-192-gcm, aes-256-gcm, default */
|
||
/***/ (function(module) {
|
||
|
||
module.exports = JSON.parse("{\"aes-128-ecb\":{\"cipher\":\"AES\",\"key\":128,\"iv\":0,\"mode\":\"ECB\",\"type\":\"block\"},\"aes-192-ecb\":{\"cipher\":\"AES\",\"key\":192,\"iv\":0,\"mode\":\"ECB\",\"type\":\"block\"},\"aes-256-ecb\":{\"cipher\":\"AES\",\"key\":256,\"iv\":0,\"mode\":\"ECB\",\"type\":\"block\"},\"aes-128-cbc\":{\"cipher\":\"AES\",\"key\":128,\"iv\":16,\"mode\":\"CBC\",\"type\":\"block\"},\"aes-192-cbc\":{\"cipher\":\"AES\",\"key\":192,\"iv\":16,\"mode\":\"CBC\",\"type\":\"block\"},\"aes-256-cbc\":{\"cipher\":\"AES\",\"key\":256,\"iv\":16,\"mode\":\"CBC\",\"type\":\"block\"},\"aes128\":{\"cipher\":\"AES\",\"key\":128,\"iv\":16,\"mode\":\"CBC\",\"type\":\"block\"},\"aes192\":{\"cipher\":\"AES\",\"key\":192,\"iv\":16,\"mode\":\"CBC\",\"type\":\"block\"},\"aes256\":{\"cipher\":\"AES\",\"key\":256,\"iv\":16,\"mode\":\"CBC\",\"type\":\"block\"},\"aes-128-cfb\":{\"cipher\":\"AES\",\"key\":128,\"iv\":16,\"mode\":\"CFB\",\"type\":\"stream\"},\"aes-192-cfb\":{\"cipher\":\"AES\",\"key\":192,\"iv\":16,\"mode\":\"CFB\",\"type\":\"stream\"},\"aes-256-cfb\":{\"cipher\":\"AES\",\"key\":256,\"iv\":16,\"mode\":\"CFB\",\"type\":\"stream\"},\"aes-128-cfb8\":{\"cipher\":\"AES\",\"key\":128,\"iv\":16,\"mode\":\"CFB8\",\"type\":\"stream\"},\"aes-192-cfb8\":{\"cipher\":\"AES\",\"key\":192,\"iv\":16,\"mode\":\"CFB8\",\"type\":\"stream\"},\"aes-256-cfb8\":{\"cipher\":\"AES\",\"key\":256,\"iv\":16,\"mode\":\"CFB8\",\"type\":\"stream\"},\"aes-128-cfb1\":{\"cipher\":\"AES\",\"key\":128,\"iv\":16,\"mode\":\"CFB1\",\"type\":\"stream\"},\"aes-192-cfb1\":{\"cipher\":\"AES\",\"key\":192,\"iv\":16,\"mode\":\"CFB1\",\"type\":\"stream\"},\"aes-256-cfb1\":{\"cipher\":\"AES\",\"key\":256,\"iv\":16,\"mode\":\"CFB1\",\"type\":\"stream\"},\"aes-128-ofb\":{\"cipher\":\"AES\",\"key\":128,\"iv\":16,\"mode\":\"OFB\",\"type\":\"stream\"},\"aes-192-ofb\":{\"cipher\":\"AES\",\"key\":192,\"iv\":16,\"mode\":\"OFB\",\"type\":\"stream\"},\"aes-256-ofb\":{\"cipher\":\"AES\",\"key\":256,\"iv\":16,\"mode\":\"OFB\",\"type\":\"stream\"},\"aes-128-ctr\":{\"cipher\":\"AES\",\"key\":128,\"iv\":16,\"mode\":\"CTR\",\"type\":\"stream\"},\"aes-192-ctr\":{\"cipher\":\"AES\",\"key\":192,\"iv\":16,\"mode\":\"CTR\",\"type\":\"stream\"},\"aes-256-ctr\":{\"cipher\":\"AES\",\"key\":256,\"iv\":16,\"mode\":\"CTR\",\"type\":\"stream\"},\"aes-128-gcm\":{\"cipher\":\"AES\",\"key\":128,\"iv\":12,\"mode\":\"GCM\",\"type\":\"auth\"},\"aes-192-gcm\":{\"cipher\":\"AES\",\"key\":192,\"iv\":12,\"mode\":\"GCM\",\"type\":\"auth\"},\"aes-256-gcm\":{\"cipher\":\"AES\",\"key\":256,\"iv\":12,\"mode\":\"GCM\",\"type\":\"auth\"}}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-aes/modes/ofb.js":
|
||
/*!**************************************************!*\
|
||
!*** ./node_modules/browserify-aes/modes/ofb.js ***!
|
||
\**************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(Buffer) {var xor = __webpack_require__(/*! buffer-xor */ "./node_modules/buffer-xor/index.js")
|
||
|
||
function getBlock (self) {
|
||
self._prev = self._cipher.encryptBlock(self._prev)
|
||
return self._prev
|
||
}
|
||
|
||
exports.encrypt = function (self, chunk) {
|
||
while (self._cache.length < chunk.length) {
|
||
self._cache = Buffer.concat([self._cache, getBlock(self)])
|
||
}
|
||
|
||
var pad = self._cache.slice(0, chunk.length)
|
||
self._cache = self._cache.slice(chunk.length)
|
||
return xor(chunk, pad)
|
||
}
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../buffer/index.js */ "./node_modules/buffer/index.js").Buffer))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-aes/streamCipher.js":
|
||
/*!*****************************************************!*\
|
||
!*** ./node_modules/browserify-aes/streamCipher.js ***!
|
||
\*****************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var aes = __webpack_require__(/*! ./aes */ "./node_modules/browserify-aes/aes.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
var Transform = __webpack_require__(/*! cipher-base */ "./node_modules/cipher-base/index.js")
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
|
||
function StreamCipher (mode, key, iv, decrypt) {
|
||
Transform.call(this)
|
||
|
||
this._cipher = new aes.AES(key)
|
||
this._prev = Buffer.from(iv)
|
||
this._cache = Buffer.allocUnsafe(0)
|
||
this._secCache = Buffer.allocUnsafe(0)
|
||
this._decrypt = decrypt
|
||
this._mode = mode
|
||
}
|
||
|
||
inherits(StreamCipher, Transform)
|
||
|
||
StreamCipher.prototype._update = function (chunk) {
|
||
return this._mode.encrypt(this, chunk, this._decrypt)
|
||
}
|
||
|
||
StreamCipher.prototype._final = function () {
|
||
this._cipher.scrub()
|
||
}
|
||
|
||
module.exports = StreamCipher
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-cipher/browser.js":
|
||
/*!***************************************************!*\
|
||
!*** ./node_modules/browserify-cipher/browser.js ***!
|
||
\***************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var DES = __webpack_require__(/*! browserify-des */ "./node_modules/browserify-des/index.js")
|
||
var aes = __webpack_require__(/*! browserify-aes/browser */ "./node_modules/browserify-aes/browser.js")
|
||
var aesModes = __webpack_require__(/*! browserify-aes/modes */ "./node_modules/browserify-aes/modes/index.js")
|
||
var desModes = __webpack_require__(/*! browserify-des/modes */ "./node_modules/browserify-des/modes.js")
|
||
var ebtk = __webpack_require__(/*! evp_bytestokey */ "./node_modules/evp_bytestokey/index.js")
|
||
|
||
function createCipher (suite, password) {
|
||
suite = suite.toLowerCase()
|
||
|
||
var keyLen, ivLen
|
||
if (aesModes[suite]) {
|
||
keyLen = aesModes[suite].key
|
||
ivLen = aesModes[suite].iv
|
||
} else if (desModes[suite]) {
|
||
keyLen = desModes[suite].key * 8
|
||
ivLen = desModes[suite].iv
|
||
} else {
|
||
throw new TypeError('invalid suite type')
|
||
}
|
||
|
||
var keys = ebtk(password, false, keyLen, ivLen)
|
||
return createCipheriv(suite, keys.key, keys.iv)
|
||
}
|
||
|
||
function createDecipher (suite, password) {
|
||
suite = suite.toLowerCase()
|
||
|
||
var keyLen, ivLen
|
||
if (aesModes[suite]) {
|
||
keyLen = aesModes[suite].key
|
||
ivLen = aesModes[suite].iv
|
||
} else if (desModes[suite]) {
|
||
keyLen = desModes[suite].key * 8
|
||
ivLen = desModes[suite].iv
|
||
} else {
|
||
throw new TypeError('invalid suite type')
|
||
}
|
||
|
||
var keys = ebtk(password, false, keyLen, ivLen)
|
||
return createDecipheriv(suite, keys.key, keys.iv)
|
||
}
|
||
|
||
function createCipheriv (suite, key, iv) {
|
||
suite = suite.toLowerCase()
|
||
if (aesModes[suite]) return aes.createCipheriv(suite, key, iv)
|
||
if (desModes[suite]) return new DES({ key: key, iv: iv, mode: suite })
|
||
|
||
throw new TypeError('invalid suite type')
|
||
}
|
||
|
||
function createDecipheriv (suite, key, iv) {
|
||
suite = suite.toLowerCase()
|
||
if (aesModes[suite]) return aes.createDecipheriv(suite, key, iv)
|
||
if (desModes[suite]) return new DES({ key: key, iv: iv, mode: suite, decrypt: true })
|
||
|
||
throw new TypeError('invalid suite type')
|
||
}
|
||
|
||
function getCiphers () {
|
||
return Object.keys(desModes).concat(aes.getCiphers())
|
||
}
|
||
|
||
exports.createCipher = exports.Cipher = createCipher
|
||
exports.createCipheriv = exports.Cipheriv = createCipheriv
|
||
exports.createDecipher = exports.Decipher = createDecipher
|
||
exports.createDecipheriv = exports.Decipheriv = createDecipheriv
|
||
exports.listCiphers = exports.getCiphers = getCiphers
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-des/index.js":
|
||
/*!**********************************************!*\
|
||
!*** ./node_modules/browserify-des/index.js ***!
|
||
\**********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var CipherBase = __webpack_require__(/*! cipher-base */ "./node_modules/cipher-base/index.js")
|
||
var des = __webpack_require__(/*! des.js */ "./node_modules/des.js/lib/des.js")
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
var modes = {
|
||
'des-ede3-cbc': des.CBC.instantiate(des.EDE),
|
||
'des-ede3': des.EDE,
|
||
'des-ede-cbc': des.CBC.instantiate(des.EDE),
|
||
'des-ede': des.EDE,
|
||
'des-cbc': des.CBC.instantiate(des.DES),
|
||
'des-ecb': des.DES
|
||
}
|
||
modes.des = modes['des-cbc']
|
||
modes.des3 = modes['des-ede3-cbc']
|
||
module.exports = DES
|
||
inherits(DES, CipherBase)
|
||
function DES (opts) {
|
||
CipherBase.call(this)
|
||
var modeName = opts.mode.toLowerCase()
|
||
var mode = modes[modeName]
|
||
var type
|
||
if (opts.decrypt) {
|
||
type = 'decrypt'
|
||
} else {
|
||
type = 'encrypt'
|
||
}
|
||
var key = opts.key
|
||
if (!Buffer.isBuffer(key)) {
|
||
key = Buffer.from(key)
|
||
}
|
||
if (modeName === 'des-ede' || modeName === 'des-ede-cbc') {
|
||
key = Buffer.concat([key, key.slice(0, 8)])
|
||
}
|
||
var iv = opts.iv
|
||
if (!Buffer.isBuffer(iv)) {
|
||
iv = Buffer.from(iv)
|
||
}
|
||
this._des = mode.create({
|
||
key: key,
|
||
iv: iv,
|
||
type: type
|
||
})
|
||
}
|
||
DES.prototype._update = function (data) {
|
||
return Buffer.from(this._des.update(data))
|
||
}
|
||
DES.prototype._final = function () {
|
||
return Buffer.from(this._des.final())
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-des/modes.js":
|
||
/*!**********************************************!*\
|
||
!*** ./node_modules/browserify-des/modes.js ***!
|
||
\**********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
exports['des-ecb'] = {
|
||
key: 8,
|
||
iv: 0
|
||
}
|
||
exports['des-cbc'] = exports.des = {
|
||
key: 8,
|
||
iv: 8
|
||
}
|
||
exports['des-ede3-cbc'] = exports.des3 = {
|
||
key: 24,
|
||
iv: 8
|
||
}
|
||
exports['des-ede3'] = {
|
||
key: 24,
|
||
iv: 0
|
||
}
|
||
exports['des-ede-cbc'] = {
|
||
key: 16,
|
||
iv: 8
|
||
}
|
||
exports['des-ede'] = {
|
||
key: 16,
|
||
iv: 0
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-rsa/index.js":
|
||
/*!**********************************************!*\
|
||
!*** ./node_modules/browserify-rsa/index.js ***!
|
||
\**********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(Buffer) {var bn = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js");
|
||
var randomBytes = __webpack_require__(/*! randombytes */ "./node_modules/randombytes/browser.js");
|
||
module.exports = crt;
|
||
function blind(priv) {
|
||
var r = getr(priv);
|
||
var blinder = r.toRed(bn.mont(priv.modulus))
|
||
.redPow(new bn(priv.publicExponent)).fromRed();
|
||
return {
|
||
blinder: blinder,
|
||
unblinder:r.invm(priv.modulus)
|
||
};
|
||
}
|
||
function crt(msg, priv) {
|
||
var blinds = blind(priv);
|
||
var len = priv.modulus.byteLength();
|
||
var mod = bn.mont(priv.modulus);
|
||
var blinded = new bn(msg).mul(blinds.blinder).umod(priv.modulus);
|
||
var c1 = blinded.toRed(bn.mont(priv.prime1));
|
||
var c2 = blinded.toRed(bn.mont(priv.prime2));
|
||
var qinv = priv.coefficient;
|
||
var p = priv.prime1;
|
||
var q = priv.prime2;
|
||
var m1 = c1.redPow(priv.exponent1);
|
||
var m2 = c2.redPow(priv.exponent2);
|
||
m1 = m1.fromRed();
|
||
m2 = m2.fromRed();
|
||
var h = m1.isub(m2).imul(qinv).umod(p);
|
||
h.imul(q);
|
||
m2.iadd(h);
|
||
return new Buffer(m2.imul(blinds.unblinder).umod(priv.modulus).toArray(false, len));
|
||
}
|
||
crt.getr = getr;
|
||
function getr(priv) {
|
||
var len = priv.modulus.byteLength();
|
||
var r = new bn(randomBytes(len));
|
||
while (r.cmp(priv.modulus) >= 0 || !r.umod(priv.prime1) || !r.umod(priv.prime2)) {
|
||
r = new bn(randomBytes(len));
|
||
}
|
||
return r;
|
||
}
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../buffer/index.js */ "./node_modules/buffer/index.js").Buffer))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-sign/algos.js":
|
||
/*!***********************************************!*\
|
||
!*** ./node_modules/browserify-sign/algos.js ***!
|
||
\***********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
module.exports = __webpack_require__(/*! ./browser/algorithms.json */ "./node_modules/browserify-sign/browser/algorithms.json")
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-sign/browser/algorithms.json":
|
||
/*!**************************************************************!*\
|
||
!*** ./node_modules/browserify-sign/browser/algorithms.json ***!
|
||
\**************************************************************/
|
||
/*! exports provided: sha224WithRSAEncryption, RSA-SHA224, sha256WithRSAEncryption, RSA-SHA256, sha384WithRSAEncryption, RSA-SHA384, sha512WithRSAEncryption, RSA-SHA512, RSA-SHA1, ecdsa-with-SHA1, sha256, sha224, sha384, sha512, DSA-SHA, DSA-SHA1, DSA, DSA-WITH-SHA224, DSA-SHA224, DSA-WITH-SHA256, DSA-SHA256, DSA-WITH-SHA384, DSA-SHA384, DSA-WITH-SHA512, DSA-SHA512, DSA-RIPEMD160, ripemd160WithRSA, RSA-RIPEMD160, md5WithRSAEncryption, RSA-MD5, default */
|
||
/***/ (function(module) {
|
||
|
||
module.exports = JSON.parse("{\"sha224WithRSAEncryption\":{\"sign\":\"rsa\",\"hash\":\"sha224\",\"id\":\"302d300d06096086480165030402040500041c\"},\"RSA-SHA224\":{\"sign\":\"ecdsa/rsa\",\"hash\":\"sha224\",\"id\":\"302d300d06096086480165030402040500041c\"},\"sha256WithRSAEncryption\":{\"sign\":\"rsa\",\"hash\":\"sha256\",\"id\":\"3031300d060960864801650304020105000420\"},\"RSA-SHA256\":{\"sign\":\"ecdsa/rsa\",\"hash\":\"sha256\",\"id\":\"3031300d060960864801650304020105000420\"},\"sha384WithRSAEncryption\":{\"sign\":\"rsa\",\"hash\":\"sha384\",\"id\":\"3041300d060960864801650304020205000430\"},\"RSA-SHA384\":{\"sign\":\"ecdsa/rsa\",\"hash\":\"sha384\",\"id\":\"3041300d060960864801650304020205000430\"},\"sha512WithRSAEncryption\":{\"sign\":\"rsa\",\"hash\":\"sha512\",\"id\":\"3051300d060960864801650304020305000440\"},\"RSA-SHA512\":{\"sign\":\"ecdsa/rsa\",\"hash\":\"sha512\",\"id\":\"3051300d060960864801650304020305000440\"},\"RSA-SHA1\":{\"sign\":\"rsa\",\"hash\":\"sha1\",\"id\":\"3021300906052b0e03021a05000414\"},\"ecdsa-with-SHA1\":{\"sign\":\"ecdsa\",\"hash\":\"sha1\",\"id\":\"\"},\"sha256\":{\"sign\":\"ecdsa\",\"hash\":\"sha256\",\"id\":\"\"},\"sha224\":{\"sign\":\"ecdsa\",\"hash\":\"sha224\",\"id\":\"\"},\"sha384\":{\"sign\":\"ecdsa\",\"hash\":\"sha384\",\"id\":\"\"},\"sha512\":{\"sign\":\"ecdsa\",\"hash\":\"sha512\",\"id\":\"\"},\"DSA-SHA\":{\"sign\":\"dsa\",\"hash\":\"sha1\",\"id\":\"\"},\"DSA-SHA1\":{\"sign\":\"dsa\",\"hash\":\"sha1\",\"id\":\"\"},\"DSA\":{\"sign\":\"dsa\",\"hash\":\"sha1\",\"id\":\"\"},\"DSA-WITH-SHA224\":{\"sign\":\"dsa\",\"hash\":\"sha224\",\"id\":\"\"},\"DSA-SHA224\":{\"sign\":\"dsa\",\"hash\":\"sha224\",\"id\":\"\"},\"DSA-WITH-SHA256\":{\"sign\":\"dsa\",\"hash\":\"sha256\",\"id\":\"\"},\"DSA-SHA256\":{\"sign\":\"dsa\",\"hash\":\"sha256\",\"id\":\"\"},\"DSA-WITH-SHA384\":{\"sign\":\"dsa\",\"hash\":\"sha384\",\"id\":\"\"},\"DSA-SHA384\":{\"sign\":\"dsa\",\"hash\":\"sha384\",\"id\":\"\"},\"DSA-WITH-SHA512\":{\"sign\":\"dsa\",\"hash\":\"sha512\",\"id\":\"\"},\"DSA-SHA512\":{\"sign\":\"dsa\",\"hash\":\"sha512\",\"id\":\"\"},\"DSA-RIPEMD160\":{\"sign\":\"dsa\",\"hash\":\"rmd160\",\"id\":\"\"},\"ripemd160WithRSA\":{\"sign\":\"rsa\",\"hash\":\"rmd160\",\"id\":\"3021300906052b2403020105000414\"},\"RSA-RIPEMD160\":{\"sign\":\"rsa\",\"hash\":\"rmd160\",\"id\":\"3021300906052b2403020105000414\"},\"md5WithRSAEncryption\":{\"sign\":\"rsa\",\"hash\":\"md5\",\"id\":\"3020300c06082a864886f70d020505000410\"},\"RSA-MD5\":{\"sign\":\"rsa\",\"hash\":\"md5\",\"id\":\"3020300c06082a864886f70d020505000410\"}}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-sign/browser/curves.json":
|
||
/*!**********************************************************!*\
|
||
!*** ./node_modules/browserify-sign/browser/curves.json ***!
|
||
\**********************************************************/
|
||
/*! exports provided: 1.3.132.0.10, 1.3.132.0.33, 1.2.840.10045.3.1.1, 1.2.840.10045.3.1.7, 1.3.132.0.34, 1.3.132.0.35, default */
|
||
/***/ (function(module) {
|
||
|
||
module.exports = JSON.parse("{\"1.3.132.0.10\":\"secp256k1\",\"1.3.132.0.33\":\"p224\",\"1.2.840.10045.3.1.1\":\"p192\",\"1.2.840.10045.3.1.7\":\"p256\",\"1.3.132.0.34\":\"p384\",\"1.3.132.0.35\":\"p521\"}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-sign/browser/index.js":
|
||
/*!*******************************************************!*\
|
||
!*** ./node_modules/browserify-sign/browser/index.js ***!
|
||
\*******************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(Buffer) {var createHash = __webpack_require__(/*! create-hash */ "./node_modules/create-hash/browser.js")
|
||
var stream = __webpack_require__(/*! stream */ "./node_modules/stream-browserify/index.js")
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
var sign = __webpack_require__(/*! ./sign */ "./node_modules/browserify-sign/browser/sign.js")
|
||
var verify = __webpack_require__(/*! ./verify */ "./node_modules/browserify-sign/browser/verify.js")
|
||
|
||
var algorithms = __webpack_require__(/*! ./algorithms.json */ "./node_modules/browserify-sign/browser/algorithms.json")
|
||
Object.keys(algorithms).forEach(function (key) {
|
||
algorithms[key].id = new Buffer(algorithms[key].id, 'hex')
|
||
algorithms[key.toLowerCase()] = algorithms[key]
|
||
})
|
||
|
||
function Sign (algorithm) {
|
||
stream.Writable.call(this)
|
||
|
||
var data = algorithms[algorithm]
|
||
if (!data) throw new Error('Unknown message digest')
|
||
|
||
this._hashType = data.hash
|
||
this._hash = createHash(data.hash)
|
||
this._tag = data.id
|
||
this._signType = data.sign
|
||
}
|
||
inherits(Sign, stream.Writable)
|
||
|
||
Sign.prototype._write = function _write (data, _, done) {
|
||
this._hash.update(data)
|
||
done()
|
||
}
|
||
|
||
Sign.prototype.update = function update (data, enc) {
|
||
if (typeof data === 'string') data = new Buffer(data, enc)
|
||
|
||
this._hash.update(data)
|
||
return this
|
||
}
|
||
|
||
Sign.prototype.sign = function signMethod (key, enc) {
|
||
this.end()
|
||
var hash = this._hash.digest()
|
||
var sig = sign(hash, key, this._hashType, this._signType, this._tag)
|
||
|
||
return enc ? sig.toString(enc) : sig
|
||
}
|
||
|
||
function Verify (algorithm) {
|
||
stream.Writable.call(this)
|
||
|
||
var data = algorithms[algorithm]
|
||
if (!data) throw new Error('Unknown message digest')
|
||
|
||
this._hash = createHash(data.hash)
|
||
this._tag = data.id
|
||
this._signType = data.sign
|
||
}
|
||
inherits(Verify, stream.Writable)
|
||
|
||
Verify.prototype._write = function _write (data, _, done) {
|
||
this._hash.update(data)
|
||
done()
|
||
}
|
||
|
||
Verify.prototype.update = function update (data, enc) {
|
||
if (typeof data === 'string') data = new Buffer(data, enc)
|
||
|
||
this._hash.update(data)
|
||
return this
|
||
}
|
||
|
||
Verify.prototype.verify = function verifyMethod (key, sig, enc) {
|
||
if (typeof sig === 'string') sig = new Buffer(sig, enc)
|
||
|
||
this.end()
|
||
var hash = this._hash.digest()
|
||
return verify(sig, hash, key, this._signType, this._tag)
|
||
}
|
||
|
||
function createSign (algorithm) {
|
||
return new Sign(algorithm)
|
||
}
|
||
|
||
function createVerify (algorithm) {
|
||
return new Verify(algorithm)
|
||
}
|
||
|
||
module.exports = {
|
||
Sign: createSign,
|
||
Verify: createVerify,
|
||
createSign: createSign,
|
||
createVerify: createVerify
|
||
}
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../buffer/index.js */ "./node_modules/buffer/index.js").Buffer))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-sign/browser/sign.js":
|
||
/*!******************************************************!*\
|
||
!*** ./node_modules/browserify-sign/browser/sign.js ***!
|
||
\******************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(Buffer) {// much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js
|
||
var createHmac = __webpack_require__(/*! create-hmac */ "./node_modules/create-hmac/browser.js")
|
||
var crt = __webpack_require__(/*! browserify-rsa */ "./node_modules/browserify-rsa/index.js")
|
||
var EC = __webpack_require__(/*! elliptic */ "./node_modules/elliptic/lib/elliptic.js").ec
|
||
var BN = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js")
|
||
var parseKeys = __webpack_require__(/*! parse-asn1 */ "./node_modules/parse-asn1/index.js")
|
||
var curves = __webpack_require__(/*! ./curves.json */ "./node_modules/browserify-sign/browser/curves.json")
|
||
|
||
function sign (hash, key, hashType, signType, tag) {
|
||
var priv = parseKeys(key)
|
||
if (priv.curve) {
|
||
// rsa keys can be interpreted as ecdsa ones in openssl
|
||
if (signType !== 'ecdsa' && signType !== 'ecdsa/rsa') throw new Error('wrong private key type')
|
||
return ecSign(hash, priv)
|
||
} else if (priv.type === 'dsa') {
|
||
if (signType !== 'dsa') throw new Error('wrong private key type')
|
||
return dsaSign(hash, priv, hashType)
|
||
} else {
|
||
if (signType !== 'rsa' && signType !== 'ecdsa/rsa') throw new Error('wrong private key type')
|
||
}
|
||
hash = Buffer.concat([tag, hash])
|
||
var len = priv.modulus.byteLength()
|
||
var pad = [ 0, 1 ]
|
||
while (hash.length + pad.length + 1 < len) pad.push(0xff)
|
||
pad.push(0x00)
|
||
var i = -1
|
||
while (++i < hash.length) pad.push(hash[i])
|
||
|
||
var out = crt(pad, priv)
|
||
return out
|
||
}
|
||
|
||
function ecSign (hash, priv) {
|
||
var curveId = curves[priv.curve.join('.')]
|
||
if (!curveId) throw new Error('unknown curve ' + priv.curve.join('.'))
|
||
|
||
var curve = new EC(curveId)
|
||
var key = curve.keyFromPrivate(priv.privateKey)
|
||
var out = key.sign(hash)
|
||
|
||
return new Buffer(out.toDER())
|
||
}
|
||
|
||
function dsaSign (hash, priv, algo) {
|
||
var x = priv.params.priv_key
|
||
var p = priv.params.p
|
||
var q = priv.params.q
|
||
var g = priv.params.g
|
||
var r = new BN(0)
|
||
var k
|
||
var H = bits2int(hash, q).mod(q)
|
||
var s = false
|
||
var kv = getKey(x, q, hash, algo)
|
||
while (s === false) {
|
||
k = makeKey(q, kv, algo)
|
||
r = makeR(g, k, p, q)
|
||
s = k.invm(q).imul(H.add(x.mul(r))).mod(q)
|
||
if (s.cmpn(0) === 0) {
|
||
s = false
|
||
r = new BN(0)
|
||
}
|
||
}
|
||
return toDER(r, s)
|
||
}
|
||
|
||
function toDER (r, s) {
|
||
r = r.toArray()
|
||
s = s.toArray()
|
||
|
||
// Pad values
|
||
if (r[0] & 0x80) r = [ 0 ].concat(r)
|
||
if (s[0] & 0x80) s = [ 0 ].concat(s)
|
||
|
||
var total = r.length + s.length + 4
|
||
var res = [ 0x30, total, 0x02, r.length ]
|
||
res = res.concat(r, [ 0x02, s.length ], s)
|
||
return new Buffer(res)
|
||
}
|
||
|
||
function getKey (x, q, hash, algo) {
|
||
x = new Buffer(x.toArray())
|
||
if (x.length < q.byteLength()) {
|
||
var zeros = new Buffer(q.byteLength() - x.length)
|
||
zeros.fill(0)
|
||
x = Buffer.concat([ zeros, x ])
|
||
}
|
||
var hlen = hash.length
|
||
var hbits = bits2octets(hash, q)
|
||
var v = new Buffer(hlen)
|
||
v.fill(1)
|
||
var k = new Buffer(hlen)
|
||
k.fill(0)
|
||
k = createHmac(algo, k).update(v).update(new Buffer([ 0 ])).update(x).update(hbits).digest()
|
||
v = createHmac(algo, k).update(v).digest()
|
||
k = createHmac(algo, k).update(v).update(new Buffer([ 1 ])).update(x).update(hbits).digest()
|
||
v = createHmac(algo, k).update(v).digest()
|
||
return { k: k, v: v }
|
||
}
|
||
|
||
function bits2int (obits, q) {
|
||
var bits = new BN(obits)
|
||
var shift = (obits.length << 3) - q.bitLength()
|
||
if (shift > 0) bits.ishrn(shift)
|
||
return bits
|
||
}
|
||
|
||
function bits2octets (bits, q) {
|
||
bits = bits2int(bits, q)
|
||
bits = bits.mod(q)
|
||
var out = new Buffer(bits.toArray())
|
||
if (out.length < q.byteLength()) {
|
||
var zeros = new Buffer(q.byteLength() - out.length)
|
||
zeros.fill(0)
|
||
out = Buffer.concat([ zeros, out ])
|
||
}
|
||
return out
|
||
}
|
||
|
||
function makeKey (q, kv, algo) {
|
||
var t
|
||
var k
|
||
|
||
do {
|
||
t = new Buffer(0)
|
||
|
||
while (t.length * 8 < q.bitLength()) {
|
||
kv.v = createHmac(algo, kv.k).update(kv.v).digest()
|
||
t = Buffer.concat([ t, kv.v ])
|
||
}
|
||
|
||
k = bits2int(t, q)
|
||
kv.k = createHmac(algo, kv.k).update(kv.v).update(new Buffer([ 0 ])).digest()
|
||
kv.v = createHmac(algo, kv.k).update(kv.v).digest()
|
||
} while (k.cmp(q) !== -1)
|
||
|
||
return k
|
||
}
|
||
|
||
function makeR (g, k, p, q) {
|
||
return g.toRed(BN.mont(p)).redPow(k).fromRed().mod(q)
|
||
}
|
||
|
||
module.exports = sign
|
||
module.exports.getKey = getKey
|
||
module.exports.makeKey = makeKey
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../buffer/index.js */ "./node_modules/buffer/index.js").Buffer))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/browserify-sign/browser/verify.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/browserify-sign/browser/verify.js ***!
|
||
\********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(Buffer) {// much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js
|
||
var BN = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js")
|
||
var EC = __webpack_require__(/*! elliptic */ "./node_modules/elliptic/lib/elliptic.js").ec
|
||
var parseKeys = __webpack_require__(/*! parse-asn1 */ "./node_modules/parse-asn1/index.js")
|
||
var curves = __webpack_require__(/*! ./curves.json */ "./node_modules/browserify-sign/browser/curves.json")
|
||
|
||
function verify (sig, hash, key, signType, tag) {
|
||
var pub = parseKeys(key)
|
||
if (pub.type === 'ec') {
|
||
// rsa keys can be interpreted as ecdsa ones in openssl
|
||
if (signType !== 'ecdsa' && signType !== 'ecdsa/rsa') throw new Error('wrong public key type')
|
||
return ecVerify(sig, hash, pub)
|
||
} else if (pub.type === 'dsa') {
|
||
if (signType !== 'dsa') throw new Error('wrong public key type')
|
||
return dsaVerify(sig, hash, pub)
|
||
} else {
|
||
if (signType !== 'rsa' && signType !== 'ecdsa/rsa') throw new Error('wrong public key type')
|
||
}
|
||
hash = Buffer.concat([tag, hash])
|
||
var len = pub.modulus.byteLength()
|
||
var pad = [ 1 ]
|
||
var padNum = 0
|
||
while (hash.length + pad.length + 2 < len) {
|
||
pad.push(0xff)
|
||
padNum++
|
||
}
|
||
pad.push(0x00)
|
||
var i = -1
|
||
while (++i < hash.length) {
|
||
pad.push(hash[i])
|
||
}
|
||
pad = new Buffer(pad)
|
||
var red = BN.mont(pub.modulus)
|
||
sig = new BN(sig).toRed(red)
|
||
|
||
sig = sig.redPow(new BN(pub.publicExponent))
|
||
sig = new Buffer(sig.fromRed().toArray())
|
||
var out = padNum < 8 ? 1 : 0
|
||
len = Math.min(sig.length, pad.length)
|
||
if (sig.length !== pad.length) out = 1
|
||
|
||
i = -1
|
||
while (++i < len) out |= sig[i] ^ pad[i]
|
||
return out === 0
|
||
}
|
||
|
||
function ecVerify (sig, hash, pub) {
|
||
var curveId = curves[pub.data.algorithm.curve.join('.')]
|
||
if (!curveId) throw new Error('unknown curve ' + pub.data.algorithm.curve.join('.'))
|
||
|
||
var curve = new EC(curveId)
|
||
var pubkey = pub.data.subjectPrivateKey.data
|
||
|
||
return curve.verify(hash, sig, pubkey)
|
||
}
|
||
|
||
function dsaVerify (sig, hash, pub) {
|
||
var p = pub.data.p
|
||
var q = pub.data.q
|
||
var g = pub.data.g
|
||
var y = pub.data.pub_key
|
||
var unpacked = parseKeys.signature.decode(sig, 'der')
|
||
var s = unpacked.s
|
||
var r = unpacked.r
|
||
checkValue(s, q)
|
||
checkValue(r, q)
|
||
var montp = BN.mont(p)
|
||
var w = s.invm(q)
|
||
var v = g.toRed(montp)
|
||
.redPow(new BN(hash).mul(w).mod(q))
|
||
.fromRed()
|
||
.mul(y.toRed(montp).redPow(r.mul(w).mod(q)).fromRed())
|
||
.mod(p)
|
||
.mod(q)
|
||
return v.cmp(r) === 0
|
||
}
|
||
|
||
function checkValue (b, q) {
|
||
if (b.cmpn(0) <= 0) throw new Error('invalid sig')
|
||
if (b.cmp(q) >= q) throw new Error('invalid sig')
|
||
}
|
||
|
||
module.exports = verify
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../buffer/index.js */ "./node_modules/buffer/index.js").Buffer))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/buffer-xor/index.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/buffer-xor/index.js ***!
|
||
\******************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(Buffer) {module.exports = function xor (a, b) {
|
||
var length = Math.min(a.length, b.length)
|
||
var buffer = new Buffer(length)
|
||
|
||
for (var i = 0; i < length; ++i) {
|
||
buffer[i] = a[i] ^ b[i]
|
||
}
|
||
|
||
return buffer
|
||
}
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../buffer/index.js */ "./node_modules/buffer/index.js").Buffer))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/buffer/index.js":
|
||
/*!**************************************!*\
|
||
!*** ./node_modules/buffer/index.js ***!
|
||
\**************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
/* WEBPACK VAR INJECTION */(function(global) {/*!
|
||
* The buffer module from node.js, for the browser.
|
||
*
|
||
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
|
||
* @license MIT
|
||
*/
|
||
/* eslint-disable no-proto */
|
||
|
||
|
||
|
||
var base64 = __webpack_require__(/*! base64-js */ "./node_modules/base64-js/index.js")
|
||
var ieee754 = __webpack_require__(/*! ieee754 */ "./node_modules/ieee754/index.js")
|
||
var isArray = __webpack_require__(/*! isarray */ "./node_modules/isarray/index.js")
|
||
|
||
exports.Buffer = Buffer
|
||
exports.SlowBuffer = SlowBuffer
|
||
exports.INSPECT_MAX_BYTES = 50
|
||
|
||
/**
|
||
* If `Buffer.TYPED_ARRAY_SUPPORT`:
|
||
* === true Use Uint8Array implementation (fastest)
|
||
* === false Use Object implementation (most compatible, even IE6)
|
||
*
|
||
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
|
||
* Opera 11.6+, iOS 4.2+.
|
||
*
|
||
* Due to various browser bugs, sometimes the Object implementation will be used even
|
||
* when the browser supports typed arrays.
|
||
*
|
||
* Note:
|
||
*
|
||
* - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
|
||
* See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
|
||
*
|
||
* - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
|
||
*
|
||
* - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
|
||
* incorrect length in some situations.
|
||
|
||
* We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
|
||
* get the Object implementation, which is slower but behaves correctly.
|
||
*/
|
||
Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
|
||
? global.TYPED_ARRAY_SUPPORT
|
||
: typedArraySupport()
|
||
|
||
/*
|
||
* Export kMaxLength after typed array support is determined.
|
||
*/
|
||
exports.kMaxLength = kMaxLength()
|
||
|
||
function typedArraySupport () {
|
||
try {
|
||
var arr = new Uint8Array(1)
|
||
arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}
|
||
return arr.foo() === 42 && // typed array instances can be augmented
|
||
typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
|
||
arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
|
||
} catch (e) {
|
||
return false
|
||
}
|
||
}
|
||
|
||
function kMaxLength () {
|
||
return Buffer.TYPED_ARRAY_SUPPORT
|
||
? 0x7fffffff
|
||
: 0x3fffffff
|
||
}
|
||
|
||
function createBuffer (that, length) {
|
||
if (kMaxLength() < length) {
|
||
throw new RangeError('Invalid typed array length')
|
||
}
|
||
if (Buffer.TYPED_ARRAY_SUPPORT) {
|
||
// Return an augmented `Uint8Array` instance, for best performance
|
||
that = new Uint8Array(length)
|
||
that.__proto__ = Buffer.prototype
|
||
} else {
|
||
// Fallback: Return an object instance of the Buffer class
|
||
if (that === null) {
|
||
that = new Buffer(length)
|
||
}
|
||
that.length = length
|
||
}
|
||
|
||
return that
|
||
}
|
||
|
||
/**
|
||
* The Buffer constructor returns instances of `Uint8Array` that have their
|
||
* prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
|
||
* `Uint8Array`, so the returned instances will have all the node `Buffer` methods
|
||
* and the `Uint8Array` methods. Square bracket notation works as expected -- it
|
||
* returns a single octet.
|
||
*
|
||
* The `Uint8Array` prototype remains unmodified.
|
||
*/
|
||
|
||
function Buffer (arg, encodingOrOffset, length) {
|
||
if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {
|
||
return new Buffer(arg, encodingOrOffset, length)
|
||
}
|
||
|
||
// Common case.
|
||
if (typeof arg === 'number') {
|
||
if (typeof encodingOrOffset === 'string') {
|
||
throw new Error(
|
||
'If encoding is specified then the first argument must be a string'
|
||
)
|
||
}
|
||
return allocUnsafe(this, arg)
|
||
}
|
||
return from(this, arg, encodingOrOffset, length)
|
||
}
|
||
|
||
Buffer.poolSize = 8192 // not used by this implementation
|
||
|
||
// TODO: Legacy, not needed anymore. Remove in next major version.
|
||
Buffer._augment = function (arr) {
|
||
arr.__proto__ = Buffer.prototype
|
||
return arr
|
||
}
|
||
|
||
function from (that, value, encodingOrOffset, length) {
|
||
if (typeof value === 'number') {
|
||
throw new TypeError('"value" argument must not be a number')
|
||
}
|
||
|
||
if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
|
||
return fromArrayBuffer(that, value, encodingOrOffset, length)
|
||
}
|
||
|
||
if (typeof value === 'string') {
|
||
return fromString(that, value, encodingOrOffset)
|
||
}
|
||
|
||
return fromObject(that, value)
|
||
}
|
||
|
||
/**
|
||
* Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
|
||
* if value is a number.
|
||
* Buffer.from(str[, encoding])
|
||
* Buffer.from(array)
|
||
* Buffer.from(buffer)
|
||
* Buffer.from(arrayBuffer[, byteOffset[, length]])
|
||
**/
|
||
Buffer.from = function (value, encodingOrOffset, length) {
|
||
return from(null, value, encodingOrOffset, length)
|
||
}
|
||
|
||
if (Buffer.TYPED_ARRAY_SUPPORT) {
|
||
Buffer.prototype.__proto__ = Uint8Array.prototype
|
||
Buffer.__proto__ = Uint8Array
|
||
if (typeof Symbol !== 'undefined' && Symbol.species &&
|
||
Buffer[Symbol.species] === Buffer) {
|
||
// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
|
||
Object.defineProperty(Buffer, Symbol.species, {
|
||
value: null,
|
||
configurable: true
|
||
})
|
||
}
|
||
}
|
||
|
||
function assertSize (size) {
|
||
if (typeof size !== 'number') {
|
||
throw new TypeError('"size" argument must be a number')
|
||
} else if (size < 0) {
|
||
throw new RangeError('"size" argument must not be negative')
|
||
}
|
||
}
|
||
|
||
function alloc (that, size, fill, encoding) {
|
||
assertSize(size)
|
||
if (size <= 0) {
|
||
return createBuffer(that, size)
|
||
}
|
||
if (fill !== undefined) {
|
||
// Only pay attention to encoding if it's a string. This
|
||
// prevents accidentally sending in a number that would
|
||
// be interpretted as a start offset.
|
||
return typeof encoding === 'string'
|
||
? createBuffer(that, size).fill(fill, encoding)
|
||
: createBuffer(that, size).fill(fill)
|
||
}
|
||
return createBuffer(that, size)
|
||
}
|
||
|
||
/**
|
||
* Creates a new filled Buffer instance.
|
||
* alloc(size[, fill[, encoding]])
|
||
**/
|
||
Buffer.alloc = function (size, fill, encoding) {
|
||
return alloc(null, size, fill, encoding)
|
||
}
|
||
|
||
function allocUnsafe (that, size) {
|
||
assertSize(size)
|
||
that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)
|
||
if (!Buffer.TYPED_ARRAY_SUPPORT) {
|
||
for (var i = 0; i < size; ++i) {
|
||
that[i] = 0
|
||
}
|
||
}
|
||
return that
|
||
}
|
||
|
||
/**
|
||
* Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
|
||
* */
|
||
Buffer.allocUnsafe = function (size) {
|
||
return allocUnsafe(null, size)
|
||
}
|
||
/**
|
||
* Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
|
||
*/
|
||
Buffer.allocUnsafeSlow = function (size) {
|
||
return allocUnsafe(null, size)
|
||
}
|
||
|
||
function fromString (that, string, encoding) {
|
||
if (typeof encoding !== 'string' || encoding === '') {
|
||
encoding = 'utf8'
|
||
}
|
||
|
||
if (!Buffer.isEncoding(encoding)) {
|
||
throw new TypeError('"encoding" must be a valid string encoding')
|
||
}
|
||
|
||
var length = byteLength(string, encoding) | 0
|
||
that = createBuffer(that, length)
|
||
|
||
var actual = that.write(string, encoding)
|
||
|
||
if (actual !== length) {
|
||
// Writing a hex string, for example, that contains invalid characters will
|
||
// cause everything after the first invalid character to be ignored. (e.g.
|
||
// 'abxxcd' will be treated as 'ab')
|
||
that = that.slice(0, actual)
|
||
}
|
||
|
||
return that
|
||
}
|
||
|
||
function fromArrayLike (that, array) {
|
||
var length = array.length < 0 ? 0 : checked(array.length) | 0
|
||
that = createBuffer(that, length)
|
||
for (var i = 0; i < length; i += 1) {
|
||
that[i] = array[i] & 255
|
||
}
|
||
return that
|
||
}
|
||
|
||
function fromArrayBuffer (that, array, byteOffset, length) {
|
||
array.byteLength // this throws if `array` is not a valid ArrayBuffer
|
||
|
||
if (byteOffset < 0 || array.byteLength < byteOffset) {
|
||
throw new RangeError('\'offset\' is out of bounds')
|
||
}
|
||
|
||
if (array.byteLength < byteOffset + (length || 0)) {
|
||
throw new RangeError('\'length\' is out of bounds')
|
||
}
|
||
|
||
if (byteOffset === undefined && length === undefined) {
|
||
array = new Uint8Array(array)
|
||
} else if (length === undefined) {
|
||
array = new Uint8Array(array, byteOffset)
|
||
} else {
|
||
array = new Uint8Array(array, byteOffset, length)
|
||
}
|
||
|
||
if (Buffer.TYPED_ARRAY_SUPPORT) {
|
||
// Return an augmented `Uint8Array` instance, for best performance
|
||
that = array
|
||
that.__proto__ = Buffer.prototype
|
||
} else {
|
||
// Fallback: Return an object instance of the Buffer class
|
||
that = fromArrayLike(that, array)
|
||
}
|
||
return that
|
||
}
|
||
|
||
function fromObject (that, obj) {
|
||
if (Buffer.isBuffer(obj)) {
|
||
var len = checked(obj.length) | 0
|
||
that = createBuffer(that, len)
|
||
|
||
if (that.length === 0) {
|
||
return that
|
||
}
|
||
|
||
obj.copy(that, 0, 0, len)
|
||
return that
|
||
}
|
||
|
||
if (obj) {
|
||
if ((typeof ArrayBuffer !== 'undefined' &&
|
||
obj.buffer instanceof ArrayBuffer) || 'length' in obj) {
|
||
if (typeof obj.length !== 'number' || isnan(obj.length)) {
|
||
return createBuffer(that, 0)
|
||
}
|
||
return fromArrayLike(that, obj)
|
||
}
|
||
|
||
if (obj.type === 'Buffer' && isArray(obj.data)) {
|
||
return fromArrayLike(that, obj.data)
|
||
}
|
||
}
|
||
|
||
throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')
|
||
}
|
||
|
||
function checked (length) {
|
||
// Note: cannot use `length < kMaxLength()` here because that fails when
|
||
// length is NaN (which is otherwise coerced to zero.)
|
||
if (length >= kMaxLength()) {
|
||
throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
|
||
'size: 0x' + kMaxLength().toString(16) + ' bytes')
|
||
}
|
||
return length | 0
|
||
}
|
||
|
||
function SlowBuffer (length) {
|
||
if (+length != length) { // eslint-disable-line eqeqeq
|
||
length = 0
|
||
}
|
||
return Buffer.alloc(+length)
|
||
}
|
||
|
||
Buffer.isBuffer = function isBuffer (b) {
|
||
return !!(b != null && b._isBuffer)
|
||
}
|
||
|
||
Buffer.compare = function compare (a, b) {
|
||
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
|
||
throw new TypeError('Arguments must be Buffers')
|
||
}
|
||
|
||
if (a === b) return 0
|
||
|
||
var x = a.length
|
||
var y = b.length
|
||
|
||
for (var i = 0, len = Math.min(x, y); i < len; ++i) {
|
||
if (a[i] !== b[i]) {
|
||
x = a[i]
|
||
y = b[i]
|
||
break
|
||
}
|
||
}
|
||
|
||
if (x < y) return -1
|
||
if (y < x) return 1
|
||
return 0
|
||
}
|
||
|
||
Buffer.isEncoding = function isEncoding (encoding) {
|
||
switch (String(encoding).toLowerCase()) {
|
||
case 'hex':
|
||
case 'utf8':
|
||
case 'utf-8':
|
||
case 'ascii':
|
||
case 'latin1':
|
||
case 'binary':
|
||
case 'base64':
|
||
case 'ucs2':
|
||
case 'ucs-2':
|
||
case 'utf16le':
|
||
case 'utf-16le':
|
||
return true
|
||
default:
|
||
return false
|
||
}
|
||
}
|
||
|
||
Buffer.concat = function concat (list, length) {
|
||
if (!isArray(list)) {
|
||
throw new TypeError('"list" argument must be an Array of Buffers')
|
||
}
|
||
|
||
if (list.length === 0) {
|
||
return Buffer.alloc(0)
|
||
}
|
||
|
||
var i
|
||
if (length === undefined) {
|
||
length = 0
|
||
for (i = 0; i < list.length; ++i) {
|
||
length += list[i].length
|
||
}
|
||
}
|
||
|
||
var buffer = Buffer.allocUnsafe(length)
|
||
var pos = 0
|
||
for (i = 0; i < list.length; ++i) {
|
||
var buf = list[i]
|
||
if (!Buffer.isBuffer(buf)) {
|
||
throw new TypeError('"list" argument must be an Array of Buffers')
|
||
}
|
||
buf.copy(buffer, pos)
|
||
pos += buf.length
|
||
}
|
||
return buffer
|
||
}
|
||
|
||
function byteLength (string, encoding) {
|
||
if (Buffer.isBuffer(string)) {
|
||
return string.length
|
||
}
|
||
if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&
|
||
(ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {
|
||
return string.byteLength
|
||
}
|
||
if (typeof string !== 'string') {
|
||
string = '' + string
|
||
}
|
||
|
||
var len = string.length
|
||
if (len === 0) return 0
|
||
|
||
// Use a for loop to avoid recursion
|
||
var loweredCase = false
|
||
for (;;) {
|
||
switch (encoding) {
|
||
case 'ascii':
|
||
case 'latin1':
|
||
case 'binary':
|
||
return len
|
||
case 'utf8':
|
||
case 'utf-8':
|
||
case undefined:
|
||
return utf8ToBytes(string).length
|
||
case 'ucs2':
|
||
case 'ucs-2':
|
||
case 'utf16le':
|
||
case 'utf-16le':
|
||
return len * 2
|
||
case 'hex':
|
||
return len >>> 1
|
||
case 'base64':
|
||
return base64ToBytes(string).length
|
||
default:
|
||
if (loweredCase) return utf8ToBytes(string).length // assume utf8
|
||
encoding = ('' + encoding).toLowerCase()
|
||
loweredCase = true
|
||
}
|
||
}
|
||
}
|
||
Buffer.byteLength = byteLength
|
||
|
||
function slowToString (encoding, start, end) {
|
||
var loweredCase = false
|
||
|
||
// No need to verify that "this.length <= MAX_UINT32" since it's a read-only
|
||
// property of a typed array.
|
||
|
||
// This behaves neither like String nor Uint8Array in that we set start/end
|
||
// to their upper/lower bounds if the value passed is out of range.
|
||
// undefined is handled specially as per ECMA-262 6th Edition,
|
||
// Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
|
||
if (start === undefined || start < 0) {
|
||
start = 0
|
||
}
|
||
// Return early if start > this.length. Done here to prevent potential uint32
|
||
// coercion fail below.
|
||
if (start > this.length) {
|
||
return ''
|
||
}
|
||
|
||
if (end === undefined || end > this.length) {
|
||
end = this.length
|
||
}
|
||
|
||
if (end <= 0) {
|
||
return ''
|
||
}
|
||
|
||
// Force coersion to uint32. This will also coerce falsey/NaN values to 0.
|
||
end >>>= 0
|
||
start >>>= 0
|
||
|
||
if (end <= start) {
|
||
return ''
|
||
}
|
||
|
||
if (!encoding) encoding = 'utf8'
|
||
|
||
while (true) {
|
||
switch (encoding) {
|
||
case 'hex':
|
||
return hexSlice(this, start, end)
|
||
|
||
case 'utf8':
|
||
case 'utf-8':
|
||
return utf8Slice(this, start, end)
|
||
|
||
case 'ascii':
|
||
return asciiSlice(this, start, end)
|
||
|
||
case 'latin1':
|
||
case 'binary':
|
||
return latin1Slice(this, start, end)
|
||
|
||
case 'base64':
|
||
return base64Slice(this, start, end)
|
||
|
||
case 'ucs2':
|
||
case 'ucs-2':
|
||
case 'utf16le':
|
||
case 'utf-16le':
|
||
return utf16leSlice(this, start, end)
|
||
|
||
default:
|
||
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
|
||
encoding = (encoding + '').toLowerCase()
|
||
loweredCase = true
|
||
}
|
||
}
|
||
}
|
||
|
||
// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect
|
||
// Buffer instances.
|
||
Buffer.prototype._isBuffer = true
|
||
|
||
function swap (b, n, m) {
|
||
var i = b[n]
|
||
b[n] = b[m]
|
||
b[m] = i
|
||
}
|
||
|
||
Buffer.prototype.swap16 = function swap16 () {
|
||
var len = this.length
|
||
if (len % 2 !== 0) {
|
||
throw new RangeError('Buffer size must be a multiple of 16-bits')
|
||
}
|
||
for (var i = 0; i < len; i += 2) {
|
||
swap(this, i, i + 1)
|
||
}
|
||
return this
|
||
}
|
||
|
||
Buffer.prototype.swap32 = function swap32 () {
|
||
var len = this.length
|
||
if (len % 4 !== 0) {
|
||
throw new RangeError('Buffer size must be a multiple of 32-bits')
|
||
}
|
||
for (var i = 0; i < len; i += 4) {
|
||
swap(this, i, i + 3)
|
||
swap(this, i + 1, i + 2)
|
||
}
|
||
return this
|
||
}
|
||
|
||
Buffer.prototype.swap64 = function swap64 () {
|
||
var len = this.length
|
||
if (len % 8 !== 0) {
|
||
throw new RangeError('Buffer size must be a multiple of 64-bits')
|
||
}
|
||
for (var i = 0; i < len; i += 8) {
|
||
swap(this, i, i + 7)
|
||
swap(this, i + 1, i + 6)
|
||
swap(this, i + 2, i + 5)
|
||
swap(this, i + 3, i + 4)
|
||
}
|
||
return this
|
||
}
|
||
|
||
Buffer.prototype.toString = function toString () {
|
||
var length = this.length | 0
|
||
if (length === 0) return ''
|
||
if (arguments.length === 0) return utf8Slice(this, 0, length)
|
||
return slowToString.apply(this, arguments)
|
||
}
|
||
|
||
Buffer.prototype.equals = function equals (b) {
|
||
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
|
||
if (this === b) return true
|
||
return Buffer.compare(this, b) === 0
|
||
}
|
||
|
||
Buffer.prototype.inspect = function inspect () {
|
||
var str = ''
|
||
var max = exports.INSPECT_MAX_BYTES
|
||
if (this.length > 0) {
|
||
str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
|
||
if (this.length > max) str += ' ... '
|
||
}
|
||
return '<Buffer ' + str + '>'
|
||
}
|
||
|
||
Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
|
||
if (!Buffer.isBuffer(target)) {
|
||
throw new TypeError('Argument must be a Buffer')
|
||
}
|
||
|
||
if (start === undefined) {
|
||
start = 0
|
||
}
|
||
if (end === undefined) {
|
||
end = target ? target.length : 0
|
||
}
|
||
if (thisStart === undefined) {
|
||
thisStart = 0
|
||
}
|
||
if (thisEnd === undefined) {
|
||
thisEnd = this.length
|
||
}
|
||
|
||
if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
|
||
throw new RangeError('out of range index')
|
||
}
|
||
|
||
if (thisStart >= thisEnd && start >= end) {
|
||
return 0
|
||
}
|
||
if (thisStart >= thisEnd) {
|
||
return -1
|
||
}
|
||
if (start >= end) {
|
||
return 1
|
||
}
|
||
|
||
start >>>= 0
|
||
end >>>= 0
|
||
thisStart >>>= 0
|
||
thisEnd >>>= 0
|
||
|
||
if (this === target) return 0
|
||
|
||
var x = thisEnd - thisStart
|
||
var y = end - start
|
||
var len = Math.min(x, y)
|
||
|
||
var thisCopy = this.slice(thisStart, thisEnd)
|
||
var targetCopy = target.slice(start, end)
|
||
|
||
for (var i = 0; i < len; ++i) {
|
||
if (thisCopy[i] !== targetCopy[i]) {
|
||
x = thisCopy[i]
|
||
y = targetCopy[i]
|
||
break
|
||
}
|
||
}
|
||
|
||
if (x < y) return -1
|
||
if (y < x) return 1
|
||
return 0
|
||
}
|
||
|
||
// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
|
||
// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
|
||
//
|
||
// Arguments:
|
||
// - buffer - a Buffer to search
|
||
// - val - a string, Buffer, or number
|
||
// - byteOffset - an index into `buffer`; will be clamped to an int32
|
||
// - encoding - an optional encoding, relevant is val is a string
|
||
// - dir - true for indexOf, false for lastIndexOf
|
||
function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
|
||
// Empty buffer means no match
|
||
if (buffer.length === 0) return -1
|
||
|
||
// Normalize byteOffset
|
||
if (typeof byteOffset === 'string') {
|
||
encoding = byteOffset
|
||
byteOffset = 0
|
||
} else if (byteOffset > 0x7fffffff) {
|
||
byteOffset = 0x7fffffff
|
||
} else if (byteOffset < -0x80000000) {
|
||
byteOffset = -0x80000000
|
||
}
|
||
byteOffset = +byteOffset // Coerce to Number.
|
||
if (isNaN(byteOffset)) {
|
||
// byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
|
||
byteOffset = dir ? 0 : (buffer.length - 1)
|
||
}
|
||
|
||
// Normalize byteOffset: negative offsets start from the end of the buffer
|
||
if (byteOffset < 0) byteOffset = buffer.length + byteOffset
|
||
if (byteOffset >= buffer.length) {
|
||
if (dir) return -1
|
||
else byteOffset = buffer.length - 1
|
||
} else if (byteOffset < 0) {
|
||
if (dir) byteOffset = 0
|
||
else return -1
|
||
}
|
||
|
||
// Normalize val
|
||
if (typeof val === 'string') {
|
||
val = Buffer.from(val, encoding)
|
||
}
|
||
|
||
// Finally, search either indexOf (if dir is true) or lastIndexOf
|
||
if (Buffer.isBuffer(val)) {
|
||
// Special case: looking for empty string/buffer always fails
|
||
if (val.length === 0) {
|
||
return -1
|
||
}
|
||
return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
|
||
} else if (typeof val === 'number') {
|
||
val = val & 0xFF // Search for a byte value [0-255]
|
||
if (Buffer.TYPED_ARRAY_SUPPORT &&
|
||
typeof Uint8Array.prototype.indexOf === 'function') {
|
||
if (dir) {
|
||
return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
|
||
} else {
|
||
return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
|
||
}
|
||
}
|
||
return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
|
||
}
|
||
|
||
throw new TypeError('val must be string, number or Buffer')
|
||
}
|
||
|
||
function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
|
||
var indexSize = 1
|
||
var arrLength = arr.length
|
||
var valLength = val.length
|
||
|
||
if (encoding !== undefined) {
|
||
encoding = String(encoding).toLowerCase()
|
||
if (encoding === 'ucs2' || encoding === 'ucs-2' ||
|
||
encoding === 'utf16le' || encoding === 'utf-16le') {
|
||
if (arr.length < 2 || val.length < 2) {
|
||
return -1
|
||
}
|
||
indexSize = 2
|
||
arrLength /= 2
|
||
valLength /= 2
|
||
byteOffset /= 2
|
||
}
|
||
}
|
||
|
||
function read (buf, i) {
|
||
if (indexSize === 1) {
|
||
return buf[i]
|
||
} else {
|
||
return buf.readUInt16BE(i * indexSize)
|
||
}
|
||
}
|
||
|
||
var i
|
||
if (dir) {
|
||
var foundIndex = -1
|
||
for (i = byteOffset; i < arrLength; i++) {
|
||
if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
|
||
if (foundIndex === -1) foundIndex = i
|
||
if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
|
||
} else {
|
||
if (foundIndex !== -1) i -= i - foundIndex
|
||
foundIndex = -1
|
||
}
|
||
}
|
||
} else {
|
||
if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
|
||
for (i = byteOffset; i >= 0; i--) {
|
||
var found = true
|
||
for (var j = 0; j < valLength; j++) {
|
||
if (read(arr, i + j) !== read(val, j)) {
|
||
found = false
|
||
break
|
||
}
|
||
}
|
||
if (found) return i
|
||
}
|
||
}
|
||
|
||
return -1
|
||
}
|
||
|
||
Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
|
||
return this.indexOf(val, byteOffset, encoding) !== -1
|
||
}
|
||
|
||
Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
|
||
return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
|
||
}
|
||
|
||
Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
|
||
return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
|
||
}
|
||
|
||
function hexWrite (buf, string, offset, length) {
|
||
offset = Number(offset) || 0
|
||
var remaining = buf.length - offset
|
||
if (!length) {
|
||
length = remaining
|
||
} else {
|
||
length = Number(length)
|
||
if (length > remaining) {
|
||
length = remaining
|
||
}
|
||
}
|
||
|
||
// must be an even number of digits
|
||
var strLen = string.length
|
||
if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')
|
||
|
||
if (length > strLen / 2) {
|
||
length = strLen / 2
|
||
}
|
||
for (var i = 0; i < length; ++i) {
|
||
var parsed = parseInt(string.substr(i * 2, 2), 16)
|
||
if (isNaN(parsed)) return i
|
||
buf[offset + i] = parsed
|
||
}
|
||
return i
|
||
}
|
||
|
||
function utf8Write (buf, string, offset, length) {
|
||
return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
|
||
}
|
||
|
||
function asciiWrite (buf, string, offset, length) {
|
||
return blitBuffer(asciiToBytes(string), buf, offset, length)
|
||
}
|
||
|
||
function latin1Write (buf, string, offset, length) {
|
||
return asciiWrite(buf, string, offset, length)
|
||
}
|
||
|
||
function base64Write (buf, string, offset, length) {
|
||
return blitBuffer(base64ToBytes(string), buf, offset, length)
|
||
}
|
||
|
||
function ucs2Write (buf, string, offset, length) {
|
||
return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
|
||
}
|
||
|
||
Buffer.prototype.write = function write (string, offset, length, encoding) {
|
||
// Buffer#write(string)
|
||
if (offset === undefined) {
|
||
encoding = 'utf8'
|
||
length = this.length
|
||
offset = 0
|
||
// Buffer#write(string, encoding)
|
||
} else if (length === undefined && typeof offset === 'string') {
|
||
encoding = offset
|
||
length = this.length
|
||
offset = 0
|
||
// Buffer#write(string, offset[, length][, encoding])
|
||
} else if (isFinite(offset)) {
|
||
offset = offset | 0
|
||
if (isFinite(length)) {
|
||
length = length | 0
|
||
if (encoding === undefined) encoding = 'utf8'
|
||
} else {
|
||
encoding = length
|
||
length = undefined
|
||
}
|
||
// legacy write(string, encoding, offset, length) - remove in v0.13
|
||
} else {
|
||
throw new Error(
|
||
'Buffer.write(string, encoding, offset[, length]) is no longer supported'
|
||
)
|
||
}
|
||
|
||
var remaining = this.length - offset
|
||
if (length === undefined || length > remaining) length = remaining
|
||
|
||
if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
|
||
throw new RangeError('Attempt to write outside buffer bounds')
|
||
}
|
||
|
||
if (!encoding) encoding = 'utf8'
|
||
|
||
var loweredCase = false
|
||
for (;;) {
|
||
switch (encoding) {
|
||
case 'hex':
|
||
return hexWrite(this, string, offset, length)
|
||
|
||
case 'utf8':
|
||
case 'utf-8':
|
||
return utf8Write(this, string, offset, length)
|
||
|
||
case 'ascii':
|
||
return asciiWrite(this, string, offset, length)
|
||
|
||
case 'latin1':
|
||
case 'binary':
|
||
return latin1Write(this, string, offset, length)
|
||
|
||
case 'base64':
|
||
// Warning: maxLength not taken into account in base64Write
|
||
return base64Write(this, string, offset, length)
|
||
|
||
case 'ucs2':
|
||
case 'ucs-2':
|
||
case 'utf16le':
|
||
case 'utf-16le':
|
||
return ucs2Write(this, string, offset, length)
|
||
|
||
default:
|
||
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
|
||
encoding = ('' + encoding).toLowerCase()
|
||
loweredCase = true
|
||
}
|
||
}
|
||
}
|
||
|
||
Buffer.prototype.toJSON = function toJSON () {
|
||
return {
|
||
type: 'Buffer',
|
||
data: Array.prototype.slice.call(this._arr || this, 0)
|
||
}
|
||
}
|
||
|
||
function base64Slice (buf, start, end) {
|
||
if (start === 0 && end === buf.length) {
|
||
return base64.fromByteArray(buf)
|
||
} else {
|
||
return base64.fromByteArray(buf.slice(start, end))
|
||
}
|
||
}
|
||
|
||
function utf8Slice (buf, start, end) {
|
||
end = Math.min(buf.length, end)
|
||
var res = []
|
||
|
||
var i = start
|
||
while (i < end) {
|
||
var firstByte = buf[i]
|
||
var codePoint = null
|
||
var bytesPerSequence = (firstByte > 0xEF) ? 4
|
||
: (firstByte > 0xDF) ? 3
|
||
: (firstByte > 0xBF) ? 2
|
||
: 1
|
||
|
||
if (i + bytesPerSequence <= end) {
|
||
var secondByte, thirdByte, fourthByte, tempCodePoint
|
||
|
||
switch (bytesPerSequence) {
|
||
case 1:
|
||
if (firstByte < 0x80) {
|
||
codePoint = firstByte
|
||
}
|
||
break
|
||
case 2:
|
||
secondByte = buf[i + 1]
|
||
if ((secondByte & 0xC0) === 0x80) {
|
||
tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
|
||
if (tempCodePoint > 0x7F) {
|
||
codePoint = tempCodePoint
|
||
}
|
||
}
|
||
break
|
||
case 3:
|
||
secondByte = buf[i + 1]
|
||
thirdByte = buf[i + 2]
|
||
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
|
||
tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
|
||
if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
|
||
codePoint = tempCodePoint
|
||
}
|
||
}
|
||
break
|
||
case 4:
|
||
secondByte = buf[i + 1]
|
||
thirdByte = buf[i + 2]
|
||
fourthByte = buf[i + 3]
|
||
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
|
||
tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
|
||
if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
|
||
codePoint = tempCodePoint
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (codePoint === null) {
|
||
// we did not generate a valid codePoint so insert a
|
||
// replacement char (U+FFFD) and advance only 1 byte
|
||
codePoint = 0xFFFD
|
||
bytesPerSequence = 1
|
||
} else if (codePoint > 0xFFFF) {
|
||
// encode to utf16 (surrogate pair dance)
|
||
codePoint -= 0x10000
|
||
res.push(codePoint >>> 10 & 0x3FF | 0xD800)
|
||
codePoint = 0xDC00 | codePoint & 0x3FF
|
||
}
|
||
|
||
res.push(codePoint)
|
||
i += bytesPerSequence
|
||
}
|
||
|
||
return decodeCodePointsArray(res)
|
||
}
|
||
|
||
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
|
||
// the lowest limit is Chrome, with 0x10000 args.
|
||
// We go 1 magnitude less, for safety
|
||
var MAX_ARGUMENTS_LENGTH = 0x1000
|
||
|
||
function decodeCodePointsArray (codePoints) {
|
||
var len = codePoints.length
|
||
if (len <= MAX_ARGUMENTS_LENGTH) {
|
||
return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
|
||
}
|
||
|
||
// Decode in chunks to avoid "call stack size exceeded".
|
||
var res = ''
|
||
var i = 0
|
||
while (i < len) {
|
||
res += String.fromCharCode.apply(
|
||
String,
|
||
codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
|
||
)
|
||
}
|
||
return res
|
||
}
|
||
|
||
function asciiSlice (buf, start, end) {
|
||
var ret = ''
|
||
end = Math.min(buf.length, end)
|
||
|
||
for (var i = start; i < end; ++i) {
|
||
ret += String.fromCharCode(buf[i] & 0x7F)
|
||
}
|
||
return ret
|
||
}
|
||
|
||
function latin1Slice (buf, start, end) {
|
||
var ret = ''
|
||
end = Math.min(buf.length, end)
|
||
|
||
for (var i = start; i < end; ++i) {
|
||
ret += String.fromCharCode(buf[i])
|
||
}
|
||
return ret
|
||
}
|
||
|
||
function hexSlice (buf, start, end) {
|
||
var len = buf.length
|
||
|
||
if (!start || start < 0) start = 0
|
||
if (!end || end < 0 || end > len) end = len
|
||
|
||
var out = ''
|
||
for (var i = start; i < end; ++i) {
|
||
out += toHex(buf[i])
|
||
}
|
||
return out
|
||
}
|
||
|
||
function utf16leSlice (buf, start, end) {
|
||
var bytes = buf.slice(start, end)
|
||
var res = ''
|
||
for (var i = 0; i < bytes.length; i += 2) {
|
||
res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
|
||
}
|
||
return res
|
||
}
|
||
|
||
Buffer.prototype.slice = function slice (start, end) {
|
||
var len = this.length
|
||
start = ~~start
|
||
end = end === undefined ? len : ~~end
|
||
|
||
if (start < 0) {
|
||
start += len
|
||
if (start < 0) start = 0
|
||
} else if (start > len) {
|
||
start = len
|
||
}
|
||
|
||
if (end < 0) {
|
||
end += len
|
||
if (end < 0) end = 0
|
||
} else if (end > len) {
|
||
end = len
|
||
}
|
||
|
||
if (end < start) end = start
|
||
|
||
var newBuf
|
||
if (Buffer.TYPED_ARRAY_SUPPORT) {
|
||
newBuf = this.subarray(start, end)
|
||
newBuf.__proto__ = Buffer.prototype
|
||
} else {
|
||
var sliceLen = end - start
|
||
newBuf = new Buffer(sliceLen, undefined)
|
||
for (var i = 0; i < sliceLen; ++i) {
|
||
newBuf[i] = this[i + start]
|
||
}
|
||
}
|
||
|
||
return newBuf
|
||
}
|
||
|
||
/*
|
||
* Need to make sure that buffer isn't trying to write out of bounds.
|
||
*/
|
||
function checkOffset (offset, ext, length) {
|
||
if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
|
||
if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
|
||
}
|
||
|
||
Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
|
||
offset = offset | 0
|
||
byteLength = byteLength | 0
|
||
if (!noAssert) checkOffset(offset, byteLength, this.length)
|
||
|
||
var val = this[offset]
|
||
var mul = 1
|
||
var i = 0
|
||
while (++i < byteLength && (mul *= 0x100)) {
|
||
val += this[offset + i] * mul
|
||
}
|
||
|
||
return val
|
||
}
|
||
|
||
Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
|
||
offset = offset | 0
|
||
byteLength = byteLength | 0
|
||
if (!noAssert) {
|
||
checkOffset(offset, byteLength, this.length)
|
||
}
|
||
|
||
var val = this[offset + --byteLength]
|
||
var mul = 1
|
||
while (byteLength > 0 && (mul *= 0x100)) {
|
||
val += this[offset + --byteLength] * mul
|
||
}
|
||
|
||
return val
|
||
}
|
||
|
||
Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
|
||
if (!noAssert) checkOffset(offset, 1, this.length)
|
||
return this[offset]
|
||
}
|
||
|
||
Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
|
||
if (!noAssert) checkOffset(offset, 2, this.length)
|
||
return this[offset] | (this[offset + 1] << 8)
|
||
}
|
||
|
||
Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
|
||
if (!noAssert) checkOffset(offset, 2, this.length)
|
||
return (this[offset] << 8) | this[offset + 1]
|
||
}
|
||
|
||
Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
|
||
if (!noAssert) checkOffset(offset, 4, this.length)
|
||
|
||
return ((this[offset]) |
|
||
(this[offset + 1] << 8) |
|
||
(this[offset + 2] << 16)) +
|
||
(this[offset + 3] * 0x1000000)
|
||
}
|
||
|
||
Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
|
||
if (!noAssert) checkOffset(offset, 4, this.length)
|
||
|
||
return (this[offset] * 0x1000000) +
|
||
((this[offset + 1] << 16) |
|
||
(this[offset + 2] << 8) |
|
||
this[offset + 3])
|
||
}
|
||
|
||
Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
|
||
offset = offset | 0
|
||
byteLength = byteLength | 0
|
||
if (!noAssert) checkOffset(offset, byteLength, this.length)
|
||
|
||
var val = this[offset]
|
||
var mul = 1
|
||
var i = 0
|
||
while (++i < byteLength && (mul *= 0x100)) {
|
||
val += this[offset + i] * mul
|
||
}
|
||
mul *= 0x80
|
||
|
||
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
|
||
|
||
return val
|
||
}
|
||
|
||
Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
|
||
offset = offset | 0
|
||
byteLength = byteLength | 0
|
||
if (!noAssert) checkOffset(offset, byteLength, this.length)
|
||
|
||
var i = byteLength
|
||
var mul = 1
|
||
var val = this[offset + --i]
|
||
while (i > 0 && (mul *= 0x100)) {
|
||
val += this[offset + --i] * mul
|
||
}
|
||
mul *= 0x80
|
||
|
||
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
|
||
|
||
return val
|
||
}
|
||
|
||
Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
|
||
if (!noAssert) checkOffset(offset, 1, this.length)
|
||
if (!(this[offset] & 0x80)) return (this[offset])
|
||
return ((0xff - this[offset] + 1) * -1)
|
||
}
|
||
|
||
Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
|
||
if (!noAssert) checkOffset(offset, 2, this.length)
|
||
var val = this[offset] | (this[offset + 1] << 8)
|
||
return (val & 0x8000) ? val | 0xFFFF0000 : val
|
||
}
|
||
|
||
Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
|
||
if (!noAssert) checkOffset(offset, 2, this.length)
|
||
var val = this[offset + 1] | (this[offset] << 8)
|
||
return (val & 0x8000) ? val | 0xFFFF0000 : val
|
||
}
|
||
|
||
Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
|
||
if (!noAssert) checkOffset(offset, 4, this.length)
|
||
|
||
return (this[offset]) |
|
||
(this[offset + 1] << 8) |
|
||
(this[offset + 2] << 16) |
|
||
(this[offset + 3] << 24)
|
||
}
|
||
|
||
Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
|
||
if (!noAssert) checkOffset(offset, 4, this.length)
|
||
|
||
return (this[offset] << 24) |
|
||
(this[offset + 1] << 16) |
|
||
(this[offset + 2] << 8) |
|
||
(this[offset + 3])
|
||
}
|
||
|
||
Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
|
||
if (!noAssert) checkOffset(offset, 4, this.length)
|
||
return ieee754.read(this, offset, true, 23, 4)
|
||
}
|
||
|
||
Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
|
||
if (!noAssert) checkOffset(offset, 4, this.length)
|
||
return ieee754.read(this, offset, false, 23, 4)
|
||
}
|
||
|
||
Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
|
||
if (!noAssert) checkOffset(offset, 8, this.length)
|
||
return ieee754.read(this, offset, true, 52, 8)
|
||
}
|
||
|
||
Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
|
||
if (!noAssert) checkOffset(offset, 8, this.length)
|
||
return ieee754.read(this, offset, false, 52, 8)
|
||
}
|
||
|
||
function checkInt (buf, value, offset, ext, max, min) {
|
||
if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
|
||
if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
|
||
if (offset + ext > buf.length) throw new RangeError('Index out of range')
|
||
}
|
||
|
||
Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
|
||
value = +value
|
||
offset = offset | 0
|
||
byteLength = byteLength | 0
|
||
if (!noAssert) {
|
||
var maxBytes = Math.pow(2, 8 * byteLength) - 1
|
||
checkInt(this, value, offset, byteLength, maxBytes, 0)
|
||
}
|
||
|
||
var mul = 1
|
||
var i = 0
|
||
this[offset] = value & 0xFF
|
||
while (++i < byteLength && (mul *= 0x100)) {
|
||
this[offset + i] = (value / mul) & 0xFF
|
||
}
|
||
|
||
return offset + byteLength
|
||
}
|
||
|
||
Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
|
||
value = +value
|
||
offset = offset | 0
|
||
byteLength = byteLength | 0
|
||
if (!noAssert) {
|
||
var maxBytes = Math.pow(2, 8 * byteLength) - 1
|
||
checkInt(this, value, offset, byteLength, maxBytes, 0)
|
||
}
|
||
|
||
var i = byteLength - 1
|
||
var mul = 1
|
||
this[offset + i] = value & 0xFF
|
||
while (--i >= 0 && (mul *= 0x100)) {
|
||
this[offset + i] = (value / mul) & 0xFF
|
||
}
|
||
|
||
return offset + byteLength
|
||
}
|
||
|
||
Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset | 0
|
||
if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
|
||
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
|
||
this[offset] = (value & 0xff)
|
||
return offset + 1
|
||
}
|
||
|
||
function objectWriteUInt16 (buf, value, offset, littleEndian) {
|
||
if (value < 0) value = 0xffff + value + 1
|
||
for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {
|
||
buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
|
||
(littleEndian ? i : 1 - i) * 8
|
||
}
|
||
}
|
||
|
||
Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset | 0
|
||
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
|
||
if (Buffer.TYPED_ARRAY_SUPPORT) {
|
||
this[offset] = (value & 0xff)
|
||
this[offset + 1] = (value >>> 8)
|
||
} else {
|
||
objectWriteUInt16(this, value, offset, true)
|
||
}
|
||
return offset + 2
|
||
}
|
||
|
||
Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset | 0
|
||
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
|
||
if (Buffer.TYPED_ARRAY_SUPPORT) {
|
||
this[offset] = (value >>> 8)
|
||
this[offset + 1] = (value & 0xff)
|
||
} else {
|
||
objectWriteUInt16(this, value, offset, false)
|
||
}
|
||
return offset + 2
|
||
}
|
||
|
||
function objectWriteUInt32 (buf, value, offset, littleEndian) {
|
||
if (value < 0) value = 0xffffffff + value + 1
|
||
for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {
|
||
buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
|
||
}
|
||
}
|
||
|
||
Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset | 0
|
||
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
|
||
if (Buffer.TYPED_ARRAY_SUPPORT) {
|
||
this[offset + 3] = (value >>> 24)
|
||
this[offset + 2] = (value >>> 16)
|
||
this[offset + 1] = (value >>> 8)
|
||
this[offset] = (value & 0xff)
|
||
} else {
|
||
objectWriteUInt32(this, value, offset, true)
|
||
}
|
||
return offset + 4
|
||
}
|
||
|
||
Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset | 0
|
||
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
|
||
if (Buffer.TYPED_ARRAY_SUPPORT) {
|
||
this[offset] = (value >>> 24)
|
||
this[offset + 1] = (value >>> 16)
|
||
this[offset + 2] = (value >>> 8)
|
||
this[offset + 3] = (value & 0xff)
|
||
} else {
|
||
objectWriteUInt32(this, value, offset, false)
|
||
}
|
||
return offset + 4
|
||
}
|
||
|
||
Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
|
||
value = +value
|
||
offset = offset | 0
|
||
if (!noAssert) {
|
||
var limit = Math.pow(2, 8 * byteLength - 1)
|
||
|
||
checkInt(this, value, offset, byteLength, limit - 1, -limit)
|
||
}
|
||
|
||
var i = 0
|
||
var mul = 1
|
||
var sub = 0
|
||
this[offset] = value & 0xFF
|
||
while (++i < byteLength && (mul *= 0x100)) {
|
||
if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
|
||
sub = 1
|
||
}
|
||
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
|
||
}
|
||
|
||
return offset + byteLength
|
||
}
|
||
|
||
Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
|
||
value = +value
|
||
offset = offset | 0
|
||
if (!noAssert) {
|
||
var limit = Math.pow(2, 8 * byteLength - 1)
|
||
|
||
checkInt(this, value, offset, byteLength, limit - 1, -limit)
|
||
}
|
||
|
||
var i = byteLength - 1
|
||
var mul = 1
|
||
var sub = 0
|
||
this[offset + i] = value & 0xFF
|
||
while (--i >= 0 && (mul *= 0x100)) {
|
||
if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
|
||
sub = 1
|
||
}
|
||
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
|
||
}
|
||
|
||
return offset + byteLength
|
||
}
|
||
|
||
Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset | 0
|
||
if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
|
||
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
|
||
if (value < 0) value = 0xff + value + 1
|
||
this[offset] = (value & 0xff)
|
||
return offset + 1
|
||
}
|
||
|
||
Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset | 0
|
||
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
|
||
if (Buffer.TYPED_ARRAY_SUPPORT) {
|
||
this[offset] = (value & 0xff)
|
||
this[offset + 1] = (value >>> 8)
|
||
} else {
|
||
objectWriteUInt16(this, value, offset, true)
|
||
}
|
||
return offset + 2
|
||
}
|
||
|
||
Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset | 0
|
||
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
|
||
if (Buffer.TYPED_ARRAY_SUPPORT) {
|
||
this[offset] = (value >>> 8)
|
||
this[offset + 1] = (value & 0xff)
|
||
} else {
|
||
objectWriteUInt16(this, value, offset, false)
|
||
}
|
||
return offset + 2
|
||
}
|
||
|
||
Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset | 0
|
||
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
|
||
if (Buffer.TYPED_ARRAY_SUPPORT) {
|
||
this[offset] = (value & 0xff)
|
||
this[offset + 1] = (value >>> 8)
|
||
this[offset + 2] = (value >>> 16)
|
||
this[offset + 3] = (value >>> 24)
|
||
} else {
|
||
objectWriteUInt32(this, value, offset, true)
|
||
}
|
||
return offset + 4
|
||
}
|
||
|
||
Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset | 0
|
||
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
|
||
if (value < 0) value = 0xffffffff + value + 1
|
||
if (Buffer.TYPED_ARRAY_SUPPORT) {
|
||
this[offset] = (value >>> 24)
|
||
this[offset + 1] = (value >>> 16)
|
||
this[offset + 2] = (value >>> 8)
|
||
this[offset + 3] = (value & 0xff)
|
||
} else {
|
||
objectWriteUInt32(this, value, offset, false)
|
||
}
|
||
return offset + 4
|
||
}
|
||
|
||
function checkIEEE754 (buf, value, offset, ext, max, min) {
|
||
if (offset + ext > buf.length) throw new RangeError('Index out of range')
|
||
if (offset < 0) throw new RangeError('Index out of range')
|
||
}
|
||
|
||
function writeFloat (buf, value, offset, littleEndian, noAssert) {
|
||
if (!noAssert) {
|
||
checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
|
||
}
|
||
ieee754.write(buf, value, offset, littleEndian, 23, 4)
|
||
return offset + 4
|
||
}
|
||
|
||
Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
|
||
return writeFloat(this, value, offset, true, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
|
||
return writeFloat(this, value, offset, false, noAssert)
|
||
}
|
||
|
||
function writeDouble (buf, value, offset, littleEndian, noAssert) {
|
||
if (!noAssert) {
|
||
checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
|
||
}
|
||
ieee754.write(buf, value, offset, littleEndian, 52, 8)
|
||
return offset + 8
|
||
}
|
||
|
||
Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
|
||
return writeDouble(this, value, offset, true, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
|
||
return writeDouble(this, value, offset, false, noAssert)
|
||
}
|
||
|
||
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
|
||
Buffer.prototype.copy = function copy (target, targetStart, start, end) {
|
||
if (!start) start = 0
|
||
if (!end && end !== 0) end = this.length
|
||
if (targetStart >= target.length) targetStart = target.length
|
||
if (!targetStart) targetStart = 0
|
||
if (end > 0 && end < start) end = start
|
||
|
||
// Copy 0 bytes; we're done
|
||
if (end === start) return 0
|
||
if (target.length === 0 || this.length === 0) return 0
|
||
|
||
// Fatal error conditions
|
||
if (targetStart < 0) {
|
||
throw new RangeError('targetStart out of bounds')
|
||
}
|
||
if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
|
||
if (end < 0) throw new RangeError('sourceEnd out of bounds')
|
||
|
||
// Are we oob?
|
||
if (end > this.length) end = this.length
|
||
if (target.length - targetStart < end - start) {
|
||
end = target.length - targetStart + start
|
||
}
|
||
|
||
var len = end - start
|
||
var i
|
||
|
||
if (this === target && start < targetStart && targetStart < end) {
|
||
// descending copy from end
|
||
for (i = len - 1; i >= 0; --i) {
|
||
target[i + targetStart] = this[i + start]
|
||
}
|
||
} else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
|
||
// ascending copy from start
|
||
for (i = 0; i < len; ++i) {
|
||
target[i + targetStart] = this[i + start]
|
||
}
|
||
} else {
|
||
Uint8Array.prototype.set.call(
|
||
target,
|
||
this.subarray(start, start + len),
|
||
targetStart
|
||
)
|
||
}
|
||
|
||
return len
|
||
}
|
||
|
||
// Usage:
|
||
// buffer.fill(number[, offset[, end]])
|
||
// buffer.fill(buffer[, offset[, end]])
|
||
// buffer.fill(string[, offset[, end]][, encoding])
|
||
Buffer.prototype.fill = function fill (val, start, end, encoding) {
|
||
// Handle string cases:
|
||
if (typeof val === 'string') {
|
||
if (typeof start === 'string') {
|
||
encoding = start
|
||
start = 0
|
||
end = this.length
|
||
} else if (typeof end === 'string') {
|
||
encoding = end
|
||
end = this.length
|
||
}
|
||
if (val.length === 1) {
|
||
var code = val.charCodeAt(0)
|
||
if (code < 256) {
|
||
val = code
|
||
}
|
||
}
|
||
if (encoding !== undefined && typeof encoding !== 'string') {
|
||
throw new TypeError('encoding must be a string')
|
||
}
|
||
if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
|
||
throw new TypeError('Unknown encoding: ' + encoding)
|
||
}
|
||
} else if (typeof val === 'number') {
|
||
val = val & 255
|
||
}
|
||
|
||
// Invalid ranges are not set to a default, so can range check early.
|
||
if (start < 0 || this.length < start || this.length < end) {
|
||
throw new RangeError('Out of range index')
|
||
}
|
||
|
||
if (end <= start) {
|
||
return this
|
||
}
|
||
|
||
start = start >>> 0
|
||
end = end === undefined ? this.length : end >>> 0
|
||
|
||
if (!val) val = 0
|
||
|
||
var i
|
||
if (typeof val === 'number') {
|
||
for (i = start; i < end; ++i) {
|
||
this[i] = val
|
||
}
|
||
} else {
|
||
var bytes = Buffer.isBuffer(val)
|
||
? val
|
||
: utf8ToBytes(new Buffer(val, encoding).toString())
|
||
var len = bytes.length
|
||
for (i = 0; i < end - start; ++i) {
|
||
this[i + start] = bytes[i % len]
|
||
}
|
||
}
|
||
|
||
return this
|
||
}
|
||
|
||
// HELPER FUNCTIONS
|
||
// ================
|
||
|
||
var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
|
||
|
||
function base64clean (str) {
|
||
// Node strips out invalid characters like \n and \t from the string, base64-js does not
|
||
str = stringtrim(str).replace(INVALID_BASE64_RE, '')
|
||
// Node converts strings with length < 2 to ''
|
||
if (str.length < 2) return ''
|
||
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
|
||
while (str.length % 4 !== 0) {
|
||
str = str + '='
|
||
}
|
||
return str
|
||
}
|
||
|
||
function stringtrim (str) {
|
||
if (str.trim) return str.trim()
|
||
return str.replace(/^\s+|\s+$/g, '')
|
||
}
|
||
|
||
function toHex (n) {
|
||
if (n < 16) return '0' + n.toString(16)
|
||
return n.toString(16)
|
||
}
|
||
|
||
function utf8ToBytes (string, units) {
|
||
units = units || Infinity
|
||
var codePoint
|
||
var length = string.length
|
||
var leadSurrogate = null
|
||
var bytes = []
|
||
|
||
for (var i = 0; i < length; ++i) {
|
||
codePoint = string.charCodeAt(i)
|
||
|
||
// is surrogate component
|
||
if (codePoint > 0xD7FF && codePoint < 0xE000) {
|
||
// last char was a lead
|
||
if (!leadSurrogate) {
|
||
// no lead yet
|
||
if (codePoint > 0xDBFF) {
|
||
// unexpected trail
|
||
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
|
||
continue
|
||
} else if (i + 1 === length) {
|
||
// unpaired lead
|
||
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
|
||
continue
|
||
}
|
||
|
||
// valid lead
|
||
leadSurrogate = codePoint
|
||
|
||
continue
|
||
}
|
||
|
||
// 2 leads in a row
|
||
if (codePoint < 0xDC00) {
|
||
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
|
||
leadSurrogate = codePoint
|
||
continue
|
||
}
|
||
|
||
// valid surrogate pair
|
||
codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
|
||
} else if (leadSurrogate) {
|
||
// valid bmp char, but last char was a lead
|
||
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
|
||
}
|
||
|
||
leadSurrogate = null
|
||
|
||
// encode utf8
|
||
if (codePoint < 0x80) {
|
||
if ((units -= 1) < 0) break
|
||
bytes.push(codePoint)
|
||
} else if (codePoint < 0x800) {
|
||
if ((units -= 2) < 0) break
|
||
bytes.push(
|
||
codePoint >> 0x6 | 0xC0,
|
||
codePoint & 0x3F | 0x80
|
||
)
|
||
} else if (codePoint < 0x10000) {
|
||
if ((units -= 3) < 0) break
|
||
bytes.push(
|
||
codePoint >> 0xC | 0xE0,
|
||
codePoint >> 0x6 & 0x3F | 0x80,
|
||
codePoint & 0x3F | 0x80
|
||
)
|
||
} else if (codePoint < 0x110000) {
|
||
if ((units -= 4) < 0) break
|
||
bytes.push(
|
||
codePoint >> 0x12 | 0xF0,
|
||
codePoint >> 0xC & 0x3F | 0x80,
|
||
codePoint >> 0x6 & 0x3F | 0x80,
|
||
codePoint & 0x3F | 0x80
|
||
)
|
||
} else {
|
||
throw new Error('Invalid code point')
|
||
}
|
||
}
|
||
|
||
return bytes
|
||
}
|
||
|
||
function asciiToBytes (str) {
|
||
var byteArray = []
|
||
for (var i = 0; i < str.length; ++i) {
|
||
// Node's code seems to be doing this and not & 0x7F..
|
||
byteArray.push(str.charCodeAt(i) & 0xFF)
|
||
}
|
||
return byteArray
|
||
}
|
||
|
||
function utf16leToBytes (str, units) {
|
||
var c, hi, lo
|
||
var byteArray = []
|
||
for (var i = 0; i < str.length; ++i) {
|
||
if ((units -= 2) < 0) break
|
||
|
||
c = str.charCodeAt(i)
|
||
hi = c >> 8
|
||
lo = c % 256
|
||
byteArray.push(lo)
|
||
byteArray.push(hi)
|
||
}
|
||
|
||
return byteArray
|
||
}
|
||
|
||
function base64ToBytes (str) {
|
||
return base64.toByteArray(base64clean(str))
|
||
}
|
||
|
||
function blitBuffer (src, dst, offset, length) {
|
||
for (var i = 0; i < length; ++i) {
|
||
if ((i + offset >= dst.length) || (i >= src.length)) break
|
||
dst[i + offset] = src[i]
|
||
}
|
||
return i
|
||
}
|
||
|
||
function isnan (val) {
|
||
return val !== val // eslint-disable-line no-self-compare
|
||
}
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js")))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/cipher-base/index.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/cipher-base/index.js ***!
|
||
\*******************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
var Transform = __webpack_require__(/*! stream */ "./node_modules/stream-browserify/index.js").Transform
|
||
var StringDecoder = __webpack_require__(/*! string_decoder */ "./node_modules/string_decoder/lib/string_decoder.js").StringDecoder
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
|
||
function CipherBase (hashMode) {
|
||
Transform.call(this)
|
||
this.hashMode = typeof hashMode === 'string'
|
||
if (this.hashMode) {
|
||
this[hashMode] = this._finalOrDigest
|
||
} else {
|
||
this.final = this._finalOrDigest
|
||
}
|
||
if (this._final) {
|
||
this.__final = this._final
|
||
this._final = null
|
||
}
|
||
this._decoder = null
|
||
this._encoding = null
|
||
}
|
||
inherits(CipherBase, Transform)
|
||
|
||
CipherBase.prototype.update = function (data, inputEnc, outputEnc) {
|
||
if (typeof data === 'string') {
|
||
data = Buffer.from(data, inputEnc)
|
||
}
|
||
|
||
var outData = this._update(data)
|
||
if (this.hashMode) return this
|
||
|
||
if (outputEnc) {
|
||
outData = this._toString(outData, outputEnc)
|
||
}
|
||
|
||
return outData
|
||
}
|
||
|
||
CipherBase.prototype.setAutoPadding = function () {}
|
||
CipherBase.prototype.getAuthTag = function () {
|
||
throw new Error('trying to get auth tag in unsupported state')
|
||
}
|
||
|
||
CipherBase.prototype.setAuthTag = function () {
|
||
throw new Error('trying to set auth tag in unsupported state')
|
||
}
|
||
|
||
CipherBase.prototype.setAAD = function () {
|
||
throw new Error('trying to set aad in unsupported state')
|
||
}
|
||
|
||
CipherBase.prototype._transform = function (data, _, next) {
|
||
var err
|
||
try {
|
||
if (this.hashMode) {
|
||
this._update(data)
|
||
} else {
|
||
this.push(this._update(data))
|
||
}
|
||
} catch (e) {
|
||
err = e
|
||
} finally {
|
||
next(err)
|
||
}
|
||
}
|
||
CipherBase.prototype._flush = function (done) {
|
||
var err
|
||
try {
|
||
this.push(this.__final())
|
||
} catch (e) {
|
||
err = e
|
||
}
|
||
|
||
done(err)
|
||
}
|
||
CipherBase.prototype._finalOrDigest = function (outputEnc) {
|
||
var outData = this.__final() || Buffer.alloc(0)
|
||
if (outputEnc) {
|
||
outData = this._toString(outData, outputEnc, true)
|
||
}
|
||
return outData
|
||
}
|
||
|
||
CipherBase.prototype._toString = function (value, enc, fin) {
|
||
if (!this._decoder) {
|
||
this._decoder = new StringDecoder(enc)
|
||
this._encoding = enc
|
||
}
|
||
|
||
if (this._encoding !== enc) throw new Error('can\'t switch encodings')
|
||
|
||
var out = this._decoder.write(value)
|
||
if (fin) {
|
||
out += this._decoder.end()
|
||
}
|
||
|
||
return out
|
||
}
|
||
|
||
module.exports = CipherBase
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/core-util-is/lib/util.js":
|
||
/*!***********************************************!*\
|
||
!*** ./node_modules/core-util-is/lib/util.js ***!
|
||
\***********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(Buffer) {// Copyright Joyent, Inc. and other Node contributors.
|
||
//
|
||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||
// copy of this software and associated documentation files (the
|
||
// "Software"), to deal in the Software without restriction, including
|
||
// without limitation the rights to use, copy, modify, merge, publish,
|
||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||
// persons to whom the Software is furnished to do so, subject to the
|
||
// following conditions:
|
||
//
|
||
// The above copyright notice and this permission notice shall be included
|
||
// in all copies or substantial portions of the Software.
|
||
//
|
||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
||
// NOTE: These type checking functions intentionally don't use `instanceof`
|
||
// because it is fragile and can be easily faked with `Object.create()`.
|
||
|
||
function isArray(arg) {
|
||
if (Array.isArray) {
|
||
return Array.isArray(arg);
|
||
}
|
||
return objectToString(arg) === '[object Array]';
|
||
}
|
||
exports.isArray = isArray;
|
||
|
||
function isBoolean(arg) {
|
||
return typeof arg === 'boolean';
|
||
}
|
||
exports.isBoolean = isBoolean;
|
||
|
||
function isNull(arg) {
|
||
return arg === null;
|
||
}
|
||
exports.isNull = isNull;
|
||
|
||
function isNullOrUndefined(arg) {
|
||
return arg == null;
|
||
}
|
||
exports.isNullOrUndefined = isNullOrUndefined;
|
||
|
||
function isNumber(arg) {
|
||
return typeof arg === 'number';
|
||
}
|
||
exports.isNumber = isNumber;
|
||
|
||
function isString(arg) {
|
||
return typeof arg === 'string';
|
||
}
|
||
exports.isString = isString;
|
||
|
||
function isSymbol(arg) {
|
||
return typeof arg === 'symbol';
|
||
}
|
||
exports.isSymbol = isSymbol;
|
||
|
||
function isUndefined(arg) {
|
||
return arg === void 0;
|
||
}
|
||
exports.isUndefined = isUndefined;
|
||
|
||
function isRegExp(re) {
|
||
return objectToString(re) === '[object RegExp]';
|
||
}
|
||
exports.isRegExp = isRegExp;
|
||
|
||
function isObject(arg) {
|
||
return typeof arg === 'object' && arg !== null;
|
||
}
|
||
exports.isObject = isObject;
|
||
|
||
function isDate(d) {
|
||
return objectToString(d) === '[object Date]';
|
||
}
|
||
exports.isDate = isDate;
|
||
|
||
function isError(e) {
|
||
return (objectToString(e) === '[object Error]' || e instanceof Error);
|
||
}
|
||
exports.isError = isError;
|
||
|
||
function isFunction(arg) {
|
||
return typeof arg === 'function';
|
||
}
|
||
exports.isFunction = isFunction;
|
||
|
||
function isPrimitive(arg) {
|
||
return arg === null ||
|
||
typeof arg === 'boolean' ||
|
||
typeof arg === 'number' ||
|
||
typeof arg === 'string' ||
|
||
typeof arg === 'symbol' || // ES6 symbol
|
||
typeof arg === 'undefined';
|
||
}
|
||
exports.isPrimitive = isPrimitive;
|
||
|
||
exports.isBuffer = Buffer.isBuffer;
|
||
|
||
function objectToString(o) {
|
||
return Object.prototype.toString.call(o);
|
||
}
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../buffer/index.js */ "./node_modules/buffer/index.js").Buffer))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/create-ecdh/browser.js":
|
||
/*!*********************************************!*\
|
||
!*** ./node_modules/create-ecdh/browser.js ***!
|
||
\*********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(Buffer) {var elliptic = __webpack_require__(/*! elliptic */ "./node_modules/elliptic/lib/elliptic.js")
|
||
var BN = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js")
|
||
|
||
module.exports = function createECDH (curve) {
|
||
return new ECDH(curve)
|
||
}
|
||
|
||
var aliases = {
|
||
secp256k1: {
|
||
name: 'secp256k1',
|
||
byteLength: 32
|
||
},
|
||
secp224r1: {
|
||
name: 'p224',
|
||
byteLength: 28
|
||
},
|
||
prime256v1: {
|
||
name: 'p256',
|
||
byteLength: 32
|
||
},
|
||
prime192v1: {
|
||
name: 'p192',
|
||
byteLength: 24
|
||
},
|
||
ed25519: {
|
||
name: 'ed25519',
|
||
byteLength: 32
|
||
},
|
||
secp384r1: {
|
||
name: 'p384',
|
||
byteLength: 48
|
||
},
|
||
secp521r1: {
|
||
name: 'p521',
|
||
byteLength: 66
|
||
}
|
||
}
|
||
|
||
aliases.p224 = aliases.secp224r1
|
||
aliases.p256 = aliases.secp256r1 = aliases.prime256v1
|
||
aliases.p192 = aliases.secp192r1 = aliases.prime192v1
|
||
aliases.p384 = aliases.secp384r1
|
||
aliases.p521 = aliases.secp521r1
|
||
|
||
function ECDH (curve) {
|
||
this.curveType = aliases[curve]
|
||
if (!this.curveType) {
|
||
this.curveType = {
|
||
name: curve
|
||
}
|
||
}
|
||
this.curve = new elliptic.ec(this.curveType.name) // eslint-disable-line new-cap
|
||
this.keys = void 0
|
||
}
|
||
|
||
ECDH.prototype.generateKeys = function (enc, format) {
|
||
this.keys = this.curve.genKeyPair()
|
||
return this.getPublicKey(enc, format)
|
||
}
|
||
|
||
ECDH.prototype.computeSecret = function (other, inenc, enc) {
|
||
inenc = inenc || 'utf8'
|
||
if (!Buffer.isBuffer(other)) {
|
||
other = new Buffer(other, inenc)
|
||
}
|
||
var otherPub = this.curve.keyFromPublic(other).getPublic()
|
||
var out = otherPub.mul(this.keys.getPrivate()).getX()
|
||
return formatReturnValue(out, enc, this.curveType.byteLength)
|
||
}
|
||
|
||
ECDH.prototype.getPublicKey = function (enc, format) {
|
||
var key = this.keys.getPublic(format === 'compressed', true)
|
||
if (format === 'hybrid') {
|
||
if (key[key.length - 1] % 2) {
|
||
key[0] = 7
|
||
} else {
|
||
key[0] = 6
|
||
}
|
||
}
|
||
return formatReturnValue(key, enc)
|
||
}
|
||
|
||
ECDH.prototype.getPrivateKey = function (enc) {
|
||
return formatReturnValue(this.keys.getPrivate(), enc)
|
||
}
|
||
|
||
ECDH.prototype.setPublicKey = function (pub, enc) {
|
||
enc = enc || 'utf8'
|
||
if (!Buffer.isBuffer(pub)) {
|
||
pub = new Buffer(pub, enc)
|
||
}
|
||
this.keys._importPublic(pub)
|
||
return this
|
||
}
|
||
|
||
ECDH.prototype.setPrivateKey = function (priv, enc) {
|
||
enc = enc || 'utf8'
|
||
if (!Buffer.isBuffer(priv)) {
|
||
priv = new Buffer(priv, enc)
|
||
}
|
||
|
||
var _priv = new BN(priv)
|
||
_priv = _priv.toString(16)
|
||
this.keys = this.curve.genKeyPair()
|
||
this.keys._importPrivate(_priv)
|
||
return this
|
||
}
|
||
|
||
function formatReturnValue (bn, enc, len) {
|
||
if (!Array.isArray(bn)) {
|
||
bn = bn.toArray()
|
||
}
|
||
var buf = new Buffer(bn)
|
||
if (len && buf.length < len) {
|
||
var zeros = new Buffer(len - buf.length)
|
||
zeros.fill(0)
|
||
buf = Buffer.concat([zeros, buf])
|
||
}
|
||
if (!enc) {
|
||
return buf
|
||
} else {
|
||
return buf.toString(enc)
|
||
}
|
||
}
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../buffer/index.js */ "./node_modules/buffer/index.js").Buffer))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/create-hash/browser.js":
|
||
/*!*********************************************!*\
|
||
!*** ./node_modules/create-hash/browser.js ***!
|
||
\*********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
var MD5 = __webpack_require__(/*! md5.js */ "./node_modules/md5.js/index.js")
|
||
var RIPEMD160 = __webpack_require__(/*! ripemd160 */ "./node_modules/ripemd160/index.js")
|
||
var sha = __webpack_require__(/*! sha.js */ "./node_modules/sha.js/index.js")
|
||
var Base = __webpack_require__(/*! cipher-base */ "./node_modules/cipher-base/index.js")
|
||
|
||
function Hash (hash) {
|
||
Base.call(this, 'digest')
|
||
|
||
this._hash = hash
|
||
}
|
||
|
||
inherits(Hash, Base)
|
||
|
||
Hash.prototype._update = function (data) {
|
||
this._hash.update(data)
|
||
}
|
||
|
||
Hash.prototype._final = function () {
|
||
return this._hash.digest()
|
||
}
|
||
|
||
module.exports = function createHash (alg) {
|
||
alg = alg.toLowerCase()
|
||
if (alg === 'md5') return new MD5()
|
||
if (alg === 'rmd160' || alg === 'ripemd160') return new RIPEMD160()
|
||
|
||
return new Hash(sha(alg))
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/create-hash/md5.js":
|
||
/*!*****************************************!*\
|
||
!*** ./node_modules/create-hash/md5.js ***!
|
||
\*****************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var MD5 = __webpack_require__(/*! md5.js */ "./node_modules/md5.js/index.js")
|
||
|
||
module.exports = function (buffer) {
|
||
return new MD5().update(buffer).digest()
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/create-hmac/browser.js":
|
||
/*!*********************************************!*\
|
||
!*** ./node_modules/create-hmac/browser.js ***!
|
||
\*********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
var Legacy = __webpack_require__(/*! ./legacy */ "./node_modules/create-hmac/legacy.js")
|
||
var Base = __webpack_require__(/*! cipher-base */ "./node_modules/cipher-base/index.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
var md5 = __webpack_require__(/*! create-hash/md5 */ "./node_modules/create-hash/md5.js")
|
||
var RIPEMD160 = __webpack_require__(/*! ripemd160 */ "./node_modules/ripemd160/index.js")
|
||
|
||
var sha = __webpack_require__(/*! sha.js */ "./node_modules/sha.js/index.js")
|
||
|
||
var ZEROS = Buffer.alloc(128)
|
||
|
||
function Hmac (alg, key) {
|
||
Base.call(this, 'digest')
|
||
if (typeof key === 'string') {
|
||
key = Buffer.from(key)
|
||
}
|
||
|
||
var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64
|
||
|
||
this._alg = alg
|
||
this._key = key
|
||
if (key.length > blocksize) {
|
||
var hash = alg === 'rmd160' ? new RIPEMD160() : sha(alg)
|
||
key = hash.update(key).digest()
|
||
} else if (key.length < blocksize) {
|
||
key = Buffer.concat([key, ZEROS], blocksize)
|
||
}
|
||
|
||
var ipad = this._ipad = Buffer.allocUnsafe(blocksize)
|
||
var opad = this._opad = Buffer.allocUnsafe(blocksize)
|
||
|
||
for (var i = 0; i < blocksize; i++) {
|
||
ipad[i] = key[i] ^ 0x36
|
||
opad[i] = key[i] ^ 0x5C
|
||
}
|
||
this._hash = alg === 'rmd160' ? new RIPEMD160() : sha(alg)
|
||
this._hash.update(ipad)
|
||
}
|
||
|
||
inherits(Hmac, Base)
|
||
|
||
Hmac.prototype._update = function (data) {
|
||
this._hash.update(data)
|
||
}
|
||
|
||
Hmac.prototype._final = function () {
|
||
var h = this._hash.digest()
|
||
var hash = this._alg === 'rmd160' ? new RIPEMD160() : sha(this._alg)
|
||
return hash.update(this._opad).update(h).digest()
|
||
}
|
||
|
||
module.exports = function createHmac (alg, key) {
|
||
alg = alg.toLowerCase()
|
||
if (alg === 'rmd160' || alg === 'ripemd160') {
|
||
return new Hmac('rmd160', key)
|
||
}
|
||
if (alg === 'md5') {
|
||
return new Legacy(md5, key)
|
||
}
|
||
return new Hmac(alg, key)
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/create-hmac/legacy.js":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/create-hmac/legacy.js ***!
|
||
\********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
var Base = __webpack_require__(/*! cipher-base */ "./node_modules/cipher-base/index.js")
|
||
|
||
var ZEROS = Buffer.alloc(128)
|
||
var blocksize = 64
|
||
|
||
function Hmac (alg, key) {
|
||
Base.call(this, 'digest')
|
||
if (typeof key === 'string') {
|
||
key = Buffer.from(key)
|
||
}
|
||
|
||
this._alg = alg
|
||
this._key = key
|
||
|
||
if (key.length > blocksize) {
|
||
key = alg(key)
|
||
} else if (key.length < blocksize) {
|
||
key = Buffer.concat([key, ZEROS], blocksize)
|
||
}
|
||
|
||
var ipad = this._ipad = Buffer.allocUnsafe(blocksize)
|
||
var opad = this._opad = Buffer.allocUnsafe(blocksize)
|
||
|
||
for (var i = 0; i < blocksize; i++) {
|
||
ipad[i] = key[i] ^ 0x36
|
||
opad[i] = key[i] ^ 0x5C
|
||
}
|
||
|
||
this._hash = [ipad]
|
||
}
|
||
|
||
inherits(Hmac, Base)
|
||
|
||
Hmac.prototype._update = function (data) {
|
||
this._hash.push(data)
|
||
}
|
||
|
||
Hmac.prototype._final = function () {
|
||
var h = this._alg(Buffer.concat(this._hash))
|
||
return this._alg(Buffer.concat([this._opad, h]))
|
||
}
|
||
module.exports = Hmac
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-browserify/index.js":
|
||
/*!*************************************************!*\
|
||
!*** ./node_modules/crypto-browserify/index.js ***!
|
||
\*************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = __webpack_require__(/*! randombytes */ "./node_modules/randombytes/browser.js")
|
||
exports.createHash = exports.Hash = __webpack_require__(/*! create-hash */ "./node_modules/create-hash/browser.js")
|
||
exports.createHmac = exports.Hmac = __webpack_require__(/*! create-hmac */ "./node_modules/create-hmac/browser.js")
|
||
|
||
var algos = __webpack_require__(/*! browserify-sign/algos */ "./node_modules/browserify-sign/algos.js")
|
||
var algoKeys = Object.keys(algos)
|
||
var hashes = ['sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'md5', 'rmd160'].concat(algoKeys)
|
||
exports.getHashes = function () {
|
||
return hashes
|
||
}
|
||
|
||
var p = __webpack_require__(/*! pbkdf2 */ "./node_modules/pbkdf2/browser.js")
|
||
exports.pbkdf2 = p.pbkdf2
|
||
exports.pbkdf2Sync = p.pbkdf2Sync
|
||
|
||
var aes = __webpack_require__(/*! browserify-cipher */ "./node_modules/browserify-cipher/browser.js")
|
||
|
||
exports.Cipher = aes.Cipher
|
||
exports.createCipher = aes.createCipher
|
||
exports.Cipheriv = aes.Cipheriv
|
||
exports.createCipheriv = aes.createCipheriv
|
||
exports.Decipher = aes.Decipher
|
||
exports.createDecipher = aes.createDecipher
|
||
exports.Decipheriv = aes.Decipheriv
|
||
exports.createDecipheriv = aes.createDecipheriv
|
||
exports.getCiphers = aes.getCiphers
|
||
exports.listCiphers = aes.listCiphers
|
||
|
||
var dh = __webpack_require__(/*! diffie-hellman */ "./node_modules/diffie-hellman/browser.js")
|
||
|
||
exports.DiffieHellmanGroup = dh.DiffieHellmanGroup
|
||
exports.createDiffieHellmanGroup = dh.createDiffieHellmanGroup
|
||
exports.getDiffieHellman = dh.getDiffieHellman
|
||
exports.createDiffieHellman = dh.createDiffieHellman
|
||
exports.DiffieHellman = dh.DiffieHellman
|
||
|
||
var sign = __webpack_require__(/*! browserify-sign */ "./node_modules/browserify-sign/browser/index.js")
|
||
|
||
exports.createSign = sign.createSign
|
||
exports.Sign = sign.Sign
|
||
exports.createVerify = sign.createVerify
|
||
exports.Verify = sign.Verify
|
||
|
||
exports.createECDH = __webpack_require__(/*! create-ecdh */ "./node_modules/create-ecdh/browser.js")
|
||
|
||
var publicEncrypt = __webpack_require__(/*! public-encrypt */ "./node_modules/public-encrypt/browser.js")
|
||
|
||
exports.publicEncrypt = publicEncrypt.publicEncrypt
|
||
exports.privateEncrypt = publicEncrypt.privateEncrypt
|
||
exports.publicDecrypt = publicEncrypt.publicDecrypt
|
||
exports.privateDecrypt = publicEncrypt.privateDecrypt
|
||
|
||
// the least I can do is make error messages for the rest of the node.js/crypto api.
|
||
// ;[
|
||
// 'createCredentials'
|
||
// ].forEach(function (name) {
|
||
// exports[name] = function () {
|
||
// throw new Error([
|
||
// 'sorry, ' + name + ' is not implemented yet',
|
||
// 'we accept pull requests',
|
||
// 'https://github.com/crypto-browserify/crypto-browserify'
|
||
// ].join('\n'))
|
||
// }
|
||
// })
|
||
|
||
var rf = __webpack_require__(/*! randomfill */ "./node_modules/randomfill/browser.js")
|
||
|
||
exports.randomFill = rf.randomFill
|
||
exports.randomFillSync = rf.randomFillSync
|
||
|
||
exports.createCredentials = function () {
|
||
throw new Error([
|
||
'sorry, createCredentials is not implemented yet',
|
||
'we accept pull requests',
|
||
'https://github.com/crypto-browserify/crypto-browserify'
|
||
].join('\n'))
|
||
}
|
||
|
||
exports.constants = {
|
||
'DH_CHECK_P_NOT_SAFE_PRIME': 2,
|
||
'DH_CHECK_P_NOT_PRIME': 1,
|
||
'DH_UNABLE_TO_CHECK_GENERATOR': 4,
|
||
'DH_NOT_SUITABLE_GENERATOR': 8,
|
||
'NPN_ENABLED': 1,
|
||
'ALPN_ENABLED': 1,
|
||
'RSA_PKCS1_PADDING': 1,
|
||
'RSA_SSLV23_PADDING': 2,
|
||
'RSA_NO_PADDING': 3,
|
||
'RSA_PKCS1_OAEP_PADDING': 4,
|
||
'RSA_X931_PADDING': 5,
|
||
'RSA_PKCS1_PSS_PADDING': 6,
|
||
'POINT_CONVERSION_COMPRESSED': 2,
|
||
'POINT_CONVERSION_UNCOMPRESSED': 4,
|
||
'POINT_CONVERSION_HYBRID': 6
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/aes.js":
|
||
/*!***************************************!*\
|
||
!*** ./node_modules/crypto-js/aes.js ***!
|
||
\***************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./enc-base64 */ "./node_modules/crypto-js/enc-base64.js"), __webpack_require__(/*! ./md5 */ "./node_modules/crypto-js/md5.js"), __webpack_require__(/*! ./evpkdf */ "./node_modules/crypto-js/evpkdf.js"), __webpack_require__(/*! ./cipher-core */ "./node_modules/crypto-js/cipher-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function () {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var BlockCipher = C_lib.BlockCipher;
|
||
var C_algo = C.algo;
|
||
|
||
// Lookup tables
|
||
var SBOX = [];
|
||
var INV_SBOX = [];
|
||
var SUB_MIX_0 = [];
|
||
var SUB_MIX_1 = [];
|
||
var SUB_MIX_2 = [];
|
||
var SUB_MIX_3 = [];
|
||
var INV_SUB_MIX_0 = [];
|
||
var INV_SUB_MIX_1 = [];
|
||
var INV_SUB_MIX_2 = [];
|
||
var INV_SUB_MIX_3 = [];
|
||
|
||
// Compute lookup tables
|
||
(function () {
|
||
// Compute double table
|
||
var d = [];
|
||
for (var i = 0; i < 256; i++) {
|
||
if (i < 128) {
|
||
d[i] = i << 1;
|
||
} else {
|
||
d[i] = (i << 1) ^ 0x11b;
|
||
}
|
||
}
|
||
|
||
// Walk GF(2^8)
|
||
var x = 0;
|
||
var xi = 0;
|
||
for (var i = 0; i < 256; i++) {
|
||
// Compute sbox
|
||
var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4);
|
||
sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63;
|
||
SBOX[x] = sx;
|
||
INV_SBOX[sx] = x;
|
||
|
||
// Compute multiplication
|
||
var x2 = d[x];
|
||
var x4 = d[x2];
|
||
var x8 = d[x4];
|
||
|
||
// Compute sub bytes, mix columns tables
|
||
var t = (d[sx] * 0x101) ^ (sx * 0x1010100);
|
||
SUB_MIX_0[x] = (t << 24) | (t >>> 8);
|
||
SUB_MIX_1[x] = (t << 16) | (t >>> 16);
|
||
SUB_MIX_2[x] = (t << 8) | (t >>> 24);
|
||
SUB_MIX_3[x] = t;
|
||
|
||
// Compute inv sub bytes, inv mix columns tables
|
||
var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);
|
||
INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8);
|
||
INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16);
|
||
INV_SUB_MIX_2[sx] = (t << 8) | (t >>> 24);
|
||
INV_SUB_MIX_3[sx] = t;
|
||
|
||
// Compute next counter
|
||
if (!x) {
|
||
x = xi = 1;
|
||
} else {
|
||
x = x2 ^ d[d[d[x8 ^ x2]]];
|
||
xi ^= d[d[xi]];
|
||
}
|
||
}
|
||
}());
|
||
|
||
// Precomputed Rcon lookup
|
||
var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
|
||
|
||
/**
|
||
* AES block cipher algorithm.
|
||
*/
|
||
var AES = C_algo.AES = BlockCipher.extend({
|
||
_doReset: function () {
|
||
var t;
|
||
|
||
// Skip reset of nRounds has been set before and key did not change
|
||
if (this._nRounds && this._keyPriorReset === this._key) {
|
||
return;
|
||
}
|
||
|
||
// Shortcuts
|
||
var key = this._keyPriorReset = this._key;
|
||
var keyWords = key.words;
|
||
var keySize = key.sigBytes / 4;
|
||
|
||
// Compute number of rounds
|
||
var nRounds = this._nRounds = keySize + 6;
|
||
|
||
// Compute number of key schedule rows
|
||
var ksRows = (nRounds + 1) * 4;
|
||
|
||
// Compute key schedule
|
||
var keySchedule = this._keySchedule = [];
|
||
for (var ksRow = 0; ksRow < ksRows; ksRow++) {
|
||
if (ksRow < keySize) {
|
||
keySchedule[ksRow] = keyWords[ksRow];
|
||
} else {
|
||
t = keySchedule[ksRow - 1];
|
||
|
||
if (!(ksRow % keySize)) {
|
||
// Rot word
|
||
t = (t << 8) | (t >>> 24);
|
||
|
||
// Sub word
|
||
t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
|
||
|
||
// Mix Rcon
|
||
t ^= RCON[(ksRow / keySize) | 0] << 24;
|
||
} else if (keySize > 6 && ksRow % keySize == 4) {
|
||
// Sub word
|
||
t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
|
||
}
|
||
|
||
keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t;
|
||
}
|
||
}
|
||
|
||
// Compute inv key schedule
|
||
var invKeySchedule = this._invKeySchedule = [];
|
||
for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) {
|
||
var ksRow = ksRows - invKsRow;
|
||
|
||
if (invKsRow % 4) {
|
||
var t = keySchedule[ksRow];
|
||
} else {
|
||
var t = keySchedule[ksRow - 4];
|
||
}
|
||
|
||
if (invKsRow < 4 || ksRow <= 4) {
|
||
invKeySchedule[invKsRow] = t;
|
||
} else {
|
||
invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^
|
||
INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]];
|
||
}
|
||
}
|
||
},
|
||
|
||
encryptBlock: function (M, offset) {
|
||
this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX);
|
||
},
|
||
|
||
decryptBlock: function (M, offset) {
|
||
// Swap 2nd and 4th rows
|
||
var t = M[offset + 1];
|
||
M[offset + 1] = M[offset + 3];
|
||
M[offset + 3] = t;
|
||
|
||
this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX);
|
||
|
||
// Inv swap 2nd and 4th rows
|
||
var t = M[offset + 1];
|
||
M[offset + 1] = M[offset + 3];
|
||
M[offset + 3] = t;
|
||
},
|
||
|
||
_doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) {
|
||
// Shortcut
|
||
var nRounds = this._nRounds;
|
||
|
||
// Get input, add round key
|
||
var s0 = M[offset] ^ keySchedule[0];
|
||
var s1 = M[offset + 1] ^ keySchedule[1];
|
||
var s2 = M[offset + 2] ^ keySchedule[2];
|
||
var s3 = M[offset + 3] ^ keySchedule[3];
|
||
|
||
// Key schedule row counter
|
||
var ksRow = 4;
|
||
|
||
// Rounds
|
||
for (var round = 1; round < nRounds; round++) {
|
||
// Shift rows, sub bytes, mix columns, add round key
|
||
var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++];
|
||
var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++];
|
||
var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++];
|
||
var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++];
|
||
|
||
// Update state
|
||
s0 = t0;
|
||
s1 = t1;
|
||
s2 = t2;
|
||
s3 = t3;
|
||
}
|
||
|
||
// Shift rows, sub bytes, add round key
|
||
var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++];
|
||
var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++];
|
||
var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++];
|
||
var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++];
|
||
|
||
// Set output
|
||
M[offset] = t0;
|
||
M[offset + 1] = t1;
|
||
M[offset + 2] = t2;
|
||
M[offset + 3] = t3;
|
||
},
|
||
|
||
keySize: 256/32
|
||
});
|
||
|
||
/**
|
||
* Shortcut functions to the cipher's object interface.
|
||
*
|
||
* @example
|
||
*
|
||
* var ciphertext = CryptoJS.AES.encrypt(message, key, cfg);
|
||
* var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg);
|
||
*/
|
||
C.AES = BlockCipher._createHelper(AES);
|
||
}());
|
||
|
||
|
||
return CryptoJS.AES;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/cipher-core.js":
|
||
/*!***********************************************!*\
|
||
!*** ./node_modules/crypto-js/cipher-core.js ***!
|
||
\***********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./evpkdf */ "./node_modules/crypto-js/evpkdf.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
/**
|
||
* Cipher core components.
|
||
*/
|
||
CryptoJS.lib.Cipher || (function (undefined) {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var Base = C_lib.Base;
|
||
var WordArray = C_lib.WordArray;
|
||
var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm;
|
||
var C_enc = C.enc;
|
||
var Utf8 = C_enc.Utf8;
|
||
var Base64 = C_enc.Base64;
|
||
var C_algo = C.algo;
|
||
var EvpKDF = C_algo.EvpKDF;
|
||
|
||
/**
|
||
* Abstract base cipher template.
|
||
*
|
||
* @property {number} keySize This cipher's key size. Default: 4 (128 bits)
|
||
* @property {number} ivSize This cipher's IV size. Default: 4 (128 bits)
|
||
* @property {number} _ENC_XFORM_MODE A constant representing encryption mode.
|
||
* @property {number} _DEC_XFORM_MODE A constant representing decryption mode.
|
||
*/
|
||
var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({
|
||
/**
|
||
* Configuration options.
|
||
*
|
||
* @property {WordArray} iv The IV to use for this operation.
|
||
*/
|
||
cfg: Base.extend(),
|
||
|
||
/**
|
||
* Creates this cipher in encryption mode.
|
||
*
|
||
* @param {WordArray} key The key.
|
||
* @param {Object} cfg (Optional) The configuration options to use for this operation.
|
||
*
|
||
* @return {Cipher} A cipher instance.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });
|
||
*/
|
||
createEncryptor: function (key, cfg) {
|
||
return this.create(this._ENC_XFORM_MODE, key, cfg);
|
||
},
|
||
|
||
/**
|
||
* Creates this cipher in decryption mode.
|
||
*
|
||
* @param {WordArray} key The key.
|
||
* @param {Object} cfg (Optional) The configuration options to use for this operation.
|
||
*
|
||
* @return {Cipher} A cipher instance.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });
|
||
*/
|
||
createDecryptor: function (key, cfg) {
|
||
return this.create(this._DEC_XFORM_MODE, key, cfg);
|
||
},
|
||
|
||
/**
|
||
* Initializes a newly created cipher.
|
||
*
|
||
* @param {number} xformMode Either the encryption or decryption transormation mode constant.
|
||
* @param {WordArray} key The key.
|
||
* @param {Object} cfg (Optional) The configuration options to use for this operation.
|
||
*
|
||
* @example
|
||
*
|
||
* var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });
|
||
*/
|
||
init: function (xformMode, key, cfg) {
|
||
// Apply config defaults
|
||
this.cfg = this.cfg.extend(cfg);
|
||
|
||
// Store transform mode and key
|
||
this._xformMode = xformMode;
|
||
this._key = key;
|
||
|
||
// Set initial values
|
||
this.reset();
|
||
},
|
||
|
||
/**
|
||
* Resets this cipher to its initial state.
|
||
*
|
||
* @example
|
||
*
|
||
* cipher.reset();
|
||
*/
|
||
reset: function () {
|
||
// Reset data buffer
|
||
BufferedBlockAlgorithm.reset.call(this);
|
||
|
||
// Perform concrete-cipher logic
|
||
this._doReset();
|
||
},
|
||
|
||
/**
|
||
* Adds data to be encrypted or decrypted.
|
||
*
|
||
* @param {WordArray|string} dataUpdate The data to encrypt or decrypt.
|
||
*
|
||
* @return {WordArray} The data after processing.
|
||
*
|
||
* @example
|
||
*
|
||
* var encrypted = cipher.process('data');
|
||
* var encrypted = cipher.process(wordArray);
|
||
*/
|
||
process: function (dataUpdate) {
|
||
// Append
|
||
this._append(dataUpdate);
|
||
|
||
// Process available blocks
|
||
return this._process();
|
||
},
|
||
|
||
/**
|
||
* Finalizes the encryption or decryption process.
|
||
* Note that the finalize operation is effectively a destructive, read-once operation.
|
||
*
|
||
* @param {WordArray|string} dataUpdate The final data to encrypt or decrypt.
|
||
*
|
||
* @return {WordArray} The data after final processing.
|
||
*
|
||
* @example
|
||
*
|
||
* var encrypted = cipher.finalize();
|
||
* var encrypted = cipher.finalize('data');
|
||
* var encrypted = cipher.finalize(wordArray);
|
||
*/
|
||
finalize: function (dataUpdate) {
|
||
// Final data update
|
||
if (dataUpdate) {
|
||
this._append(dataUpdate);
|
||
}
|
||
|
||
// Perform concrete-cipher logic
|
||
var finalProcessedData = this._doFinalize();
|
||
|
||
return finalProcessedData;
|
||
},
|
||
|
||
keySize: 128/32,
|
||
|
||
ivSize: 128/32,
|
||
|
||
_ENC_XFORM_MODE: 1,
|
||
|
||
_DEC_XFORM_MODE: 2,
|
||
|
||
/**
|
||
* Creates shortcut functions to a cipher's object interface.
|
||
*
|
||
* @param {Cipher} cipher The cipher to create a helper for.
|
||
*
|
||
* @return {Object} An object with encrypt and decrypt shortcut functions.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);
|
||
*/
|
||
_createHelper: (function () {
|
||
function selectCipherStrategy(key) {
|
||
if (typeof key == 'string') {
|
||
return PasswordBasedCipher;
|
||
} else {
|
||
return SerializableCipher;
|
||
}
|
||
}
|
||
|
||
return function (cipher) {
|
||
return {
|
||
encrypt: function (message, key, cfg) {
|
||
return selectCipherStrategy(key).encrypt(cipher, message, key, cfg);
|
||
},
|
||
|
||
decrypt: function (ciphertext, key, cfg) {
|
||
return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg);
|
||
}
|
||
};
|
||
};
|
||
}())
|
||
});
|
||
|
||
/**
|
||
* Abstract base stream cipher template.
|
||
*
|
||
* @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits)
|
||
*/
|
||
var StreamCipher = C_lib.StreamCipher = Cipher.extend({
|
||
_doFinalize: function () {
|
||
// Process partial blocks
|
||
var finalProcessedBlocks = this._process(!!'flush');
|
||
|
||
return finalProcessedBlocks;
|
||
},
|
||
|
||
blockSize: 1
|
||
});
|
||
|
||
/**
|
||
* Mode namespace.
|
||
*/
|
||
var C_mode = C.mode = {};
|
||
|
||
/**
|
||
* Abstract base block cipher mode template.
|
||
*/
|
||
var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({
|
||
/**
|
||
* Creates this mode for encryption.
|
||
*
|
||
* @param {Cipher} cipher A block cipher instance.
|
||
* @param {Array} iv The IV words.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);
|
||
*/
|
||
createEncryptor: function (cipher, iv) {
|
||
return this.Encryptor.create(cipher, iv);
|
||
},
|
||
|
||
/**
|
||
* Creates this mode for decryption.
|
||
*
|
||
* @param {Cipher} cipher A block cipher instance.
|
||
* @param {Array} iv The IV words.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words);
|
||
*/
|
||
createDecryptor: function (cipher, iv) {
|
||
return this.Decryptor.create(cipher, iv);
|
||
},
|
||
|
||
/**
|
||
* Initializes a newly created mode.
|
||
*
|
||
* @param {Cipher} cipher A block cipher instance.
|
||
* @param {Array} iv The IV words.
|
||
*
|
||
* @example
|
||
*
|
||
* var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words);
|
||
*/
|
||
init: function (cipher, iv) {
|
||
this._cipher = cipher;
|
||
this._iv = iv;
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Cipher Block Chaining mode.
|
||
*/
|
||
var CBC = C_mode.CBC = (function () {
|
||
/**
|
||
* Abstract base CBC mode.
|
||
*/
|
||
var CBC = BlockCipherMode.extend();
|
||
|
||
/**
|
||
* CBC encryptor.
|
||
*/
|
||
CBC.Encryptor = CBC.extend({
|
||
/**
|
||
* Processes the data block at offset.
|
||
*
|
||
* @param {Array} words The data words to operate on.
|
||
* @param {number} offset The offset where the block starts.
|
||
*
|
||
* @example
|
||
*
|
||
* mode.processBlock(data.words, offset);
|
||
*/
|
||
processBlock: function (words, offset) {
|
||
// Shortcuts
|
||
var cipher = this._cipher;
|
||
var blockSize = cipher.blockSize;
|
||
|
||
// XOR and encrypt
|
||
xorBlock.call(this, words, offset, blockSize);
|
||
cipher.encryptBlock(words, offset);
|
||
|
||
// Remember this block to use with next block
|
||
this._prevBlock = words.slice(offset, offset + blockSize);
|
||
}
|
||
});
|
||
|
||
/**
|
||
* CBC decryptor.
|
||
*/
|
||
CBC.Decryptor = CBC.extend({
|
||
/**
|
||
* Processes the data block at offset.
|
||
*
|
||
* @param {Array} words The data words to operate on.
|
||
* @param {number} offset The offset where the block starts.
|
||
*
|
||
* @example
|
||
*
|
||
* mode.processBlock(data.words, offset);
|
||
*/
|
||
processBlock: function (words, offset) {
|
||
// Shortcuts
|
||
var cipher = this._cipher;
|
||
var blockSize = cipher.blockSize;
|
||
|
||
// Remember this block to use with next block
|
||
var thisBlock = words.slice(offset, offset + blockSize);
|
||
|
||
// Decrypt and XOR
|
||
cipher.decryptBlock(words, offset);
|
||
xorBlock.call(this, words, offset, blockSize);
|
||
|
||
// This block becomes the previous block
|
||
this._prevBlock = thisBlock;
|
||
}
|
||
});
|
||
|
||
function xorBlock(words, offset, blockSize) {
|
||
var block;
|
||
|
||
// Shortcut
|
||
var iv = this._iv;
|
||
|
||
// Choose mixing block
|
||
if (iv) {
|
||
block = iv;
|
||
|
||
// Remove IV for subsequent blocks
|
||
this._iv = undefined;
|
||
} else {
|
||
block = this._prevBlock;
|
||
}
|
||
|
||
// XOR blocks
|
||
for (var i = 0; i < blockSize; i++) {
|
||
words[offset + i] ^= block[i];
|
||
}
|
||
}
|
||
|
||
return CBC;
|
||
}());
|
||
|
||
/**
|
||
* Padding namespace.
|
||
*/
|
||
var C_pad = C.pad = {};
|
||
|
||
/**
|
||
* PKCS #5/7 padding strategy.
|
||
*/
|
||
var Pkcs7 = C_pad.Pkcs7 = {
|
||
/**
|
||
* Pads data using the algorithm defined in PKCS #5/7.
|
||
*
|
||
* @param {WordArray} data The data to pad.
|
||
* @param {number} blockSize The multiple that the data should be padded to.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* CryptoJS.pad.Pkcs7.pad(wordArray, 4);
|
||
*/
|
||
pad: function (data, blockSize) {
|
||
// Shortcut
|
||
var blockSizeBytes = blockSize * 4;
|
||
|
||
// Count padding bytes
|
||
var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;
|
||
|
||
// Create padding word
|
||
var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes;
|
||
|
||
// Create padding
|
||
var paddingWords = [];
|
||
for (var i = 0; i < nPaddingBytes; i += 4) {
|
||
paddingWords.push(paddingWord);
|
||
}
|
||
var padding = WordArray.create(paddingWords, nPaddingBytes);
|
||
|
||
// Add padding
|
||
data.concat(padding);
|
||
},
|
||
|
||
/**
|
||
* Unpads data that had been padded using the algorithm defined in PKCS #5/7.
|
||
*
|
||
* @param {WordArray} data The data to unpad.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* CryptoJS.pad.Pkcs7.unpad(wordArray);
|
||
*/
|
||
unpad: function (data) {
|
||
// Get number of padding bytes from last byte
|
||
var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
|
||
|
||
// Remove padding
|
||
data.sigBytes -= nPaddingBytes;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Abstract base block cipher template.
|
||
*
|
||
* @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits)
|
||
*/
|
||
var BlockCipher = C_lib.BlockCipher = Cipher.extend({
|
||
/**
|
||
* Configuration options.
|
||
*
|
||
* @property {Mode} mode The block mode to use. Default: CBC
|
||
* @property {Padding} padding The padding strategy to use. Default: Pkcs7
|
||
*/
|
||
cfg: Cipher.cfg.extend({
|
||
mode: CBC,
|
||
padding: Pkcs7
|
||
}),
|
||
|
||
reset: function () {
|
||
var modeCreator;
|
||
|
||
// Reset cipher
|
||
Cipher.reset.call(this);
|
||
|
||
// Shortcuts
|
||
var cfg = this.cfg;
|
||
var iv = cfg.iv;
|
||
var mode = cfg.mode;
|
||
|
||
// Reset block mode
|
||
if (this._xformMode == this._ENC_XFORM_MODE) {
|
||
modeCreator = mode.createEncryptor;
|
||
} else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
|
||
modeCreator = mode.createDecryptor;
|
||
// Keep at least one block in the buffer for unpadding
|
||
this._minBufferSize = 1;
|
||
}
|
||
|
||
if (this._mode && this._mode.__creator == modeCreator) {
|
||
this._mode.init(this, iv && iv.words);
|
||
} else {
|
||
this._mode = modeCreator.call(mode, this, iv && iv.words);
|
||
this._mode.__creator = modeCreator;
|
||
}
|
||
},
|
||
|
||
_doProcessBlock: function (words, offset) {
|
||
this._mode.processBlock(words, offset);
|
||
},
|
||
|
||
_doFinalize: function () {
|
||
var finalProcessedBlocks;
|
||
|
||
// Shortcut
|
||
var padding = this.cfg.padding;
|
||
|
||
// Finalize
|
||
if (this._xformMode == this._ENC_XFORM_MODE) {
|
||
// Pad data
|
||
padding.pad(this._data, this.blockSize);
|
||
|
||
// Process final blocks
|
||
finalProcessedBlocks = this._process(!!'flush');
|
||
} else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
|
||
// Process final blocks
|
||
finalProcessedBlocks = this._process(!!'flush');
|
||
|
||
// Unpad data
|
||
padding.unpad(finalProcessedBlocks);
|
||
}
|
||
|
||
return finalProcessedBlocks;
|
||
},
|
||
|
||
blockSize: 128/32
|
||
});
|
||
|
||
/**
|
||
* A collection of cipher parameters.
|
||
*
|
||
* @property {WordArray} ciphertext The raw ciphertext.
|
||
* @property {WordArray} key The key to this ciphertext.
|
||
* @property {WordArray} iv The IV used in the ciphering operation.
|
||
* @property {WordArray} salt The salt used with a key derivation function.
|
||
* @property {Cipher} algorithm The cipher algorithm.
|
||
* @property {Mode} mode The block mode used in the ciphering operation.
|
||
* @property {Padding} padding The padding scheme used in the ciphering operation.
|
||
* @property {number} blockSize The block size of the cipher.
|
||
* @property {Format} formatter The default formatting strategy to convert this cipher params object to a string.
|
||
*/
|
||
var CipherParams = C_lib.CipherParams = Base.extend({
|
||
/**
|
||
* Initializes a newly created cipher params object.
|
||
*
|
||
* @param {Object} cipherParams An object with any of the possible cipher parameters.
|
||
*
|
||
* @example
|
||
*
|
||
* var cipherParams = CryptoJS.lib.CipherParams.create({
|
||
* ciphertext: ciphertextWordArray,
|
||
* key: keyWordArray,
|
||
* iv: ivWordArray,
|
||
* salt: saltWordArray,
|
||
* algorithm: CryptoJS.algo.AES,
|
||
* mode: CryptoJS.mode.CBC,
|
||
* padding: CryptoJS.pad.PKCS7,
|
||
* blockSize: 4,
|
||
* formatter: CryptoJS.format.OpenSSL
|
||
* });
|
||
*/
|
||
init: function (cipherParams) {
|
||
this.mixIn(cipherParams);
|
||
},
|
||
|
||
/**
|
||
* Converts this cipher params object to a string.
|
||
*
|
||
* @param {Format} formatter (Optional) The formatting strategy to use.
|
||
*
|
||
* @return {string} The stringified cipher params.
|
||
*
|
||
* @throws Error If neither the formatter nor the default formatter is set.
|
||
*
|
||
* @example
|
||
*
|
||
* var string = cipherParams + '';
|
||
* var string = cipherParams.toString();
|
||
* var string = cipherParams.toString(CryptoJS.format.OpenSSL);
|
||
*/
|
||
toString: function (formatter) {
|
||
return (formatter || this.formatter).stringify(this);
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Format namespace.
|
||
*/
|
||
var C_format = C.format = {};
|
||
|
||
/**
|
||
* OpenSSL formatting strategy.
|
||
*/
|
||
var OpenSSLFormatter = C_format.OpenSSL = {
|
||
/**
|
||
* Converts a cipher params object to an OpenSSL-compatible string.
|
||
*
|
||
* @param {CipherParams} cipherParams The cipher params object.
|
||
*
|
||
* @return {string} The OpenSSL-compatible string.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams);
|
||
*/
|
||
stringify: function (cipherParams) {
|
||
var wordArray;
|
||
|
||
// Shortcuts
|
||
var ciphertext = cipherParams.ciphertext;
|
||
var salt = cipherParams.salt;
|
||
|
||
// Format
|
||
if (salt) {
|
||
wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);
|
||
} else {
|
||
wordArray = ciphertext;
|
||
}
|
||
|
||
return wordArray.toString(Base64);
|
||
},
|
||
|
||
/**
|
||
* Converts an OpenSSL-compatible string to a cipher params object.
|
||
*
|
||
* @param {string} openSSLStr The OpenSSL-compatible string.
|
||
*
|
||
* @return {CipherParams} The cipher params object.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString);
|
||
*/
|
||
parse: function (openSSLStr) {
|
||
var salt;
|
||
|
||
// Parse base64
|
||
var ciphertext = Base64.parse(openSSLStr);
|
||
|
||
// Shortcut
|
||
var ciphertextWords = ciphertext.words;
|
||
|
||
// Test for salt
|
||
if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) {
|
||
// Extract salt
|
||
salt = WordArray.create(ciphertextWords.slice(2, 4));
|
||
|
||
// Remove salt from ciphertext
|
||
ciphertextWords.splice(0, 4);
|
||
ciphertext.sigBytes -= 16;
|
||
}
|
||
|
||
return CipherParams.create({ ciphertext: ciphertext, salt: salt });
|
||
}
|
||
};
|
||
|
||
/**
|
||
* A cipher wrapper that returns ciphertext as a serializable cipher params object.
|
||
*/
|
||
var SerializableCipher = C_lib.SerializableCipher = Base.extend({
|
||
/**
|
||
* Configuration options.
|
||
*
|
||
* @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL
|
||
*/
|
||
cfg: Base.extend({
|
||
format: OpenSSLFormatter
|
||
}),
|
||
|
||
/**
|
||
* Encrypts a message.
|
||
*
|
||
* @param {Cipher} cipher The cipher algorithm to use.
|
||
* @param {WordArray|string} message The message to encrypt.
|
||
* @param {WordArray} key The key.
|
||
* @param {Object} cfg (Optional) The configuration options to use for this operation.
|
||
*
|
||
* @return {CipherParams} A cipher params object.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key);
|
||
* var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv });
|
||
* var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL });
|
||
*/
|
||
encrypt: function (cipher, message, key, cfg) {
|
||
// Apply config defaults
|
||
cfg = this.cfg.extend(cfg);
|
||
|
||
// Encrypt
|
||
var encryptor = cipher.createEncryptor(key, cfg);
|
||
var ciphertext = encryptor.finalize(message);
|
||
|
||
// Shortcut
|
||
var cipherCfg = encryptor.cfg;
|
||
|
||
// Create and return serializable cipher params
|
||
return CipherParams.create({
|
||
ciphertext: ciphertext,
|
||
key: key,
|
||
iv: cipherCfg.iv,
|
||
algorithm: cipher,
|
||
mode: cipherCfg.mode,
|
||
padding: cipherCfg.padding,
|
||
blockSize: cipher.blockSize,
|
||
formatter: cfg.format
|
||
});
|
||
},
|
||
|
||
/**
|
||
* Decrypts serialized ciphertext.
|
||
*
|
||
* @param {Cipher} cipher The cipher algorithm to use.
|
||
* @param {CipherParams|string} ciphertext The ciphertext to decrypt.
|
||
* @param {WordArray} key The key.
|
||
* @param {Object} cfg (Optional) The configuration options to use for this operation.
|
||
*
|
||
* @return {WordArray} The plaintext.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL });
|
||
* var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL });
|
||
*/
|
||
decrypt: function (cipher, ciphertext, key, cfg) {
|
||
// Apply config defaults
|
||
cfg = this.cfg.extend(cfg);
|
||
|
||
// Convert string to CipherParams
|
||
ciphertext = this._parse(ciphertext, cfg.format);
|
||
|
||
// Decrypt
|
||
var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext);
|
||
|
||
return plaintext;
|
||
},
|
||
|
||
/**
|
||
* Converts serialized ciphertext to CipherParams,
|
||
* else assumed CipherParams already and returns ciphertext unchanged.
|
||
*
|
||
* @param {CipherParams|string} ciphertext The ciphertext.
|
||
* @param {Formatter} format The formatting strategy to use to parse serialized ciphertext.
|
||
*
|
||
* @return {CipherParams} The unserialized ciphertext.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format);
|
||
*/
|
||
_parse: function (ciphertext, format) {
|
||
if (typeof ciphertext == 'string') {
|
||
return format.parse(ciphertext, this);
|
||
} else {
|
||
return ciphertext;
|
||
}
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Key derivation function namespace.
|
||
*/
|
||
var C_kdf = C.kdf = {};
|
||
|
||
/**
|
||
* OpenSSL key derivation function.
|
||
*/
|
||
var OpenSSLKdf = C_kdf.OpenSSL = {
|
||
/**
|
||
* Derives a key and IV from a password.
|
||
*
|
||
* @param {string} password The password to derive from.
|
||
* @param {number} keySize The size in words of the key to generate.
|
||
* @param {number} ivSize The size in words of the IV to generate.
|
||
* @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly.
|
||
*
|
||
* @return {CipherParams} A cipher params object with the key, IV, and salt.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32);
|
||
* var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt');
|
||
*/
|
||
execute: function (password, keySize, ivSize, salt) {
|
||
// Generate random salt
|
||
if (!salt) {
|
||
salt = WordArray.random(64/8);
|
||
}
|
||
|
||
// Derive key and IV
|
||
var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);
|
||
|
||
// Separate key and IV
|
||
var iv = WordArray.create(key.words.slice(keySize), ivSize * 4);
|
||
key.sigBytes = keySize * 4;
|
||
|
||
// Return params
|
||
return CipherParams.create({ key: key, iv: iv, salt: salt });
|
||
}
|
||
};
|
||
|
||
/**
|
||
* A serializable cipher wrapper that derives the key from a password,
|
||
* and returns ciphertext as a serializable cipher params object.
|
||
*/
|
||
var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({
|
||
/**
|
||
* Configuration options.
|
||
*
|
||
* @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL
|
||
*/
|
||
cfg: SerializableCipher.cfg.extend({
|
||
kdf: OpenSSLKdf
|
||
}),
|
||
|
||
/**
|
||
* Encrypts a message using a password.
|
||
*
|
||
* @param {Cipher} cipher The cipher algorithm to use.
|
||
* @param {WordArray|string} message The message to encrypt.
|
||
* @param {string} password The password.
|
||
* @param {Object} cfg (Optional) The configuration options to use for this operation.
|
||
*
|
||
* @return {CipherParams} A cipher params object.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password');
|
||
* var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL });
|
||
*/
|
||
encrypt: function (cipher, message, password, cfg) {
|
||
// Apply config defaults
|
||
cfg = this.cfg.extend(cfg);
|
||
|
||
// Derive key and other params
|
||
var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize);
|
||
|
||
// Add IV to config
|
||
cfg.iv = derivedParams.iv;
|
||
|
||
// Encrypt
|
||
var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);
|
||
|
||
// Mix in derived params
|
||
ciphertext.mixIn(derivedParams);
|
||
|
||
return ciphertext;
|
||
},
|
||
|
||
/**
|
||
* Decrypts serialized ciphertext using a password.
|
||
*
|
||
* @param {Cipher} cipher The cipher algorithm to use.
|
||
* @param {CipherParams|string} ciphertext The ciphertext to decrypt.
|
||
* @param {string} password The password.
|
||
* @param {Object} cfg (Optional) The configuration options to use for this operation.
|
||
*
|
||
* @return {WordArray} The plaintext.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL });
|
||
* var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL });
|
||
*/
|
||
decrypt: function (cipher, ciphertext, password, cfg) {
|
||
// Apply config defaults
|
||
cfg = this.cfg.extend(cfg);
|
||
|
||
// Convert string to CipherParams
|
||
ciphertext = this._parse(ciphertext, cfg.format);
|
||
|
||
// Derive key and other params
|
||
var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt);
|
||
|
||
// Add IV to config
|
||
cfg.iv = derivedParams.iv;
|
||
|
||
// Decrypt
|
||
var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg);
|
||
|
||
return plaintext;
|
||
}
|
||
});
|
||
}());
|
||
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/core.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/crypto-js/core.js ***!
|
||
\****************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(global) {;(function (root, factory) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory();
|
||
}
|
||
else {}
|
||
}(this, function () {
|
||
|
||
/*globals window, global, require*/
|
||
|
||
/**
|
||
* CryptoJS core components.
|
||
*/
|
||
var CryptoJS = CryptoJS || (function (Math, undefined) {
|
||
|
||
var crypto;
|
||
|
||
// Native crypto from window (Browser)
|
||
if (typeof window !== 'undefined' && window.crypto) {
|
||
crypto = window.crypto;
|
||
}
|
||
|
||
// Native (experimental IE 11) crypto from window (Browser)
|
||
if (!crypto && typeof window !== 'undefined' && window.msCrypto) {
|
||
crypto = window.msCrypto;
|
||
}
|
||
|
||
// Native crypto from global (NodeJS)
|
||
if (!crypto && typeof global !== 'undefined' && global.crypto) {
|
||
crypto = global.crypto;
|
||
}
|
||
|
||
// Native crypto import via require (NodeJS)
|
||
if (!crypto && "function" === 'function') {
|
||
try {
|
||
crypto = __webpack_require__(/*! crypto */ "./node_modules/crypto-browserify/index.js");
|
||
} catch (err) {}
|
||
}
|
||
|
||
/*
|
||
* Cryptographically secure pseudorandom number generator
|
||
*
|
||
* As Math.random() is cryptographically not safe to use
|
||
*/
|
||
var cryptoSecureRandomInt = function () {
|
||
if (crypto) {
|
||
// Use getRandomValues method (Browser)
|
||
if (typeof crypto.getRandomValues === 'function') {
|
||
try {
|
||
return crypto.getRandomValues(new Uint32Array(1))[0];
|
||
} catch (err) {}
|
||
}
|
||
|
||
// Use randomBytes method (NodeJS)
|
||
if (typeof crypto.randomBytes === 'function') {
|
||
try {
|
||
return crypto.randomBytes(4).readInt32LE();
|
||
} catch (err) {}
|
||
}
|
||
}
|
||
|
||
throw new Error('Native crypto module could not be used to get secure random number.');
|
||
};
|
||
|
||
/*
|
||
* Local polyfill of Object.create
|
||
|
||
*/
|
||
var create = Object.create || (function () {
|
||
function F() {}
|
||
|
||
return function (obj) {
|
||
var subtype;
|
||
|
||
F.prototype = obj;
|
||
|
||
subtype = new F();
|
||
|
||
F.prototype = null;
|
||
|
||
return subtype;
|
||
};
|
||
}())
|
||
|
||
/**
|
||
* CryptoJS namespace.
|
||
*/
|
||
var C = {};
|
||
|
||
/**
|
||
* Library namespace.
|
||
*/
|
||
var C_lib = C.lib = {};
|
||
|
||
/**
|
||
* Base object for prototypal inheritance.
|
||
*/
|
||
var Base = C_lib.Base = (function () {
|
||
|
||
|
||
return {
|
||
/**
|
||
* Creates a new object that inherits from this object.
|
||
*
|
||
* @param {Object} overrides Properties to copy into the new object.
|
||
*
|
||
* @return {Object} The new object.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var MyType = CryptoJS.lib.Base.extend({
|
||
* field: 'value',
|
||
*
|
||
* method: function () {
|
||
* }
|
||
* });
|
||
*/
|
||
extend: function (overrides) {
|
||
// Spawn
|
||
var subtype = create(this);
|
||
|
||
// Augment
|
||
if (overrides) {
|
||
subtype.mixIn(overrides);
|
||
}
|
||
|
||
// Create default initializer
|
||
if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {
|
||
subtype.init = function () {
|
||
subtype.$super.init.apply(this, arguments);
|
||
};
|
||
}
|
||
|
||
// Initializer's prototype is the subtype object
|
||
subtype.init.prototype = subtype;
|
||
|
||
// Reference supertype
|
||
subtype.$super = this;
|
||
|
||
return subtype;
|
||
},
|
||
|
||
/**
|
||
* Extends this object and runs the init method.
|
||
* Arguments to create() will be passed to init().
|
||
*
|
||
* @return {Object} The new object.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var instance = MyType.create();
|
||
*/
|
||
create: function () {
|
||
var instance = this.extend();
|
||
instance.init.apply(instance, arguments);
|
||
|
||
return instance;
|
||
},
|
||
|
||
/**
|
||
* Initializes a newly created object.
|
||
* Override this method to add some logic when your objects are created.
|
||
*
|
||
* @example
|
||
*
|
||
* var MyType = CryptoJS.lib.Base.extend({
|
||
* init: function () {
|
||
* // ...
|
||
* }
|
||
* });
|
||
*/
|
||
init: function () {
|
||
},
|
||
|
||
/**
|
||
* Copies properties into this object.
|
||
*
|
||
* @param {Object} properties The properties to mix in.
|
||
*
|
||
* @example
|
||
*
|
||
* MyType.mixIn({
|
||
* field: 'value'
|
||
* });
|
||
*/
|
||
mixIn: function (properties) {
|
||
for (var propertyName in properties) {
|
||
if (properties.hasOwnProperty(propertyName)) {
|
||
this[propertyName] = properties[propertyName];
|
||
}
|
||
}
|
||
|
||
// IE won't copy toString using the loop above
|
||
if (properties.hasOwnProperty('toString')) {
|
||
this.toString = properties.toString;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Creates a copy of this object.
|
||
*
|
||
* @return {Object} The clone.
|
||
*
|
||
* @example
|
||
*
|
||
* var clone = instance.clone();
|
||
*/
|
||
clone: function () {
|
||
return this.init.prototype.extend(this);
|
||
}
|
||
};
|
||
}());
|
||
|
||
/**
|
||
* An array of 32-bit words.
|
||
*
|
||
* @property {Array} words The array of 32-bit words.
|
||
* @property {number} sigBytes The number of significant bytes in this word array.
|
||
*/
|
||
var WordArray = C_lib.WordArray = Base.extend({
|
||
/**
|
||
* Initializes a newly created word array.
|
||
*
|
||
* @param {Array} words (Optional) An array of 32-bit words.
|
||
* @param {number} sigBytes (Optional) The number of significant bytes in the words.
|
||
*
|
||
* @example
|
||
*
|
||
* var wordArray = CryptoJS.lib.WordArray.create();
|
||
* var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);
|
||
* var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);
|
||
*/
|
||
init: function (words, sigBytes) {
|
||
words = this.words = words || [];
|
||
|
||
if (sigBytes != undefined) {
|
||
this.sigBytes = sigBytes;
|
||
} else {
|
||
this.sigBytes = words.length * 4;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Converts this word array to a string.
|
||
*
|
||
* @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex
|
||
*
|
||
* @return {string} The stringified word array.
|
||
*
|
||
* @example
|
||
*
|
||
* var string = wordArray + '';
|
||
* var string = wordArray.toString();
|
||
* var string = wordArray.toString(CryptoJS.enc.Utf8);
|
||
*/
|
||
toString: function (encoder) {
|
||
return (encoder || Hex).stringify(this);
|
||
},
|
||
|
||
/**
|
||
* Concatenates a word array to this word array.
|
||
*
|
||
* @param {WordArray} wordArray The word array to append.
|
||
*
|
||
* @return {WordArray} This word array.
|
||
*
|
||
* @example
|
||
*
|
||
* wordArray1.concat(wordArray2);
|
||
*/
|
||
concat: function (wordArray) {
|
||
// Shortcuts
|
||
var thisWords = this.words;
|
||
var thatWords = wordArray.words;
|
||
var thisSigBytes = this.sigBytes;
|
||
var thatSigBytes = wordArray.sigBytes;
|
||
|
||
// Clamp excess bits
|
||
this.clamp();
|
||
|
||
// Concat
|
||
if (thisSigBytes % 4) {
|
||
// Copy one byte at a time
|
||
for (var i = 0; i < thatSigBytes; i++) {
|
||
var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
|
||
thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
|
||
}
|
||
} else {
|
||
// Copy one word at a time
|
||
for (var i = 0; i < thatSigBytes; i += 4) {
|
||
thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2];
|
||
}
|
||
}
|
||
this.sigBytes += thatSigBytes;
|
||
|
||
// Chainable
|
||
return this;
|
||
},
|
||
|
||
/**
|
||
* Removes insignificant bits.
|
||
*
|
||
* @example
|
||
*
|
||
* wordArray.clamp();
|
||
*/
|
||
clamp: function () {
|
||
// Shortcuts
|
||
var words = this.words;
|
||
var sigBytes = this.sigBytes;
|
||
|
||
// Clamp
|
||
words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
|
||
words.length = Math.ceil(sigBytes / 4);
|
||
},
|
||
|
||
/**
|
||
* Creates a copy of this word array.
|
||
*
|
||
* @return {WordArray} The clone.
|
||
*
|
||
* @example
|
||
*
|
||
* var clone = wordArray.clone();
|
||
*/
|
||
clone: function () {
|
||
var clone = Base.clone.call(this);
|
||
clone.words = this.words.slice(0);
|
||
|
||
return clone;
|
||
},
|
||
|
||
/**
|
||
* Creates a word array filled with random bytes.
|
||
*
|
||
* @param {number} nBytes The number of random bytes to generate.
|
||
*
|
||
* @return {WordArray} The random word array.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var wordArray = CryptoJS.lib.WordArray.random(16);
|
||
*/
|
||
random: function (nBytes) {
|
||
var words = [];
|
||
|
||
for (var i = 0; i < nBytes; i += 4) {
|
||
words.push(cryptoSecureRandomInt());
|
||
}
|
||
|
||
return new WordArray.init(words, nBytes);
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Encoder namespace.
|
||
*/
|
||
var C_enc = C.enc = {};
|
||
|
||
/**
|
||
* Hex encoding strategy.
|
||
*/
|
||
var Hex = C_enc.Hex = {
|
||
/**
|
||
* Converts a word array to a hex string.
|
||
*
|
||
* @param {WordArray} wordArray The word array.
|
||
*
|
||
* @return {string} The hex string.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hexString = CryptoJS.enc.Hex.stringify(wordArray);
|
||
*/
|
||
stringify: function (wordArray) {
|
||
// Shortcuts
|
||
var words = wordArray.words;
|
||
var sigBytes = wordArray.sigBytes;
|
||
|
||
// Convert
|
||
var hexChars = [];
|
||
for (var i = 0; i < sigBytes; i++) {
|
||
var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
|
||
hexChars.push((bite >>> 4).toString(16));
|
||
hexChars.push((bite & 0x0f).toString(16));
|
||
}
|
||
|
||
return hexChars.join('');
|
||
},
|
||
|
||
/**
|
||
* Converts a hex string to a word array.
|
||
*
|
||
* @param {string} hexStr The hex string.
|
||
*
|
||
* @return {WordArray} The word array.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var wordArray = CryptoJS.enc.Hex.parse(hexString);
|
||
*/
|
||
parse: function (hexStr) {
|
||
// Shortcut
|
||
var hexStrLength = hexStr.length;
|
||
|
||
// Convert
|
||
var words = [];
|
||
for (var i = 0; i < hexStrLength; i += 2) {
|
||
words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
|
||
}
|
||
|
||
return new WordArray.init(words, hexStrLength / 2);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Latin1 encoding strategy.
|
||
*/
|
||
var Latin1 = C_enc.Latin1 = {
|
||
/**
|
||
* Converts a word array to a Latin1 string.
|
||
*
|
||
* @param {WordArray} wordArray The word array.
|
||
*
|
||
* @return {string} The Latin1 string.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);
|
||
*/
|
||
stringify: function (wordArray) {
|
||
// Shortcuts
|
||
var words = wordArray.words;
|
||
var sigBytes = wordArray.sigBytes;
|
||
|
||
// Convert
|
||
var latin1Chars = [];
|
||
for (var i = 0; i < sigBytes; i++) {
|
||
var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
|
||
latin1Chars.push(String.fromCharCode(bite));
|
||
}
|
||
|
||
return latin1Chars.join('');
|
||
},
|
||
|
||
/**
|
||
* Converts a Latin1 string to a word array.
|
||
*
|
||
* @param {string} latin1Str The Latin1 string.
|
||
*
|
||
* @return {WordArray} The word array.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var wordArray = CryptoJS.enc.Latin1.parse(latin1String);
|
||
*/
|
||
parse: function (latin1Str) {
|
||
// Shortcut
|
||
var latin1StrLength = latin1Str.length;
|
||
|
||
// Convert
|
||
var words = [];
|
||
for (var i = 0; i < latin1StrLength; i++) {
|
||
words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
|
||
}
|
||
|
||
return new WordArray.init(words, latin1StrLength);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* UTF-8 encoding strategy.
|
||
*/
|
||
var Utf8 = C_enc.Utf8 = {
|
||
/**
|
||
* Converts a word array to a UTF-8 string.
|
||
*
|
||
* @param {WordArray} wordArray The word array.
|
||
*
|
||
* @return {string} The UTF-8 string.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);
|
||
*/
|
||
stringify: function (wordArray) {
|
||
try {
|
||
return decodeURIComponent(escape(Latin1.stringify(wordArray)));
|
||
} catch (e) {
|
||
throw new Error('Malformed UTF-8 data');
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Converts a UTF-8 string to a word array.
|
||
*
|
||
* @param {string} utf8Str The UTF-8 string.
|
||
*
|
||
* @return {WordArray} The word array.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var wordArray = CryptoJS.enc.Utf8.parse(utf8String);
|
||
*/
|
||
parse: function (utf8Str) {
|
||
return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Abstract buffered block algorithm template.
|
||
*
|
||
* The property blockSize must be implemented in a concrete subtype.
|
||
*
|
||
* @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0
|
||
*/
|
||
var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({
|
||
/**
|
||
* Resets this block algorithm's data buffer to its initial state.
|
||
*
|
||
* @example
|
||
*
|
||
* bufferedBlockAlgorithm.reset();
|
||
*/
|
||
reset: function () {
|
||
// Initial values
|
||
this._data = new WordArray.init();
|
||
this._nDataBytes = 0;
|
||
},
|
||
|
||
/**
|
||
* Adds new data to this block algorithm's buffer.
|
||
*
|
||
* @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.
|
||
*
|
||
* @example
|
||
*
|
||
* bufferedBlockAlgorithm._append('data');
|
||
* bufferedBlockAlgorithm._append(wordArray);
|
||
*/
|
||
_append: function (data) {
|
||
// Convert string to WordArray, else assume WordArray already
|
||
if (typeof data == 'string') {
|
||
data = Utf8.parse(data);
|
||
}
|
||
|
||
// Append
|
||
this._data.concat(data);
|
||
this._nDataBytes += data.sigBytes;
|
||
},
|
||
|
||
/**
|
||
* Processes available data blocks.
|
||
*
|
||
* This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.
|
||
*
|
||
* @param {boolean} doFlush Whether all blocks and partial blocks should be processed.
|
||
*
|
||
* @return {WordArray} The processed data.
|
||
*
|
||
* @example
|
||
*
|
||
* var processedData = bufferedBlockAlgorithm._process();
|
||
* var processedData = bufferedBlockAlgorithm._process(!!'flush');
|
||
*/
|
||
_process: function (doFlush) {
|
||
var processedWords;
|
||
|
||
// Shortcuts
|
||
var data = this._data;
|
||
var dataWords = data.words;
|
||
var dataSigBytes = data.sigBytes;
|
||
var blockSize = this.blockSize;
|
||
var blockSizeBytes = blockSize * 4;
|
||
|
||
// Count blocks ready
|
||
var nBlocksReady = dataSigBytes / blockSizeBytes;
|
||
if (doFlush) {
|
||
// Round up to include partial blocks
|
||
nBlocksReady = Math.ceil(nBlocksReady);
|
||
} else {
|
||
// Round down to include only full blocks,
|
||
// less the number of blocks that must remain in the buffer
|
||
nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
|
||
}
|
||
|
||
// Count words ready
|
||
var nWordsReady = nBlocksReady * blockSize;
|
||
|
||
// Count bytes ready
|
||
var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
|
||
|
||
// Process blocks
|
||
if (nWordsReady) {
|
||
for (var offset = 0; offset < nWordsReady; offset += blockSize) {
|
||
// Perform concrete-algorithm logic
|
||
this._doProcessBlock(dataWords, offset);
|
||
}
|
||
|
||
// Remove processed words
|
||
processedWords = dataWords.splice(0, nWordsReady);
|
||
data.sigBytes -= nBytesReady;
|
||
}
|
||
|
||
// Return processed words
|
||
return new WordArray.init(processedWords, nBytesReady);
|
||
},
|
||
|
||
/**
|
||
* Creates a copy of this object.
|
||
*
|
||
* @return {Object} The clone.
|
||
*
|
||
* @example
|
||
*
|
||
* var clone = bufferedBlockAlgorithm.clone();
|
||
*/
|
||
clone: function () {
|
||
var clone = Base.clone.call(this);
|
||
clone._data = this._data.clone();
|
||
|
||
return clone;
|
||
},
|
||
|
||
_minBufferSize: 0
|
||
});
|
||
|
||
/**
|
||
* Abstract hasher template.
|
||
*
|
||
* @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)
|
||
*/
|
||
var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({
|
||
/**
|
||
* Configuration options.
|
||
*/
|
||
cfg: Base.extend(),
|
||
|
||
/**
|
||
* Initializes a newly created hasher.
|
||
*
|
||
* @param {Object} cfg (Optional) The configuration options to use for this hash computation.
|
||
*
|
||
* @example
|
||
*
|
||
* var hasher = CryptoJS.algo.SHA256.create();
|
||
*/
|
||
init: function (cfg) {
|
||
// Apply config defaults
|
||
this.cfg = this.cfg.extend(cfg);
|
||
|
||
// Set initial values
|
||
this.reset();
|
||
},
|
||
|
||
/**
|
||
* Resets this hasher to its initial state.
|
||
*
|
||
* @example
|
||
*
|
||
* hasher.reset();
|
||
*/
|
||
reset: function () {
|
||
// Reset data buffer
|
||
BufferedBlockAlgorithm.reset.call(this);
|
||
|
||
// Perform concrete-hasher logic
|
||
this._doReset();
|
||
},
|
||
|
||
/**
|
||
* Updates this hasher with a message.
|
||
*
|
||
* @param {WordArray|string} messageUpdate The message to append.
|
||
*
|
||
* @return {Hasher} This hasher.
|
||
*
|
||
* @example
|
||
*
|
||
* hasher.update('message');
|
||
* hasher.update(wordArray);
|
||
*/
|
||
update: function (messageUpdate) {
|
||
// Append
|
||
this._append(messageUpdate);
|
||
|
||
// Update the hash
|
||
this._process();
|
||
|
||
// Chainable
|
||
return this;
|
||
},
|
||
|
||
/**
|
||
* Finalizes the hash computation.
|
||
* Note that the finalize operation is effectively a destructive, read-once operation.
|
||
*
|
||
* @param {WordArray|string} messageUpdate (Optional) A final message update.
|
||
*
|
||
* @return {WordArray} The hash.
|
||
*
|
||
* @example
|
||
*
|
||
* var hash = hasher.finalize();
|
||
* var hash = hasher.finalize('message');
|
||
* var hash = hasher.finalize(wordArray);
|
||
*/
|
||
finalize: function (messageUpdate) {
|
||
// Final message update
|
||
if (messageUpdate) {
|
||
this._append(messageUpdate);
|
||
}
|
||
|
||
// Perform concrete-hasher logic
|
||
var hash = this._doFinalize();
|
||
|
||
return hash;
|
||
},
|
||
|
||
blockSize: 512/32,
|
||
|
||
/**
|
||
* Creates a shortcut function to a hasher's object interface.
|
||
*
|
||
* @param {Hasher} hasher The hasher to create a helper for.
|
||
*
|
||
* @return {Function} The shortcut function.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
|
||
*/
|
||
_createHelper: function (hasher) {
|
||
return function (message, cfg) {
|
||
return new hasher.init(cfg).finalize(message);
|
||
};
|
||
},
|
||
|
||
/**
|
||
* Creates a shortcut function to the HMAC's object interface.
|
||
*
|
||
* @param {Hasher} hasher The hasher to use in this HMAC helper.
|
||
*
|
||
* @return {Function} The shortcut function.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
|
||
*/
|
||
_createHmacHelper: function (hasher) {
|
||
return function (message, key) {
|
||
return new C_algo.HMAC.init(hasher, key).finalize(message);
|
||
};
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Algorithm namespace.
|
||
*/
|
||
var C_algo = C.algo = {};
|
||
|
||
return C;
|
||
}(Math));
|
||
|
||
|
||
return CryptoJS;
|
||
|
||
}));
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js")))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/enc-base64.js":
|
||
/*!**********************************************!*\
|
||
!*** ./node_modules/crypto-js/enc-base64.js ***!
|
||
\**********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function () {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var WordArray = C_lib.WordArray;
|
||
var C_enc = C.enc;
|
||
|
||
/**
|
||
* Base64 encoding strategy.
|
||
*/
|
||
var Base64 = C_enc.Base64 = {
|
||
/**
|
||
* Converts a word array to a Base64 string.
|
||
*
|
||
* @param {WordArray} wordArray The word array.
|
||
*
|
||
* @return {string} The Base64 string.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var base64String = CryptoJS.enc.Base64.stringify(wordArray);
|
||
*/
|
||
stringify: function (wordArray) {
|
||
// Shortcuts
|
||
var words = wordArray.words;
|
||
var sigBytes = wordArray.sigBytes;
|
||
var map = this._map;
|
||
|
||
// Clamp excess bits
|
||
wordArray.clamp();
|
||
|
||
// Convert
|
||
var base64Chars = [];
|
||
for (var i = 0; i < sigBytes; i += 3) {
|
||
var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
|
||
var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;
|
||
var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;
|
||
|
||
var triplet = (byte1 << 16) | (byte2 << 8) | byte3;
|
||
|
||
for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) {
|
||
base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));
|
||
}
|
||
}
|
||
|
||
// Add padding
|
||
var paddingChar = map.charAt(64);
|
||
if (paddingChar) {
|
||
while (base64Chars.length % 4) {
|
||
base64Chars.push(paddingChar);
|
||
}
|
||
}
|
||
|
||
return base64Chars.join('');
|
||
},
|
||
|
||
/**
|
||
* Converts a Base64 string to a word array.
|
||
*
|
||
* @param {string} base64Str The Base64 string.
|
||
*
|
||
* @return {WordArray} The word array.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var wordArray = CryptoJS.enc.Base64.parse(base64String);
|
||
*/
|
||
parse: function (base64Str) {
|
||
// Shortcuts
|
||
var base64StrLength = base64Str.length;
|
||
var map = this._map;
|
||
var reverseMap = this._reverseMap;
|
||
|
||
if (!reverseMap) {
|
||
reverseMap = this._reverseMap = [];
|
||
for (var j = 0; j < map.length; j++) {
|
||
reverseMap[map.charCodeAt(j)] = j;
|
||
}
|
||
}
|
||
|
||
// Ignore padding
|
||
var paddingChar = map.charAt(64);
|
||
if (paddingChar) {
|
||
var paddingIndex = base64Str.indexOf(paddingChar);
|
||
if (paddingIndex !== -1) {
|
||
base64StrLength = paddingIndex;
|
||
}
|
||
}
|
||
|
||
// Convert
|
||
return parseLoop(base64Str, base64StrLength, reverseMap);
|
||
|
||
},
|
||
|
||
_map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
|
||
};
|
||
|
||
function parseLoop(base64Str, base64StrLength, reverseMap) {
|
||
var words = [];
|
||
var nBytes = 0;
|
||
for (var i = 0; i < base64StrLength; i++) {
|
||
if (i % 4) {
|
||
var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2);
|
||
var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2);
|
||
var bitsCombined = bits1 | bits2;
|
||
words[nBytes >>> 2] |= bitsCombined << (24 - (nBytes % 4) * 8);
|
||
nBytes++;
|
||
}
|
||
}
|
||
return WordArray.create(words, nBytes);
|
||
}
|
||
}());
|
||
|
||
|
||
return CryptoJS.enc.Base64;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/enc-utf16.js":
|
||
/*!*********************************************!*\
|
||
!*** ./node_modules/crypto-js/enc-utf16.js ***!
|
||
\*********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function () {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var WordArray = C_lib.WordArray;
|
||
var C_enc = C.enc;
|
||
|
||
/**
|
||
* UTF-16 BE encoding strategy.
|
||
*/
|
||
var Utf16BE = C_enc.Utf16 = C_enc.Utf16BE = {
|
||
/**
|
||
* Converts a word array to a UTF-16 BE string.
|
||
*
|
||
* @param {WordArray} wordArray The word array.
|
||
*
|
||
* @return {string} The UTF-16 BE string.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var utf16String = CryptoJS.enc.Utf16.stringify(wordArray);
|
||
*/
|
||
stringify: function (wordArray) {
|
||
// Shortcuts
|
||
var words = wordArray.words;
|
||
var sigBytes = wordArray.sigBytes;
|
||
|
||
// Convert
|
||
var utf16Chars = [];
|
||
for (var i = 0; i < sigBytes; i += 2) {
|
||
var codePoint = (words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff;
|
||
utf16Chars.push(String.fromCharCode(codePoint));
|
||
}
|
||
|
||
return utf16Chars.join('');
|
||
},
|
||
|
||
/**
|
||
* Converts a UTF-16 BE string to a word array.
|
||
*
|
||
* @param {string} utf16Str The UTF-16 BE string.
|
||
*
|
||
* @return {WordArray} The word array.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var wordArray = CryptoJS.enc.Utf16.parse(utf16String);
|
||
*/
|
||
parse: function (utf16Str) {
|
||
// Shortcut
|
||
var utf16StrLength = utf16Str.length;
|
||
|
||
// Convert
|
||
var words = [];
|
||
for (var i = 0; i < utf16StrLength; i++) {
|
||
words[i >>> 1] |= utf16Str.charCodeAt(i) << (16 - (i % 2) * 16);
|
||
}
|
||
|
||
return WordArray.create(words, utf16StrLength * 2);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* UTF-16 LE encoding strategy.
|
||
*/
|
||
C_enc.Utf16LE = {
|
||
/**
|
||
* Converts a word array to a UTF-16 LE string.
|
||
*
|
||
* @param {WordArray} wordArray The word array.
|
||
*
|
||
* @return {string} The UTF-16 LE string.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var utf16Str = CryptoJS.enc.Utf16LE.stringify(wordArray);
|
||
*/
|
||
stringify: function (wordArray) {
|
||
// Shortcuts
|
||
var words = wordArray.words;
|
||
var sigBytes = wordArray.sigBytes;
|
||
|
||
// Convert
|
||
var utf16Chars = [];
|
||
for (var i = 0; i < sigBytes; i += 2) {
|
||
var codePoint = swapEndian((words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff);
|
||
utf16Chars.push(String.fromCharCode(codePoint));
|
||
}
|
||
|
||
return utf16Chars.join('');
|
||
},
|
||
|
||
/**
|
||
* Converts a UTF-16 LE string to a word array.
|
||
*
|
||
* @param {string} utf16Str The UTF-16 LE string.
|
||
*
|
||
* @return {WordArray} The word array.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var wordArray = CryptoJS.enc.Utf16LE.parse(utf16Str);
|
||
*/
|
||
parse: function (utf16Str) {
|
||
// Shortcut
|
||
var utf16StrLength = utf16Str.length;
|
||
|
||
// Convert
|
||
var words = [];
|
||
for (var i = 0; i < utf16StrLength; i++) {
|
||
words[i >>> 1] |= swapEndian(utf16Str.charCodeAt(i) << (16 - (i % 2) * 16));
|
||
}
|
||
|
||
return WordArray.create(words, utf16StrLength * 2);
|
||
}
|
||
};
|
||
|
||
function swapEndian(word) {
|
||
return ((word << 8) & 0xff00ff00) | ((word >>> 8) & 0x00ff00ff);
|
||
}
|
||
}());
|
||
|
||
|
||
return CryptoJS.enc.Utf16;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/evpkdf.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/crypto-js/evpkdf.js ***!
|
||
\******************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./sha1 */ "./node_modules/crypto-js/sha1.js"), __webpack_require__(/*! ./hmac */ "./node_modules/crypto-js/hmac.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function () {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var Base = C_lib.Base;
|
||
var WordArray = C_lib.WordArray;
|
||
var C_algo = C.algo;
|
||
var MD5 = C_algo.MD5;
|
||
|
||
/**
|
||
* This key derivation function is meant to conform with EVP_BytesToKey.
|
||
* www.openssl.org/docs/crypto/EVP_BytesToKey.html
|
||
*/
|
||
var EvpKDF = C_algo.EvpKDF = Base.extend({
|
||
/**
|
||
* Configuration options.
|
||
*
|
||
* @property {number} keySize The key size in words to generate. Default: 4 (128 bits)
|
||
* @property {Hasher} hasher The hash algorithm to use. Default: MD5
|
||
* @property {number} iterations The number of iterations to perform. Default: 1
|
||
*/
|
||
cfg: Base.extend({
|
||
keySize: 128/32,
|
||
hasher: MD5,
|
||
iterations: 1
|
||
}),
|
||
|
||
/**
|
||
* Initializes a newly created key derivation function.
|
||
*
|
||
* @param {Object} cfg (Optional) The configuration options to use for the derivation.
|
||
*
|
||
* @example
|
||
*
|
||
* var kdf = CryptoJS.algo.EvpKDF.create();
|
||
* var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 });
|
||
* var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 });
|
||
*/
|
||
init: function (cfg) {
|
||
this.cfg = this.cfg.extend(cfg);
|
||
},
|
||
|
||
/**
|
||
* Derives a key from a password.
|
||
*
|
||
* @param {WordArray|string} password The password.
|
||
* @param {WordArray|string} salt A salt.
|
||
*
|
||
* @return {WordArray} The derived key.
|
||
*
|
||
* @example
|
||
*
|
||
* var key = kdf.compute(password, salt);
|
||
*/
|
||
compute: function (password, salt) {
|
||
var block;
|
||
|
||
// Shortcut
|
||
var cfg = this.cfg;
|
||
|
||
// Init hasher
|
||
var hasher = cfg.hasher.create();
|
||
|
||
// Initial values
|
||
var derivedKey = WordArray.create();
|
||
|
||
// Shortcuts
|
||
var derivedKeyWords = derivedKey.words;
|
||
var keySize = cfg.keySize;
|
||
var iterations = cfg.iterations;
|
||
|
||
// Generate key
|
||
while (derivedKeyWords.length < keySize) {
|
||
if (block) {
|
||
hasher.update(block);
|
||
}
|
||
block = hasher.update(password).finalize(salt);
|
||
hasher.reset();
|
||
|
||
// Iterations
|
||
for (var i = 1; i < iterations; i++) {
|
||
block = hasher.finalize(block);
|
||
hasher.reset();
|
||
}
|
||
|
||
derivedKey.concat(block);
|
||
}
|
||
derivedKey.sigBytes = keySize * 4;
|
||
|
||
return derivedKey;
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Derives a key from a password.
|
||
*
|
||
* @param {WordArray|string} password The password.
|
||
* @param {WordArray|string} salt A salt.
|
||
* @param {Object} cfg (Optional) The configuration options to use for this computation.
|
||
*
|
||
* @return {WordArray} The derived key.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var key = CryptoJS.EvpKDF(password, salt);
|
||
* var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 });
|
||
* var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 });
|
||
*/
|
||
C.EvpKDF = function (password, salt, cfg) {
|
||
return EvpKDF.create(cfg).compute(password, salt);
|
||
};
|
||
}());
|
||
|
||
|
||
return CryptoJS.EvpKDF;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/format-hex.js":
|
||
/*!**********************************************!*\
|
||
!*** ./node_modules/crypto-js/format-hex.js ***!
|
||
\**********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./cipher-core */ "./node_modules/crypto-js/cipher-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function (undefined) {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var CipherParams = C_lib.CipherParams;
|
||
var C_enc = C.enc;
|
||
var Hex = C_enc.Hex;
|
||
var C_format = C.format;
|
||
|
||
var HexFormatter = C_format.Hex = {
|
||
/**
|
||
* Converts the ciphertext of a cipher params object to a hexadecimally encoded string.
|
||
*
|
||
* @param {CipherParams} cipherParams The cipher params object.
|
||
*
|
||
* @return {string} The hexadecimally encoded string.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hexString = CryptoJS.format.Hex.stringify(cipherParams);
|
||
*/
|
||
stringify: function (cipherParams) {
|
||
return cipherParams.ciphertext.toString(Hex);
|
||
},
|
||
|
||
/**
|
||
* Converts a hexadecimally encoded ciphertext string to a cipher params object.
|
||
*
|
||
* @param {string} input The hexadecimally encoded string.
|
||
*
|
||
* @return {CipherParams} The cipher params object.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var cipherParams = CryptoJS.format.Hex.parse(hexString);
|
||
*/
|
||
parse: function (input) {
|
||
var ciphertext = Hex.parse(input);
|
||
return CipherParams.create({ ciphertext: ciphertext });
|
||
}
|
||
};
|
||
}());
|
||
|
||
|
||
return CryptoJS.format.Hex;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/hmac.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/crypto-js/hmac.js ***!
|
||
\****************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function () {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var Base = C_lib.Base;
|
||
var C_enc = C.enc;
|
||
var Utf8 = C_enc.Utf8;
|
||
var C_algo = C.algo;
|
||
|
||
/**
|
||
* HMAC algorithm.
|
||
*/
|
||
var HMAC = C_algo.HMAC = Base.extend({
|
||
/**
|
||
* Initializes a newly created HMAC.
|
||
*
|
||
* @param {Hasher} hasher The hash algorithm to use.
|
||
* @param {WordArray|string} key The secret key.
|
||
*
|
||
* @example
|
||
*
|
||
* var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key);
|
||
*/
|
||
init: function (hasher, key) {
|
||
// Init hasher
|
||
hasher = this._hasher = new hasher.init();
|
||
|
||
// Convert string to WordArray, else assume WordArray already
|
||
if (typeof key == 'string') {
|
||
key = Utf8.parse(key);
|
||
}
|
||
|
||
// Shortcuts
|
||
var hasherBlockSize = hasher.blockSize;
|
||
var hasherBlockSizeBytes = hasherBlockSize * 4;
|
||
|
||
// Allow arbitrary length keys
|
||
if (key.sigBytes > hasherBlockSizeBytes) {
|
||
key = hasher.finalize(key);
|
||
}
|
||
|
||
// Clamp excess bits
|
||
key.clamp();
|
||
|
||
// Clone key for inner and outer pads
|
||
var oKey = this._oKey = key.clone();
|
||
var iKey = this._iKey = key.clone();
|
||
|
||
// Shortcuts
|
||
var oKeyWords = oKey.words;
|
||
var iKeyWords = iKey.words;
|
||
|
||
// XOR keys with pad constants
|
||
for (var i = 0; i < hasherBlockSize; i++) {
|
||
oKeyWords[i] ^= 0x5c5c5c5c;
|
||
iKeyWords[i] ^= 0x36363636;
|
||
}
|
||
oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes;
|
||
|
||
// Set initial values
|
||
this.reset();
|
||
},
|
||
|
||
/**
|
||
* Resets this HMAC to its initial state.
|
||
*
|
||
* @example
|
||
*
|
||
* hmacHasher.reset();
|
||
*/
|
||
reset: function () {
|
||
// Shortcut
|
||
var hasher = this._hasher;
|
||
|
||
// Reset
|
||
hasher.reset();
|
||
hasher.update(this._iKey);
|
||
},
|
||
|
||
/**
|
||
* Updates this HMAC with a message.
|
||
*
|
||
* @param {WordArray|string} messageUpdate The message to append.
|
||
*
|
||
* @return {HMAC} This HMAC instance.
|
||
*
|
||
* @example
|
||
*
|
||
* hmacHasher.update('message');
|
||
* hmacHasher.update(wordArray);
|
||
*/
|
||
update: function (messageUpdate) {
|
||
this._hasher.update(messageUpdate);
|
||
|
||
// Chainable
|
||
return this;
|
||
},
|
||
|
||
/**
|
||
* Finalizes the HMAC computation.
|
||
* Note that the finalize operation is effectively a destructive, read-once operation.
|
||
*
|
||
* @param {WordArray|string} messageUpdate (Optional) A final message update.
|
||
*
|
||
* @return {WordArray} The HMAC.
|
||
*
|
||
* @example
|
||
*
|
||
* var hmac = hmacHasher.finalize();
|
||
* var hmac = hmacHasher.finalize('message');
|
||
* var hmac = hmacHasher.finalize(wordArray);
|
||
*/
|
||
finalize: function (messageUpdate) {
|
||
// Shortcut
|
||
var hasher = this._hasher;
|
||
|
||
// Compute HMAC
|
||
var innerHash = hasher.finalize(messageUpdate);
|
||
hasher.reset();
|
||
var hmac = hasher.finalize(this._oKey.clone().concat(innerHash));
|
||
|
||
return hmac;
|
||
}
|
||
});
|
||
}());
|
||
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/index.js":
|
||
/*!*****************************************!*\
|
||
!*** ./node_modules/crypto-js/index.js ***!
|
||
\*****************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./x64-core */ "./node_modules/crypto-js/x64-core.js"), __webpack_require__(/*! ./lib-typedarrays */ "./node_modules/crypto-js/lib-typedarrays.js"), __webpack_require__(/*! ./enc-utf16 */ "./node_modules/crypto-js/enc-utf16.js"), __webpack_require__(/*! ./enc-base64 */ "./node_modules/crypto-js/enc-base64.js"), __webpack_require__(/*! ./md5 */ "./node_modules/crypto-js/md5.js"), __webpack_require__(/*! ./sha1 */ "./node_modules/crypto-js/sha1.js"), __webpack_require__(/*! ./sha256 */ "./node_modules/crypto-js/sha256.js"), __webpack_require__(/*! ./sha224 */ "./node_modules/crypto-js/sha224.js"), __webpack_require__(/*! ./sha512 */ "./node_modules/crypto-js/sha512.js"), __webpack_require__(/*! ./sha384 */ "./node_modules/crypto-js/sha384.js"), __webpack_require__(/*! ./sha3 */ "./node_modules/crypto-js/sha3.js"), __webpack_require__(/*! ./ripemd160 */ "./node_modules/crypto-js/ripemd160.js"), __webpack_require__(/*! ./hmac */ "./node_modules/crypto-js/hmac.js"), __webpack_require__(/*! ./pbkdf2 */ "./node_modules/crypto-js/pbkdf2.js"), __webpack_require__(/*! ./evpkdf */ "./node_modules/crypto-js/evpkdf.js"), __webpack_require__(/*! ./cipher-core */ "./node_modules/crypto-js/cipher-core.js"), __webpack_require__(/*! ./mode-cfb */ "./node_modules/crypto-js/mode-cfb.js"), __webpack_require__(/*! ./mode-ctr */ "./node_modules/crypto-js/mode-ctr.js"), __webpack_require__(/*! ./mode-ctr-gladman */ "./node_modules/crypto-js/mode-ctr-gladman.js"), __webpack_require__(/*! ./mode-ofb */ "./node_modules/crypto-js/mode-ofb.js"), __webpack_require__(/*! ./mode-ecb */ "./node_modules/crypto-js/mode-ecb.js"), __webpack_require__(/*! ./pad-ansix923 */ "./node_modules/crypto-js/pad-ansix923.js"), __webpack_require__(/*! ./pad-iso10126 */ "./node_modules/crypto-js/pad-iso10126.js"), __webpack_require__(/*! ./pad-iso97971 */ "./node_modules/crypto-js/pad-iso97971.js"), __webpack_require__(/*! ./pad-zeropadding */ "./node_modules/crypto-js/pad-zeropadding.js"), __webpack_require__(/*! ./pad-nopadding */ "./node_modules/crypto-js/pad-nopadding.js"), __webpack_require__(/*! ./format-hex */ "./node_modules/crypto-js/format-hex.js"), __webpack_require__(/*! ./aes */ "./node_modules/crypto-js/aes.js"), __webpack_require__(/*! ./tripledes */ "./node_modules/crypto-js/tripledes.js"), __webpack_require__(/*! ./rc4 */ "./node_modules/crypto-js/rc4.js"), __webpack_require__(/*! ./rabbit */ "./node_modules/crypto-js/rabbit.js"), __webpack_require__(/*! ./rabbit-legacy */ "./node_modules/crypto-js/rabbit-legacy.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
return CryptoJS;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/lib-typedarrays.js":
|
||
/*!***************************************************!*\
|
||
!*** ./node_modules/crypto-js/lib-typedarrays.js ***!
|
||
\***************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function () {
|
||
// Check if typed arrays are supported
|
||
if (typeof ArrayBuffer != 'function') {
|
||
return;
|
||
}
|
||
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var WordArray = C_lib.WordArray;
|
||
|
||
// Reference original init
|
||
var superInit = WordArray.init;
|
||
|
||
// Augment WordArray.init to handle typed arrays
|
||
var subInit = WordArray.init = function (typedArray) {
|
||
// Convert buffers to uint8
|
||
if (typedArray instanceof ArrayBuffer) {
|
||
typedArray = new Uint8Array(typedArray);
|
||
}
|
||
|
||
// Convert other array views to uint8
|
||
if (
|
||
typedArray instanceof Int8Array ||
|
||
(typeof Uint8ClampedArray !== "undefined" && typedArray instanceof Uint8ClampedArray) ||
|
||
typedArray instanceof Int16Array ||
|
||
typedArray instanceof Uint16Array ||
|
||
typedArray instanceof Int32Array ||
|
||
typedArray instanceof Uint32Array ||
|
||
typedArray instanceof Float32Array ||
|
||
typedArray instanceof Float64Array
|
||
) {
|
||
typedArray = new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength);
|
||
}
|
||
|
||
// Handle Uint8Array
|
||
if (typedArray instanceof Uint8Array) {
|
||
// Shortcut
|
||
var typedArrayByteLength = typedArray.byteLength;
|
||
|
||
// Extract bytes
|
||
var words = [];
|
||
for (var i = 0; i < typedArrayByteLength; i++) {
|
||
words[i >>> 2] |= typedArray[i] << (24 - (i % 4) * 8);
|
||
}
|
||
|
||
// Initialize this word array
|
||
superInit.call(this, words, typedArrayByteLength);
|
||
} else {
|
||
// Else call normal init
|
||
superInit.apply(this, arguments);
|
||
}
|
||
};
|
||
|
||
subInit.prototype = WordArray;
|
||
}());
|
||
|
||
|
||
return CryptoJS.lib.WordArray;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/md5.js":
|
||
/*!***************************************!*\
|
||
!*** ./node_modules/crypto-js/md5.js ***!
|
||
\***************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function (Math) {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var WordArray = C_lib.WordArray;
|
||
var Hasher = C_lib.Hasher;
|
||
var C_algo = C.algo;
|
||
|
||
// Constants table
|
||
var T = [];
|
||
|
||
// Compute constants
|
||
(function () {
|
||
for (var i = 0; i < 64; i++) {
|
||
T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;
|
||
}
|
||
}());
|
||
|
||
/**
|
||
* MD5 hash algorithm.
|
||
*/
|
||
var MD5 = C_algo.MD5 = Hasher.extend({
|
||
_doReset: function () {
|
||
this._hash = new WordArray.init([
|
||
0x67452301, 0xefcdab89,
|
||
0x98badcfe, 0x10325476
|
||
]);
|
||
},
|
||
|
||
_doProcessBlock: function (M, offset) {
|
||
// Swap endian
|
||
for (var i = 0; i < 16; i++) {
|
||
// Shortcuts
|
||
var offset_i = offset + i;
|
||
var M_offset_i = M[offset_i];
|
||
|
||
M[offset_i] = (
|
||
(((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) |
|
||
(((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00)
|
||
);
|
||
}
|
||
|
||
// Shortcuts
|
||
var H = this._hash.words;
|
||
|
||
var M_offset_0 = M[offset + 0];
|
||
var M_offset_1 = M[offset + 1];
|
||
var M_offset_2 = M[offset + 2];
|
||
var M_offset_3 = M[offset + 3];
|
||
var M_offset_4 = M[offset + 4];
|
||
var M_offset_5 = M[offset + 5];
|
||
var M_offset_6 = M[offset + 6];
|
||
var M_offset_7 = M[offset + 7];
|
||
var M_offset_8 = M[offset + 8];
|
||
var M_offset_9 = M[offset + 9];
|
||
var M_offset_10 = M[offset + 10];
|
||
var M_offset_11 = M[offset + 11];
|
||
var M_offset_12 = M[offset + 12];
|
||
var M_offset_13 = M[offset + 13];
|
||
var M_offset_14 = M[offset + 14];
|
||
var M_offset_15 = M[offset + 15];
|
||
|
||
// Working varialbes
|
||
var a = H[0];
|
||
var b = H[1];
|
||
var c = H[2];
|
||
var d = H[3];
|
||
|
||
// Computation
|
||
a = FF(a, b, c, d, M_offset_0, 7, T[0]);
|
||
d = FF(d, a, b, c, M_offset_1, 12, T[1]);
|
||
c = FF(c, d, a, b, M_offset_2, 17, T[2]);
|
||
b = FF(b, c, d, a, M_offset_3, 22, T[3]);
|
||
a = FF(a, b, c, d, M_offset_4, 7, T[4]);
|
||
d = FF(d, a, b, c, M_offset_5, 12, T[5]);
|
||
c = FF(c, d, a, b, M_offset_6, 17, T[6]);
|
||
b = FF(b, c, d, a, M_offset_7, 22, T[7]);
|
||
a = FF(a, b, c, d, M_offset_8, 7, T[8]);
|
||
d = FF(d, a, b, c, M_offset_9, 12, T[9]);
|
||
c = FF(c, d, a, b, M_offset_10, 17, T[10]);
|
||
b = FF(b, c, d, a, M_offset_11, 22, T[11]);
|
||
a = FF(a, b, c, d, M_offset_12, 7, T[12]);
|
||
d = FF(d, a, b, c, M_offset_13, 12, T[13]);
|
||
c = FF(c, d, a, b, M_offset_14, 17, T[14]);
|
||
b = FF(b, c, d, a, M_offset_15, 22, T[15]);
|
||
|
||
a = GG(a, b, c, d, M_offset_1, 5, T[16]);
|
||
d = GG(d, a, b, c, M_offset_6, 9, T[17]);
|
||
c = GG(c, d, a, b, M_offset_11, 14, T[18]);
|
||
b = GG(b, c, d, a, M_offset_0, 20, T[19]);
|
||
a = GG(a, b, c, d, M_offset_5, 5, T[20]);
|
||
d = GG(d, a, b, c, M_offset_10, 9, T[21]);
|
||
c = GG(c, d, a, b, M_offset_15, 14, T[22]);
|
||
b = GG(b, c, d, a, M_offset_4, 20, T[23]);
|
||
a = GG(a, b, c, d, M_offset_9, 5, T[24]);
|
||
d = GG(d, a, b, c, M_offset_14, 9, T[25]);
|
||
c = GG(c, d, a, b, M_offset_3, 14, T[26]);
|
||
b = GG(b, c, d, a, M_offset_8, 20, T[27]);
|
||
a = GG(a, b, c, d, M_offset_13, 5, T[28]);
|
||
d = GG(d, a, b, c, M_offset_2, 9, T[29]);
|
||
c = GG(c, d, a, b, M_offset_7, 14, T[30]);
|
||
b = GG(b, c, d, a, M_offset_12, 20, T[31]);
|
||
|
||
a = HH(a, b, c, d, M_offset_5, 4, T[32]);
|
||
d = HH(d, a, b, c, M_offset_8, 11, T[33]);
|
||
c = HH(c, d, a, b, M_offset_11, 16, T[34]);
|
||
b = HH(b, c, d, a, M_offset_14, 23, T[35]);
|
||
a = HH(a, b, c, d, M_offset_1, 4, T[36]);
|
||
d = HH(d, a, b, c, M_offset_4, 11, T[37]);
|
||
c = HH(c, d, a, b, M_offset_7, 16, T[38]);
|
||
b = HH(b, c, d, a, M_offset_10, 23, T[39]);
|
||
a = HH(a, b, c, d, M_offset_13, 4, T[40]);
|
||
d = HH(d, a, b, c, M_offset_0, 11, T[41]);
|
||
c = HH(c, d, a, b, M_offset_3, 16, T[42]);
|
||
b = HH(b, c, d, a, M_offset_6, 23, T[43]);
|
||
a = HH(a, b, c, d, M_offset_9, 4, T[44]);
|
||
d = HH(d, a, b, c, M_offset_12, 11, T[45]);
|
||
c = HH(c, d, a, b, M_offset_15, 16, T[46]);
|
||
b = HH(b, c, d, a, M_offset_2, 23, T[47]);
|
||
|
||
a = II(a, b, c, d, M_offset_0, 6, T[48]);
|
||
d = II(d, a, b, c, M_offset_7, 10, T[49]);
|
||
c = II(c, d, a, b, M_offset_14, 15, T[50]);
|
||
b = II(b, c, d, a, M_offset_5, 21, T[51]);
|
||
a = II(a, b, c, d, M_offset_12, 6, T[52]);
|
||
d = II(d, a, b, c, M_offset_3, 10, T[53]);
|
||
c = II(c, d, a, b, M_offset_10, 15, T[54]);
|
||
b = II(b, c, d, a, M_offset_1, 21, T[55]);
|
||
a = II(a, b, c, d, M_offset_8, 6, T[56]);
|
||
d = II(d, a, b, c, M_offset_15, 10, T[57]);
|
||
c = II(c, d, a, b, M_offset_6, 15, T[58]);
|
||
b = II(b, c, d, a, M_offset_13, 21, T[59]);
|
||
a = II(a, b, c, d, M_offset_4, 6, T[60]);
|
||
d = II(d, a, b, c, M_offset_11, 10, T[61]);
|
||
c = II(c, d, a, b, M_offset_2, 15, T[62]);
|
||
b = II(b, c, d, a, M_offset_9, 21, T[63]);
|
||
|
||
// Intermediate hash value
|
||
H[0] = (H[0] + a) | 0;
|
||
H[1] = (H[1] + b) | 0;
|
||
H[2] = (H[2] + c) | 0;
|
||
H[3] = (H[3] + d) | 0;
|
||
},
|
||
|
||
_doFinalize: function () {
|
||
// Shortcuts
|
||
var data = this._data;
|
||
var dataWords = data.words;
|
||
|
||
var nBitsTotal = this._nDataBytes * 8;
|
||
var nBitsLeft = data.sigBytes * 8;
|
||
|
||
// Add padding
|
||
dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
|
||
|
||
var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000);
|
||
var nBitsTotalL = nBitsTotal;
|
||
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = (
|
||
(((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) |
|
||
(((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00)
|
||
);
|
||
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (
|
||
(((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) |
|
||
(((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00)
|
||
);
|
||
|
||
data.sigBytes = (dataWords.length + 1) * 4;
|
||
|
||
// Hash final blocks
|
||
this._process();
|
||
|
||
// Shortcuts
|
||
var hash = this._hash;
|
||
var H = hash.words;
|
||
|
||
// Swap endian
|
||
for (var i = 0; i < 4; i++) {
|
||
// Shortcut
|
||
var H_i = H[i];
|
||
|
||
H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) |
|
||
(((H_i << 24) | (H_i >>> 8)) & 0xff00ff00);
|
||
}
|
||
|
||
// Return final computed hash
|
||
return hash;
|
||
},
|
||
|
||
clone: function () {
|
||
var clone = Hasher.clone.call(this);
|
||
clone._hash = this._hash.clone();
|
||
|
||
return clone;
|
||
}
|
||
});
|
||
|
||
function FF(a, b, c, d, x, s, t) {
|
||
var n = a + ((b & c) | (~b & d)) + x + t;
|
||
return ((n << s) | (n >>> (32 - s))) + b;
|
||
}
|
||
|
||
function GG(a, b, c, d, x, s, t) {
|
||
var n = a + ((b & d) | (c & ~d)) + x + t;
|
||
return ((n << s) | (n >>> (32 - s))) + b;
|
||
}
|
||
|
||
function HH(a, b, c, d, x, s, t) {
|
||
var n = a + (b ^ c ^ d) + x + t;
|
||
return ((n << s) | (n >>> (32 - s))) + b;
|
||
}
|
||
|
||
function II(a, b, c, d, x, s, t) {
|
||
var n = a + (c ^ (b | ~d)) + x + t;
|
||
return ((n << s) | (n >>> (32 - s))) + b;
|
||
}
|
||
|
||
/**
|
||
* Shortcut function to the hasher's object interface.
|
||
*
|
||
* @param {WordArray|string} message The message to hash.
|
||
*
|
||
* @return {WordArray} The hash.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hash = CryptoJS.MD5('message');
|
||
* var hash = CryptoJS.MD5(wordArray);
|
||
*/
|
||
C.MD5 = Hasher._createHelper(MD5);
|
||
|
||
/**
|
||
* Shortcut function to the HMAC's object interface.
|
||
*
|
||
* @param {WordArray|string} message The message to hash.
|
||
* @param {WordArray|string} key The secret key.
|
||
*
|
||
* @return {WordArray} The HMAC.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hmac = CryptoJS.HmacMD5(message, key);
|
||
*/
|
||
C.HmacMD5 = Hasher._createHmacHelper(MD5);
|
||
}(Math));
|
||
|
||
|
||
return CryptoJS.MD5;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/mode-cfb.js":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/crypto-js/mode-cfb.js ***!
|
||
\********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./cipher-core */ "./node_modules/crypto-js/cipher-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
/**
|
||
* Cipher Feedback block mode.
|
||
*/
|
||
CryptoJS.mode.CFB = (function () {
|
||
var CFB = CryptoJS.lib.BlockCipherMode.extend();
|
||
|
||
CFB.Encryptor = CFB.extend({
|
||
processBlock: function (words, offset) {
|
||
// Shortcuts
|
||
var cipher = this._cipher;
|
||
var blockSize = cipher.blockSize;
|
||
|
||
generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher);
|
||
|
||
// Remember this block to use with next block
|
||
this._prevBlock = words.slice(offset, offset + blockSize);
|
||
}
|
||
});
|
||
|
||
CFB.Decryptor = CFB.extend({
|
||
processBlock: function (words, offset) {
|
||
// Shortcuts
|
||
var cipher = this._cipher;
|
||
var blockSize = cipher.blockSize;
|
||
|
||
// Remember this block to use with next block
|
||
var thisBlock = words.slice(offset, offset + blockSize);
|
||
|
||
generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher);
|
||
|
||
// This block becomes the previous block
|
||
this._prevBlock = thisBlock;
|
||
}
|
||
});
|
||
|
||
function generateKeystreamAndEncrypt(words, offset, blockSize, cipher) {
|
||
var keystream;
|
||
|
||
// Shortcut
|
||
var iv = this._iv;
|
||
|
||
// Generate keystream
|
||
if (iv) {
|
||
keystream = iv.slice(0);
|
||
|
||
// Remove IV for subsequent blocks
|
||
this._iv = undefined;
|
||
} else {
|
||
keystream = this._prevBlock;
|
||
}
|
||
cipher.encryptBlock(keystream, 0);
|
||
|
||
// Encrypt
|
||
for (var i = 0; i < blockSize; i++) {
|
||
words[offset + i] ^= keystream[i];
|
||
}
|
||
}
|
||
|
||
return CFB;
|
||
}());
|
||
|
||
|
||
return CryptoJS.mode.CFB;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/mode-ctr-gladman.js":
|
||
/*!****************************************************!*\
|
||
!*** ./node_modules/crypto-js/mode-ctr-gladman.js ***!
|
||
\****************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./cipher-core */ "./node_modules/crypto-js/cipher-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
/** @preserve
|
||
* Counter block mode compatible with Dr Brian Gladman fileenc.c
|
||
* derived from CryptoJS.mode.CTR
|
||
* Jan Hruby jhruby.web@gmail.com
|
||
*/
|
||
CryptoJS.mode.CTRGladman = (function () {
|
||
var CTRGladman = CryptoJS.lib.BlockCipherMode.extend();
|
||
|
||
function incWord(word)
|
||
{
|
||
if (((word >> 24) & 0xff) === 0xff) { //overflow
|
||
var b1 = (word >> 16)&0xff;
|
||
var b2 = (word >> 8)&0xff;
|
||
var b3 = word & 0xff;
|
||
|
||
if (b1 === 0xff) // overflow b1
|
||
{
|
||
b1 = 0;
|
||
if (b2 === 0xff)
|
||
{
|
||
b2 = 0;
|
||
if (b3 === 0xff)
|
||
{
|
||
b3 = 0;
|
||
}
|
||
else
|
||
{
|
||
++b3;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
++b2;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
++b1;
|
||
}
|
||
|
||
word = 0;
|
||
word += (b1 << 16);
|
||
word += (b2 << 8);
|
||
word += b3;
|
||
}
|
||
else
|
||
{
|
||
word += (0x01 << 24);
|
||
}
|
||
return word;
|
||
}
|
||
|
||
function incCounter(counter)
|
||
{
|
||
if ((counter[0] = incWord(counter[0])) === 0)
|
||
{
|
||
// encr_data in fileenc.c from Dr Brian Gladman's counts only with DWORD j < 8
|
||
counter[1] = incWord(counter[1]);
|
||
}
|
||
return counter;
|
||
}
|
||
|
||
var Encryptor = CTRGladman.Encryptor = CTRGladman.extend({
|
||
processBlock: function (words, offset) {
|
||
// Shortcuts
|
||
var cipher = this._cipher
|
||
var blockSize = cipher.blockSize;
|
||
var iv = this._iv;
|
||
var counter = this._counter;
|
||
|
||
// Generate keystream
|
||
if (iv) {
|
||
counter = this._counter = iv.slice(0);
|
||
|
||
// Remove IV for subsequent blocks
|
||
this._iv = undefined;
|
||
}
|
||
|
||
incCounter(counter);
|
||
|
||
var keystream = counter.slice(0);
|
||
cipher.encryptBlock(keystream, 0);
|
||
|
||
// Encrypt
|
||
for (var i = 0; i < blockSize; i++) {
|
||
words[offset + i] ^= keystream[i];
|
||
}
|
||
}
|
||
});
|
||
|
||
CTRGladman.Decryptor = Encryptor;
|
||
|
||
return CTRGladman;
|
||
}());
|
||
|
||
|
||
|
||
|
||
return CryptoJS.mode.CTRGladman;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/mode-ctr.js":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/crypto-js/mode-ctr.js ***!
|
||
\********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./cipher-core */ "./node_modules/crypto-js/cipher-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
/**
|
||
* Counter block mode.
|
||
*/
|
||
CryptoJS.mode.CTR = (function () {
|
||
var CTR = CryptoJS.lib.BlockCipherMode.extend();
|
||
|
||
var Encryptor = CTR.Encryptor = CTR.extend({
|
||
processBlock: function (words, offset) {
|
||
// Shortcuts
|
||
var cipher = this._cipher
|
||
var blockSize = cipher.blockSize;
|
||
var iv = this._iv;
|
||
var counter = this._counter;
|
||
|
||
// Generate keystream
|
||
if (iv) {
|
||
counter = this._counter = iv.slice(0);
|
||
|
||
// Remove IV for subsequent blocks
|
||
this._iv = undefined;
|
||
}
|
||
var keystream = counter.slice(0);
|
||
cipher.encryptBlock(keystream, 0);
|
||
|
||
// Increment counter
|
||
counter[blockSize - 1] = (counter[blockSize - 1] + 1) | 0
|
||
|
||
// Encrypt
|
||
for (var i = 0; i < blockSize; i++) {
|
||
words[offset + i] ^= keystream[i];
|
||
}
|
||
}
|
||
});
|
||
|
||
CTR.Decryptor = Encryptor;
|
||
|
||
return CTR;
|
||
}());
|
||
|
||
|
||
return CryptoJS.mode.CTR;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/mode-ecb.js":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/crypto-js/mode-ecb.js ***!
|
||
\********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./cipher-core */ "./node_modules/crypto-js/cipher-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
/**
|
||
* Electronic Codebook block mode.
|
||
*/
|
||
CryptoJS.mode.ECB = (function () {
|
||
var ECB = CryptoJS.lib.BlockCipherMode.extend();
|
||
|
||
ECB.Encryptor = ECB.extend({
|
||
processBlock: function (words, offset) {
|
||
this._cipher.encryptBlock(words, offset);
|
||
}
|
||
});
|
||
|
||
ECB.Decryptor = ECB.extend({
|
||
processBlock: function (words, offset) {
|
||
this._cipher.decryptBlock(words, offset);
|
||
}
|
||
});
|
||
|
||
return ECB;
|
||
}());
|
||
|
||
|
||
return CryptoJS.mode.ECB;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/mode-ofb.js":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/crypto-js/mode-ofb.js ***!
|
||
\********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./cipher-core */ "./node_modules/crypto-js/cipher-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
/**
|
||
* Output Feedback block mode.
|
||
*/
|
||
CryptoJS.mode.OFB = (function () {
|
||
var OFB = CryptoJS.lib.BlockCipherMode.extend();
|
||
|
||
var Encryptor = OFB.Encryptor = OFB.extend({
|
||
processBlock: function (words, offset) {
|
||
// Shortcuts
|
||
var cipher = this._cipher
|
||
var blockSize = cipher.blockSize;
|
||
var iv = this._iv;
|
||
var keystream = this._keystream;
|
||
|
||
// Generate keystream
|
||
if (iv) {
|
||
keystream = this._keystream = iv.slice(0);
|
||
|
||
// Remove IV for subsequent blocks
|
||
this._iv = undefined;
|
||
}
|
||
cipher.encryptBlock(keystream, 0);
|
||
|
||
// Encrypt
|
||
for (var i = 0; i < blockSize; i++) {
|
||
words[offset + i] ^= keystream[i];
|
||
}
|
||
}
|
||
});
|
||
|
||
OFB.Decryptor = Encryptor;
|
||
|
||
return OFB;
|
||
}());
|
||
|
||
|
||
return CryptoJS.mode.OFB;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/pad-ansix923.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/crypto-js/pad-ansix923.js ***!
|
||
\************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./cipher-core */ "./node_modules/crypto-js/cipher-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
/**
|
||
* ANSI X.923 padding strategy.
|
||
*/
|
||
CryptoJS.pad.AnsiX923 = {
|
||
pad: function (data, blockSize) {
|
||
// Shortcuts
|
||
var dataSigBytes = data.sigBytes;
|
||
var blockSizeBytes = blockSize * 4;
|
||
|
||
// Count padding bytes
|
||
var nPaddingBytes = blockSizeBytes - dataSigBytes % blockSizeBytes;
|
||
|
||
// Compute last byte position
|
||
var lastBytePos = dataSigBytes + nPaddingBytes - 1;
|
||
|
||
// Pad
|
||
data.clamp();
|
||
data.words[lastBytePos >>> 2] |= nPaddingBytes << (24 - (lastBytePos % 4) * 8);
|
||
data.sigBytes += nPaddingBytes;
|
||
},
|
||
|
||
unpad: function (data) {
|
||
// Get number of padding bytes from last byte
|
||
var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
|
||
|
||
// Remove padding
|
||
data.sigBytes -= nPaddingBytes;
|
||
}
|
||
};
|
||
|
||
|
||
return CryptoJS.pad.Ansix923;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/pad-iso10126.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/crypto-js/pad-iso10126.js ***!
|
||
\************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./cipher-core */ "./node_modules/crypto-js/cipher-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
/**
|
||
* ISO 10126 padding strategy.
|
||
*/
|
||
CryptoJS.pad.Iso10126 = {
|
||
pad: function (data, blockSize) {
|
||
// Shortcut
|
||
var blockSizeBytes = blockSize * 4;
|
||
|
||
// Count padding bytes
|
||
var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;
|
||
|
||
// Pad
|
||
data.concat(CryptoJS.lib.WordArray.random(nPaddingBytes - 1)).
|
||
concat(CryptoJS.lib.WordArray.create([nPaddingBytes << 24], 1));
|
||
},
|
||
|
||
unpad: function (data) {
|
||
// Get number of padding bytes from last byte
|
||
var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
|
||
|
||
// Remove padding
|
||
data.sigBytes -= nPaddingBytes;
|
||
}
|
||
};
|
||
|
||
|
||
return CryptoJS.pad.Iso10126;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/pad-iso97971.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/crypto-js/pad-iso97971.js ***!
|
||
\************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./cipher-core */ "./node_modules/crypto-js/cipher-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
/**
|
||
* ISO/IEC 9797-1 Padding Method 2.
|
||
*/
|
||
CryptoJS.pad.Iso97971 = {
|
||
pad: function (data, blockSize) {
|
||
// Add 0x80 byte
|
||
data.concat(CryptoJS.lib.WordArray.create([0x80000000], 1));
|
||
|
||
// Zero pad the rest
|
||
CryptoJS.pad.ZeroPadding.pad(data, blockSize);
|
||
},
|
||
|
||
unpad: function (data) {
|
||
// Remove zero padding
|
||
CryptoJS.pad.ZeroPadding.unpad(data);
|
||
|
||
// Remove one more byte -- the 0x80 byte
|
||
data.sigBytes--;
|
||
}
|
||
};
|
||
|
||
|
||
return CryptoJS.pad.Iso97971;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/pad-nopadding.js":
|
||
/*!*************************************************!*\
|
||
!*** ./node_modules/crypto-js/pad-nopadding.js ***!
|
||
\*************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./cipher-core */ "./node_modules/crypto-js/cipher-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
/**
|
||
* A noop padding strategy.
|
||
*/
|
||
CryptoJS.pad.NoPadding = {
|
||
pad: function () {
|
||
},
|
||
|
||
unpad: function () {
|
||
}
|
||
};
|
||
|
||
|
||
return CryptoJS.pad.NoPadding;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/pad-zeropadding.js":
|
||
/*!***************************************************!*\
|
||
!*** ./node_modules/crypto-js/pad-zeropadding.js ***!
|
||
\***************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./cipher-core */ "./node_modules/crypto-js/cipher-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
/**
|
||
* Zero padding strategy.
|
||
*/
|
||
CryptoJS.pad.ZeroPadding = {
|
||
pad: function (data, blockSize) {
|
||
// Shortcut
|
||
var blockSizeBytes = blockSize * 4;
|
||
|
||
// Pad
|
||
data.clamp();
|
||
data.sigBytes += blockSizeBytes - ((data.sigBytes % blockSizeBytes) || blockSizeBytes);
|
||
},
|
||
|
||
unpad: function (data) {
|
||
// Shortcut
|
||
var dataWords = data.words;
|
||
|
||
// Unpad
|
||
var i = data.sigBytes - 1;
|
||
for (var i = data.sigBytes - 1; i >= 0; i--) {
|
||
if (((dataWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff)) {
|
||
data.sigBytes = i + 1;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
return CryptoJS.pad.ZeroPadding;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/pbkdf2.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/crypto-js/pbkdf2.js ***!
|
||
\******************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./sha1 */ "./node_modules/crypto-js/sha1.js"), __webpack_require__(/*! ./hmac */ "./node_modules/crypto-js/hmac.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function () {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var Base = C_lib.Base;
|
||
var WordArray = C_lib.WordArray;
|
||
var C_algo = C.algo;
|
||
var SHA1 = C_algo.SHA1;
|
||
var HMAC = C_algo.HMAC;
|
||
|
||
/**
|
||
* Password-Based Key Derivation Function 2 algorithm.
|
||
*/
|
||
var PBKDF2 = C_algo.PBKDF2 = Base.extend({
|
||
/**
|
||
* Configuration options.
|
||
*
|
||
* @property {number} keySize The key size in words to generate. Default: 4 (128 bits)
|
||
* @property {Hasher} hasher The hasher to use. Default: SHA1
|
||
* @property {number} iterations The number of iterations to perform. Default: 1
|
||
*/
|
||
cfg: Base.extend({
|
||
keySize: 128/32,
|
||
hasher: SHA1,
|
||
iterations: 1
|
||
}),
|
||
|
||
/**
|
||
* Initializes a newly created key derivation function.
|
||
*
|
||
* @param {Object} cfg (Optional) The configuration options to use for the derivation.
|
||
*
|
||
* @example
|
||
*
|
||
* var kdf = CryptoJS.algo.PBKDF2.create();
|
||
* var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8 });
|
||
* var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8, iterations: 1000 });
|
||
*/
|
||
init: function (cfg) {
|
||
this.cfg = this.cfg.extend(cfg);
|
||
},
|
||
|
||
/**
|
||
* Computes the Password-Based Key Derivation Function 2.
|
||
*
|
||
* @param {WordArray|string} password The password.
|
||
* @param {WordArray|string} salt A salt.
|
||
*
|
||
* @return {WordArray} The derived key.
|
||
*
|
||
* @example
|
||
*
|
||
* var key = kdf.compute(password, salt);
|
||
*/
|
||
compute: function (password, salt) {
|
||
// Shortcut
|
||
var cfg = this.cfg;
|
||
|
||
// Init HMAC
|
||
var hmac = HMAC.create(cfg.hasher, password);
|
||
|
||
// Initial values
|
||
var derivedKey = WordArray.create();
|
||
var blockIndex = WordArray.create([0x00000001]);
|
||
|
||
// Shortcuts
|
||
var derivedKeyWords = derivedKey.words;
|
||
var blockIndexWords = blockIndex.words;
|
||
var keySize = cfg.keySize;
|
||
var iterations = cfg.iterations;
|
||
|
||
// Generate key
|
||
while (derivedKeyWords.length < keySize) {
|
||
var block = hmac.update(salt).finalize(blockIndex);
|
||
hmac.reset();
|
||
|
||
// Shortcuts
|
||
var blockWords = block.words;
|
||
var blockWordsLength = blockWords.length;
|
||
|
||
// Iterations
|
||
var intermediate = block;
|
||
for (var i = 1; i < iterations; i++) {
|
||
intermediate = hmac.finalize(intermediate);
|
||
hmac.reset();
|
||
|
||
// Shortcut
|
||
var intermediateWords = intermediate.words;
|
||
|
||
// XOR intermediate with block
|
||
for (var j = 0; j < blockWordsLength; j++) {
|
||
blockWords[j] ^= intermediateWords[j];
|
||
}
|
||
}
|
||
|
||
derivedKey.concat(block);
|
||
blockIndexWords[0]++;
|
||
}
|
||
derivedKey.sigBytes = keySize * 4;
|
||
|
||
return derivedKey;
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Computes the Password-Based Key Derivation Function 2.
|
||
*
|
||
* @param {WordArray|string} password The password.
|
||
* @param {WordArray|string} salt A salt.
|
||
* @param {Object} cfg (Optional) The configuration options to use for this computation.
|
||
*
|
||
* @return {WordArray} The derived key.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var key = CryptoJS.PBKDF2(password, salt);
|
||
* var key = CryptoJS.PBKDF2(password, salt, { keySize: 8 });
|
||
* var key = CryptoJS.PBKDF2(password, salt, { keySize: 8, iterations: 1000 });
|
||
*/
|
||
C.PBKDF2 = function (password, salt, cfg) {
|
||
return PBKDF2.create(cfg).compute(password, salt);
|
||
};
|
||
}());
|
||
|
||
|
||
return CryptoJS.PBKDF2;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/rabbit-legacy.js":
|
||
/*!*************************************************!*\
|
||
!*** ./node_modules/crypto-js/rabbit-legacy.js ***!
|
||
\*************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./enc-base64 */ "./node_modules/crypto-js/enc-base64.js"), __webpack_require__(/*! ./md5 */ "./node_modules/crypto-js/md5.js"), __webpack_require__(/*! ./evpkdf */ "./node_modules/crypto-js/evpkdf.js"), __webpack_require__(/*! ./cipher-core */ "./node_modules/crypto-js/cipher-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function () {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var StreamCipher = C_lib.StreamCipher;
|
||
var C_algo = C.algo;
|
||
|
||
// Reusable objects
|
||
var S = [];
|
||
var C_ = [];
|
||
var G = [];
|
||
|
||
/**
|
||
* Rabbit stream cipher algorithm.
|
||
*
|
||
* This is a legacy version that neglected to convert the key to little-endian.
|
||
* This error doesn't affect the cipher's security,
|
||
* but it does affect its compatibility with other implementations.
|
||
*/
|
||
var RabbitLegacy = C_algo.RabbitLegacy = StreamCipher.extend({
|
||
_doReset: function () {
|
||
// Shortcuts
|
||
var K = this._key.words;
|
||
var iv = this.cfg.iv;
|
||
|
||
// Generate initial state values
|
||
var X = this._X = [
|
||
K[0], (K[3] << 16) | (K[2] >>> 16),
|
||
K[1], (K[0] << 16) | (K[3] >>> 16),
|
||
K[2], (K[1] << 16) | (K[0] >>> 16),
|
||
K[3], (K[2] << 16) | (K[1] >>> 16)
|
||
];
|
||
|
||
// Generate initial counter values
|
||
var C = this._C = [
|
||
(K[2] << 16) | (K[2] >>> 16), (K[0] & 0xffff0000) | (K[1] & 0x0000ffff),
|
||
(K[3] << 16) | (K[3] >>> 16), (K[1] & 0xffff0000) | (K[2] & 0x0000ffff),
|
||
(K[0] << 16) | (K[0] >>> 16), (K[2] & 0xffff0000) | (K[3] & 0x0000ffff),
|
||
(K[1] << 16) | (K[1] >>> 16), (K[3] & 0xffff0000) | (K[0] & 0x0000ffff)
|
||
];
|
||
|
||
// Carry bit
|
||
this._b = 0;
|
||
|
||
// Iterate the system four times
|
||
for (var i = 0; i < 4; i++) {
|
||
nextState.call(this);
|
||
}
|
||
|
||
// Modify the counters
|
||
for (var i = 0; i < 8; i++) {
|
||
C[i] ^= X[(i + 4) & 7];
|
||
}
|
||
|
||
// IV setup
|
||
if (iv) {
|
||
// Shortcuts
|
||
var IV = iv.words;
|
||
var IV_0 = IV[0];
|
||
var IV_1 = IV[1];
|
||
|
||
// Generate four subvectors
|
||
var i0 = (((IV_0 << 8) | (IV_0 >>> 24)) & 0x00ff00ff) | (((IV_0 << 24) | (IV_0 >>> 8)) & 0xff00ff00);
|
||
var i2 = (((IV_1 << 8) | (IV_1 >>> 24)) & 0x00ff00ff) | (((IV_1 << 24) | (IV_1 >>> 8)) & 0xff00ff00);
|
||
var i1 = (i0 >>> 16) | (i2 & 0xffff0000);
|
||
var i3 = (i2 << 16) | (i0 & 0x0000ffff);
|
||
|
||
// Modify counter values
|
||
C[0] ^= i0;
|
||
C[1] ^= i1;
|
||
C[2] ^= i2;
|
||
C[3] ^= i3;
|
||
C[4] ^= i0;
|
||
C[5] ^= i1;
|
||
C[6] ^= i2;
|
||
C[7] ^= i3;
|
||
|
||
// Iterate the system four times
|
||
for (var i = 0; i < 4; i++) {
|
||
nextState.call(this);
|
||
}
|
||
}
|
||
},
|
||
|
||
_doProcessBlock: function (M, offset) {
|
||
// Shortcut
|
||
var X = this._X;
|
||
|
||
// Iterate the system
|
||
nextState.call(this);
|
||
|
||
// Generate four keystream words
|
||
S[0] = X[0] ^ (X[5] >>> 16) ^ (X[3] << 16);
|
||
S[1] = X[2] ^ (X[7] >>> 16) ^ (X[5] << 16);
|
||
S[2] = X[4] ^ (X[1] >>> 16) ^ (X[7] << 16);
|
||
S[3] = X[6] ^ (X[3] >>> 16) ^ (X[1] << 16);
|
||
|
||
for (var i = 0; i < 4; i++) {
|
||
// Swap endian
|
||
S[i] = (((S[i] << 8) | (S[i] >>> 24)) & 0x00ff00ff) |
|
||
(((S[i] << 24) | (S[i] >>> 8)) & 0xff00ff00);
|
||
|
||
// Encrypt
|
||
M[offset + i] ^= S[i];
|
||
}
|
||
},
|
||
|
||
blockSize: 128/32,
|
||
|
||
ivSize: 64/32
|
||
});
|
||
|
||
function nextState() {
|
||
// Shortcuts
|
||
var X = this._X;
|
||
var C = this._C;
|
||
|
||
// Save old counter values
|
||
for (var i = 0; i < 8; i++) {
|
||
C_[i] = C[i];
|
||
}
|
||
|
||
// Calculate new counter values
|
||
C[0] = (C[0] + 0x4d34d34d + this._b) | 0;
|
||
C[1] = (C[1] + 0xd34d34d3 + ((C[0] >>> 0) < (C_[0] >>> 0) ? 1 : 0)) | 0;
|
||
C[2] = (C[2] + 0x34d34d34 + ((C[1] >>> 0) < (C_[1] >>> 0) ? 1 : 0)) | 0;
|
||
C[3] = (C[3] + 0x4d34d34d + ((C[2] >>> 0) < (C_[2] >>> 0) ? 1 : 0)) | 0;
|
||
C[4] = (C[4] + 0xd34d34d3 + ((C[3] >>> 0) < (C_[3] >>> 0) ? 1 : 0)) | 0;
|
||
C[5] = (C[5] + 0x34d34d34 + ((C[4] >>> 0) < (C_[4] >>> 0) ? 1 : 0)) | 0;
|
||
C[6] = (C[6] + 0x4d34d34d + ((C[5] >>> 0) < (C_[5] >>> 0) ? 1 : 0)) | 0;
|
||
C[7] = (C[7] + 0xd34d34d3 + ((C[6] >>> 0) < (C_[6] >>> 0) ? 1 : 0)) | 0;
|
||
this._b = (C[7] >>> 0) < (C_[7] >>> 0) ? 1 : 0;
|
||
|
||
// Calculate the g-values
|
||
for (var i = 0; i < 8; i++) {
|
||
var gx = X[i] + C[i];
|
||
|
||
// Construct high and low argument for squaring
|
||
var ga = gx & 0xffff;
|
||
var gb = gx >>> 16;
|
||
|
||
// Calculate high and low result of squaring
|
||
var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb;
|
||
var gl = (((gx & 0xffff0000) * gx) | 0) + (((gx & 0x0000ffff) * gx) | 0);
|
||
|
||
// High XOR low
|
||
G[i] = gh ^ gl;
|
||
}
|
||
|
||
// Calculate new state values
|
||
X[0] = (G[0] + ((G[7] << 16) | (G[7] >>> 16)) + ((G[6] << 16) | (G[6] >>> 16))) | 0;
|
||
X[1] = (G[1] + ((G[0] << 8) | (G[0] >>> 24)) + G[7]) | 0;
|
||
X[2] = (G[2] + ((G[1] << 16) | (G[1] >>> 16)) + ((G[0] << 16) | (G[0] >>> 16))) | 0;
|
||
X[3] = (G[3] + ((G[2] << 8) | (G[2] >>> 24)) + G[1]) | 0;
|
||
X[4] = (G[4] + ((G[3] << 16) | (G[3] >>> 16)) + ((G[2] << 16) | (G[2] >>> 16))) | 0;
|
||
X[5] = (G[5] + ((G[4] << 8) | (G[4] >>> 24)) + G[3]) | 0;
|
||
X[6] = (G[6] + ((G[5] << 16) | (G[5] >>> 16)) + ((G[4] << 16) | (G[4] >>> 16))) | 0;
|
||
X[7] = (G[7] + ((G[6] << 8) | (G[6] >>> 24)) + G[5]) | 0;
|
||
}
|
||
|
||
/**
|
||
* Shortcut functions to the cipher's object interface.
|
||
*
|
||
* @example
|
||
*
|
||
* var ciphertext = CryptoJS.RabbitLegacy.encrypt(message, key, cfg);
|
||
* var plaintext = CryptoJS.RabbitLegacy.decrypt(ciphertext, key, cfg);
|
||
*/
|
||
C.RabbitLegacy = StreamCipher._createHelper(RabbitLegacy);
|
||
}());
|
||
|
||
|
||
return CryptoJS.RabbitLegacy;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/rabbit.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/crypto-js/rabbit.js ***!
|
||
\******************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./enc-base64 */ "./node_modules/crypto-js/enc-base64.js"), __webpack_require__(/*! ./md5 */ "./node_modules/crypto-js/md5.js"), __webpack_require__(/*! ./evpkdf */ "./node_modules/crypto-js/evpkdf.js"), __webpack_require__(/*! ./cipher-core */ "./node_modules/crypto-js/cipher-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function () {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var StreamCipher = C_lib.StreamCipher;
|
||
var C_algo = C.algo;
|
||
|
||
// Reusable objects
|
||
var S = [];
|
||
var C_ = [];
|
||
var G = [];
|
||
|
||
/**
|
||
* Rabbit stream cipher algorithm
|
||
*/
|
||
var Rabbit = C_algo.Rabbit = StreamCipher.extend({
|
||
_doReset: function () {
|
||
// Shortcuts
|
||
var K = this._key.words;
|
||
var iv = this.cfg.iv;
|
||
|
||
// Swap endian
|
||
for (var i = 0; i < 4; i++) {
|
||
K[i] = (((K[i] << 8) | (K[i] >>> 24)) & 0x00ff00ff) |
|
||
(((K[i] << 24) | (K[i] >>> 8)) & 0xff00ff00);
|
||
}
|
||
|
||
// Generate initial state values
|
||
var X = this._X = [
|
||
K[0], (K[3] << 16) | (K[2] >>> 16),
|
||
K[1], (K[0] << 16) | (K[3] >>> 16),
|
||
K[2], (K[1] << 16) | (K[0] >>> 16),
|
||
K[3], (K[2] << 16) | (K[1] >>> 16)
|
||
];
|
||
|
||
// Generate initial counter values
|
||
var C = this._C = [
|
||
(K[2] << 16) | (K[2] >>> 16), (K[0] & 0xffff0000) | (K[1] & 0x0000ffff),
|
||
(K[3] << 16) | (K[3] >>> 16), (K[1] & 0xffff0000) | (K[2] & 0x0000ffff),
|
||
(K[0] << 16) | (K[0] >>> 16), (K[2] & 0xffff0000) | (K[3] & 0x0000ffff),
|
||
(K[1] << 16) | (K[1] >>> 16), (K[3] & 0xffff0000) | (K[0] & 0x0000ffff)
|
||
];
|
||
|
||
// Carry bit
|
||
this._b = 0;
|
||
|
||
// Iterate the system four times
|
||
for (var i = 0; i < 4; i++) {
|
||
nextState.call(this);
|
||
}
|
||
|
||
// Modify the counters
|
||
for (var i = 0; i < 8; i++) {
|
||
C[i] ^= X[(i + 4) & 7];
|
||
}
|
||
|
||
// IV setup
|
||
if (iv) {
|
||
// Shortcuts
|
||
var IV = iv.words;
|
||
var IV_0 = IV[0];
|
||
var IV_1 = IV[1];
|
||
|
||
// Generate four subvectors
|
||
var i0 = (((IV_0 << 8) | (IV_0 >>> 24)) & 0x00ff00ff) | (((IV_0 << 24) | (IV_0 >>> 8)) & 0xff00ff00);
|
||
var i2 = (((IV_1 << 8) | (IV_1 >>> 24)) & 0x00ff00ff) | (((IV_1 << 24) | (IV_1 >>> 8)) & 0xff00ff00);
|
||
var i1 = (i0 >>> 16) | (i2 & 0xffff0000);
|
||
var i3 = (i2 << 16) | (i0 & 0x0000ffff);
|
||
|
||
// Modify counter values
|
||
C[0] ^= i0;
|
||
C[1] ^= i1;
|
||
C[2] ^= i2;
|
||
C[3] ^= i3;
|
||
C[4] ^= i0;
|
||
C[5] ^= i1;
|
||
C[6] ^= i2;
|
||
C[7] ^= i3;
|
||
|
||
// Iterate the system four times
|
||
for (var i = 0; i < 4; i++) {
|
||
nextState.call(this);
|
||
}
|
||
}
|
||
},
|
||
|
||
_doProcessBlock: function (M, offset) {
|
||
// Shortcut
|
||
var X = this._X;
|
||
|
||
// Iterate the system
|
||
nextState.call(this);
|
||
|
||
// Generate four keystream words
|
||
S[0] = X[0] ^ (X[5] >>> 16) ^ (X[3] << 16);
|
||
S[1] = X[2] ^ (X[7] >>> 16) ^ (X[5] << 16);
|
||
S[2] = X[4] ^ (X[1] >>> 16) ^ (X[7] << 16);
|
||
S[3] = X[6] ^ (X[3] >>> 16) ^ (X[1] << 16);
|
||
|
||
for (var i = 0; i < 4; i++) {
|
||
// Swap endian
|
||
S[i] = (((S[i] << 8) | (S[i] >>> 24)) & 0x00ff00ff) |
|
||
(((S[i] << 24) | (S[i] >>> 8)) & 0xff00ff00);
|
||
|
||
// Encrypt
|
||
M[offset + i] ^= S[i];
|
||
}
|
||
},
|
||
|
||
blockSize: 128/32,
|
||
|
||
ivSize: 64/32
|
||
});
|
||
|
||
function nextState() {
|
||
// Shortcuts
|
||
var X = this._X;
|
||
var C = this._C;
|
||
|
||
// Save old counter values
|
||
for (var i = 0; i < 8; i++) {
|
||
C_[i] = C[i];
|
||
}
|
||
|
||
// Calculate new counter values
|
||
C[0] = (C[0] + 0x4d34d34d + this._b) | 0;
|
||
C[1] = (C[1] + 0xd34d34d3 + ((C[0] >>> 0) < (C_[0] >>> 0) ? 1 : 0)) | 0;
|
||
C[2] = (C[2] + 0x34d34d34 + ((C[1] >>> 0) < (C_[1] >>> 0) ? 1 : 0)) | 0;
|
||
C[3] = (C[3] + 0x4d34d34d + ((C[2] >>> 0) < (C_[2] >>> 0) ? 1 : 0)) | 0;
|
||
C[4] = (C[4] + 0xd34d34d3 + ((C[3] >>> 0) < (C_[3] >>> 0) ? 1 : 0)) | 0;
|
||
C[5] = (C[5] + 0x34d34d34 + ((C[4] >>> 0) < (C_[4] >>> 0) ? 1 : 0)) | 0;
|
||
C[6] = (C[6] + 0x4d34d34d + ((C[5] >>> 0) < (C_[5] >>> 0) ? 1 : 0)) | 0;
|
||
C[7] = (C[7] + 0xd34d34d3 + ((C[6] >>> 0) < (C_[6] >>> 0) ? 1 : 0)) | 0;
|
||
this._b = (C[7] >>> 0) < (C_[7] >>> 0) ? 1 : 0;
|
||
|
||
// Calculate the g-values
|
||
for (var i = 0; i < 8; i++) {
|
||
var gx = X[i] + C[i];
|
||
|
||
// Construct high and low argument for squaring
|
||
var ga = gx & 0xffff;
|
||
var gb = gx >>> 16;
|
||
|
||
// Calculate high and low result of squaring
|
||
var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb;
|
||
var gl = (((gx & 0xffff0000) * gx) | 0) + (((gx & 0x0000ffff) * gx) | 0);
|
||
|
||
// High XOR low
|
||
G[i] = gh ^ gl;
|
||
}
|
||
|
||
// Calculate new state values
|
||
X[0] = (G[0] + ((G[7] << 16) | (G[7] >>> 16)) + ((G[6] << 16) | (G[6] >>> 16))) | 0;
|
||
X[1] = (G[1] + ((G[0] << 8) | (G[0] >>> 24)) + G[7]) | 0;
|
||
X[2] = (G[2] + ((G[1] << 16) | (G[1] >>> 16)) + ((G[0] << 16) | (G[0] >>> 16))) | 0;
|
||
X[3] = (G[3] + ((G[2] << 8) | (G[2] >>> 24)) + G[1]) | 0;
|
||
X[4] = (G[4] + ((G[3] << 16) | (G[3] >>> 16)) + ((G[2] << 16) | (G[2] >>> 16))) | 0;
|
||
X[5] = (G[5] + ((G[4] << 8) | (G[4] >>> 24)) + G[3]) | 0;
|
||
X[6] = (G[6] + ((G[5] << 16) | (G[5] >>> 16)) + ((G[4] << 16) | (G[4] >>> 16))) | 0;
|
||
X[7] = (G[7] + ((G[6] << 8) | (G[6] >>> 24)) + G[5]) | 0;
|
||
}
|
||
|
||
/**
|
||
* Shortcut functions to the cipher's object interface.
|
||
*
|
||
* @example
|
||
*
|
||
* var ciphertext = CryptoJS.Rabbit.encrypt(message, key, cfg);
|
||
* var plaintext = CryptoJS.Rabbit.decrypt(ciphertext, key, cfg);
|
||
*/
|
||
C.Rabbit = StreamCipher._createHelper(Rabbit);
|
||
}());
|
||
|
||
|
||
return CryptoJS.Rabbit;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/rc4.js":
|
||
/*!***************************************!*\
|
||
!*** ./node_modules/crypto-js/rc4.js ***!
|
||
\***************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./enc-base64 */ "./node_modules/crypto-js/enc-base64.js"), __webpack_require__(/*! ./md5 */ "./node_modules/crypto-js/md5.js"), __webpack_require__(/*! ./evpkdf */ "./node_modules/crypto-js/evpkdf.js"), __webpack_require__(/*! ./cipher-core */ "./node_modules/crypto-js/cipher-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function () {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var StreamCipher = C_lib.StreamCipher;
|
||
var C_algo = C.algo;
|
||
|
||
/**
|
||
* RC4 stream cipher algorithm.
|
||
*/
|
||
var RC4 = C_algo.RC4 = StreamCipher.extend({
|
||
_doReset: function () {
|
||
// Shortcuts
|
||
var key = this._key;
|
||
var keyWords = key.words;
|
||
var keySigBytes = key.sigBytes;
|
||
|
||
// Init sbox
|
||
var S = this._S = [];
|
||
for (var i = 0; i < 256; i++) {
|
||
S[i] = i;
|
||
}
|
||
|
||
// Key setup
|
||
for (var i = 0, j = 0; i < 256; i++) {
|
||
var keyByteIndex = i % keySigBytes;
|
||
var keyByte = (keyWords[keyByteIndex >>> 2] >>> (24 - (keyByteIndex % 4) * 8)) & 0xff;
|
||
|
||
j = (j + S[i] + keyByte) % 256;
|
||
|
||
// Swap
|
||
var t = S[i];
|
||
S[i] = S[j];
|
||
S[j] = t;
|
||
}
|
||
|
||
// Counters
|
||
this._i = this._j = 0;
|
||
},
|
||
|
||
_doProcessBlock: function (M, offset) {
|
||
M[offset] ^= generateKeystreamWord.call(this);
|
||
},
|
||
|
||
keySize: 256/32,
|
||
|
||
ivSize: 0
|
||
});
|
||
|
||
function generateKeystreamWord() {
|
||
// Shortcuts
|
||
var S = this._S;
|
||
var i = this._i;
|
||
var j = this._j;
|
||
|
||
// Generate keystream word
|
||
var keystreamWord = 0;
|
||
for (var n = 0; n < 4; n++) {
|
||
i = (i + 1) % 256;
|
||
j = (j + S[i]) % 256;
|
||
|
||
// Swap
|
||
var t = S[i];
|
||
S[i] = S[j];
|
||
S[j] = t;
|
||
|
||
keystreamWord |= S[(S[i] + S[j]) % 256] << (24 - n * 8);
|
||
}
|
||
|
||
// Update counters
|
||
this._i = i;
|
||
this._j = j;
|
||
|
||
return keystreamWord;
|
||
}
|
||
|
||
/**
|
||
* Shortcut functions to the cipher's object interface.
|
||
*
|
||
* @example
|
||
*
|
||
* var ciphertext = CryptoJS.RC4.encrypt(message, key, cfg);
|
||
* var plaintext = CryptoJS.RC4.decrypt(ciphertext, key, cfg);
|
||
*/
|
||
C.RC4 = StreamCipher._createHelper(RC4);
|
||
|
||
/**
|
||
* Modified RC4 stream cipher algorithm.
|
||
*/
|
||
var RC4Drop = C_algo.RC4Drop = RC4.extend({
|
||
/**
|
||
* Configuration options.
|
||
*
|
||
* @property {number} drop The number of keystream words to drop. Default 192
|
||
*/
|
||
cfg: RC4.cfg.extend({
|
||
drop: 192
|
||
}),
|
||
|
||
_doReset: function () {
|
||
RC4._doReset.call(this);
|
||
|
||
// Drop
|
||
for (var i = this.cfg.drop; i > 0; i--) {
|
||
generateKeystreamWord.call(this);
|
||
}
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Shortcut functions to the cipher's object interface.
|
||
*
|
||
* @example
|
||
*
|
||
* var ciphertext = CryptoJS.RC4Drop.encrypt(message, key, cfg);
|
||
* var plaintext = CryptoJS.RC4Drop.decrypt(ciphertext, key, cfg);
|
||
*/
|
||
C.RC4Drop = StreamCipher._createHelper(RC4Drop);
|
||
}());
|
||
|
||
|
||
return CryptoJS.RC4;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/ripemd160.js":
|
||
/*!*********************************************!*\
|
||
!*** ./node_modules/crypto-js/ripemd160.js ***!
|
||
\*********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
/** @preserve
|
||
(c) 2012 by Cédric Mesnil. All rights reserved.
|
||
|
||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||
|
||
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
*/
|
||
|
||
(function (Math) {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var WordArray = C_lib.WordArray;
|
||
var Hasher = C_lib.Hasher;
|
||
var C_algo = C.algo;
|
||
|
||
// Constants table
|
||
var _zl = WordArray.create([
|
||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||
7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
|
||
3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
|
||
1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
|
||
4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13]);
|
||
var _zr = WordArray.create([
|
||
5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
|
||
6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
|
||
15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
|
||
8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
|
||
12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11]);
|
||
var _sl = WordArray.create([
|
||
11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
|
||
7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
|
||
11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
|
||
11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
|
||
9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 ]);
|
||
var _sr = WordArray.create([
|
||
8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
|
||
9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
|
||
9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
|
||
15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
|
||
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 ]);
|
||
|
||
var _hl = WordArray.create([ 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E]);
|
||
var _hr = WordArray.create([ 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000]);
|
||
|
||
/**
|
||
* RIPEMD160 hash algorithm.
|
||
*/
|
||
var RIPEMD160 = C_algo.RIPEMD160 = Hasher.extend({
|
||
_doReset: function () {
|
||
this._hash = WordArray.create([0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]);
|
||
},
|
||
|
||
_doProcessBlock: function (M, offset) {
|
||
|
||
// Swap endian
|
||
for (var i = 0; i < 16; i++) {
|
||
// Shortcuts
|
||
var offset_i = offset + i;
|
||
var M_offset_i = M[offset_i];
|
||
|
||
// Swap
|
||
M[offset_i] = (
|
||
(((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) |
|
||
(((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00)
|
||
);
|
||
}
|
||
// Shortcut
|
||
var H = this._hash.words;
|
||
var hl = _hl.words;
|
||
var hr = _hr.words;
|
||
var zl = _zl.words;
|
||
var zr = _zr.words;
|
||
var sl = _sl.words;
|
||
var sr = _sr.words;
|
||
|
||
// Working variables
|
||
var al, bl, cl, dl, el;
|
||
var ar, br, cr, dr, er;
|
||
|
||
ar = al = H[0];
|
||
br = bl = H[1];
|
||
cr = cl = H[2];
|
||
dr = dl = H[3];
|
||
er = el = H[4];
|
||
// Computation
|
||
var t;
|
||
for (var i = 0; i < 80; i += 1) {
|
||
t = (al + M[offset+zl[i]])|0;
|
||
if (i<16){
|
||
t += f1(bl,cl,dl) + hl[0];
|
||
} else if (i<32) {
|
||
t += f2(bl,cl,dl) + hl[1];
|
||
} else if (i<48) {
|
||
t += f3(bl,cl,dl) + hl[2];
|
||
} else if (i<64) {
|
||
t += f4(bl,cl,dl) + hl[3];
|
||
} else {// if (i<80) {
|
||
t += f5(bl,cl,dl) + hl[4];
|
||
}
|
||
t = t|0;
|
||
t = rotl(t,sl[i]);
|
||
t = (t+el)|0;
|
||
al = el;
|
||
el = dl;
|
||
dl = rotl(cl, 10);
|
||
cl = bl;
|
||
bl = t;
|
||
|
||
t = (ar + M[offset+zr[i]])|0;
|
||
if (i<16){
|
||
t += f5(br,cr,dr) + hr[0];
|
||
} else if (i<32) {
|
||
t += f4(br,cr,dr) + hr[1];
|
||
} else if (i<48) {
|
||
t += f3(br,cr,dr) + hr[2];
|
||
} else if (i<64) {
|
||
t += f2(br,cr,dr) + hr[3];
|
||
} else {// if (i<80) {
|
||
t += f1(br,cr,dr) + hr[4];
|
||
}
|
||
t = t|0;
|
||
t = rotl(t,sr[i]) ;
|
||
t = (t+er)|0;
|
||
ar = er;
|
||
er = dr;
|
||
dr = rotl(cr, 10);
|
||
cr = br;
|
||
br = t;
|
||
}
|
||
// Intermediate hash value
|
||
t = (H[1] + cl + dr)|0;
|
||
H[1] = (H[2] + dl + er)|0;
|
||
H[2] = (H[3] + el + ar)|0;
|
||
H[3] = (H[4] + al + br)|0;
|
||
H[4] = (H[0] + bl + cr)|0;
|
||
H[0] = t;
|
||
},
|
||
|
||
_doFinalize: function () {
|
||
// Shortcuts
|
||
var data = this._data;
|
||
var dataWords = data.words;
|
||
|
||
var nBitsTotal = this._nDataBytes * 8;
|
||
var nBitsLeft = data.sigBytes * 8;
|
||
|
||
// Add padding
|
||
dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
|
||
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (
|
||
(((nBitsTotal << 8) | (nBitsTotal >>> 24)) & 0x00ff00ff) |
|
||
(((nBitsTotal << 24) | (nBitsTotal >>> 8)) & 0xff00ff00)
|
||
);
|
||
data.sigBytes = (dataWords.length + 1) * 4;
|
||
|
||
// Hash final blocks
|
||
this._process();
|
||
|
||
// Shortcuts
|
||
var hash = this._hash;
|
||
var H = hash.words;
|
||
|
||
// Swap endian
|
||
for (var i = 0; i < 5; i++) {
|
||
// Shortcut
|
||
var H_i = H[i];
|
||
|
||
// Swap
|
||
H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) |
|
||
(((H_i << 24) | (H_i >>> 8)) & 0xff00ff00);
|
||
}
|
||
|
||
// Return final computed hash
|
||
return hash;
|
||
},
|
||
|
||
clone: function () {
|
||
var clone = Hasher.clone.call(this);
|
||
clone._hash = this._hash.clone();
|
||
|
||
return clone;
|
||
}
|
||
});
|
||
|
||
|
||
function f1(x, y, z) {
|
||
return ((x) ^ (y) ^ (z));
|
||
|
||
}
|
||
|
||
function f2(x, y, z) {
|
||
return (((x)&(y)) | ((~x)&(z)));
|
||
}
|
||
|
||
function f3(x, y, z) {
|
||
return (((x) | (~(y))) ^ (z));
|
||
}
|
||
|
||
function f4(x, y, z) {
|
||
return (((x) & (z)) | ((y)&(~(z))));
|
||
}
|
||
|
||
function f5(x, y, z) {
|
||
return ((x) ^ ((y) |(~(z))));
|
||
|
||
}
|
||
|
||
function rotl(x,n) {
|
||
return (x<<n) | (x>>>(32-n));
|
||
}
|
||
|
||
|
||
/**
|
||
* Shortcut function to the hasher's object interface.
|
||
*
|
||
* @param {WordArray|string} message The message to hash.
|
||
*
|
||
* @return {WordArray} The hash.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hash = CryptoJS.RIPEMD160('message');
|
||
* var hash = CryptoJS.RIPEMD160(wordArray);
|
||
*/
|
||
C.RIPEMD160 = Hasher._createHelper(RIPEMD160);
|
||
|
||
/**
|
||
* Shortcut function to the HMAC's object interface.
|
||
*
|
||
* @param {WordArray|string} message The message to hash.
|
||
* @param {WordArray|string} key The secret key.
|
||
*
|
||
* @return {WordArray} The HMAC.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hmac = CryptoJS.HmacRIPEMD160(message, key);
|
||
*/
|
||
C.HmacRIPEMD160 = Hasher._createHmacHelper(RIPEMD160);
|
||
}(Math));
|
||
|
||
|
||
return CryptoJS.RIPEMD160;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/sha1.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/crypto-js/sha1.js ***!
|
||
\****************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function () {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var WordArray = C_lib.WordArray;
|
||
var Hasher = C_lib.Hasher;
|
||
var C_algo = C.algo;
|
||
|
||
// Reusable object
|
||
var W = [];
|
||
|
||
/**
|
||
* SHA-1 hash algorithm.
|
||
*/
|
||
var SHA1 = C_algo.SHA1 = Hasher.extend({
|
||
_doReset: function () {
|
||
this._hash = new WordArray.init([
|
||
0x67452301, 0xefcdab89,
|
||
0x98badcfe, 0x10325476,
|
||
0xc3d2e1f0
|
||
]);
|
||
},
|
||
|
||
_doProcessBlock: function (M, offset) {
|
||
// Shortcut
|
||
var H = this._hash.words;
|
||
|
||
// Working variables
|
||
var a = H[0];
|
||
var b = H[1];
|
||
var c = H[2];
|
||
var d = H[3];
|
||
var e = H[4];
|
||
|
||
// Computation
|
||
for (var i = 0; i < 80; i++) {
|
||
if (i < 16) {
|
||
W[i] = M[offset + i] | 0;
|
||
} else {
|
||
var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
|
||
W[i] = (n << 1) | (n >>> 31);
|
||
}
|
||
|
||
var t = ((a << 5) | (a >>> 27)) + e + W[i];
|
||
if (i < 20) {
|
||
t += ((b & c) | (~b & d)) + 0x5a827999;
|
||
} else if (i < 40) {
|
||
t += (b ^ c ^ d) + 0x6ed9eba1;
|
||
} else if (i < 60) {
|
||
t += ((b & c) | (b & d) | (c & d)) - 0x70e44324;
|
||
} else /* if (i < 80) */ {
|
||
t += (b ^ c ^ d) - 0x359d3e2a;
|
||
}
|
||
|
||
e = d;
|
||
d = c;
|
||
c = (b << 30) | (b >>> 2);
|
||
b = a;
|
||
a = t;
|
||
}
|
||
|
||
// Intermediate hash value
|
||
H[0] = (H[0] + a) | 0;
|
||
H[1] = (H[1] + b) | 0;
|
||
H[2] = (H[2] + c) | 0;
|
||
H[3] = (H[3] + d) | 0;
|
||
H[4] = (H[4] + e) | 0;
|
||
},
|
||
|
||
_doFinalize: function () {
|
||
// Shortcuts
|
||
var data = this._data;
|
||
var dataWords = data.words;
|
||
|
||
var nBitsTotal = this._nDataBytes * 8;
|
||
var nBitsLeft = data.sigBytes * 8;
|
||
|
||
// Add padding
|
||
dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
|
||
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);
|
||
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;
|
||
data.sigBytes = dataWords.length * 4;
|
||
|
||
// Hash final blocks
|
||
this._process();
|
||
|
||
// Return final computed hash
|
||
return this._hash;
|
||
},
|
||
|
||
clone: function () {
|
||
var clone = Hasher.clone.call(this);
|
||
clone._hash = this._hash.clone();
|
||
|
||
return clone;
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Shortcut function to the hasher's object interface.
|
||
*
|
||
* @param {WordArray|string} message The message to hash.
|
||
*
|
||
* @return {WordArray} The hash.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hash = CryptoJS.SHA1('message');
|
||
* var hash = CryptoJS.SHA1(wordArray);
|
||
*/
|
||
C.SHA1 = Hasher._createHelper(SHA1);
|
||
|
||
/**
|
||
* Shortcut function to the HMAC's object interface.
|
||
*
|
||
* @param {WordArray|string} message The message to hash.
|
||
* @param {WordArray|string} key The secret key.
|
||
*
|
||
* @return {WordArray} The HMAC.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hmac = CryptoJS.HmacSHA1(message, key);
|
||
*/
|
||
C.HmacSHA1 = Hasher._createHmacHelper(SHA1);
|
||
}());
|
||
|
||
|
||
return CryptoJS.SHA1;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/sha224.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/crypto-js/sha224.js ***!
|
||
\******************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./sha256 */ "./node_modules/crypto-js/sha256.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function () {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var WordArray = C_lib.WordArray;
|
||
var C_algo = C.algo;
|
||
var SHA256 = C_algo.SHA256;
|
||
|
||
/**
|
||
* SHA-224 hash algorithm.
|
||
*/
|
||
var SHA224 = C_algo.SHA224 = SHA256.extend({
|
||
_doReset: function () {
|
||
this._hash = new WordArray.init([
|
||
0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
|
||
0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
|
||
]);
|
||
},
|
||
|
||
_doFinalize: function () {
|
||
var hash = SHA256._doFinalize.call(this);
|
||
|
||
hash.sigBytes -= 4;
|
||
|
||
return hash;
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Shortcut function to the hasher's object interface.
|
||
*
|
||
* @param {WordArray|string} message The message to hash.
|
||
*
|
||
* @return {WordArray} The hash.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hash = CryptoJS.SHA224('message');
|
||
* var hash = CryptoJS.SHA224(wordArray);
|
||
*/
|
||
C.SHA224 = SHA256._createHelper(SHA224);
|
||
|
||
/**
|
||
* Shortcut function to the HMAC's object interface.
|
||
*
|
||
* @param {WordArray|string} message The message to hash.
|
||
* @param {WordArray|string} key The secret key.
|
||
*
|
||
* @return {WordArray} The HMAC.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hmac = CryptoJS.HmacSHA224(message, key);
|
||
*/
|
||
C.HmacSHA224 = SHA256._createHmacHelper(SHA224);
|
||
}());
|
||
|
||
|
||
return CryptoJS.SHA224;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/sha256.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/crypto-js/sha256.js ***!
|
||
\******************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function (Math) {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var WordArray = C_lib.WordArray;
|
||
var Hasher = C_lib.Hasher;
|
||
var C_algo = C.algo;
|
||
|
||
// Initialization and round constants tables
|
||
var H = [];
|
||
var K = [];
|
||
|
||
// Compute constants
|
||
(function () {
|
||
function isPrime(n) {
|
||
var sqrtN = Math.sqrt(n);
|
||
for (var factor = 2; factor <= sqrtN; factor++) {
|
||
if (!(n % factor)) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
function getFractionalBits(n) {
|
||
return ((n - (n | 0)) * 0x100000000) | 0;
|
||
}
|
||
|
||
var n = 2;
|
||
var nPrime = 0;
|
||
while (nPrime < 64) {
|
||
if (isPrime(n)) {
|
||
if (nPrime < 8) {
|
||
H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2));
|
||
}
|
||
K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3));
|
||
|
||
nPrime++;
|
||
}
|
||
|
||
n++;
|
||
}
|
||
}());
|
||
|
||
// Reusable object
|
||
var W = [];
|
||
|
||
/**
|
||
* SHA-256 hash algorithm.
|
||
*/
|
||
var SHA256 = C_algo.SHA256 = Hasher.extend({
|
||
_doReset: function () {
|
||
this._hash = new WordArray.init(H.slice(0));
|
||
},
|
||
|
||
_doProcessBlock: function (M, offset) {
|
||
// Shortcut
|
||
var H = this._hash.words;
|
||
|
||
// Working variables
|
||
var a = H[0];
|
||
var b = H[1];
|
||
var c = H[2];
|
||
var d = H[3];
|
||
var e = H[4];
|
||
var f = H[5];
|
||
var g = H[6];
|
||
var h = H[7];
|
||
|
||
// Computation
|
||
for (var i = 0; i < 64; i++) {
|
||
if (i < 16) {
|
||
W[i] = M[offset + i] | 0;
|
||
} else {
|
||
var gamma0x = W[i - 15];
|
||
var gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^
|
||
((gamma0x << 14) | (gamma0x >>> 18)) ^
|
||
(gamma0x >>> 3);
|
||
|
||
var gamma1x = W[i - 2];
|
||
var gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^
|
||
((gamma1x << 13) | (gamma1x >>> 19)) ^
|
||
(gamma1x >>> 10);
|
||
|
||
W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16];
|
||
}
|
||
|
||
var ch = (e & f) ^ (~e & g);
|
||
var maj = (a & b) ^ (a & c) ^ (b & c);
|
||
|
||
var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22));
|
||
var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25));
|
||
|
||
var t1 = h + sigma1 + ch + K[i] + W[i];
|
||
var t2 = sigma0 + maj;
|
||
|
||
h = g;
|
||
g = f;
|
||
f = e;
|
||
e = (d + t1) | 0;
|
||
d = c;
|
||
c = b;
|
||
b = a;
|
||
a = (t1 + t2) | 0;
|
||
}
|
||
|
||
// Intermediate hash value
|
||
H[0] = (H[0] + a) | 0;
|
||
H[1] = (H[1] + b) | 0;
|
||
H[2] = (H[2] + c) | 0;
|
||
H[3] = (H[3] + d) | 0;
|
||
H[4] = (H[4] + e) | 0;
|
||
H[5] = (H[5] + f) | 0;
|
||
H[6] = (H[6] + g) | 0;
|
||
H[7] = (H[7] + h) | 0;
|
||
},
|
||
|
||
_doFinalize: function () {
|
||
// Shortcuts
|
||
var data = this._data;
|
||
var dataWords = data.words;
|
||
|
||
var nBitsTotal = this._nDataBytes * 8;
|
||
var nBitsLeft = data.sigBytes * 8;
|
||
|
||
// Add padding
|
||
dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
|
||
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);
|
||
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;
|
||
data.sigBytes = dataWords.length * 4;
|
||
|
||
// Hash final blocks
|
||
this._process();
|
||
|
||
// Return final computed hash
|
||
return this._hash;
|
||
},
|
||
|
||
clone: function () {
|
||
var clone = Hasher.clone.call(this);
|
||
clone._hash = this._hash.clone();
|
||
|
||
return clone;
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Shortcut function to the hasher's object interface.
|
||
*
|
||
* @param {WordArray|string} message The message to hash.
|
||
*
|
||
* @return {WordArray} The hash.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hash = CryptoJS.SHA256('message');
|
||
* var hash = CryptoJS.SHA256(wordArray);
|
||
*/
|
||
C.SHA256 = Hasher._createHelper(SHA256);
|
||
|
||
/**
|
||
* Shortcut function to the HMAC's object interface.
|
||
*
|
||
* @param {WordArray|string} message The message to hash.
|
||
* @param {WordArray|string} key The secret key.
|
||
*
|
||
* @return {WordArray} The HMAC.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hmac = CryptoJS.HmacSHA256(message, key);
|
||
*/
|
||
C.HmacSHA256 = Hasher._createHmacHelper(SHA256);
|
||
}(Math));
|
||
|
||
|
||
return CryptoJS.SHA256;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/sha3.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/crypto-js/sha3.js ***!
|
||
\****************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./x64-core */ "./node_modules/crypto-js/x64-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function (Math) {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var WordArray = C_lib.WordArray;
|
||
var Hasher = C_lib.Hasher;
|
||
var C_x64 = C.x64;
|
||
var X64Word = C_x64.Word;
|
||
var C_algo = C.algo;
|
||
|
||
// Constants tables
|
||
var RHO_OFFSETS = [];
|
||
var PI_INDEXES = [];
|
||
var ROUND_CONSTANTS = [];
|
||
|
||
// Compute Constants
|
||
(function () {
|
||
// Compute rho offset constants
|
||
var x = 1, y = 0;
|
||
for (var t = 0; t < 24; t++) {
|
||
RHO_OFFSETS[x + 5 * y] = ((t + 1) * (t + 2) / 2) % 64;
|
||
|
||
var newX = y % 5;
|
||
var newY = (2 * x + 3 * y) % 5;
|
||
x = newX;
|
||
y = newY;
|
||
}
|
||
|
||
// Compute pi index constants
|
||
for (var x = 0; x < 5; x++) {
|
||
for (var y = 0; y < 5; y++) {
|
||
PI_INDEXES[x + 5 * y] = y + ((2 * x + 3 * y) % 5) * 5;
|
||
}
|
||
}
|
||
|
||
// Compute round constants
|
||
var LFSR = 0x01;
|
||
for (var i = 0; i < 24; i++) {
|
||
var roundConstantMsw = 0;
|
||
var roundConstantLsw = 0;
|
||
|
||
for (var j = 0; j < 7; j++) {
|
||
if (LFSR & 0x01) {
|
||
var bitPosition = (1 << j) - 1;
|
||
if (bitPosition < 32) {
|
||
roundConstantLsw ^= 1 << bitPosition;
|
||
} else /* if (bitPosition >= 32) */ {
|
||
roundConstantMsw ^= 1 << (bitPosition - 32);
|
||
}
|
||
}
|
||
|
||
// Compute next LFSR
|
||
if (LFSR & 0x80) {
|
||
// Primitive polynomial over GF(2): x^8 + x^6 + x^5 + x^4 + 1
|
||
LFSR = (LFSR << 1) ^ 0x71;
|
||
} else {
|
||
LFSR <<= 1;
|
||
}
|
||
}
|
||
|
||
ROUND_CONSTANTS[i] = X64Word.create(roundConstantMsw, roundConstantLsw);
|
||
}
|
||
}());
|
||
|
||
// Reusable objects for temporary values
|
||
var T = [];
|
||
(function () {
|
||
for (var i = 0; i < 25; i++) {
|
||
T[i] = X64Word.create();
|
||
}
|
||
}());
|
||
|
||
/**
|
||
* SHA-3 hash algorithm.
|
||
*/
|
||
var SHA3 = C_algo.SHA3 = Hasher.extend({
|
||
/**
|
||
* Configuration options.
|
||
*
|
||
* @property {number} outputLength
|
||
* The desired number of bits in the output hash.
|
||
* Only values permitted are: 224, 256, 384, 512.
|
||
* Default: 512
|
||
*/
|
||
cfg: Hasher.cfg.extend({
|
||
outputLength: 512
|
||
}),
|
||
|
||
_doReset: function () {
|
||
var state = this._state = []
|
||
for (var i = 0; i < 25; i++) {
|
||
state[i] = new X64Word.init();
|
||
}
|
||
|
||
this.blockSize = (1600 - 2 * this.cfg.outputLength) / 32;
|
||
},
|
||
|
||
_doProcessBlock: function (M, offset) {
|
||
// Shortcuts
|
||
var state = this._state;
|
||
var nBlockSizeLanes = this.blockSize / 2;
|
||
|
||
// Absorb
|
||
for (var i = 0; i < nBlockSizeLanes; i++) {
|
||
// Shortcuts
|
||
var M2i = M[offset + 2 * i];
|
||
var M2i1 = M[offset + 2 * i + 1];
|
||
|
||
// Swap endian
|
||
M2i = (
|
||
(((M2i << 8) | (M2i >>> 24)) & 0x00ff00ff) |
|
||
(((M2i << 24) | (M2i >>> 8)) & 0xff00ff00)
|
||
);
|
||
M2i1 = (
|
||
(((M2i1 << 8) | (M2i1 >>> 24)) & 0x00ff00ff) |
|
||
(((M2i1 << 24) | (M2i1 >>> 8)) & 0xff00ff00)
|
||
);
|
||
|
||
// Absorb message into state
|
||
var lane = state[i];
|
||
lane.high ^= M2i1;
|
||
lane.low ^= M2i;
|
||
}
|
||
|
||
// Rounds
|
||
for (var round = 0; round < 24; round++) {
|
||
// Theta
|
||
for (var x = 0; x < 5; x++) {
|
||
// Mix column lanes
|
||
var tMsw = 0, tLsw = 0;
|
||
for (var y = 0; y < 5; y++) {
|
||
var lane = state[x + 5 * y];
|
||
tMsw ^= lane.high;
|
||
tLsw ^= lane.low;
|
||
}
|
||
|
||
// Temporary values
|
||
var Tx = T[x];
|
||
Tx.high = tMsw;
|
||
Tx.low = tLsw;
|
||
}
|
||
for (var x = 0; x < 5; x++) {
|
||
// Shortcuts
|
||
var Tx4 = T[(x + 4) % 5];
|
||
var Tx1 = T[(x + 1) % 5];
|
||
var Tx1Msw = Tx1.high;
|
||
var Tx1Lsw = Tx1.low;
|
||
|
||
// Mix surrounding columns
|
||
var tMsw = Tx4.high ^ ((Tx1Msw << 1) | (Tx1Lsw >>> 31));
|
||
var tLsw = Tx4.low ^ ((Tx1Lsw << 1) | (Tx1Msw >>> 31));
|
||
for (var y = 0; y < 5; y++) {
|
||
var lane = state[x + 5 * y];
|
||
lane.high ^= tMsw;
|
||
lane.low ^= tLsw;
|
||
}
|
||
}
|
||
|
||
// Rho Pi
|
||
for (var laneIndex = 1; laneIndex < 25; laneIndex++) {
|
||
var tMsw;
|
||
var tLsw;
|
||
|
||
// Shortcuts
|
||
var lane = state[laneIndex];
|
||
var laneMsw = lane.high;
|
||
var laneLsw = lane.low;
|
||
var rhoOffset = RHO_OFFSETS[laneIndex];
|
||
|
||
// Rotate lanes
|
||
if (rhoOffset < 32) {
|
||
tMsw = (laneMsw << rhoOffset) | (laneLsw >>> (32 - rhoOffset));
|
||
tLsw = (laneLsw << rhoOffset) | (laneMsw >>> (32 - rhoOffset));
|
||
} else /* if (rhoOffset >= 32) */ {
|
||
tMsw = (laneLsw << (rhoOffset - 32)) | (laneMsw >>> (64 - rhoOffset));
|
||
tLsw = (laneMsw << (rhoOffset - 32)) | (laneLsw >>> (64 - rhoOffset));
|
||
}
|
||
|
||
// Transpose lanes
|
||
var TPiLane = T[PI_INDEXES[laneIndex]];
|
||
TPiLane.high = tMsw;
|
||
TPiLane.low = tLsw;
|
||
}
|
||
|
||
// Rho pi at x = y = 0
|
||
var T0 = T[0];
|
||
var state0 = state[0];
|
||
T0.high = state0.high;
|
||
T0.low = state0.low;
|
||
|
||
// Chi
|
||
for (var x = 0; x < 5; x++) {
|
||
for (var y = 0; y < 5; y++) {
|
||
// Shortcuts
|
||
var laneIndex = x + 5 * y;
|
||
var lane = state[laneIndex];
|
||
var TLane = T[laneIndex];
|
||
var Tx1Lane = T[((x + 1) % 5) + 5 * y];
|
||
var Tx2Lane = T[((x + 2) % 5) + 5 * y];
|
||
|
||
// Mix rows
|
||
lane.high = TLane.high ^ (~Tx1Lane.high & Tx2Lane.high);
|
||
lane.low = TLane.low ^ (~Tx1Lane.low & Tx2Lane.low);
|
||
}
|
||
}
|
||
|
||
// Iota
|
||
var lane = state[0];
|
||
var roundConstant = ROUND_CONSTANTS[round];
|
||
lane.high ^= roundConstant.high;
|
||
lane.low ^= roundConstant.low;
|
||
}
|
||
},
|
||
|
||
_doFinalize: function () {
|
||
// Shortcuts
|
||
var data = this._data;
|
||
var dataWords = data.words;
|
||
var nBitsTotal = this._nDataBytes * 8;
|
||
var nBitsLeft = data.sigBytes * 8;
|
||
var blockSizeBits = this.blockSize * 32;
|
||
|
||
// Add padding
|
||
dataWords[nBitsLeft >>> 5] |= 0x1 << (24 - nBitsLeft % 32);
|
||
dataWords[((Math.ceil((nBitsLeft + 1) / blockSizeBits) * blockSizeBits) >>> 5) - 1] |= 0x80;
|
||
data.sigBytes = dataWords.length * 4;
|
||
|
||
// Hash final blocks
|
||
this._process();
|
||
|
||
// Shortcuts
|
||
var state = this._state;
|
||
var outputLengthBytes = this.cfg.outputLength / 8;
|
||
var outputLengthLanes = outputLengthBytes / 8;
|
||
|
||
// Squeeze
|
||
var hashWords = [];
|
||
for (var i = 0; i < outputLengthLanes; i++) {
|
||
// Shortcuts
|
||
var lane = state[i];
|
||
var laneMsw = lane.high;
|
||
var laneLsw = lane.low;
|
||
|
||
// Swap endian
|
||
laneMsw = (
|
||
(((laneMsw << 8) | (laneMsw >>> 24)) & 0x00ff00ff) |
|
||
(((laneMsw << 24) | (laneMsw >>> 8)) & 0xff00ff00)
|
||
);
|
||
laneLsw = (
|
||
(((laneLsw << 8) | (laneLsw >>> 24)) & 0x00ff00ff) |
|
||
(((laneLsw << 24) | (laneLsw >>> 8)) & 0xff00ff00)
|
||
);
|
||
|
||
// Squeeze state to retrieve hash
|
||
hashWords.push(laneLsw);
|
||
hashWords.push(laneMsw);
|
||
}
|
||
|
||
// Return final computed hash
|
||
return new WordArray.init(hashWords, outputLengthBytes);
|
||
},
|
||
|
||
clone: function () {
|
||
var clone = Hasher.clone.call(this);
|
||
|
||
var state = clone._state = this._state.slice(0);
|
||
for (var i = 0; i < 25; i++) {
|
||
state[i] = state[i].clone();
|
||
}
|
||
|
||
return clone;
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Shortcut function to the hasher's object interface.
|
||
*
|
||
* @param {WordArray|string} message The message to hash.
|
||
*
|
||
* @return {WordArray} The hash.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hash = CryptoJS.SHA3('message');
|
||
* var hash = CryptoJS.SHA3(wordArray);
|
||
*/
|
||
C.SHA3 = Hasher._createHelper(SHA3);
|
||
|
||
/**
|
||
* Shortcut function to the HMAC's object interface.
|
||
*
|
||
* @param {WordArray|string} message The message to hash.
|
||
* @param {WordArray|string} key The secret key.
|
||
*
|
||
* @return {WordArray} The HMAC.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hmac = CryptoJS.HmacSHA3(message, key);
|
||
*/
|
||
C.HmacSHA3 = Hasher._createHmacHelper(SHA3);
|
||
}(Math));
|
||
|
||
|
||
return CryptoJS.SHA3;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/sha384.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/crypto-js/sha384.js ***!
|
||
\******************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./x64-core */ "./node_modules/crypto-js/x64-core.js"), __webpack_require__(/*! ./sha512 */ "./node_modules/crypto-js/sha512.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function () {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_x64 = C.x64;
|
||
var X64Word = C_x64.Word;
|
||
var X64WordArray = C_x64.WordArray;
|
||
var C_algo = C.algo;
|
||
var SHA512 = C_algo.SHA512;
|
||
|
||
/**
|
||
* SHA-384 hash algorithm.
|
||
*/
|
||
var SHA384 = C_algo.SHA384 = SHA512.extend({
|
||
_doReset: function () {
|
||
this._hash = new X64WordArray.init([
|
||
new X64Word.init(0xcbbb9d5d, 0xc1059ed8), new X64Word.init(0x629a292a, 0x367cd507),
|
||
new X64Word.init(0x9159015a, 0x3070dd17), new X64Word.init(0x152fecd8, 0xf70e5939),
|
||
new X64Word.init(0x67332667, 0xffc00b31), new X64Word.init(0x8eb44a87, 0x68581511),
|
||
new X64Word.init(0xdb0c2e0d, 0x64f98fa7), new X64Word.init(0x47b5481d, 0xbefa4fa4)
|
||
]);
|
||
},
|
||
|
||
_doFinalize: function () {
|
||
var hash = SHA512._doFinalize.call(this);
|
||
|
||
hash.sigBytes -= 16;
|
||
|
||
return hash;
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Shortcut function to the hasher's object interface.
|
||
*
|
||
* @param {WordArray|string} message The message to hash.
|
||
*
|
||
* @return {WordArray} The hash.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hash = CryptoJS.SHA384('message');
|
||
* var hash = CryptoJS.SHA384(wordArray);
|
||
*/
|
||
C.SHA384 = SHA512._createHelper(SHA384);
|
||
|
||
/**
|
||
* Shortcut function to the HMAC's object interface.
|
||
*
|
||
* @param {WordArray|string} message The message to hash.
|
||
* @param {WordArray|string} key The secret key.
|
||
*
|
||
* @return {WordArray} The HMAC.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hmac = CryptoJS.HmacSHA384(message, key);
|
||
*/
|
||
C.HmacSHA384 = SHA512._createHmacHelper(SHA384);
|
||
}());
|
||
|
||
|
||
return CryptoJS.SHA384;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/sha512.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/crypto-js/sha512.js ***!
|
||
\******************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./x64-core */ "./node_modules/crypto-js/x64-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function () {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var Hasher = C_lib.Hasher;
|
||
var C_x64 = C.x64;
|
||
var X64Word = C_x64.Word;
|
||
var X64WordArray = C_x64.WordArray;
|
||
var C_algo = C.algo;
|
||
|
||
function X64Word_create() {
|
||
return X64Word.create.apply(X64Word, arguments);
|
||
}
|
||
|
||
// Constants
|
||
var K = [
|
||
X64Word_create(0x428a2f98, 0xd728ae22), X64Word_create(0x71374491, 0x23ef65cd),
|
||
X64Word_create(0xb5c0fbcf, 0xec4d3b2f), X64Word_create(0xe9b5dba5, 0x8189dbbc),
|
||
X64Word_create(0x3956c25b, 0xf348b538), X64Word_create(0x59f111f1, 0xb605d019),
|
||
X64Word_create(0x923f82a4, 0xaf194f9b), X64Word_create(0xab1c5ed5, 0xda6d8118),
|
||
X64Word_create(0xd807aa98, 0xa3030242), X64Word_create(0x12835b01, 0x45706fbe),
|
||
X64Word_create(0x243185be, 0x4ee4b28c), X64Word_create(0x550c7dc3, 0xd5ffb4e2),
|
||
X64Word_create(0x72be5d74, 0xf27b896f), X64Word_create(0x80deb1fe, 0x3b1696b1),
|
||
X64Word_create(0x9bdc06a7, 0x25c71235), X64Word_create(0xc19bf174, 0xcf692694),
|
||
X64Word_create(0xe49b69c1, 0x9ef14ad2), X64Word_create(0xefbe4786, 0x384f25e3),
|
||
X64Word_create(0x0fc19dc6, 0x8b8cd5b5), X64Word_create(0x240ca1cc, 0x77ac9c65),
|
||
X64Word_create(0x2de92c6f, 0x592b0275), X64Word_create(0x4a7484aa, 0x6ea6e483),
|
||
X64Word_create(0x5cb0a9dc, 0xbd41fbd4), X64Word_create(0x76f988da, 0x831153b5),
|
||
X64Word_create(0x983e5152, 0xee66dfab), X64Word_create(0xa831c66d, 0x2db43210),
|
||
X64Word_create(0xb00327c8, 0x98fb213f), X64Word_create(0xbf597fc7, 0xbeef0ee4),
|
||
X64Word_create(0xc6e00bf3, 0x3da88fc2), X64Word_create(0xd5a79147, 0x930aa725),
|
||
X64Word_create(0x06ca6351, 0xe003826f), X64Word_create(0x14292967, 0x0a0e6e70),
|
||
X64Word_create(0x27b70a85, 0x46d22ffc), X64Word_create(0x2e1b2138, 0x5c26c926),
|
||
X64Word_create(0x4d2c6dfc, 0x5ac42aed), X64Word_create(0x53380d13, 0x9d95b3df),
|
||
X64Word_create(0x650a7354, 0x8baf63de), X64Word_create(0x766a0abb, 0x3c77b2a8),
|
||
X64Word_create(0x81c2c92e, 0x47edaee6), X64Word_create(0x92722c85, 0x1482353b),
|
||
X64Word_create(0xa2bfe8a1, 0x4cf10364), X64Word_create(0xa81a664b, 0xbc423001),
|
||
X64Word_create(0xc24b8b70, 0xd0f89791), X64Word_create(0xc76c51a3, 0x0654be30),
|
||
X64Word_create(0xd192e819, 0xd6ef5218), X64Word_create(0xd6990624, 0x5565a910),
|
||
X64Word_create(0xf40e3585, 0x5771202a), X64Word_create(0x106aa070, 0x32bbd1b8),
|
||
X64Word_create(0x19a4c116, 0xb8d2d0c8), X64Word_create(0x1e376c08, 0x5141ab53),
|
||
X64Word_create(0x2748774c, 0xdf8eeb99), X64Word_create(0x34b0bcb5, 0xe19b48a8),
|
||
X64Word_create(0x391c0cb3, 0xc5c95a63), X64Word_create(0x4ed8aa4a, 0xe3418acb),
|
||
X64Word_create(0x5b9cca4f, 0x7763e373), X64Word_create(0x682e6ff3, 0xd6b2b8a3),
|
||
X64Word_create(0x748f82ee, 0x5defb2fc), X64Word_create(0x78a5636f, 0x43172f60),
|
||
X64Word_create(0x84c87814, 0xa1f0ab72), X64Word_create(0x8cc70208, 0x1a6439ec),
|
||
X64Word_create(0x90befffa, 0x23631e28), X64Word_create(0xa4506ceb, 0xde82bde9),
|
||
X64Word_create(0xbef9a3f7, 0xb2c67915), X64Word_create(0xc67178f2, 0xe372532b),
|
||
X64Word_create(0xca273ece, 0xea26619c), X64Word_create(0xd186b8c7, 0x21c0c207),
|
||
X64Word_create(0xeada7dd6, 0xcde0eb1e), X64Word_create(0xf57d4f7f, 0xee6ed178),
|
||
X64Word_create(0x06f067aa, 0x72176fba), X64Word_create(0x0a637dc5, 0xa2c898a6),
|
||
X64Word_create(0x113f9804, 0xbef90dae), X64Word_create(0x1b710b35, 0x131c471b),
|
||
X64Word_create(0x28db77f5, 0x23047d84), X64Word_create(0x32caab7b, 0x40c72493),
|
||
X64Word_create(0x3c9ebe0a, 0x15c9bebc), X64Word_create(0x431d67c4, 0x9c100d4c),
|
||
X64Word_create(0x4cc5d4be, 0xcb3e42b6), X64Word_create(0x597f299c, 0xfc657e2a),
|
||
X64Word_create(0x5fcb6fab, 0x3ad6faec), X64Word_create(0x6c44198c, 0x4a475817)
|
||
];
|
||
|
||
// Reusable objects
|
||
var W = [];
|
||
(function () {
|
||
for (var i = 0; i < 80; i++) {
|
||
W[i] = X64Word_create();
|
||
}
|
||
}());
|
||
|
||
/**
|
||
* SHA-512 hash algorithm.
|
||
*/
|
||
var SHA512 = C_algo.SHA512 = Hasher.extend({
|
||
_doReset: function () {
|
||
this._hash = new X64WordArray.init([
|
||
new X64Word.init(0x6a09e667, 0xf3bcc908), new X64Word.init(0xbb67ae85, 0x84caa73b),
|
||
new X64Word.init(0x3c6ef372, 0xfe94f82b), new X64Word.init(0xa54ff53a, 0x5f1d36f1),
|
||
new X64Word.init(0x510e527f, 0xade682d1), new X64Word.init(0x9b05688c, 0x2b3e6c1f),
|
||
new X64Word.init(0x1f83d9ab, 0xfb41bd6b), new X64Word.init(0x5be0cd19, 0x137e2179)
|
||
]);
|
||
},
|
||
|
||
_doProcessBlock: function (M, offset) {
|
||
// Shortcuts
|
||
var H = this._hash.words;
|
||
|
||
var H0 = H[0];
|
||
var H1 = H[1];
|
||
var H2 = H[2];
|
||
var H3 = H[3];
|
||
var H4 = H[4];
|
||
var H5 = H[5];
|
||
var H6 = H[6];
|
||
var H7 = H[7];
|
||
|
||
var H0h = H0.high;
|
||
var H0l = H0.low;
|
||
var H1h = H1.high;
|
||
var H1l = H1.low;
|
||
var H2h = H2.high;
|
||
var H2l = H2.low;
|
||
var H3h = H3.high;
|
||
var H3l = H3.low;
|
||
var H4h = H4.high;
|
||
var H4l = H4.low;
|
||
var H5h = H5.high;
|
||
var H5l = H5.low;
|
||
var H6h = H6.high;
|
||
var H6l = H6.low;
|
||
var H7h = H7.high;
|
||
var H7l = H7.low;
|
||
|
||
// Working variables
|
||
var ah = H0h;
|
||
var al = H0l;
|
||
var bh = H1h;
|
||
var bl = H1l;
|
||
var ch = H2h;
|
||
var cl = H2l;
|
||
var dh = H3h;
|
||
var dl = H3l;
|
||
var eh = H4h;
|
||
var el = H4l;
|
||
var fh = H5h;
|
||
var fl = H5l;
|
||
var gh = H6h;
|
||
var gl = H6l;
|
||
var hh = H7h;
|
||
var hl = H7l;
|
||
|
||
// Rounds
|
||
for (var i = 0; i < 80; i++) {
|
||
var Wil;
|
||
var Wih;
|
||
|
||
// Shortcut
|
||
var Wi = W[i];
|
||
|
||
// Extend message
|
||
if (i < 16) {
|
||
Wih = Wi.high = M[offset + i * 2] | 0;
|
||
Wil = Wi.low = M[offset + i * 2 + 1] | 0;
|
||
} else {
|
||
// Gamma0
|
||
var gamma0x = W[i - 15];
|
||
var gamma0xh = gamma0x.high;
|
||
var gamma0xl = gamma0x.low;
|
||
var gamma0h = ((gamma0xh >>> 1) | (gamma0xl << 31)) ^ ((gamma0xh >>> 8) | (gamma0xl << 24)) ^ (gamma0xh >>> 7);
|
||
var gamma0l = ((gamma0xl >>> 1) | (gamma0xh << 31)) ^ ((gamma0xl >>> 8) | (gamma0xh << 24)) ^ ((gamma0xl >>> 7) | (gamma0xh << 25));
|
||
|
||
// Gamma1
|
||
var gamma1x = W[i - 2];
|
||
var gamma1xh = gamma1x.high;
|
||
var gamma1xl = gamma1x.low;
|
||
var gamma1h = ((gamma1xh >>> 19) | (gamma1xl << 13)) ^ ((gamma1xh << 3) | (gamma1xl >>> 29)) ^ (gamma1xh >>> 6);
|
||
var gamma1l = ((gamma1xl >>> 19) | (gamma1xh << 13)) ^ ((gamma1xl << 3) | (gamma1xh >>> 29)) ^ ((gamma1xl >>> 6) | (gamma1xh << 26));
|
||
|
||
// W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]
|
||
var Wi7 = W[i - 7];
|
||
var Wi7h = Wi7.high;
|
||
var Wi7l = Wi7.low;
|
||
|
||
var Wi16 = W[i - 16];
|
||
var Wi16h = Wi16.high;
|
||
var Wi16l = Wi16.low;
|
||
|
||
Wil = gamma0l + Wi7l;
|
||
Wih = gamma0h + Wi7h + ((Wil >>> 0) < (gamma0l >>> 0) ? 1 : 0);
|
||
Wil = Wil + gamma1l;
|
||
Wih = Wih + gamma1h + ((Wil >>> 0) < (gamma1l >>> 0) ? 1 : 0);
|
||
Wil = Wil + Wi16l;
|
||
Wih = Wih + Wi16h + ((Wil >>> 0) < (Wi16l >>> 0) ? 1 : 0);
|
||
|
||
Wi.high = Wih;
|
||
Wi.low = Wil;
|
||
}
|
||
|
||
var chh = (eh & fh) ^ (~eh & gh);
|
||
var chl = (el & fl) ^ (~el & gl);
|
||
var majh = (ah & bh) ^ (ah & ch) ^ (bh & ch);
|
||
var majl = (al & bl) ^ (al & cl) ^ (bl & cl);
|
||
|
||
var sigma0h = ((ah >>> 28) | (al << 4)) ^ ((ah << 30) | (al >>> 2)) ^ ((ah << 25) | (al >>> 7));
|
||
var sigma0l = ((al >>> 28) | (ah << 4)) ^ ((al << 30) | (ah >>> 2)) ^ ((al << 25) | (ah >>> 7));
|
||
var sigma1h = ((eh >>> 14) | (el << 18)) ^ ((eh >>> 18) | (el << 14)) ^ ((eh << 23) | (el >>> 9));
|
||
var sigma1l = ((el >>> 14) | (eh << 18)) ^ ((el >>> 18) | (eh << 14)) ^ ((el << 23) | (eh >>> 9));
|
||
|
||
// t1 = h + sigma1 + ch + K[i] + W[i]
|
||
var Ki = K[i];
|
||
var Kih = Ki.high;
|
||
var Kil = Ki.low;
|
||
|
||
var t1l = hl + sigma1l;
|
||
var t1h = hh + sigma1h + ((t1l >>> 0) < (hl >>> 0) ? 1 : 0);
|
||
var t1l = t1l + chl;
|
||
var t1h = t1h + chh + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0);
|
||
var t1l = t1l + Kil;
|
||
var t1h = t1h + Kih + ((t1l >>> 0) < (Kil >>> 0) ? 1 : 0);
|
||
var t1l = t1l + Wil;
|
||
var t1h = t1h + Wih + ((t1l >>> 0) < (Wil >>> 0) ? 1 : 0);
|
||
|
||
// t2 = sigma0 + maj
|
||
var t2l = sigma0l + majl;
|
||
var t2h = sigma0h + majh + ((t2l >>> 0) < (sigma0l >>> 0) ? 1 : 0);
|
||
|
||
// Update working variables
|
||
hh = gh;
|
||
hl = gl;
|
||
gh = fh;
|
||
gl = fl;
|
||
fh = eh;
|
||
fl = el;
|
||
el = (dl + t1l) | 0;
|
||
eh = (dh + t1h + ((el >>> 0) < (dl >>> 0) ? 1 : 0)) | 0;
|
||
dh = ch;
|
||
dl = cl;
|
||
ch = bh;
|
||
cl = bl;
|
||
bh = ah;
|
||
bl = al;
|
||
al = (t1l + t2l) | 0;
|
||
ah = (t1h + t2h + ((al >>> 0) < (t1l >>> 0) ? 1 : 0)) | 0;
|
||
}
|
||
|
||
// Intermediate hash value
|
||
H0l = H0.low = (H0l + al);
|
||
H0.high = (H0h + ah + ((H0l >>> 0) < (al >>> 0) ? 1 : 0));
|
||
H1l = H1.low = (H1l + bl);
|
||
H1.high = (H1h + bh + ((H1l >>> 0) < (bl >>> 0) ? 1 : 0));
|
||
H2l = H2.low = (H2l + cl);
|
||
H2.high = (H2h + ch + ((H2l >>> 0) < (cl >>> 0) ? 1 : 0));
|
||
H3l = H3.low = (H3l + dl);
|
||
H3.high = (H3h + dh + ((H3l >>> 0) < (dl >>> 0) ? 1 : 0));
|
||
H4l = H4.low = (H4l + el);
|
||
H4.high = (H4h + eh + ((H4l >>> 0) < (el >>> 0) ? 1 : 0));
|
||
H5l = H5.low = (H5l + fl);
|
||
H5.high = (H5h + fh + ((H5l >>> 0) < (fl >>> 0) ? 1 : 0));
|
||
H6l = H6.low = (H6l + gl);
|
||
H6.high = (H6h + gh + ((H6l >>> 0) < (gl >>> 0) ? 1 : 0));
|
||
H7l = H7.low = (H7l + hl);
|
||
H7.high = (H7h + hh + ((H7l >>> 0) < (hl >>> 0) ? 1 : 0));
|
||
},
|
||
|
||
_doFinalize: function () {
|
||
// Shortcuts
|
||
var data = this._data;
|
||
var dataWords = data.words;
|
||
|
||
var nBitsTotal = this._nDataBytes * 8;
|
||
var nBitsLeft = data.sigBytes * 8;
|
||
|
||
// Add padding
|
||
dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
|
||
dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 30] = Math.floor(nBitsTotal / 0x100000000);
|
||
dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 31] = nBitsTotal;
|
||
data.sigBytes = dataWords.length * 4;
|
||
|
||
// Hash final blocks
|
||
this._process();
|
||
|
||
// Convert hash to 32-bit word array before returning
|
||
var hash = this._hash.toX32();
|
||
|
||
// Return final computed hash
|
||
return hash;
|
||
},
|
||
|
||
clone: function () {
|
||
var clone = Hasher.clone.call(this);
|
||
clone._hash = this._hash.clone();
|
||
|
||
return clone;
|
||
},
|
||
|
||
blockSize: 1024/32
|
||
});
|
||
|
||
/**
|
||
* Shortcut function to the hasher's object interface.
|
||
*
|
||
* @param {WordArray|string} message The message to hash.
|
||
*
|
||
* @return {WordArray} The hash.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hash = CryptoJS.SHA512('message');
|
||
* var hash = CryptoJS.SHA512(wordArray);
|
||
*/
|
||
C.SHA512 = Hasher._createHelper(SHA512);
|
||
|
||
/**
|
||
* Shortcut function to the HMAC's object interface.
|
||
*
|
||
* @param {WordArray|string} message The message to hash.
|
||
* @param {WordArray|string} key The secret key.
|
||
*
|
||
* @return {WordArray} The HMAC.
|
||
*
|
||
* @static
|
||
*
|
||
* @example
|
||
*
|
||
* var hmac = CryptoJS.HmacSHA512(message, key);
|
||
*/
|
||
C.HmacSHA512 = Hasher._createHmacHelper(SHA512);
|
||
}());
|
||
|
||
|
||
return CryptoJS.SHA512;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/tripledes.js":
|
||
/*!*********************************************!*\
|
||
!*** ./node_modules/crypto-js/tripledes.js ***!
|
||
\*********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory, undef) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"), __webpack_require__(/*! ./enc-base64 */ "./node_modules/crypto-js/enc-base64.js"), __webpack_require__(/*! ./md5 */ "./node_modules/crypto-js/md5.js"), __webpack_require__(/*! ./evpkdf */ "./node_modules/crypto-js/evpkdf.js"), __webpack_require__(/*! ./cipher-core */ "./node_modules/crypto-js/cipher-core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function () {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var WordArray = C_lib.WordArray;
|
||
var BlockCipher = C_lib.BlockCipher;
|
||
var C_algo = C.algo;
|
||
|
||
// Permuted Choice 1 constants
|
||
var PC1 = [
|
||
57, 49, 41, 33, 25, 17, 9, 1,
|
||
58, 50, 42, 34, 26, 18, 10, 2,
|
||
59, 51, 43, 35, 27, 19, 11, 3,
|
||
60, 52, 44, 36, 63, 55, 47, 39,
|
||
31, 23, 15, 7, 62, 54, 46, 38,
|
||
30, 22, 14, 6, 61, 53, 45, 37,
|
||
29, 21, 13, 5, 28, 20, 12, 4
|
||
];
|
||
|
||
// Permuted Choice 2 constants
|
||
var PC2 = [
|
||
14, 17, 11, 24, 1, 5,
|
||
3, 28, 15, 6, 21, 10,
|
||
23, 19, 12, 4, 26, 8,
|
||
16, 7, 27, 20, 13, 2,
|
||
41, 52, 31, 37, 47, 55,
|
||
30, 40, 51, 45, 33, 48,
|
||
44, 49, 39, 56, 34, 53,
|
||
46, 42, 50, 36, 29, 32
|
||
];
|
||
|
||
// Cumulative bit shift constants
|
||
var BIT_SHIFTS = [1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28];
|
||
|
||
// SBOXes and round permutation constants
|
||
var SBOX_P = [
|
||
{
|
||
0x0: 0x808200,
|
||
0x10000000: 0x8000,
|
||
0x20000000: 0x808002,
|
||
0x30000000: 0x2,
|
||
0x40000000: 0x200,
|
||
0x50000000: 0x808202,
|
||
0x60000000: 0x800202,
|
||
0x70000000: 0x800000,
|
||
0x80000000: 0x202,
|
||
0x90000000: 0x800200,
|
||
0xa0000000: 0x8200,
|
||
0xb0000000: 0x808000,
|
||
0xc0000000: 0x8002,
|
||
0xd0000000: 0x800002,
|
||
0xe0000000: 0x0,
|
||
0xf0000000: 0x8202,
|
||
0x8000000: 0x0,
|
||
0x18000000: 0x808202,
|
||
0x28000000: 0x8202,
|
||
0x38000000: 0x8000,
|
||
0x48000000: 0x808200,
|
||
0x58000000: 0x200,
|
||
0x68000000: 0x808002,
|
||
0x78000000: 0x2,
|
||
0x88000000: 0x800200,
|
||
0x98000000: 0x8200,
|
||
0xa8000000: 0x808000,
|
||
0xb8000000: 0x800202,
|
||
0xc8000000: 0x800002,
|
||
0xd8000000: 0x8002,
|
||
0xe8000000: 0x202,
|
||
0xf8000000: 0x800000,
|
||
0x1: 0x8000,
|
||
0x10000001: 0x2,
|
||
0x20000001: 0x808200,
|
||
0x30000001: 0x800000,
|
||
0x40000001: 0x808002,
|
||
0x50000001: 0x8200,
|
||
0x60000001: 0x200,
|
||
0x70000001: 0x800202,
|
||
0x80000001: 0x808202,
|
||
0x90000001: 0x808000,
|
||
0xa0000001: 0x800002,
|
||
0xb0000001: 0x8202,
|
||
0xc0000001: 0x202,
|
||
0xd0000001: 0x800200,
|
||
0xe0000001: 0x8002,
|
||
0xf0000001: 0x0,
|
||
0x8000001: 0x808202,
|
||
0x18000001: 0x808000,
|
||
0x28000001: 0x800000,
|
||
0x38000001: 0x200,
|
||
0x48000001: 0x8000,
|
||
0x58000001: 0x800002,
|
||
0x68000001: 0x2,
|
||
0x78000001: 0x8202,
|
||
0x88000001: 0x8002,
|
||
0x98000001: 0x800202,
|
||
0xa8000001: 0x202,
|
||
0xb8000001: 0x808200,
|
||
0xc8000001: 0x800200,
|
||
0xd8000001: 0x0,
|
||
0xe8000001: 0x8200,
|
||
0xf8000001: 0x808002
|
||
},
|
||
{
|
||
0x0: 0x40084010,
|
||
0x1000000: 0x4000,
|
||
0x2000000: 0x80000,
|
||
0x3000000: 0x40080010,
|
||
0x4000000: 0x40000010,
|
||
0x5000000: 0x40084000,
|
||
0x6000000: 0x40004000,
|
||
0x7000000: 0x10,
|
||
0x8000000: 0x84000,
|
||
0x9000000: 0x40004010,
|
||
0xa000000: 0x40000000,
|
||
0xb000000: 0x84010,
|
||
0xc000000: 0x80010,
|
||
0xd000000: 0x0,
|
||
0xe000000: 0x4010,
|
||
0xf000000: 0x40080000,
|
||
0x800000: 0x40004000,
|
||
0x1800000: 0x84010,
|
||
0x2800000: 0x10,
|
||
0x3800000: 0x40004010,
|
||
0x4800000: 0x40084010,
|
||
0x5800000: 0x40000000,
|
||
0x6800000: 0x80000,
|
||
0x7800000: 0x40080010,
|
||
0x8800000: 0x80010,
|
||
0x9800000: 0x0,
|
||
0xa800000: 0x4000,
|
||
0xb800000: 0x40080000,
|
||
0xc800000: 0x40000010,
|
||
0xd800000: 0x84000,
|
||
0xe800000: 0x40084000,
|
||
0xf800000: 0x4010,
|
||
0x10000000: 0x0,
|
||
0x11000000: 0x40080010,
|
||
0x12000000: 0x40004010,
|
||
0x13000000: 0x40084000,
|
||
0x14000000: 0x40080000,
|
||
0x15000000: 0x10,
|
||
0x16000000: 0x84010,
|
||
0x17000000: 0x4000,
|
||
0x18000000: 0x4010,
|
||
0x19000000: 0x80000,
|
||
0x1a000000: 0x80010,
|
||
0x1b000000: 0x40000010,
|
||
0x1c000000: 0x84000,
|
||
0x1d000000: 0x40004000,
|
||
0x1e000000: 0x40000000,
|
||
0x1f000000: 0x40084010,
|
||
0x10800000: 0x84010,
|
||
0x11800000: 0x80000,
|
||
0x12800000: 0x40080000,
|
||
0x13800000: 0x4000,
|
||
0x14800000: 0x40004000,
|
||
0x15800000: 0x40084010,
|
||
0x16800000: 0x10,
|
||
0x17800000: 0x40000000,
|
||
0x18800000: 0x40084000,
|
||
0x19800000: 0x40000010,
|
||
0x1a800000: 0x40004010,
|
||
0x1b800000: 0x80010,
|
||
0x1c800000: 0x0,
|
||
0x1d800000: 0x4010,
|
||
0x1e800000: 0x40080010,
|
||
0x1f800000: 0x84000
|
||
},
|
||
{
|
||
0x0: 0x104,
|
||
0x100000: 0x0,
|
||
0x200000: 0x4000100,
|
||
0x300000: 0x10104,
|
||
0x400000: 0x10004,
|
||
0x500000: 0x4000004,
|
||
0x600000: 0x4010104,
|
||
0x700000: 0x4010000,
|
||
0x800000: 0x4000000,
|
||
0x900000: 0x4010100,
|
||
0xa00000: 0x10100,
|
||
0xb00000: 0x4010004,
|
||
0xc00000: 0x4000104,
|
||
0xd00000: 0x10000,
|
||
0xe00000: 0x4,
|
||
0xf00000: 0x100,
|
||
0x80000: 0x4010100,
|
||
0x180000: 0x4010004,
|
||
0x280000: 0x0,
|
||
0x380000: 0x4000100,
|
||
0x480000: 0x4000004,
|
||
0x580000: 0x10000,
|
||
0x680000: 0x10004,
|
||
0x780000: 0x104,
|
||
0x880000: 0x4,
|
||
0x980000: 0x100,
|
||
0xa80000: 0x4010000,
|
||
0xb80000: 0x10104,
|
||
0xc80000: 0x10100,
|
||
0xd80000: 0x4000104,
|
||
0xe80000: 0x4010104,
|
||
0xf80000: 0x4000000,
|
||
0x1000000: 0x4010100,
|
||
0x1100000: 0x10004,
|
||
0x1200000: 0x10000,
|
||
0x1300000: 0x4000100,
|
||
0x1400000: 0x100,
|
||
0x1500000: 0x4010104,
|
||
0x1600000: 0x4000004,
|
||
0x1700000: 0x0,
|
||
0x1800000: 0x4000104,
|
||
0x1900000: 0x4000000,
|
||
0x1a00000: 0x4,
|
||
0x1b00000: 0x10100,
|
||
0x1c00000: 0x4010000,
|
||
0x1d00000: 0x104,
|
||
0x1e00000: 0x10104,
|
||
0x1f00000: 0x4010004,
|
||
0x1080000: 0x4000000,
|
||
0x1180000: 0x104,
|
||
0x1280000: 0x4010100,
|
||
0x1380000: 0x0,
|
||
0x1480000: 0x10004,
|
||
0x1580000: 0x4000100,
|
||
0x1680000: 0x100,
|
||
0x1780000: 0x4010004,
|
||
0x1880000: 0x10000,
|
||
0x1980000: 0x4010104,
|
||
0x1a80000: 0x10104,
|
||
0x1b80000: 0x4000004,
|
||
0x1c80000: 0x4000104,
|
||
0x1d80000: 0x4010000,
|
||
0x1e80000: 0x4,
|
||
0x1f80000: 0x10100
|
||
},
|
||
{
|
||
0x0: 0x80401000,
|
||
0x10000: 0x80001040,
|
||
0x20000: 0x401040,
|
||
0x30000: 0x80400000,
|
||
0x40000: 0x0,
|
||
0x50000: 0x401000,
|
||
0x60000: 0x80000040,
|
||
0x70000: 0x400040,
|
||
0x80000: 0x80000000,
|
||
0x90000: 0x400000,
|
||
0xa0000: 0x40,
|
||
0xb0000: 0x80001000,
|
||
0xc0000: 0x80400040,
|
||
0xd0000: 0x1040,
|
||
0xe0000: 0x1000,
|
||
0xf0000: 0x80401040,
|
||
0x8000: 0x80001040,
|
||
0x18000: 0x40,
|
||
0x28000: 0x80400040,
|
||
0x38000: 0x80001000,
|
||
0x48000: 0x401000,
|
||
0x58000: 0x80401040,
|
||
0x68000: 0x0,
|
||
0x78000: 0x80400000,
|
||
0x88000: 0x1000,
|
||
0x98000: 0x80401000,
|
||
0xa8000: 0x400000,
|
||
0xb8000: 0x1040,
|
||
0xc8000: 0x80000000,
|
||
0xd8000: 0x400040,
|
||
0xe8000: 0x401040,
|
||
0xf8000: 0x80000040,
|
||
0x100000: 0x400040,
|
||
0x110000: 0x401000,
|
||
0x120000: 0x80000040,
|
||
0x130000: 0x0,
|
||
0x140000: 0x1040,
|
||
0x150000: 0x80400040,
|
||
0x160000: 0x80401000,
|
||
0x170000: 0x80001040,
|
||
0x180000: 0x80401040,
|
||
0x190000: 0x80000000,
|
||
0x1a0000: 0x80400000,
|
||
0x1b0000: 0x401040,
|
||
0x1c0000: 0x80001000,
|
||
0x1d0000: 0x400000,
|
||
0x1e0000: 0x40,
|
||
0x1f0000: 0x1000,
|
||
0x108000: 0x80400000,
|
||
0x118000: 0x80401040,
|
||
0x128000: 0x0,
|
||
0x138000: 0x401000,
|
||
0x148000: 0x400040,
|
||
0x158000: 0x80000000,
|
||
0x168000: 0x80001040,
|
||
0x178000: 0x40,
|
||
0x188000: 0x80000040,
|
||
0x198000: 0x1000,
|
||
0x1a8000: 0x80001000,
|
||
0x1b8000: 0x80400040,
|
||
0x1c8000: 0x1040,
|
||
0x1d8000: 0x80401000,
|
||
0x1e8000: 0x400000,
|
||
0x1f8000: 0x401040
|
||
},
|
||
{
|
||
0x0: 0x80,
|
||
0x1000: 0x1040000,
|
||
0x2000: 0x40000,
|
||
0x3000: 0x20000000,
|
||
0x4000: 0x20040080,
|
||
0x5000: 0x1000080,
|
||
0x6000: 0x21000080,
|
||
0x7000: 0x40080,
|
||
0x8000: 0x1000000,
|
||
0x9000: 0x20040000,
|
||
0xa000: 0x20000080,
|
||
0xb000: 0x21040080,
|
||
0xc000: 0x21040000,
|
||
0xd000: 0x0,
|
||
0xe000: 0x1040080,
|
||
0xf000: 0x21000000,
|
||
0x800: 0x1040080,
|
||
0x1800: 0x21000080,
|
||
0x2800: 0x80,
|
||
0x3800: 0x1040000,
|
||
0x4800: 0x40000,
|
||
0x5800: 0x20040080,
|
||
0x6800: 0x21040000,
|
||
0x7800: 0x20000000,
|
||
0x8800: 0x20040000,
|
||
0x9800: 0x0,
|
||
0xa800: 0x21040080,
|
||
0xb800: 0x1000080,
|
||
0xc800: 0x20000080,
|
||
0xd800: 0x21000000,
|
||
0xe800: 0x1000000,
|
||
0xf800: 0x40080,
|
||
0x10000: 0x40000,
|
||
0x11000: 0x80,
|
||
0x12000: 0x20000000,
|
||
0x13000: 0x21000080,
|
||
0x14000: 0x1000080,
|
||
0x15000: 0x21040000,
|
||
0x16000: 0x20040080,
|
||
0x17000: 0x1000000,
|
||
0x18000: 0x21040080,
|
||
0x19000: 0x21000000,
|
||
0x1a000: 0x1040000,
|
||
0x1b000: 0x20040000,
|
||
0x1c000: 0x40080,
|
||
0x1d000: 0x20000080,
|
||
0x1e000: 0x0,
|
||
0x1f000: 0x1040080,
|
||
0x10800: 0x21000080,
|
||
0x11800: 0x1000000,
|
||
0x12800: 0x1040000,
|
||
0x13800: 0x20040080,
|
||
0x14800: 0x20000000,
|
||
0x15800: 0x1040080,
|
||
0x16800: 0x80,
|
||
0x17800: 0x21040000,
|
||
0x18800: 0x40080,
|
||
0x19800: 0x21040080,
|
||
0x1a800: 0x0,
|
||
0x1b800: 0x21000000,
|
||
0x1c800: 0x1000080,
|
||
0x1d800: 0x40000,
|
||
0x1e800: 0x20040000,
|
||
0x1f800: 0x20000080
|
||
},
|
||
{
|
||
0x0: 0x10000008,
|
||
0x100: 0x2000,
|
||
0x200: 0x10200000,
|
||
0x300: 0x10202008,
|
||
0x400: 0x10002000,
|
||
0x500: 0x200000,
|
||
0x600: 0x200008,
|
||
0x700: 0x10000000,
|
||
0x800: 0x0,
|
||
0x900: 0x10002008,
|
||
0xa00: 0x202000,
|
||
0xb00: 0x8,
|
||
0xc00: 0x10200008,
|
||
0xd00: 0x202008,
|
||
0xe00: 0x2008,
|
||
0xf00: 0x10202000,
|
||
0x80: 0x10200000,
|
||
0x180: 0x10202008,
|
||
0x280: 0x8,
|
||
0x380: 0x200000,
|
||
0x480: 0x202008,
|
||
0x580: 0x10000008,
|
||
0x680: 0x10002000,
|
||
0x780: 0x2008,
|
||
0x880: 0x200008,
|
||
0x980: 0x2000,
|
||
0xa80: 0x10002008,
|
||
0xb80: 0x10200008,
|
||
0xc80: 0x0,
|
||
0xd80: 0x10202000,
|
||
0xe80: 0x202000,
|
||
0xf80: 0x10000000,
|
||
0x1000: 0x10002000,
|
||
0x1100: 0x10200008,
|
||
0x1200: 0x10202008,
|
||
0x1300: 0x2008,
|
||
0x1400: 0x200000,
|
||
0x1500: 0x10000000,
|
||
0x1600: 0x10000008,
|
||
0x1700: 0x202000,
|
||
0x1800: 0x202008,
|
||
0x1900: 0x0,
|
||
0x1a00: 0x8,
|
||
0x1b00: 0x10200000,
|
||
0x1c00: 0x2000,
|
||
0x1d00: 0x10002008,
|
||
0x1e00: 0x10202000,
|
||
0x1f00: 0x200008,
|
||
0x1080: 0x8,
|
||
0x1180: 0x202000,
|
||
0x1280: 0x200000,
|
||
0x1380: 0x10000008,
|
||
0x1480: 0x10002000,
|
||
0x1580: 0x2008,
|
||
0x1680: 0x10202008,
|
||
0x1780: 0x10200000,
|
||
0x1880: 0x10202000,
|
||
0x1980: 0x10200008,
|
||
0x1a80: 0x2000,
|
||
0x1b80: 0x202008,
|
||
0x1c80: 0x200008,
|
||
0x1d80: 0x0,
|
||
0x1e80: 0x10000000,
|
||
0x1f80: 0x10002008
|
||
},
|
||
{
|
||
0x0: 0x100000,
|
||
0x10: 0x2000401,
|
||
0x20: 0x400,
|
||
0x30: 0x100401,
|
||
0x40: 0x2100401,
|
||
0x50: 0x0,
|
||
0x60: 0x1,
|
||
0x70: 0x2100001,
|
||
0x80: 0x2000400,
|
||
0x90: 0x100001,
|
||
0xa0: 0x2000001,
|
||
0xb0: 0x2100400,
|
||
0xc0: 0x2100000,
|
||
0xd0: 0x401,
|
||
0xe0: 0x100400,
|
||
0xf0: 0x2000000,
|
||
0x8: 0x2100001,
|
||
0x18: 0x0,
|
||
0x28: 0x2000401,
|
||
0x38: 0x2100400,
|
||
0x48: 0x100000,
|
||
0x58: 0x2000001,
|
||
0x68: 0x2000000,
|
||
0x78: 0x401,
|
||
0x88: 0x100401,
|
||
0x98: 0x2000400,
|
||
0xa8: 0x2100000,
|
||
0xb8: 0x100001,
|
||
0xc8: 0x400,
|
||
0xd8: 0x2100401,
|
||
0xe8: 0x1,
|
||
0xf8: 0x100400,
|
||
0x100: 0x2000000,
|
||
0x110: 0x100000,
|
||
0x120: 0x2000401,
|
||
0x130: 0x2100001,
|
||
0x140: 0x100001,
|
||
0x150: 0x2000400,
|
||
0x160: 0x2100400,
|
||
0x170: 0x100401,
|
||
0x180: 0x401,
|
||
0x190: 0x2100401,
|
||
0x1a0: 0x100400,
|
||
0x1b0: 0x1,
|
||
0x1c0: 0x0,
|
||
0x1d0: 0x2100000,
|
||
0x1e0: 0x2000001,
|
||
0x1f0: 0x400,
|
||
0x108: 0x100400,
|
||
0x118: 0x2000401,
|
||
0x128: 0x2100001,
|
||
0x138: 0x1,
|
||
0x148: 0x2000000,
|
||
0x158: 0x100000,
|
||
0x168: 0x401,
|
||
0x178: 0x2100400,
|
||
0x188: 0x2000001,
|
||
0x198: 0x2100000,
|
||
0x1a8: 0x0,
|
||
0x1b8: 0x2100401,
|
||
0x1c8: 0x100401,
|
||
0x1d8: 0x400,
|
||
0x1e8: 0x2000400,
|
||
0x1f8: 0x100001
|
||
},
|
||
{
|
||
0x0: 0x8000820,
|
||
0x1: 0x20000,
|
||
0x2: 0x8000000,
|
||
0x3: 0x20,
|
||
0x4: 0x20020,
|
||
0x5: 0x8020820,
|
||
0x6: 0x8020800,
|
||
0x7: 0x800,
|
||
0x8: 0x8020000,
|
||
0x9: 0x8000800,
|
||
0xa: 0x20800,
|
||
0xb: 0x8020020,
|
||
0xc: 0x820,
|
||
0xd: 0x0,
|
||
0xe: 0x8000020,
|
||
0xf: 0x20820,
|
||
0x80000000: 0x800,
|
||
0x80000001: 0x8020820,
|
||
0x80000002: 0x8000820,
|
||
0x80000003: 0x8000000,
|
||
0x80000004: 0x8020000,
|
||
0x80000005: 0x20800,
|
||
0x80000006: 0x20820,
|
||
0x80000007: 0x20,
|
||
0x80000008: 0x8000020,
|
||
0x80000009: 0x820,
|
||
0x8000000a: 0x20020,
|
||
0x8000000b: 0x8020800,
|
||
0x8000000c: 0x0,
|
||
0x8000000d: 0x8020020,
|
||
0x8000000e: 0x8000800,
|
||
0x8000000f: 0x20000,
|
||
0x10: 0x20820,
|
||
0x11: 0x8020800,
|
||
0x12: 0x20,
|
||
0x13: 0x800,
|
||
0x14: 0x8000800,
|
||
0x15: 0x8000020,
|
||
0x16: 0x8020020,
|
||
0x17: 0x20000,
|
||
0x18: 0x0,
|
||
0x19: 0x20020,
|
||
0x1a: 0x8020000,
|
||
0x1b: 0x8000820,
|
||
0x1c: 0x8020820,
|
||
0x1d: 0x20800,
|
||
0x1e: 0x820,
|
||
0x1f: 0x8000000,
|
||
0x80000010: 0x20000,
|
||
0x80000011: 0x800,
|
||
0x80000012: 0x8020020,
|
||
0x80000013: 0x20820,
|
||
0x80000014: 0x20,
|
||
0x80000015: 0x8020000,
|
||
0x80000016: 0x8000000,
|
||
0x80000017: 0x8000820,
|
||
0x80000018: 0x8020820,
|
||
0x80000019: 0x8000020,
|
||
0x8000001a: 0x8000800,
|
||
0x8000001b: 0x0,
|
||
0x8000001c: 0x20800,
|
||
0x8000001d: 0x820,
|
||
0x8000001e: 0x20020,
|
||
0x8000001f: 0x8020800
|
||
}
|
||
];
|
||
|
||
// Masks that select the SBOX input
|
||
var SBOX_MASK = [
|
||
0xf8000001, 0x1f800000, 0x01f80000, 0x001f8000,
|
||
0x0001f800, 0x00001f80, 0x000001f8, 0x8000001f
|
||
];
|
||
|
||
/**
|
||
* DES block cipher algorithm.
|
||
*/
|
||
var DES = C_algo.DES = BlockCipher.extend({
|
||
_doReset: function () {
|
||
// Shortcuts
|
||
var key = this._key;
|
||
var keyWords = key.words;
|
||
|
||
// Select 56 bits according to PC1
|
||
var keyBits = [];
|
||
for (var i = 0; i < 56; i++) {
|
||
var keyBitPos = PC1[i] - 1;
|
||
keyBits[i] = (keyWords[keyBitPos >>> 5] >>> (31 - keyBitPos % 32)) & 1;
|
||
}
|
||
|
||
// Assemble 16 subkeys
|
||
var subKeys = this._subKeys = [];
|
||
for (var nSubKey = 0; nSubKey < 16; nSubKey++) {
|
||
// Create subkey
|
||
var subKey = subKeys[nSubKey] = [];
|
||
|
||
// Shortcut
|
||
var bitShift = BIT_SHIFTS[nSubKey];
|
||
|
||
// Select 48 bits according to PC2
|
||
for (var i = 0; i < 24; i++) {
|
||
// Select from the left 28 key bits
|
||
subKey[(i / 6) | 0] |= keyBits[((PC2[i] - 1) + bitShift) % 28] << (31 - i % 6);
|
||
|
||
// Select from the right 28 key bits
|
||
subKey[4 + ((i / 6) | 0)] |= keyBits[28 + (((PC2[i + 24] - 1) + bitShift) % 28)] << (31 - i % 6);
|
||
}
|
||
|
||
// Since each subkey is applied to an expanded 32-bit input,
|
||
// the subkey can be broken into 8 values scaled to 32-bits,
|
||
// which allows the key to be used without expansion
|
||
subKey[0] = (subKey[0] << 1) | (subKey[0] >>> 31);
|
||
for (var i = 1; i < 7; i++) {
|
||
subKey[i] = subKey[i] >>> ((i - 1) * 4 + 3);
|
||
}
|
||
subKey[7] = (subKey[7] << 5) | (subKey[7] >>> 27);
|
||
}
|
||
|
||
// Compute inverse subkeys
|
||
var invSubKeys = this._invSubKeys = [];
|
||
for (var i = 0; i < 16; i++) {
|
||
invSubKeys[i] = subKeys[15 - i];
|
||
}
|
||
},
|
||
|
||
encryptBlock: function (M, offset) {
|
||
this._doCryptBlock(M, offset, this._subKeys);
|
||
},
|
||
|
||
decryptBlock: function (M, offset) {
|
||
this._doCryptBlock(M, offset, this._invSubKeys);
|
||
},
|
||
|
||
_doCryptBlock: function (M, offset, subKeys) {
|
||
// Get input
|
||
this._lBlock = M[offset];
|
||
this._rBlock = M[offset + 1];
|
||
|
||
// Initial permutation
|
||
exchangeLR.call(this, 4, 0x0f0f0f0f);
|
||
exchangeLR.call(this, 16, 0x0000ffff);
|
||
exchangeRL.call(this, 2, 0x33333333);
|
||
exchangeRL.call(this, 8, 0x00ff00ff);
|
||
exchangeLR.call(this, 1, 0x55555555);
|
||
|
||
// Rounds
|
||
for (var round = 0; round < 16; round++) {
|
||
// Shortcuts
|
||
var subKey = subKeys[round];
|
||
var lBlock = this._lBlock;
|
||
var rBlock = this._rBlock;
|
||
|
||
// Feistel function
|
||
var f = 0;
|
||
for (var i = 0; i < 8; i++) {
|
||
f |= SBOX_P[i][((rBlock ^ subKey[i]) & SBOX_MASK[i]) >>> 0];
|
||
}
|
||
this._lBlock = rBlock;
|
||
this._rBlock = lBlock ^ f;
|
||
}
|
||
|
||
// Undo swap from last round
|
||
var t = this._lBlock;
|
||
this._lBlock = this._rBlock;
|
||
this._rBlock = t;
|
||
|
||
// Final permutation
|
||
exchangeLR.call(this, 1, 0x55555555);
|
||
exchangeRL.call(this, 8, 0x00ff00ff);
|
||
exchangeRL.call(this, 2, 0x33333333);
|
||
exchangeLR.call(this, 16, 0x0000ffff);
|
||
exchangeLR.call(this, 4, 0x0f0f0f0f);
|
||
|
||
// Set output
|
||
M[offset] = this._lBlock;
|
||
M[offset + 1] = this._rBlock;
|
||
},
|
||
|
||
keySize: 64/32,
|
||
|
||
ivSize: 64/32,
|
||
|
||
blockSize: 64/32
|
||
});
|
||
|
||
// Swap bits across the left and right words
|
||
function exchangeLR(offset, mask) {
|
||
var t = ((this._lBlock >>> offset) ^ this._rBlock) & mask;
|
||
this._rBlock ^= t;
|
||
this._lBlock ^= t << offset;
|
||
}
|
||
|
||
function exchangeRL(offset, mask) {
|
||
var t = ((this._rBlock >>> offset) ^ this._lBlock) & mask;
|
||
this._lBlock ^= t;
|
||
this._rBlock ^= t << offset;
|
||
}
|
||
|
||
/**
|
||
* Shortcut functions to the cipher's object interface.
|
||
*
|
||
* @example
|
||
*
|
||
* var ciphertext = CryptoJS.DES.encrypt(message, key, cfg);
|
||
* var plaintext = CryptoJS.DES.decrypt(ciphertext, key, cfg);
|
||
*/
|
||
C.DES = BlockCipher._createHelper(DES);
|
||
|
||
/**
|
||
* Triple-DES block cipher algorithm.
|
||
*/
|
||
var TripleDES = C_algo.TripleDES = BlockCipher.extend({
|
||
_doReset: function () {
|
||
// Shortcuts
|
||
var key = this._key;
|
||
var keyWords = key.words;
|
||
// Make sure the key length is valid (64, 128 or >= 192 bit)
|
||
if (keyWords.length !== 2 && keyWords.length !== 4 && keyWords.length < 6) {
|
||
throw new Error('Invalid key length - 3DES requires the key length to be 64, 128, 192 or >192.');
|
||
}
|
||
|
||
// Extend the key according to the keying options defined in 3DES standard
|
||
var key1 = keyWords.slice(0, 2);
|
||
var key2 = keyWords.length < 4 ? keyWords.slice(0, 2) : keyWords.slice(2, 4);
|
||
var key3 = keyWords.length < 6 ? keyWords.slice(0, 2) : keyWords.slice(4, 6);
|
||
|
||
// Create DES instances
|
||
this._des1 = DES.createEncryptor(WordArray.create(key1));
|
||
this._des2 = DES.createEncryptor(WordArray.create(key2));
|
||
this._des3 = DES.createEncryptor(WordArray.create(key3));
|
||
},
|
||
|
||
encryptBlock: function (M, offset) {
|
||
this._des1.encryptBlock(M, offset);
|
||
this._des2.decryptBlock(M, offset);
|
||
this._des3.encryptBlock(M, offset);
|
||
},
|
||
|
||
decryptBlock: function (M, offset) {
|
||
this._des3.decryptBlock(M, offset);
|
||
this._des2.encryptBlock(M, offset);
|
||
this._des1.decryptBlock(M, offset);
|
||
},
|
||
|
||
keySize: 192/32,
|
||
|
||
ivSize: 64/32,
|
||
|
||
blockSize: 64/32
|
||
});
|
||
|
||
/**
|
||
* Shortcut functions to the cipher's object interface.
|
||
*
|
||
* @example
|
||
*
|
||
* var ciphertext = CryptoJS.TripleDES.encrypt(message, key, cfg);
|
||
* var plaintext = CryptoJS.TripleDES.decrypt(ciphertext, key, cfg);
|
||
*/
|
||
C.TripleDES = BlockCipher._createHelper(TripleDES);
|
||
}());
|
||
|
||
|
||
return CryptoJS.TripleDES;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/crypto-js/x64-core.js":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/crypto-js/x64-core.js ***!
|
||
\********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
;(function (root, factory) {
|
||
if (true) {
|
||
// CommonJS
|
||
module.exports = exports = factory(__webpack_require__(/*! ./core */ "./node_modules/crypto-js/core.js"));
|
||
}
|
||
else {}
|
||
}(this, function (CryptoJS) {
|
||
|
||
(function (undefined) {
|
||
// Shortcuts
|
||
var C = CryptoJS;
|
||
var C_lib = C.lib;
|
||
var Base = C_lib.Base;
|
||
var X32WordArray = C_lib.WordArray;
|
||
|
||
/**
|
||
* x64 namespace.
|
||
*/
|
||
var C_x64 = C.x64 = {};
|
||
|
||
/**
|
||
* A 64-bit word.
|
||
*/
|
||
var X64Word = C_x64.Word = Base.extend({
|
||
/**
|
||
* Initializes a newly created 64-bit word.
|
||
*
|
||
* @param {number} high The high 32 bits.
|
||
* @param {number} low The low 32 bits.
|
||
*
|
||
* @example
|
||
*
|
||
* var x64Word = CryptoJS.x64.Word.create(0x00010203, 0x04050607);
|
||
*/
|
||
init: function (high, low) {
|
||
this.high = high;
|
||
this.low = low;
|
||
}
|
||
|
||
/**
|
||
* Bitwise NOTs this word.
|
||
*
|
||
* @return {X64Word} A new x64-Word object after negating.
|
||
*
|
||
* @example
|
||
*
|
||
* var negated = x64Word.not();
|
||
*/
|
||
// not: function () {
|
||
// var high = ~this.high;
|
||
// var low = ~this.low;
|
||
|
||
// return X64Word.create(high, low);
|
||
// },
|
||
|
||
/**
|
||
* Bitwise ANDs this word with the passed word.
|
||
*
|
||
* @param {X64Word} word The x64-Word to AND with this word.
|
||
*
|
||
* @return {X64Word} A new x64-Word object after ANDing.
|
||
*
|
||
* @example
|
||
*
|
||
* var anded = x64Word.and(anotherX64Word);
|
||
*/
|
||
// and: function (word) {
|
||
// var high = this.high & word.high;
|
||
// var low = this.low & word.low;
|
||
|
||
// return X64Word.create(high, low);
|
||
// },
|
||
|
||
/**
|
||
* Bitwise ORs this word with the passed word.
|
||
*
|
||
* @param {X64Word} word The x64-Word to OR with this word.
|
||
*
|
||
* @return {X64Word} A new x64-Word object after ORing.
|
||
*
|
||
* @example
|
||
*
|
||
* var ored = x64Word.or(anotherX64Word);
|
||
*/
|
||
// or: function (word) {
|
||
// var high = this.high | word.high;
|
||
// var low = this.low | word.low;
|
||
|
||
// return X64Word.create(high, low);
|
||
// },
|
||
|
||
/**
|
||
* Bitwise XORs this word with the passed word.
|
||
*
|
||
* @param {X64Word} word The x64-Word to XOR with this word.
|
||
*
|
||
* @return {X64Word} A new x64-Word object after XORing.
|
||
*
|
||
* @example
|
||
*
|
||
* var xored = x64Word.xor(anotherX64Word);
|
||
*/
|
||
// xor: function (word) {
|
||
// var high = this.high ^ word.high;
|
||
// var low = this.low ^ word.low;
|
||
|
||
// return X64Word.create(high, low);
|
||
// },
|
||
|
||
/**
|
||
* Shifts this word n bits to the left.
|
||
*
|
||
* @param {number} n The number of bits to shift.
|
||
*
|
||
* @return {X64Word} A new x64-Word object after shifting.
|
||
*
|
||
* @example
|
||
*
|
||
* var shifted = x64Word.shiftL(25);
|
||
*/
|
||
// shiftL: function (n) {
|
||
// if (n < 32) {
|
||
// var high = (this.high << n) | (this.low >>> (32 - n));
|
||
// var low = this.low << n;
|
||
// } else {
|
||
// var high = this.low << (n - 32);
|
||
// var low = 0;
|
||
// }
|
||
|
||
// return X64Word.create(high, low);
|
||
// },
|
||
|
||
/**
|
||
* Shifts this word n bits to the right.
|
||
*
|
||
* @param {number} n The number of bits to shift.
|
||
*
|
||
* @return {X64Word} A new x64-Word object after shifting.
|
||
*
|
||
* @example
|
||
*
|
||
* var shifted = x64Word.shiftR(7);
|
||
*/
|
||
// shiftR: function (n) {
|
||
// if (n < 32) {
|
||
// var low = (this.low >>> n) | (this.high << (32 - n));
|
||
// var high = this.high >>> n;
|
||
// } else {
|
||
// var low = this.high >>> (n - 32);
|
||
// var high = 0;
|
||
// }
|
||
|
||
// return X64Word.create(high, low);
|
||
// },
|
||
|
||
/**
|
||
* Rotates this word n bits to the left.
|
||
*
|
||
* @param {number} n The number of bits to rotate.
|
||
*
|
||
* @return {X64Word} A new x64-Word object after rotating.
|
||
*
|
||
* @example
|
||
*
|
||
* var rotated = x64Word.rotL(25);
|
||
*/
|
||
// rotL: function (n) {
|
||
// return this.shiftL(n).or(this.shiftR(64 - n));
|
||
// },
|
||
|
||
/**
|
||
* Rotates this word n bits to the right.
|
||
*
|
||
* @param {number} n The number of bits to rotate.
|
||
*
|
||
* @return {X64Word} A new x64-Word object after rotating.
|
||
*
|
||
* @example
|
||
*
|
||
* var rotated = x64Word.rotR(7);
|
||
*/
|
||
// rotR: function (n) {
|
||
// return this.shiftR(n).or(this.shiftL(64 - n));
|
||
// },
|
||
|
||
/**
|
||
* Adds this word with the passed word.
|
||
*
|
||
* @param {X64Word} word The x64-Word to add with this word.
|
||
*
|
||
* @return {X64Word} A new x64-Word object after adding.
|
||
*
|
||
* @example
|
||
*
|
||
* var added = x64Word.add(anotherX64Word);
|
||
*/
|
||
// add: function (word) {
|
||
// var low = (this.low + word.low) | 0;
|
||
// var carry = (low >>> 0) < (this.low >>> 0) ? 1 : 0;
|
||
// var high = (this.high + word.high + carry) | 0;
|
||
|
||
// return X64Word.create(high, low);
|
||
// }
|
||
});
|
||
|
||
/**
|
||
* An array of 64-bit words.
|
||
*
|
||
* @property {Array} words The array of CryptoJS.x64.Word objects.
|
||
* @property {number} sigBytes The number of significant bytes in this word array.
|
||
*/
|
||
var X64WordArray = C_x64.WordArray = Base.extend({
|
||
/**
|
||
* Initializes a newly created word array.
|
||
*
|
||
* @param {Array} words (Optional) An array of CryptoJS.x64.Word objects.
|
||
* @param {number} sigBytes (Optional) The number of significant bytes in the words.
|
||
*
|
||
* @example
|
||
*
|
||
* var wordArray = CryptoJS.x64.WordArray.create();
|
||
*
|
||
* var wordArray = CryptoJS.x64.WordArray.create([
|
||
* CryptoJS.x64.Word.create(0x00010203, 0x04050607),
|
||
* CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f)
|
||
* ]);
|
||
*
|
||
* var wordArray = CryptoJS.x64.WordArray.create([
|
||
* CryptoJS.x64.Word.create(0x00010203, 0x04050607),
|
||
* CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f)
|
||
* ], 10);
|
||
*/
|
||
init: function (words, sigBytes) {
|
||
words = this.words = words || [];
|
||
|
||
if (sigBytes != undefined) {
|
||
this.sigBytes = sigBytes;
|
||
} else {
|
||
this.sigBytes = words.length * 8;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Converts this 64-bit word array to a 32-bit word array.
|
||
*
|
||
* @return {CryptoJS.lib.WordArray} This word array's data as a 32-bit word array.
|
||
*
|
||
* @example
|
||
*
|
||
* var x32WordArray = x64WordArray.toX32();
|
||
*/
|
||
toX32: function () {
|
||
// Shortcuts
|
||
var x64Words = this.words;
|
||
var x64WordsLength = x64Words.length;
|
||
|
||
// Convert
|
||
var x32Words = [];
|
||
for (var i = 0; i < x64WordsLength; i++) {
|
||
var x64Word = x64Words[i];
|
||
x32Words.push(x64Word.high);
|
||
x32Words.push(x64Word.low);
|
||
}
|
||
|
||
return X32WordArray.create(x32Words, this.sigBytes);
|
||
},
|
||
|
||
/**
|
||
* Creates a copy of this word array.
|
||
*
|
||
* @return {X64WordArray} The clone.
|
||
*
|
||
* @example
|
||
*
|
||
* var clone = x64WordArray.clone();
|
||
*/
|
||
clone: function () {
|
||
var clone = Base.clone.call(this);
|
||
|
||
// Clone "words" array
|
||
var words = clone.words = this.words.slice(0);
|
||
|
||
// Clone each X64Word object
|
||
var wordsLength = words.length;
|
||
for (var i = 0; i < wordsLength; i++) {
|
||
words[i] = words[i].clone();
|
||
}
|
||
|
||
return clone;
|
||
}
|
||
});
|
||
}());
|
||
|
||
|
||
return CryptoJS;
|
||
|
||
}));
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/des.js/lib/des.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/des.js/lib/des.js ***!
|
||
\****************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
exports.utils = __webpack_require__(/*! ./des/utils */ "./node_modules/des.js/lib/des/utils.js");
|
||
exports.Cipher = __webpack_require__(/*! ./des/cipher */ "./node_modules/des.js/lib/des/cipher.js");
|
||
exports.DES = __webpack_require__(/*! ./des/des */ "./node_modules/des.js/lib/des/des.js");
|
||
exports.CBC = __webpack_require__(/*! ./des/cbc */ "./node_modules/des.js/lib/des/cbc.js");
|
||
exports.EDE = __webpack_require__(/*! ./des/ede */ "./node_modules/des.js/lib/des/ede.js");
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/des.js/lib/des/cbc.js":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/des.js/lib/des/cbc.js ***!
|
||
\********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var assert = __webpack_require__(/*! minimalistic-assert */ "./node_modules/minimalistic-assert/index.js");
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
|
||
var proto = {};
|
||
|
||
function CBCState(iv) {
|
||
assert.equal(iv.length, 8, 'Invalid IV length');
|
||
|
||
this.iv = new Array(8);
|
||
for (var i = 0; i < this.iv.length; i++)
|
||
this.iv[i] = iv[i];
|
||
}
|
||
|
||
function instantiate(Base) {
|
||
function CBC(options) {
|
||
Base.call(this, options);
|
||
this._cbcInit();
|
||
}
|
||
inherits(CBC, Base);
|
||
|
||
var keys = Object.keys(proto);
|
||
for (var i = 0; i < keys.length; i++) {
|
||
var key = keys[i];
|
||
CBC.prototype[key] = proto[key];
|
||
}
|
||
|
||
CBC.create = function create(options) {
|
||
return new CBC(options);
|
||
};
|
||
|
||
return CBC;
|
||
}
|
||
|
||
exports.instantiate = instantiate;
|
||
|
||
proto._cbcInit = function _cbcInit() {
|
||
var state = new CBCState(this.options.iv);
|
||
this._cbcState = state;
|
||
};
|
||
|
||
proto._update = function _update(inp, inOff, out, outOff) {
|
||
var state = this._cbcState;
|
||
var superProto = this.constructor.super_.prototype;
|
||
|
||
var iv = state.iv;
|
||
if (this.type === 'encrypt') {
|
||
for (var i = 0; i < this.blockSize; i++)
|
||
iv[i] ^= inp[inOff + i];
|
||
|
||
superProto._update.call(this, iv, 0, out, outOff);
|
||
|
||
for (var i = 0; i < this.blockSize; i++)
|
||
iv[i] = out[outOff + i];
|
||
} else {
|
||
superProto._update.call(this, inp, inOff, out, outOff);
|
||
|
||
for (var i = 0; i < this.blockSize; i++)
|
||
out[outOff + i] ^= iv[i];
|
||
|
||
for (var i = 0; i < this.blockSize; i++)
|
||
iv[i] = inp[inOff + i];
|
||
}
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/des.js/lib/des/cipher.js":
|
||
/*!***********************************************!*\
|
||
!*** ./node_modules/des.js/lib/des/cipher.js ***!
|
||
\***********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var assert = __webpack_require__(/*! minimalistic-assert */ "./node_modules/minimalistic-assert/index.js");
|
||
|
||
function Cipher(options) {
|
||
this.options = options;
|
||
|
||
this.type = this.options.type;
|
||
this.blockSize = 8;
|
||
this._init();
|
||
|
||
this.buffer = new Array(this.blockSize);
|
||
this.bufferOff = 0;
|
||
}
|
||
module.exports = Cipher;
|
||
|
||
Cipher.prototype._init = function _init() {
|
||
// Might be overrided
|
||
};
|
||
|
||
Cipher.prototype.update = function update(data) {
|
||
if (data.length === 0)
|
||
return [];
|
||
|
||
if (this.type === 'decrypt')
|
||
return this._updateDecrypt(data);
|
||
else
|
||
return this._updateEncrypt(data);
|
||
};
|
||
|
||
Cipher.prototype._buffer = function _buffer(data, off) {
|
||
// Append data to buffer
|
||
var min = Math.min(this.buffer.length - this.bufferOff, data.length - off);
|
||
for (var i = 0; i < min; i++)
|
||
this.buffer[this.bufferOff + i] = data[off + i];
|
||
this.bufferOff += min;
|
||
|
||
// Shift next
|
||
return min;
|
||
};
|
||
|
||
Cipher.prototype._flushBuffer = function _flushBuffer(out, off) {
|
||
this._update(this.buffer, 0, out, off);
|
||
this.bufferOff = 0;
|
||
return this.blockSize;
|
||
};
|
||
|
||
Cipher.prototype._updateEncrypt = function _updateEncrypt(data) {
|
||
var inputOff = 0;
|
||
var outputOff = 0;
|
||
|
||
var count = ((this.bufferOff + data.length) / this.blockSize) | 0;
|
||
var out = new Array(count * this.blockSize);
|
||
|
||
if (this.bufferOff !== 0) {
|
||
inputOff += this._buffer(data, inputOff);
|
||
|
||
if (this.bufferOff === this.buffer.length)
|
||
outputOff += this._flushBuffer(out, outputOff);
|
||
}
|
||
|
||
// Write blocks
|
||
var max = data.length - ((data.length - inputOff) % this.blockSize);
|
||
for (; inputOff < max; inputOff += this.blockSize) {
|
||
this._update(data, inputOff, out, outputOff);
|
||
outputOff += this.blockSize;
|
||
}
|
||
|
||
// Queue rest
|
||
for (; inputOff < data.length; inputOff++, this.bufferOff++)
|
||
this.buffer[this.bufferOff] = data[inputOff];
|
||
|
||
return out;
|
||
};
|
||
|
||
Cipher.prototype._updateDecrypt = function _updateDecrypt(data) {
|
||
var inputOff = 0;
|
||
var outputOff = 0;
|
||
|
||
var count = Math.ceil((this.bufferOff + data.length) / this.blockSize) - 1;
|
||
var out = new Array(count * this.blockSize);
|
||
|
||
// TODO(indutny): optimize it, this is far from optimal
|
||
for (; count > 0; count--) {
|
||
inputOff += this._buffer(data, inputOff);
|
||
outputOff += this._flushBuffer(out, outputOff);
|
||
}
|
||
|
||
// Buffer rest of the input
|
||
inputOff += this._buffer(data, inputOff);
|
||
|
||
return out;
|
||
};
|
||
|
||
Cipher.prototype.final = function final(buffer) {
|
||
var first;
|
||
if (buffer)
|
||
first = this.update(buffer);
|
||
|
||
var last;
|
||
if (this.type === 'encrypt')
|
||
last = this._finalEncrypt();
|
||
else
|
||
last = this._finalDecrypt();
|
||
|
||
if (first)
|
||
return first.concat(last);
|
||
else
|
||
return last;
|
||
};
|
||
|
||
Cipher.prototype._pad = function _pad(buffer, off) {
|
||
if (off === 0)
|
||
return false;
|
||
|
||
while (off < buffer.length)
|
||
buffer[off++] = 0;
|
||
|
||
return true;
|
||
};
|
||
|
||
Cipher.prototype._finalEncrypt = function _finalEncrypt() {
|
||
if (!this._pad(this.buffer, this.bufferOff))
|
||
return [];
|
||
|
||
var out = new Array(this.blockSize);
|
||
this._update(this.buffer, 0, out, 0);
|
||
return out;
|
||
};
|
||
|
||
Cipher.prototype._unpad = function _unpad(buffer) {
|
||
return buffer;
|
||
};
|
||
|
||
Cipher.prototype._finalDecrypt = function _finalDecrypt() {
|
||
assert.equal(this.bufferOff, this.blockSize, 'Not enough data to decrypt');
|
||
var out = new Array(this.blockSize);
|
||
this._flushBuffer(out, 0);
|
||
|
||
return this._unpad(out);
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/des.js/lib/des/des.js":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/des.js/lib/des/des.js ***!
|
||
\********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var assert = __webpack_require__(/*! minimalistic-assert */ "./node_modules/minimalistic-assert/index.js");
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
|
||
var des = __webpack_require__(/*! ../des */ "./node_modules/des.js/lib/des.js");
|
||
var utils = des.utils;
|
||
var Cipher = des.Cipher;
|
||
|
||
function DESState() {
|
||
this.tmp = new Array(2);
|
||
this.keys = null;
|
||
}
|
||
|
||
function DES(options) {
|
||
Cipher.call(this, options);
|
||
|
||
var state = new DESState();
|
||
this._desState = state;
|
||
|
||
this.deriveKeys(state, options.key);
|
||
}
|
||
inherits(DES, Cipher);
|
||
module.exports = DES;
|
||
|
||
DES.create = function create(options) {
|
||
return new DES(options);
|
||
};
|
||
|
||
var shiftTable = [
|
||
1, 1, 2, 2, 2, 2, 2, 2,
|
||
1, 2, 2, 2, 2, 2, 2, 1
|
||
];
|
||
|
||
DES.prototype.deriveKeys = function deriveKeys(state, key) {
|
||
state.keys = new Array(16 * 2);
|
||
|
||
assert.equal(key.length, this.blockSize, 'Invalid key length');
|
||
|
||
var kL = utils.readUInt32BE(key, 0);
|
||
var kR = utils.readUInt32BE(key, 4);
|
||
|
||
utils.pc1(kL, kR, state.tmp, 0);
|
||
kL = state.tmp[0];
|
||
kR = state.tmp[1];
|
||
for (var i = 0; i < state.keys.length; i += 2) {
|
||
var shift = shiftTable[i >>> 1];
|
||
kL = utils.r28shl(kL, shift);
|
||
kR = utils.r28shl(kR, shift);
|
||
utils.pc2(kL, kR, state.keys, i);
|
||
}
|
||
};
|
||
|
||
DES.prototype._update = function _update(inp, inOff, out, outOff) {
|
||
var state = this._desState;
|
||
|
||
var l = utils.readUInt32BE(inp, inOff);
|
||
var r = utils.readUInt32BE(inp, inOff + 4);
|
||
|
||
// Initial Permutation
|
||
utils.ip(l, r, state.tmp, 0);
|
||
l = state.tmp[0];
|
||
r = state.tmp[1];
|
||
|
||
if (this.type === 'encrypt')
|
||
this._encrypt(state, l, r, state.tmp, 0);
|
||
else
|
||
this._decrypt(state, l, r, state.tmp, 0);
|
||
|
||
l = state.tmp[0];
|
||
r = state.tmp[1];
|
||
|
||
utils.writeUInt32BE(out, l, outOff);
|
||
utils.writeUInt32BE(out, r, outOff + 4);
|
||
};
|
||
|
||
DES.prototype._pad = function _pad(buffer, off) {
|
||
var value = buffer.length - off;
|
||
for (var i = off; i < buffer.length; i++)
|
||
buffer[i] = value;
|
||
|
||
return true;
|
||
};
|
||
|
||
DES.prototype._unpad = function _unpad(buffer) {
|
||
var pad = buffer[buffer.length - 1];
|
||
for (var i = buffer.length - pad; i < buffer.length; i++)
|
||
assert.equal(buffer[i], pad);
|
||
|
||
return buffer.slice(0, buffer.length - pad);
|
||
};
|
||
|
||
DES.prototype._encrypt = function _encrypt(state, lStart, rStart, out, off) {
|
||
var l = lStart;
|
||
var r = rStart;
|
||
|
||
// Apply f() x16 times
|
||
for (var i = 0; i < state.keys.length; i += 2) {
|
||
var keyL = state.keys[i];
|
||
var keyR = state.keys[i + 1];
|
||
|
||
// f(r, k)
|
||
utils.expand(r, state.tmp, 0);
|
||
|
||
keyL ^= state.tmp[0];
|
||
keyR ^= state.tmp[1];
|
||
var s = utils.substitute(keyL, keyR);
|
||
var f = utils.permute(s);
|
||
|
||
var t = r;
|
||
r = (l ^ f) >>> 0;
|
||
l = t;
|
||
}
|
||
|
||
// Reverse Initial Permutation
|
||
utils.rip(r, l, out, off);
|
||
};
|
||
|
||
DES.prototype._decrypt = function _decrypt(state, lStart, rStart, out, off) {
|
||
var l = rStart;
|
||
var r = lStart;
|
||
|
||
// Apply f() x16 times
|
||
for (var i = state.keys.length - 2; i >= 0; i -= 2) {
|
||
var keyL = state.keys[i];
|
||
var keyR = state.keys[i + 1];
|
||
|
||
// f(r, k)
|
||
utils.expand(l, state.tmp, 0);
|
||
|
||
keyL ^= state.tmp[0];
|
||
keyR ^= state.tmp[1];
|
||
var s = utils.substitute(keyL, keyR);
|
||
var f = utils.permute(s);
|
||
|
||
var t = l;
|
||
l = (r ^ f) >>> 0;
|
||
r = t;
|
||
}
|
||
|
||
// Reverse Initial Permutation
|
||
utils.rip(l, r, out, off);
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/des.js/lib/des/ede.js":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/des.js/lib/des/ede.js ***!
|
||
\********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var assert = __webpack_require__(/*! minimalistic-assert */ "./node_modules/minimalistic-assert/index.js");
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
|
||
var des = __webpack_require__(/*! ../des */ "./node_modules/des.js/lib/des.js");
|
||
var Cipher = des.Cipher;
|
||
var DES = des.DES;
|
||
|
||
function EDEState(type, key) {
|
||
assert.equal(key.length, 24, 'Invalid key length');
|
||
|
||
var k1 = key.slice(0, 8);
|
||
var k2 = key.slice(8, 16);
|
||
var k3 = key.slice(16, 24);
|
||
|
||
if (type === 'encrypt') {
|
||
this.ciphers = [
|
||
DES.create({ type: 'encrypt', key: k1 }),
|
||
DES.create({ type: 'decrypt', key: k2 }),
|
||
DES.create({ type: 'encrypt', key: k3 })
|
||
];
|
||
} else {
|
||
this.ciphers = [
|
||
DES.create({ type: 'decrypt', key: k3 }),
|
||
DES.create({ type: 'encrypt', key: k2 }),
|
||
DES.create({ type: 'decrypt', key: k1 })
|
||
];
|
||
}
|
||
}
|
||
|
||
function EDE(options) {
|
||
Cipher.call(this, options);
|
||
|
||
var state = new EDEState(this.type, this.options.key);
|
||
this._edeState = state;
|
||
}
|
||
inherits(EDE, Cipher);
|
||
|
||
module.exports = EDE;
|
||
|
||
EDE.create = function create(options) {
|
||
return new EDE(options);
|
||
};
|
||
|
||
EDE.prototype._update = function _update(inp, inOff, out, outOff) {
|
||
var state = this._edeState;
|
||
|
||
state.ciphers[0]._update(inp, inOff, out, outOff);
|
||
state.ciphers[1]._update(out, outOff, out, outOff);
|
||
state.ciphers[2]._update(out, outOff, out, outOff);
|
||
};
|
||
|
||
EDE.prototype._pad = DES.prototype._pad;
|
||
EDE.prototype._unpad = DES.prototype._unpad;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/des.js/lib/des/utils.js":
|
||
/*!**********************************************!*\
|
||
!*** ./node_modules/des.js/lib/des/utils.js ***!
|
||
\**********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
exports.readUInt32BE = function readUInt32BE(bytes, off) {
|
||
var res = (bytes[0 + off] << 24) |
|
||
(bytes[1 + off] << 16) |
|
||
(bytes[2 + off] << 8) |
|
||
bytes[3 + off];
|
||
return res >>> 0;
|
||
};
|
||
|
||
exports.writeUInt32BE = function writeUInt32BE(bytes, value, off) {
|
||
bytes[0 + off] = value >>> 24;
|
||
bytes[1 + off] = (value >>> 16) & 0xff;
|
||
bytes[2 + off] = (value >>> 8) & 0xff;
|
||
bytes[3 + off] = value & 0xff;
|
||
};
|
||
|
||
exports.ip = function ip(inL, inR, out, off) {
|
||
var outL = 0;
|
||
var outR = 0;
|
||
|
||
for (var i = 6; i >= 0; i -= 2) {
|
||
for (var j = 0; j <= 24; j += 8) {
|
||
outL <<= 1;
|
||
outL |= (inR >>> (j + i)) & 1;
|
||
}
|
||
for (var j = 0; j <= 24; j += 8) {
|
||
outL <<= 1;
|
||
outL |= (inL >>> (j + i)) & 1;
|
||
}
|
||
}
|
||
|
||
for (var i = 6; i >= 0; i -= 2) {
|
||
for (var j = 1; j <= 25; j += 8) {
|
||
outR <<= 1;
|
||
outR |= (inR >>> (j + i)) & 1;
|
||
}
|
||
for (var j = 1; j <= 25; j += 8) {
|
||
outR <<= 1;
|
||
outR |= (inL >>> (j + i)) & 1;
|
||
}
|
||
}
|
||
|
||
out[off + 0] = outL >>> 0;
|
||
out[off + 1] = outR >>> 0;
|
||
};
|
||
|
||
exports.rip = function rip(inL, inR, out, off) {
|
||
var outL = 0;
|
||
var outR = 0;
|
||
|
||
for (var i = 0; i < 4; i++) {
|
||
for (var j = 24; j >= 0; j -= 8) {
|
||
outL <<= 1;
|
||
outL |= (inR >>> (j + i)) & 1;
|
||
outL <<= 1;
|
||
outL |= (inL >>> (j + i)) & 1;
|
||
}
|
||
}
|
||
for (var i = 4; i < 8; i++) {
|
||
for (var j = 24; j >= 0; j -= 8) {
|
||
outR <<= 1;
|
||
outR |= (inR >>> (j + i)) & 1;
|
||
outR <<= 1;
|
||
outR |= (inL >>> (j + i)) & 1;
|
||
}
|
||
}
|
||
|
||
out[off + 0] = outL >>> 0;
|
||
out[off + 1] = outR >>> 0;
|
||
};
|
||
|
||
exports.pc1 = function pc1(inL, inR, out, off) {
|
||
var outL = 0;
|
||
var outR = 0;
|
||
|
||
// 7, 15, 23, 31, 39, 47, 55, 63
|
||
// 6, 14, 22, 30, 39, 47, 55, 63
|
||
// 5, 13, 21, 29, 39, 47, 55, 63
|
||
// 4, 12, 20, 28
|
||
for (var i = 7; i >= 5; i--) {
|
||
for (var j = 0; j <= 24; j += 8) {
|
||
outL <<= 1;
|
||
outL |= (inR >> (j + i)) & 1;
|
||
}
|
||
for (var j = 0; j <= 24; j += 8) {
|
||
outL <<= 1;
|
||
outL |= (inL >> (j + i)) & 1;
|
||
}
|
||
}
|
||
for (var j = 0; j <= 24; j += 8) {
|
||
outL <<= 1;
|
||
outL |= (inR >> (j + i)) & 1;
|
||
}
|
||
|
||
// 1, 9, 17, 25, 33, 41, 49, 57
|
||
// 2, 10, 18, 26, 34, 42, 50, 58
|
||
// 3, 11, 19, 27, 35, 43, 51, 59
|
||
// 36, 44, 52, 60
|
||
for (var i = 1; i <= 3; i++) {
|
||
for (var j = 0; j <= 24; j += 8) {
|
||
outR <<= 1;
|
||
outR |= (inR >> (j + i)) & 1;
|
||
}
|
||
for (var j = 0; j <= 24; j += 8) {
|
||
outR <<= 1;
|
||
outR |= (inL >> (j + i)) & 1;
|
||
}
|
||
}
|
||
for (var j = 0; j <= 24; j += 8) {
|
||
outR <<= 1;
|
||
outR |= (inL >> (j + i)) & 1;
|
||
}
|
||
|
||
out[off + 0] = outL >>> 0;
|
||
out[off + 1] = outR >>> 0;
|
||
};
|
||
|
||
exports.r28shl = function r28shl(num, shift) {
|
||
return ((num << shift) & 0xfffffff) | (num >>> (28 - shift));
|
||
};
|
||
|
||
var pc2table = [
|
||
// inL => outL
|
||
14, 11, 17, 4, 27, 23, 25, 0,
|
||
13, 22, 7, 18, 5, 9, 16, 24,
|
||
2, 20, 12, 21, 1, 8, 15, 26,
|
||
|
||
// inR => outR
|
||
15, 4, 25, 19, 9, 1, 26, 16,
|
||
5, 11, 23, 8, 12, 7, 17, 0,
|
||
22, 3, 10, 14, 6, 20, 27, 24
|
||
];
|
||
|
||
exports.pc2 = function pc2(inL, inR, out, off) {
|
||
var outL = 0;
|
||
var outR = 0;
|
||
|
||
var len = pc2table.length >>> 1;
|
||
for (var i = 0; i < len; i++) {
|
||
outL <<= 1;
|
||
outL |= (inL >>> pc2table[i]) & 0x1;
|
||
}
|
||
for (var i = len; i < pc2table.length; i++) {
|
||
outR <<= 1;
|
||
outR |= (inR >>> pc2table[i]) & 0x1;
|
||
}
|
||
|
||
out[off + 0] = outL >>> 0;
|
||
out[off + 1] = outR >>> 0;
|
||
};
|
||
|
||
exports.expand = function expand(r, out, off) {
|
||
var outL = 0;
|
||
var outR = 0;
|
||
|
||
outL = ((r & 1) << 5) | (r >>> 27);
|
||
for (var i = 23; i >= 15; i -= 4) {
|
||
outL <<= 6;
|
||
outL |= (r >>> i) & 0x3f;
|
||
}
|
||
for (var i = 11; i >= 3; i -= 4) {
|
||
outR |= (r >>> i) & 0x3f;
|
||
outR <<= 6;
|
||
}
|
||
outR |= ((r & 0x1f) << 1) | (r >>> 31);
|
||
|
||
out[off + 0] = outL >>> 0;
|
||
out[off + 1] = outR >>> 0;
|
||
};
|
||
|
||
var sTable = [
|
||
14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1,
|
||
3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8,
|
||
4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7,
|
||
15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13,
|
||
|
||
15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14,
|
||
9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5,
|
||
0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2,
|
||
5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9,
|
||
|
||
10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10,
|
||
1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1,
|
||
13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7,
|
||
11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12,
|
||
|
||
7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3,
|
||
1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9,
|
||
10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8,
|
||
15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14,
|
||
|
||
2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1,
|
||
8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6,
|
||
4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13,
|
||
15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3,
|
||
|
||
12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5,
|
||
0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8,
|
||
9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10,
|
||
7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13,
|
||
|
||
4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10,
|
||
3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6,
|
||
1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,
|
||
10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12,
|
||
|
||
13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4,
|
||
10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2,
|
||
7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13,
|
||
0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11
|
||
];
|
||
|
||
exports.substitute = function substitute(inL, inR) {
|
||
var out = 0;
|
||
for (var i = 0; i < 4; i++) {
|
||
var b = (inL >>> (18 - i * 6)) & 0x3f;
|
||
var sb = sTable[i * 0x40 + b];
|
||
|
||
out <<= 4;
|
||
out |= sb;
|
||
}
|
||
for (var i = 0; i < 4; i++) {
|
||
var b = (inR >>> (18 - i * 6)) & 0x3f;
|
||
var sb = sTable[4 * 0x40 + i * 0x40 + b];
|
||
|
||
out <<= 4;
|
||
out |= sb;
|
||
}
|
||
return out >>> 0;
|
||
};
|
||
|
||
var permuteTable = [
|
||
16, 25, 12, 11, 3, 20, 4, 15, 31, 17, 9, 6, 27, 14, 1, 22,
|
||
30, 24, 8, 18, 0, 5, 29, 23, 13, 19, 2, 26, 10, 21, 28, 7
|
||
];
|
||
|
||
exports.permute = function permute(num) {
|
||
var out = 0;
|
||
for (var i = 0; i < permuteTable.length; i++) {
|
||
out <<= 1;
|
||
out |= (num >>> permuteTable[i]) & 0x1;
|
||
}
|
||
return out >>> 0;
|
||
};
|
||
|
||
exports.padSplit = function padSplit(num, size, group) {
|
||
var str = num.toString(2);
|
||
while (str.length < size)
|
||
str = '0' + str;
|
||
|
||
var out = [];
|
||
for (var i = 0; i < size; i += group)
|
||
out.push(str.slice(i, i + group));
|
||
return out.join(' ');
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/diffie-hellman/browser.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/diffie-hellman/browser.js ***!
|
||
\************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(Buffer) {var generatePrime = __webpack_require__(/*! ./lib/generatePrime */ "./node_modules/diffie-hellman/lib/generatePrime.js")
|
||
var primes = __webpack_require__(/*! ./lib/primes.json */ "./node_modules/diffie-hellman/lib/primes.json")
|
||
|
||
var DH = __webpack_require__(/*! ./lib/dh */ "./node_modules/diffie-hellman/lib/dh.js")
|
||
|
||
function getDiffieHellman (mod) {
|
||
var prime = new Buffer(primes[mod].prime, 'hex')
|
||
var gen = new Buffer(primes[mod].gen, 'hex')
|
||
|
||
return new DH(prime, gen)
|
||
}
|
||
|
||
var ENCODINGS = {
|
||
'binary': true, 'hex': true, 'base64': true
|
||
}
|
||
|
||
function createDiffieHellman (prime, enc, generator, genc) {
|
||
if (Buffer.isBuffer(enc) || ENCODINGS[enc] === undefined) {
|
||
return createDiffieHellman(prime, 'binary', enc, generator)
|
||
}
|
||
|
||
enc = enc || 'binary'
|
||
genc = genc || 'binary'
|
||
generator = generator || new Buffer([2])
|
||
|
||
if (!Buffer.isBuffer(generator)) {
|
||
generator = new Buffer(generator, genc)
|
||
}
|
||
|
||
if (typeof prime === 'number') {
|
||
return new DH(generatePrime(prime, generator), generator, true)
|
||
}
|
||
|
||
if (!Buffer.isBuffer(prime)) {
|
||
prime = new Buffer(prime, enc)
|
||
}
|
||
|
||
return new DH(prime, generator, true)
|
||
}
|
||
|
||
exports.DiffieHellmanGroup = exports.createDiffieHellmanGroup = exports.getDiffieHellman = getDiffieHellman
|
||
exports.createDiffieHellman = exports.DiffieHellman = createDiffieHellman
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../buffer/index.js */ "./node_modules/buffer/index.js").Buffer))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/diffie-hellman/lib/dh.js":
|
||
/*!***********************************************!*\
|
||
!*** ./node_modules/diffie-hellman/lib/dh.js ***!
|
||
\***********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(Buffer) {var BN = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js");
|
||
var MillerRabin = __webpack_require__(/*! miller-rabin */ "./node_modules/miller-rabin/lib/mr.js");
|
||
var millerRabin = new MillerRabin();
|
||
var TWENTYFOUR = new BN(24);
|
||
var ELEVEN = new BN(11);
|
||
var TEN = new BN(10);
|
||
var THREE = new BN(3);
|
||
var SEVEN = new BN(7);
|
||
var primes = __webpack_require__(/*! ./generatePrime */ "./node_modules/diffie-hellman/lib/generatePrime.js");
|
||
var randomBytes = __webpack_require__(/*! randombytes */ "./node_modules/randombytes/browser.js");
|
||
module.exports = DH;
|
||
|
||
function setPublicKey(pub, enc) {
|
||
enc = enc || 'utf8';
|
||
if (!Buffer.isBuffer(pub)) {
|
||
pub = new Buffer(pub, enc);
|
||
}
|
||
this._pub = new BN(pub);
|
||
return this;
|
||
}
|
||
|
||
function setPrivateKey(priv, enc) {
|
||
enc = enc || 'utf8';
|
||
if (!Buffer.isBuffer(priv)) {
|
||
priv = new Buffer(priv, enc);
|
||
}
|
||
this._priv = new BN(priv);
|
||
return this;
|
||
}
|
||
|
||
var primeCache = {};
|
||
function checkPrime(prime, generator) {
|
||
var gen = generator.toString('hex');
|
||
var hex = [gen, prime.toString(16)].join('_');
|
||
if (hex in primeCache) {
|
||
return primeCache[hex];
|
||
}
|
||
var error = 0;
|
||
|
||
if (prime.isEven() ||
|
||
!primes.simpleSieve ||
|
||
!primes.fermatTest(prime) ||
|
||
!millerRabin.test(prime)) {
|
||
//not a prime so +1
|
||
error += 1;
|
||
|
||
if (gen === '02' || gen === '05') {
|
||
// we'd be able to check the generator
|
||
// it would fail so +8
|
||
error += 8;
|
||
} else {
|
||
//we wouldn't be able to test the generator
|
||
// so +4
|
||
error += 4;
|
||
}
|
||
primeCache[hex] = error;
|
||
return error;
|
||
}
|
||
if (!millerRabin.test(prime.shrn(1))) {
|
||
//not a safe prime
|
||
error += 2;
|
||
}
|
||
var rem;
|
||
switch (gen) {
|
||
case '02':
|
||
if (prime.mod(TWENTYFOUR).cmp(ELEVEN)) {
|
||
// unsuidable generator
|
||
error += 8;
|
||
}
|
||
break;
|
||
case '05':
|
||
rem = prime.mod(TEN);
|
||
if (rem.cmp(THREE) && rem.cmp(SEVEN)) {
|
||
// prime mod 10 needs to equal 3 or 7
|
||
error += 8;
|
||
}
|
||
break;
|
||
default:
|
||
error += 4;
|
||
}
|
||
primeCache[hex] = error;
|
||
return error;
|
||
}
|
||
|
||
function DH(prime, generator, malleable) {
|
||
this.setGenerator(generator);
|
||
this.__prime = new BN(prime);
|
||
this._prime = BN.mont(this.__prime);
|
||
this._primeLen = prime.length;
|
||
this._pub = undefined;
|
||
this._priv = undefined;
|
||
this._primeCode = undefined;
|
||
if (malleable) {
|
||
this.setPublicKey = setPublicKey;
|
||
this.setPrivateKey = setPrivateKey;
|
||
} else {
|
||
this._primeCode = 8;
|
||
}
|
||
}
|
||
Object.defineProperty(DH.prototype, 'verifyError', {
|
||
enumerable: true,
|
||
get: function () {
|
||
if (typeof this._primeCode !== 'number') {
|
||
this._primeCode = checkPrime(this.__prime, this.__gen);
|
||
}
|
||
return this._primeCode;
|
||
}
|
||
});
|
||
DH.prototype.generateKeys = function () {
|
||
if (!this._priv) {
|
||
this._priv = new BN(randomBytes(this._primeLen));
|
||
}
|
||
this._pub = this._gen.toRed(this._prime).redPow(this._priv).fromRed();
|
||
return this.getPublicKey();
|
||
};
|
||
|
||
DH.prototype.computeSecret = function (other) {
|
||
other = new BN(other);
|
||
other = other.toRed(this._prime);
|
||
var secret = other.redPow(this._priv).fromRed();
|
||
var out = new Buffer(secret.toArray());
|
||
var prime = this.getPrime();
|
||
if (out.length < prime.length) {
|
||
var front = new Buffer(prime.length - out.length);
|
||
front.fill(0);
|
||
out = Buffer.concat([front, out]);
|
||
}
|
||
return out;
|
||
};
|
||
|
||
DH.prototype.getPublicKey = function getPublicKey(enc) {
|
||
return formatReturnValue(this._pub, enc);
|
||
};
|
||
|
||
DH.prototype.getPrivateKey = function getPrivateKey(enc) {
|
||
return formatReturnValue(this._priv, enc);
|
||
};
|
||
|
||
DH.prototype.getPrime = function (enc) {
|
||
return formatReturnValue(this.__prime, enc);
|
||
};
|
||
|
||
DH.prototype.getGenerator = function (enc) {
|
||
return formatReturnValue(this._gen, enc);
|
||
};
|
||
|
||
DH.prototype.setGenerator = function (gen, enc) {
|
||
enc = enc || 'utf8';
|
||
if (!Buffer.isBuffer(gen)) {
|
||
gen = new Buffer(gen, enc);
|
||
}
|
||
this.__gen = gen;
|
||
this._gen = new BN(gen);
|
||
return this;
|
||
};
|
||
|
||
function formatReturnValue(bn, enc) {
|
||
var buf = new Buffer(bn.toArray());
|
||
if (!enc) {
|
||
return buf;
|
||
} else {
|
||
return buf.toString(enc);
|
||
}
|
||
}
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../buffer/index.js */ "./node_modules/buffer/index.js").Buffer))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/diffie-hellman/lib/generatePrime.js":
|
||
/*!**********************************************************!*\
|
||
!*** ./node_modules/diffie-hellman/lib/generatePrime.js ***!
|
||
\**********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var randomBytes = __webpack_require__(/*! randombytes */ "./node_modules/randombytes/browser.js");
|
||
module.exports = findPrime;
|
||
findPrime.simpleSieve = simpleSieve;
|
||
findPrime.fermatTest = fermatTest;
|
||
var BN = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js");
|
||
var TWENTYFOUR = new BN(24);
|
||
var MillerRabin = __webpack_require__(/*! miller-rabin */ "./node_modules/miller-rabin/lib/mr.js");
|
||
var millerRabin = new MillerRabin();
|
||
var ONE = new BN(1);
|
||
var TWO = new BN(2);
|
||
var FIVE = new BN(5);
|
||
var SIXTEEN = new BN(16);
|
||
var EIGHT = new BN(8);
|
||
var TEN = new BN(10);
|
||
var THREE = new BN(3);
|
||
var SEVEN = new BN(7);
|
||
var ELEVEN = new BN(11);
|
||
var FOUR = new BN(4);
|
||
var TWELVE = new BN(12);
|
||
var primes = null;
|
||
|
||
function _getPrimes() {
|
||
if (primes !== null)
|
||
return primes;
|
||
|
||
var limit = 0x100000;
|
||
var res = [];
|
||
res[0] = 2;
|
||
for (var i = 1, k = 3; k < limit; k += 2) {
|
||
var sqrt = Math.ceil(Math.sqrt(k));
|
||
for (var j = 0; j < i && res[j] <= sqrt; j++)
|
||
if (k % res[j] === 0)
|
||
break;
|
||
|
||
if (i !== j && res[j] <= sqrt)
|
||
continue;
|
||
|
||
res[i++] = k;
|
||
}
|
||
primes = res;
|
||
return res;
|
||
}
|
||
|
||
function simpleSieve(p) {
|
||
var primes = _getPrimes();
|
||
|
||
for (var i = 0; i < primes.length; i++)
|
||
if (p.modn(primes[i]) === 0) {
|
||
if (p.cmpn(primes[i]) === 0) {
|
||
return true;
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
function fermatTest(p) {
|
||
var red = BN.mont(p);
|
||
return TWO.toRed(red).redPow(p.subn(1)).fromRed().cmpn(1) === 0;
|
||
}
|
||
|
||
function findPrime(bits, gen) {
|
||
if (bits < 16) {
|
||
// this is what openssl does
|
||
if (gen === 2 || gen === 5) {
|
||
return new BN([0x8c, 0x7b]);
|
||
} else {
|
||
return new BN([0x8c, 0x27]);
|
||
}
|
||
}
|
||
gen = new BN(gen);
|
||
|
||
var num, n2;
|
||
|
||
while (true) {
|
||
num = new BN(randomBytes(Math.ceil(bits / 8)));
|
||
while (num.bitLength() > bits) {
|
||
num.ishrn(1);
|
||
}
|
||
if (num.isEven()) {
|
||
num.iadd(ONE);
|
||
}
|
||
if (!num.testn(1)) {
|
||
num.iadd(TWO);
|
||
}
|
||
if (!gen.cmp(TWO)) {
|
||
while (num.mod(TWENTYFOUR).cmp(ELEVEN)) {
|
||
num.iadd(FOUR);
|
||
}
|
||
} else if (!gen.cmp(FIVE)) {
|
||
while (num.mod(TEN).cmp(THREE)) {
|
||
num.iadd(FOUR);
|
||
}
|
||
}
|
||
n2 = num.shrn(1);
|
||
if (simpleSieve(n2) && simpleSieve(num) &&
|
||
fermatTest(n2) && fermatTest(num) &&
|
||
millerRabin.test(n2) && millerRabin.test(num)) {
|
||
return num;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/diffie-hellman/lib/primes.json":
|
||
/*!*****************************************************!*\
|
||
!*** ./node_modules/diffie-hellman/lib/primes.json ***!
|
||
\*****************************************************/
|
||
/*! exports provided: modp1, modp2, modp5, modp14, modp15, modp16, modp17, modp18, default */
|
||
/***/ (function(module) {
|
||
|
||
module.exports = JSON.parse("{\"modp1\":{\"gen\":\"02\",\"prime\":\"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a63a3620ffffffffffffffff\"},\"modp2\":{\"gen\":\"02\",\"prime\":\"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffff\"},\"modp5\":{\"gen\":\"02\",\"prime\":\"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff\"},\"modp14\":{\"gen\":\"02\",\"prime\":\"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff\"},\"modp15\":{\"gen\":\"02\",\"prime\":\"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a93ad2caffffffffffffffff\"},\"modp16\":{\"gen\":\"02\",\"prime\":\"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c934063199ffffffffffffffff\"},\"modp17\":{\"gen\":\"02\",\"prime\":\"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dcc4024ffffffffffffffff\"},\"modp18\":{\"gen\":\"02\",\"prime\":\"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dbe115974a3926f12fee5e438777cb6a932df8cd8bec4d073b931ba3bc832b68d9dd300741fa7bf8afc47ed2576f6936ba424663aab639c5ae4f5683423b4742bf1c978238f16cbe39d652de3fdb8befc848ad922222e04a4037c0713eb57a81a23f0c73473fc646cea306b4bcbc8862f8385ddfa9d4b7fa2c087e879683303ed5bdd3a062b3cf5b3a278a66d2a13f83f44f82ddf310ee074ab6a364597e899a0255dc164f31cc50846851df9ab48195ded7ea1b1d510bd7ee74d73faf36bc31ecfa268359046f4eb879f924009438b481c6cd7889a002ed5ee382bc9190da6fc026e479558e4475677e9aa9e3050e2765694dfc81f56e880b96e7160c980dd98edd3dfffffffffffffffff\"}}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/elliptic/lib/elliptic.js":
|
||
/*!***********************************************!*\
|
||
!*** ./node_modules/elliptic/lib/elliptic.js ***!
|
||
\***********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var elliptic = exports;
|
||
|
||
elliptic.version = __webpack_require__(/*! ../package.json */ "./node_modules/elliptic/package.json").version;
|
||
elliptic.utils = __webpack_require__(/*! ./elliptic/utils */ "./node_modules/elliptic/lib/elliptic/utils.js");
|
||
elliptic.rand = __webpack_require__(/*! brorand */ "./node_modules/brorand/index.js");
|
||
elliptic.curve = __webpack_require__(/*! ./elliptic/curve */ "./node_modules/elliptic/lib/elliptic/curve/index.js");
|
||
elliptic.curves = __webpack_require__(/*! ./elliptic/curves */ "./node_modules/elliptic/lib/elliptic/curves.js");
|
||
|
||
// Protocols
|
||
elliptic.ec = __webpack_require__(/*! ./elliptic/ec */ "./node_modules/elliptic/lib/elliptic/ec/index.js");
|
||
elliptic.eddsa = __webpack_require__(/*! ./elliptic/eddsa */ "./node_modules/elliptic/lib/elliptic/eddsa/index.js");
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/elliptic/lib/elliptic/curve/base.js":
|
||
/*!**********************************************************!*\
|
||
!*** ./node_modules/elliptic/lib/elliptic/curve/base.js ***!
|
||
\**********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var BN = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js");
|
||
var utils = __webpack_require__(/*! ../utils */ "./node_modules/elliptic/lib/elliptic/utils.js");
|
||
var getNAF = utils.getNAF;
|
||
var getJSF = utils.getJSF;
|
||
var assert = utils.assert;
|
||
|
||
function BaseCurve(type, conf) {
|
||
this.type = type;
|
||
this.p = new BN(conf.p, 16);
|
||
|
||
// Use Montgomery, when there is no fast reduction for the prime
|
||
this.red = conf.prime ? BN.red(conf.prime) : BN.mont(this.p);
|
||
|
||
// Useful for many curves
|
||
this.zero = new BN(0).toRed(this.red);
|
||
this.one = new BN(1).toRed(this.red);
|
||
this.two = new BN(2).toRed(this.red);
|
||
|
||
// Curve configuration, optional
|
||
this.n = conf.n && new BN(conf.n, 16);
|
||
this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed);
|
||
|
||
// Temporary arrays
|
||
this._wnafT1 = new Array(4);
|
||
this._wnafT2 = new Array(4);
|
||
this._wnafT3 = new Array(4);
|
||
this._wnafT4 = new Array(4);
|
||
|
||
this._bitLength = this.n ? this.n.bitLength() : 0;
|
||
|
||
// Generalized Greg Maxwell's trick
|
||
var adjustCount = this.n && this.p.div(this.n);
|
||
if (!adjustCount || adjustCount.cmpn(100) > 0) {
|
||
this.redN = null;
|
||
} else {
|
||
this._maxwellTrick = true;
|
||
this.redN = this.n.toRed(this.red);
|
||
}
|
||
}
|
||
module.exports = BaseCurve;
|
||
|
||
BaseCurve.prototype.point = function point() {
|
||
throw new Error('Not implemented');
|
||
};
|
||
|
||
BaseCurve.prototype.validate = function validate() {
|
||
throw new Error('Not implemented');
|
||
};
|
||
|
||
BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) {
|
||
assert(p.precomputed);
|
||
var doubles = p._getDoubles();
|
||
|
||
var naf = getNAF(k, 1, this._bitLength);
|
||
var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1);
|
||
I /= 3;
|
||
|
||
// Translate into more windowed form
|
||
var repr = [];
|
||
for (var j = 0; j < naf.length; j += doubles.step) {
|
||
var nafW = 0;
|
||
for (var k = j + doubles.step - 1; k >= j; k--)
|
||
nafW = (nafW << 1) + naf[k];
|
||
repr.push(nafW);
|
||
}
|
||
|
||
var a = this.jpoint(null, null, null);
|
||
var b = this.jpoint(null, null, null);
|
||
for (var i = I; i > 0; i--) {
|
||
for (var j = 0; j < repr.length; j++) {
|
||
var nafW = repr[j];
|
||
if (nafW === i)
|
||
b = b.mixedAdd(doubles.points[j]);
|
||
else if (nafW === -i)
|
||
b = b.mixedAdd(doubles.points[j].neg());
|
||
}
|
||
a = a.add(b);
|
||
}
|
||
return a.toP();
|
||
};
|
||
|
||
BaseCurve.prototype._wnafMul = function _wnafMul(p, k) {
|
||
var w = 4;
|
||
|
||
// Precompute window
|
||
var nafPoints = p._getNAFPoints(w);
|
||
w = nafPoints.wnd;
|
||
var wnd = nafPoints.points;
|
||
|
||
// Get NAF form
|
||
var naf = getNAF(k, w, this._bitLength);
|
||
|
||
// Add `this`*(N+1) for every w-NAF index
|
||
var acc = this.jpoint(null, null, null);
|
||
for (var i = naf.length - 1; i >= 0; i--) {
|
||
// Count zeroes
|
||
for (var k = 0; i >= 0 && naf[i] === 0; i--)
|
||
k++;
|
||
if (i >= 0)
|
||
k++;
|
||
acc = acc.dblp(k);
|
||
|
||
if (i < 0)
|
||
break;
|
||
var z = naf[i];
|
||
assert(z !== 0);
|
||
if (p.type === 'affine') {
|
||
// J +- P
|
||
if (z > 0)
|
||
acc = acc.mixedAdd(wnd[(z - 1) >> 1]);
|
||
else
|
||
acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg());
|
||
} else {
|
||
// J +- J
|
||
if (z > 0)
|
||
acc = acc.add(wnd[(z - 1) >> 1]);
|
||
else
|
||
acc = acc.add(wnd[(-z - 1) >> 1].neg());
|
||
}
|
||
}
|
||
return p.type === 'affine' ? acc.toP() : acc;
|
||
};
|
||
|
||
BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW,
|
||
points,
|
||
coeffs,
|
||
len,
|
||
jacobianResult) {
|
||
var wndWidth = this._wnafT1;
|
||
var wnd = this._wnafT2;
|
||
var naf = this._wnafT3;
|
||
|
||
// Fill all arrays
|
||
var max = 0;
|
||
for (var i = 0; i < len; i++) {
|
||
var p = points[i];
|
||
var nafPoints = p._getNAFPoints(defW);
|
||
wndWidth[i] = nafPoints.wnd;
|
||
wnd[i] = nafPoints.points;
|
||
}
|
||
|
||
// Comb small window NAFs
|
||
for (var i = len - 1; i >= 1; i -= 2) {
|
||
var a = i - 1;
|
||
var b = i;
|
||
if (wndWidth[a] !== 1 || wndWidth[b] !== 1) {
|
||
naf[a] = getNAF(coeffs[a], wndWidth[a], this._bitLength);
|
||
naf[b] = getNAF(coeffs[b], wndWidth[b], this._bitLength);
|
||
max = Math.max(naf[a].length, max);
|
||
max = Math.max(naf[b].length, max);
|
||
continue;
|
||
}
|
||
|
||
var comb = [
|
||
points[a], /* 1 */
|
||
null, /* 3 */
|
||
null, /* 5 */
|
||
points[b] /* 7 */
|
||
];
|
||
|
||
// Try to avoid Projective points, if possible
|
||
if (points[a].y.cmp(points[b].y) === 0) {
|
||
comb[1] = points[a].add(points[b]);
|
||
comb[2] = points[a].toJ().mixedAdd(points[b].neg());
|
||
} else if (points[a].y.cmp(points[b].y.redNeg()) === 0) {
|
||
comb[1] = points[a].toJ().mixedAdd(points[b]);
|
||
comb[2] = points[a].add(points[b].neg());
|
||
} else {
|
||
comb[1] = points[a].toJ().mixedAdd(points[b]);
|
||
comb[2] = points[a].toJ().mixedAdd(points[b].neg());
|
||
}
|
||
|
||
var index = [
|
||
-3, /* -1 -1 */
|
||
-1, /* -1 0 */
|
||
-5, /* -1 1 */
|
||
-7, /* 0 -1 */
|
||
0, /* 0 0 */
|
||
7, /* 0 1 */
|
||
5, /* 1 -1 */
|
||
1, /* 1 0 */
|
||
3 /* 1 1 */
|
||
];
|
||
|
||
var jsf = getJSF(coeffs[a], coeffs[b]);
|
||
max = Math.max(jsf[0].length, max);
|
||
naf[a] = new Array(max);
|
||
naf[b] = new Array(max);
|
||
for (var j = 0; j < max; j++) {
|
||
var ja = jsf[0][j] | 0;
|
||
var jb = jsf[1][j] | 0;
|
||
|
||
naf[a][j] = index[(ja + 1) * 3 + (jb + 1)];
|
||
naf[b][j] = 0;
|
||
wnd[a] = comb;
|
||
}
|
||
}
|
||
|
||
var acc = this.jpoint(null, null, null);
|
||
var tmp = this._wnafT4;
|
||
for (var i = max; i >= 0; i--) {
|
||
var k = 0;
|
||
|
||
while (i >= 0) {
|
||
var zero = true;
|
||
for (var j = 0; j < len; j++) {
|
||
tmp[j] = naf[j][i] | 0;
|
||
if (tmp[j] !== 0)
|
||
zero = false;
|
||
}
|
||
if (!zero)
|
||
break;
|
||
k++;
|
||
i--;
|
||
}
|
||
if (i >= 0)
|
||
k++;
|
||
acc = acc.dblp(k);
|
||
if (i < 0)
|
||
break;
|
||
|
||
for (var j = 0; j < len; j++) {
|
||
var z = tmp[j];
|
||
var p;
|
||
if (z === 0)
|
||
continue;
|
||
else if (z > 0)
|
||
p = wnd[j][(z - 1) >> 1];
|
||
else if (z < 0)
|
||
p = wnd[j][(-z - 1) >> 1].neg();
|
||
|
||
if (p.type === 'affine')
|
||
acc = acc.mixedAdd(p);
|
||
else
|
||
acc = acc.add(p);
|
||
}
|
||
}
|
||
// Zeroify references
|
||
for (var i = 0; i < len; i++)
|
||
wnd[i] = null;
|
||
|
||
if (jacobianResult)
|
||
return acc;
|
||
else
|
||
return acc.toP();
|
||
};
|
||
|
||
function BasePoint(curve, type) {
|
||
this.curve = curve;
|
||
this.type = type;
|
||
this.precomputed = null;
|
||
}
|
||
BaseCurve.BasePoint = BasePoint;
|
||
|
||
BasePoint.prototype.eq = function eq(/*other*/) {
|
||
throw new Error('Not implemented');
|
||
};
|
||
|
||
BasePoint.prototype.validate = function validate() {
|
||
return this.curve.validate(this);
|
||
};
|
||
|
||
BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
|
||
bytes = utils.toArray(bytes, enc);
|
||
|
||
var len = this.p.byteLength();
|
||
|
||
// uncompressed, hybrid-odd, hybrid-even
|
||
if ((bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) &&
|
||
bytes.length - 1 === 2 * len) {
|
||
if (bytes[0] === 0x06)
|
||
assert(bytes[bytes.length - 1] % 2 === 0);
|
||
else if (bytes[0] === 0x07)
|
||
assert(bytes[bytes.length - 1] % 2 === 1);
|
||
|
||
var res = this.point(bytes.slice(1, 1 + len),
|
||
bytes.slice(1 + len, 1 + 2 * len));
|
||
|
||
return res;
|
||
} else if ((bytes[0] === 0x02 || bytes[0] === 0x03) &&
|
||
bytes.length - 1 === len) {
|
||
return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03);
|
||
}
|
||
throw new Error('Unknown point format');
|
||
};
|
||
|
||
BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) {
|
||
return this.encode(enc, true);
|
||
};
|
||
|
||
BasePoint.prototype._encode = function _encode(compact) {
|
||
var len = this.curve.p.byteLength();
|
||
var x = this.getX().toArray('be', len);
|
||
|
||
if (compact)
|
||
return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x);
|
||
|
||
return [ 0x04 ].concat(x, this.getY().toArray('be', len)) ;
|
||
};
|
||
|
||
BasePoint.prototype.encode = function encode(enc, compact) {
|
||
return utils.encode(this._encode(compact), enc);
|
||
};
|
||
|
||
BasePoint.prototype.precompute = function precompute(power) {
|
||
if (this.precomputed)
|
||
return this;
|
||
|
||
var precomputed = {
|
||
doubles: null,
|
||
naf: null,
|
||
beta: null
|
||
};
|
||
precomputed.naf = this._getNAFPoints(8);
|
||
precomputed.doubles = this._getDoubles(4, power);
|
||
precomputed.beta = this._getBeta();
|
||
this.precomputed = precomputed;
|
||
|
||
return this;
|
||
};
|
||
|
||
BasePoint.prototype._hasDoubles = function _hasDoubles(k) {
|
||
if (!this.precomputed)
|
||
return false;
|
||
|
||
var doubles = this.precomputed.doubles;
|
||
if (!doubles)
|
||
return false;
|
||
|
||
return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step);
|
||
};
|
||
|
||
BasePoint.prototype._getDoubles = function _getDoubles(step, power) {
|
||
if (this.precomputed && this.precomputed.doubles)
|
||
return this.precomputed.doubles;
|
||
|
||
var doubles = [ this ];
|
||
var acc = this;
|
||
for (var i = 0; i < power; i += step) {
|
||
for (var j = 0; j < step; j++)
|
||
acc = acc.dbl();
|
||
doubles.push(acc);
|
||
}
|
||
return {
|
||
step: step,
|
||
points: doubles
|
||
};
|
||
};
|
||
|
||
BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) {
|
||
if (this.precomputed && this.precomputed.naf)
|
||
return this.precomputed.naf;
|
||
|
||
var res = [ this ];
|
||
var max = (1 << wnd) - 1;
|
||
var dbl = max === 1 ? null : this.dbl();
|
||
for (var i = 1; i < max; i++)
|
||
res[i] = res[i - 1].add(dbl);
|
||
return {
|
||
wnd: wnd,
|
||
points: res
|
||
};
|
||
};
|
||
|
||
BasePoint.prototype._getBeta = function _getBeta() {
|
||
return null;
|
||
};
|
||
|
||
BasePoint.prototype.dblp = function dblp(k) {
|
||
var r = this;
|
||
for (var i = 0; i < k; i++)
|
||
r = r.dbl();
|
||
return r;
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/elliptic/lib/elliptic/curve/edwards.js":
|
||
/*!*************************************************************!*\
|
||
!*** ./node_modules/elliptic/lib/elliptic/curve/edwards.js ***!
|
||
\*************************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var utils = __webpack_require__(/*! ../utils */ "./node_modules/elliptic/lib/elliptic/utils.js");
|
||
var BN = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js");
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
var Base = __webpack_require__(/*! ./base */ "./node_modules/elliptic/lib/elliptic/curve/base.js");
|
||
|
||
var assert = utils.assert;
|
||
|
||
function EdwardsCurve(conf) {
|
||
// NOTE: Important as we are creating point in Base.call()
|
||
this.twisted = (conf.a | 0) !== 1;
|
||
this.mOneA = this.twisted && (conf.a | 0) === -1;
|
||
this.extended = this.mOneA;
|
||
|
||
Base.call(this, 'edwards', conf);
|
||
|
||
this.a = new BN(conf.a, 16).umod(this.red.m);
|
||
this.a = this.a.toRed(this.red);
|
||
this.c = new BN(conf.c, 16).toRed(this.red);
|
||
this.c2 = this.c.redSqr();
|
||
this.d = new BN(conf.d, 16).toRed(this.red);
|
||
this.dd = this.d.redAdd(this.d);
|
||
|
||
assert(!this.twisted || this.c.fromRed().cmpn(1) === 0);
|
||
this.oneC = (conf.c | 0) === 1;
|
||
}
|
||
inherits(EdwardsCurve, Base);
|
||
module.exports = EdwardsCurve;
|
||
|
||
EdwardsCurve.prototype._mulA = function _mulA(num) {
|
||
if (this.mOneA)
|
||
return num.redNeg();
|
||
else
|
||
return this.a.redMul(num);
|
||
};
|
||
|
||
EdwardsCurve.prototype._mulC = function _mulC(num) {
|
||
if (this.oneC)
|
||
return num;
|
||
else
|
||
return this.c.redMul(num);
|
||
};
|
||
|
||
// Just for compatibility with Short curve
|
||
EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) {
|
||
return this.point(x, y, z, t);
|
||
};
|
||
|
||
EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) {
|
||
x = new BN(x, 16);
|
||
if (!x.red)
|
||
x = x.toRed(this.red);
|
||
|
||
var x2 = x.redSqr();
|
||
var rhs = this.c2.redSub(this.a.redMul(x2));
|
||
var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2));
|
||
|
||
var y2 = rhs.redMul(lhs.redInvm());
|
||
var y = y2.redSqrt();
|
||
if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
|
||
throw new Error('invalid point');
|
||
|
||
var isOdd = y.fromRed().isOdd();
|
||
if (odd && !isOdd || !odd && isOdd)
|
||
y = y.redNeg();
|
||
|
||
return this.point(x, y);
|
||
};
|
||
|
||
EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) {
|
||
y = new BN(y, 16);
|
||
if (!y.red)
|
||
y = y.toRed(this.red);
|
||
|
||
// x^2 = (y^2 - c^2) / (c^2 d y^2 - a)
|
||
var y2 = y.redSqr();
|
||
var lhs = y2.redSub(this.c2);
|
||
var rhs = y2.redMul(this.d).redMul(this.c2).redSub(this.a);
|
||
var x2 = lhs.redMul(rhs.redInvm());
|
||
|
||
if (x2.cmp(this.zero) === 0) {
|
||
if (odd)
|
||
throw new Error('invalid point');
|
||
else
|
||
return this.point(this.zero, y);
|
||
}
|
||
|
||
var x = x2.redSqrt();
|
||
if (x.redSqr().redSub(x2).cmp(this.zero) !== 0)
|
||
throw new Error('invalid point');
|
||
|
||
if (x.fromRed().isOdd() !== odd)
|
||
x = x.redNeg();
|
||
|
||
return this.point(x, y);
|
||
};
|
||
|
||
EdwardsCurve.prototype.validate = function validate(point) {
|
||
if (point.isInfinity())
|
||
return true;
|
||
|
||
// Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2)
|
||
point.normalize();
|
||
|
||
var x2 = point.x.redSqr();
|
||
var y2 = point.y.redSqr();
|
||
var lhs = x2.redMul(this.a).redAdd(y2);
|
||
var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2)));
|
||
|
||
return lhs.cmp(rhs) === 0;
|
||
};
|
||
|
||
function Point(curve, x, y, z, t) {
|
||
Base.BasePoint.call(this, curve, 'projective');
|
||
if (x === null && y === null && z === null) {
|
||
this.x = this.curve.zero;
|
||
this.y = this.curve.one;
|
||
this.z = this.curve.one;
|
||
this.t = this.curve.zero;
|
||
this.zOne = true;
|
||
} else {
|
||
this.x = new BN(x, 16);
|
||
this.y = new BN(y, 16);
|
||
this.z = z ? new BN(z, 16) : this.curve.one;
|
||
this.t = t && new BN(t, 16);
|
||
if (!this.x.red)
|
||
this.x = this.x.toRed(this.curve.red);
|
||
if (!this.y.red)
|
||
this.y = this.y.toRed(this.curve.red);
|
||
if (!this.z.red)
|
||
this.z = this.z.toRed(this.curve.red);
|
||
if (this.t && !this.t.red)
|
||
this.t = this.t.toRed(this.curve.red);
|
||
this.zOne = this.z === this.curve.one;
|
||
|
||
// Use extended coordinates
|
||
if (this.curve.extended && !this.t) {
|
||
this.t = this.x.redMul(this.y);
|
||
if (!this.zOne)
|
||
this.t = this.t.redMul(this.z.redInvm());
|
||
}
|
||
}
|
||
}
|
||
inherits(Point, Base.BasePoint);
|
||
|
||
EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
|
||
return Point.fromJSON(this, obj);
|
||
};
|
||
|
||
EdwardsCurve.prototype.point = function point(x, y, z, t) {
|
||
return new Point(this, x, y, z, t);
|
||
};
|
||
|
||
Point.fromJSON = function fromJSON(curve, obj) {
|
||
return new Point(curve, obj[0], obj[1], obj[2]);
|
||
};
|
||
|
||
Point.prototype.inspect = function inspect() {
|
||
if (this.isInfinity())
|
||
return '<EC Point Infinity>';
|
||
return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
|
||
' y: ' + this.y.fromRed().toString(16, 2) +
|
||
' z: ' + this.z.fromRed().toString(16, 2) + '>';
|
||
};
|
||
|
||
Point.prototype.isInfinity = function isInfinity() {
|
||
// XXX This code assumes that zero is always zero in red
|
||
return this.x.cmpn(0) === 0 &&
|
||
(this.y.cmp(this.z) === 0 ||
|
||
(this.zOne && this.y.cmp(this.curve.c) === 0));
|
||
};
|
||
|
||
Point.prototype._extDbl = function _extDbl() {
|
||
// hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
|
||
// #doubling-dbl-2008-hwcd
|
||
// 4M + 4S
|
||
|
||
// A = X1^2
|
||
var a = this.x.redSqr();
|
||
// B = Y1^2
|
||
var b = this.y.redSqr();
|
||
// C = 2 * Z1^2
|
||
var c = this.z.redSqr();
|
||
c = c.redIAdd(c);
|
||
// D = a * A
|
||
var d = this.curve._mulA(a);
|
||
// E = (X1 + Y1)^2 - A - B
|
||
var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b);
|
||
// G = D + B
|
||
var g = d.redAdd(b);
|
||
// F = G - C
|
||
var f = g.redSub(c);
|
||
// H = D - B
|
||
var h = d.redSub(b);
|
||
// X3 = E * F
|
||
var nx = e.redMul(f);
|
||
// Y3 = G * H
|
||
var ny = g.redMul(h);
|
||
// T3 = E * H
|
||
var nt = e.redMul(h);
|
||
// Z3 = F * G
|
||
var nz = f.redMul(g);
|
||
return this.curve.point(nx, ny, nz, nt);
|
||
};
|
||
|
||
Point.prototype._projDbl = function _projDbl() {
|
||
// hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
|
||
// #doubling-dbl-2008-bbjlp
|
||
// #doubling-dbl-2007-bl
|
||
// and others
|
||
// Generally 3M + 4S or 2M + 4S
|
||
|
||
// B = (X1 + Y1)^2
|
||
var b = this.x.redAdd(this.y).redSqr();
|
||
// C = X1^2
|
||
var c = this.x.redSqr();
|
||
// D = Y1^2
|
||
var d = this.y.redSqr();
|
||
|
||
var nx;
|
||
var ny;
|
||
var nz;
|
||
if (this.curve.twisted) {
|
||
// E = a * C
|
||
var e = this.curve._mulA(c);
|
||
// F = E + D
|
||
var f = e.redAdd(d);
|
||
if (this.zOne) {
|
||
// X3 = (B - C - D) * (F - 2)
|
||
nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two));
|
||
// Y3 = F * (E - D)
|
||
ny = f.redMul(e.redSub(d));
|
||
// Z3 = F^2 - 2 * F
|
||
nz = f.redSqr().redSub(f).redSub(f);
|
||
} else {
|
||
// H = Z1^2
|
||
var h = this.z.redSqr();
|
||
// J = F - 2 * H
|
||
var j = f.redSub(h).redISub(h);
|
||
// X3 = (B-C-D)*J
|
||
nx = b.redSub(c).redISub(d).redMul(j);
|
||
// Y3 = F * (E - D)
|
||
ny = f.redMul(e.redSub(d));
|
||
// Z3 = F * J
|
||
nz = f.redMul(j);
|
||
}
|
||
} else {
|
||
// E = C + D
|
||
var e = c.redAdd(d);
|
||
// H = (c * Z1)^2
|
||
var h = this.curve._mulC(this.z).redSqr();
|
||
// J = E - 2 * H
|
||
var j = e.redSub(h).redSub(h);
|
||
// X3 = c * (B - E) * J
|
||
nx = this.curve._mulC(b.redISub(e)).redMul(j);
|
||
// Y3 = c * E * (C - D)
|
||
ny = this.curve._mulC(e).redMul(c.redISub(d));
|
||
// Z3 = E * J
|
||
nz = e.redMul(j);
|
||
}
|
||
return this.curve.point(nx, ny, nz);
|
||
};
|
||
|
||
Point.prototype.dbl = function dbl() {
|
||
if (this.isInfinity())
|
||
return this;
|
||
|
||
// Double in extended coordinates
|
||
if (this.curve.extended)
|
||
return this._extDbl();
|
||
else
|
||
return this._projDbl();
|
||
};
|
||
|
||
Point.prototype._extAdd = function _extAdd(p) {
|
||
// hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
|
||
// #addition-add-2008-hwcd-3
|
||
// 8M
|
||
|
||
// A = (Y1 - X1) * (Y2 - X2)
|
||
var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x));
|
||
// B = (Y1 + X1) * (Y2 + X2)
|
||
var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x));
|
||
// C = T1 * k * T2
|
||
var c = this.t.redMul(this.curve.dd).redMul(p.t);
|
||
// D = Z1 * 2 * Z2
|
||
var d = this.z.redMul(p.z.redAdd(p.z));
|
||
// E = B - A
|
||
var e = b.redSub(a);
|
||
// F = D - C
|
||
var f = d.redSub(c);
|
||
// G = D + C
|
||
var g = d.redAdd(c);
|
||
// H = B + A
|
||
var h = b.redAdd(a);
|
||
// X3 = E * F
|
||
var nx = e.redMul(f);
|
||
// Y3 = G * H
|
||
var ny = g.redMul(h);
|
||
// T3 = E * H
|
||
var nt = e.redMul(h);
|
||
// Z3 = F * G
|
||
var nz = f.redMul(g);
|
||
return this.curve.point(nx, ny, nz, nt);
|
||
};
|
||
|
||
Point.prototype._projAdd = function _projAdd(p) {
|
||
// hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
|
||
// #addition-add-2008-bbjlp
|
||
// #addition-add-2007-bl
|
||
// 10M + 1S
|
||
|
||
// A = Z1 * Z2
|
||
var a = this.z.redMul(p.z);
|
||
// B = A^2
|
||
var b = a.redSqr();
|
||
// C = X1 * X2
|
||
var c = this.x.redMul(p.x);
|
||
// D = Y1 * Y2
|
||
var d = this.y.redMul(p.y);
|
||
// E = d * C * D
|
||
var e = this.curve.d.redMul(c).redMul(d);
|
||
// F = B - E
|
||
var f = b.redSub(e);
|
||
// G = B + E
|
||
var g = b.redAdd(e);
|
||
// X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D)
|
||
var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d);
|
||
var nx = a.redMul(f).redMul(tmp);
|
||
var ny;
|
||
var nz;
|
||
if (this.curve.twisted) {
|
||
// Y3 = A * G * (D - a * C)
|
||
ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c)));
|
||
// Z3 = F * G
|
||
nz = f.redMul(g);
|
||
} else {
|
||
// Y3 = A * G * (D - C)
|
||
ny = a.redMul(g).redMul(d.redSub(c));
|
||
// Z3 = c * F * G
|
||
nz = this.curve._mulC(f).redMul(g);
|
||
}
|
||
return this.curve.point(nx, ny, nz);
|
||
};
|
||
|
||
Point.prototype.add = function add(p) {
|
||
if (this.isInfinity())
|
||
return p;
|
||
if (p.isInfinity())
|
||
return this;
|
||
|
||
if (this.curve.extended)
|
||
return this._extAdd(p);
|
||
else
|
||
return this._projAdd(p);
|
||
};
|
||
|
||
Point.prototype.mul = function mul(k) {
|
||
if (this._hasDoubles(k))
|
||
return this.curve._fixedNafMul(this, k);
|
||
else
|
||
return this.curve._wnafMul(this, k);
|
||
};
|
||
|
||
Point.prototype.mulAdd = function mulAdd(k1, p, k2) {
|
||
return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, false);
|
||
};
|
||
|
||
Point.prototype.jmulAdd = function jmulAdd(k1, p, k2) {
|
||
return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, true);
|
||
};
|
||
|
||
Point.prototype.normalize = function normalize() {
|
||
if (this.zOne)
|
||
return this;
|
||
|
||
// Normalize coordinates
|
||
var zi = this.z.redInvm();
|
||
this.x = this.x.redMul(zi);
|
||
this.y = this.y.redMul(zi);
|
||
if (this.t)
|
||
this.t = this.t.redMul(zi);
|
||
this.z = this.curve.one;
|
||
this.zOne = true;
|
||
return this;
|
||
};
|
||
|
||
Point.prototype.neg = function neg() {
|
||
return this.curve.point(this.x.redNeg(),
|
||
this.y,
|
||
this.z,
|
||
this.t && this.t.redNeg());
|
||
};
|
||
|
||
Point.prototype.getX = function getX() {
|
||
this.normalize();
|
||
return this.x.fromRed();
|
||
};
|
||
|
||
Point.prototype.getY = function getY() {
|
||
this.normalize();
|
||
return this.y.fromRed();
|
||
};
|
||
|
||
Point.prototype.eq = function eq(other) {
|
||
return this === other ||
|
||
this.getX().cmp(other.getX()) === 0 &&
|
||
this.getY().cmp(other.getY()) === 0;
|
||
};
|
||
|
||
Point.prototype.eqXToP = function eqXToP(x) {
|
||
var rx = x.toRed(this.curve.red).redMul(this.z);
|
||
if (this.x.cmp(rx) === 0)
|
||
return true;
|
||
|
||
var xc = x.clone();
|
||
var t = this.curve.redN.redMul(this.z);
|
||
for (;;) {
|
||
xc.iadd(this.curve.n);
|
||
if (xc.cmp(this.curve.p) >= 0)
|
||
return false;
|
||
|
||
rx.redIAdd(t);
|
||
if (this.x.cmp(rx) === 0)
|
||
return true;
|
||
}
|
||
};
|
||
|
||
// Compatibility with BaseCurve
|
||
Point.prototype.toP = Point.prototype.normalize;
|
||
Point.prototype.mixedAdd = Point.prototype.add;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/elliptic/lib/elliptic/curve/index.js":
|
||
/*!***********************************************************!*\
|
||
!*** ./node_modules/elliptic/lib/elliptic/curve/index.js ***!
|
||
\***********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var curve = exports;
|
||
|
||
curve.base = __webpack_require__(/*! ./base */ "./node_modules/elliptic/lib/elliptic/curve/base.js");
|
||
curve.short = __webpack_require__(/*! ./short */ "./node_modules/elliptic/lib/elliptic/curve/short.js");
|
||
curve.mont = __webpack_require__(/*! ./mont */ "./node_modules/elliptic/lib/elliptic/curve/mont.js");
|
||
curve.edwards = __webpack_require__(/*! ./edwards */ "./node_modules/elliptic/lib/elliptic/curve/edwards.js");
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/elliptic/lib/elliptic/curve/mont.js":
|
||
/*!**********************************************************!*\
|
||
!*** ./node_modules/elliptic/lib/elliptic/curve/mont.js ***!
|
||
\**********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var BN = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js");
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
var Base = __webpack_require__(/*! ./base */ "./node_modules/elliptic/lib/elliptic/curve/base.js");
|
||
|
||
var utils = __webpack_require__(/*! ../utils */ "./node_modules/elliptic/lib/elliptic/utils.js");
|
||
|
||
function MontCurve(conf) {
|
||
Base.call(this, 'mont', conf);
|
||
|
||
this.a = new BN(conf.a, 16).toRed(this.red);
|
||
this.b = new BN(conf.b, 16).toRed(this.red);
|
||
this.i4 = new BN(4).toRed(this.red).redInvm();
|
||
this.two = new BN(2).toRed(this.red);
|
||
this.a24 = this.i4.redMul(this.a.redAdd(this.two));
|
||
}
|
||
inherits(MontCurve, Base);
|
||
module.exports = MontCurve;
|
||
|
||
MontCurve.prototype.validate = function validate(point) {
|
||
var x = point.normalize().x;
|
||
var x2 = x.redSqr();
|
||
var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x);
|
||
var y = rhs.redSqrt();
|
||
|
||
return y.redSqr().cmp(rhs) === 0;
|
||
};
|
||
|
||
function Point(curve, x, z) {
|
||
Base.BasePoint.call(this, curve, 'projective');
|
||
if (x === null && z === null) {
|
||
this.x = this.curve.one;
|
||
this.z = this.curve.zero;
|
||
} else {
|
||
this.x = new BN(x, 16);
|
||
this.z = new BN(z, 16);
|
||
if (!this.x.red)
|
||
this.x = this.x.toRed(this.curve.red);
|
||
if (!this.z.red)
|
||
this.z = this.z.toRed(this.curve.red);
|
||
}
|
||
}
|
||
inherits(Point, Base.BasePoint);
|
||
|
||
MontCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
|
||
return this.point(utils.toArray(bytes, enc), 1);
|
||
};
|
||
|
||
MontCurve.prototype.point = function point(x, z) {
|
||
return new Point(this, x, z);
|
||
};
|
||
|
||
MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
|
||
return Point.fromJSON(this, obj);
|
||
};
|
||
|
||
Point.prototype.precompute = function precompute() {
|
||
// No-op
|
||
};
|
||
|
||
Point.prototype._encode = function _encode() {
|
||
return this.getX().toArray('be', this.curve.p.byteLength());
|
||
};
|
||
|
||
Point.fromJSON = function fromJSON(curve, obj) {
|
||
return new Point(curve, obj[0], obj[1] || curve.one);
|
||
};
|
||
|
||
Point.prototype.inspect = function inspect() {
|
||
if (this.isInfinity())
|
||
return '<EC Point Infinity>';
|
||
return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
|
||
' z: ' + this.z.fromRed().toString(16, 2) + '>';
|
||
};
|
||
|
||
Point.prototype.isInfinity = function isInfinity() {
|
||
// XXX This code assumes that zero is always zero in red
|
||
return this.z.cmpn(0) === 0;
|
||
};
|
||
|
||
Point.prototype.dbl = function dbl() {
|
||
// http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3
|
||
// 2M + 2S + 4A
|
||
|
||
// A = X1 + Z1
|
||
var a = this.x.redAdd(this.z);
|
||
// AA = A^2
|
||
var aa = a.redSqr();
|
||
// B = X1 - Z1
|
||
var b = this.x.redSub(this.z);
|
||
// BB = B^2
|
||
var bb = b.redSqr();
|
||
// C = AA - BB
|
||
var c = aa.redSub(bb);
|
||
// X3 = AA * BB
|
||
var nx = aa.redMul(bb);
|
||
// Z3 = C * (BB + A24 * C)
|
||
var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c)));
|
||
return this.curve.point(nx, nz);
|
||
};
|
||
|
||
Point.prototype.add = function add() {
|
||
throw new Error('Not supported on Montgomery curve');
|
||
};
|
||
|
||
Point.prototype.diffAdd = function diffAdd(p, diff) {
|
||
// http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3
|
||
// 4M + 2S + 6A
|
||
|
||
// A = X2 + Z2
|
||
var a = this.x.redAdd(this.z);
|
||
// B = X2 - Z2
|
||
var b = this.x.redSub(this.z);
|
||
// C = X3 + Z3
|
||
var c = p.x.redAdd(p.z);
|
||
// D = X3 - Z3
|
||
var d = p.x.redSub(p.z);
|
||
// DA = D * A
|
||
var da = d.redMul(a);
|
||
// CB = C * B
|
||
var cb = c.redMul(b);
|
||
// X5 = Z1 * (DA + CB)^2
|
||
var nx = diff.z.redMul(da.redAdd(cb).redSqr());
|
||
// Z5 = X1 * (DA - CB)^2
|
||
var nz = diff.x.redMul(da.redISub(cb).redSqr());
|
||
return this.curve.point(nx, nz);
|
||
};
|
||
|
||
Point.prototype.mul = function mul(k) {
|
||
var t = k.clone();
|
||
var a = this; // (N / 2) * Q + Q
|
||
var b = this.curve.point(null, null); // (N / 2) * Q
|
||
var c = this; // Q
|
||
|
||
for (var bits = []; t.cmpn(0) !== 0; t.iushrn(1))
|
||
bits.push(t.andln(1));
|
||
|
||
for (var i = bits.length - 1; i >= 0; i--) {
|
||
if (bits[i] === 0) {
|
||
// N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q
|
||
a = a.diffAdd(b, c);
|
||
// N * Q = 2 * ((N / 2) * Q + Q))
|
||
b = b.dbl();
|
||
} else {
|
||
// N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q)
|
||
b = a.diffAdd(b, c);
|
||
// N * Q + Q = 2 * ((N / 2) * Q + Q)
|
||
a = a.dbl();
|
||
}
|
||
}
|
||
return b;
|
||
};
|
||
|
||
Point.prototype.mulAdd = function mulAdd() {
|
||
throw new Error('Not supported on Montgomery curve');
|
||
};
|
||
|
||
Point.prototype.jumlAdd = function jumlAdd() {
|
||
throw new Error('Not supported on Montgomery curve');
|
||
};
|
||
|
||
Point.prototype.eq = function eq(other) {
|
||
return this.getX().cmp(other.getX()) === 0;
|
||
};
|
||
|
||
Point.prototype.normalize = function normalize() {
|
||
this.x = this.x.redMul(this.z.redInvm());
|
||
this.z = this.curve.one;
|
||
return this;
|
||
};
|
||
|
||
Point.prototype.getX = function getX() {
|
||
// Normalize coordinates
|
||
this.normalize();
|
||
|
||
return this.x.fromRed();
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/elliptic/lib/elliptic/curve/short.js":
|
||
/*!***********************************************************!*\
|
||
!*** ./node_modules/elliptic/lib/elliptic/curve/short.js ***!
|
||
\***********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var utils = __webpack_require__(/*! ../utils */ "./node_modules/elliptic/lib/elliptic/utils.js");
|
||
var BN = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js");
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
var Base = __webpack_require__(/*! ./base */ "./node_modules/elliptic/lib/elliptic/curve/base.js");
|
||
|
||
var assert = utils.assert;
|
||
|
||
function ShortCurve(conf) {
|
||
Base.call(this, 'short', conf);
|
||
|
||
this.a = new BN(conf.a, 16).toRed(this.red);
|
||
this.b = new BN(conf.b, 16).toRed(this.red);
|
||
this.tinv = this.two.redInvm();
|
||
|
||
this.zeroA = this.a.fromRed().cmpn(0) === 0;
|
||
this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0;
|
||
|
||
// If the curve is endomorphic, precalculate beta and lambda
|
||
this.endo = this._getEndomorphism(conf);
|
||
this._endoWnafT1 = new Array(4);
|
||
this._endoWnafT2 = new Array(4);
|
||
}
|
||
inherits(ShortCurve, Base);
|
||
module.exports = ShortCurve;
|
||
|
||
ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) {
|
||
// No efficient endomorphism
|
||
if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1)
|
||
return;
|
||
|
||
// Compute beta and lambda, that lambda * P = (beta * Px; Py)
|
||
var beta;
|
||
var lambda;
|
||
if (conf.beta) {
|
||
beta = new BN(conf.beta, 16).toRed(this.red);
|
||
} else {
|
||
var betas = this._getEndoRoots(this.p);
|
||
// Choose the smallest beta
|
||
beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1];
|
||
beta = beta.toRed(this.red);
|
||
}
|
||
if (conf.lambda) {
|
||
lambda = new BN(conf.lambda, 16);
|
||
} else {
|
||
// Choose the lambda that is matching selected beta
|
||
var lambdas = this._getEndoRoots(this.n);
|
||
if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) {
|
||
lambda = lambdas[0];
|
||
} else {
|
||
lambda = lambdas[1];
|
||
assert(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0);
|
||
}
|
||
}
|
||
|
||
// Get basis vectors, used for balanced length-two representation
|
||
var basis;
|
||
if (conf.basis) {
|
||
basis = conf.basis.map(function(vec) {
|
||
return {
|
||
a: new BN(vec.a, 16),
|
||
b: new BN(vec.b, 16)
|
||
};
|
||
});
|
||
} else {
|
||
basis = this._getEndoBasis(lambda);
|
||
}
|
||
|
||
return {
|
||
beta: beta,
|
||
lambda: lambda,
|
||
basis: basis
|
||
};
|
||
};
|
||
|
||
ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) {
|
||
// Find roots of for x^2 + x + 1 in F
|
||
// Root = (-1 +- Sqrt(-3)) / 2
|
||
//
|
||
var red = num === this.p ? this.red : BN.mont(num);
|
||
var tinv = new BN(2).toRed(red).redInvm();
|
||
var ntinv = tinv.redNeg();
|
||
|
||
var s = new BN(3).toRed(red).redNeg().redSqrt().redMul(tinv);
|
||
|
||
var l1 = ntinv.redAdd(s).fromRed();
|
||
var l2 = ntinv.redSub(s).fromRed();
|
||
return [ l1, l2 ];
|
||
};
|
||
|
||
ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) {
|
||
// aprxSqrt >= sqrt(this.n)
|
||
var aprxSqrt = this.n.ushrn(Math.floor(this.n.bitLength() / 2));
|
||
|
||
// 3.74
|
||
// Run EGCD, until r(L + 1) < aprxSqrt
|
||
var u = lambda;
|
||
var v = this.n.clone();
|
||
var x1 = new BN(1);
|
||
var y1 = new BN(0);
|
||
var x2 = new BN(0);
|
||
var y2 = new BN(1);
|
||
|
||
// NOTE: all vectors are roots of: a + b * lambda = 0 (mod n)
|
||
var a0;
|
||
var b0;
|
||
// First vector
|
||
var a1;
|
||
var b1;
|
||
// Second vector
|
||
var a2;
|
||
var b2;
|
||
|
||
var prevR;
|
||
var i = 0;
|
||
var r;
|
||
var x;
|
||
while (u.cmpn(0) !== 0) {
|
||
var q = v.div(u);
|
||
r = v.sub(q.mul(u));
|
||
x = x2.sub(q.mul(x1));
|
||
var y = y2.sub(q.mul(y1));
|
||
|
||
if (!a1 && r.cmp(aprxSqrt) < 0) {
|
||
a0 = prevR.neg();
|
||
b0 = x1;
|
||
a1 = r.neg();
|
||
b1 = x;
|
||
} else if (a1 && ++i === 2) {
|
||
break;
|
||
}
|
||
prevR = r;
|
||
|
||
v = u;
|
||
u = r;
|
||
x2 = x1;
|
||
x1 = x;
|
||
y2 = y1;
|
||
y1 = y;
|
||
}
|
||
a2 = r.neg();
|
||
b2 = x;
|
||
|
||
var len1 = a1.sqr().add(b1.sqr());
|
||
var len2 = a2.sqr().add(b2.sqr());
|
||
if (len2.cmp(len1) >= 0) {
|
||
a2 = a0;
|
||
b2 = b0;
|
||
}
|
||
|
||
// Normalize signs
|
||
if (a1.negative) {
|
||
a1 = a1.neg();
|
||
b1 = b1.neg();
|
||
}
|
||
if (a2.negative) {
|
||
a2 = a2.neg();
|
||
b2 = b2.neg();
|
||
}
|
||
|
||
return [
|
||
{ a: a1, b: b1 },
|
||
{ a: a2, b: b2 }
|
||
];
|
||
};
|
||
|
||
ShortCurve.prototype._endoSplit = function _endoSplit(k) {
|
||
var basis = this.endo.basis;
|
||
var v1 = basis[0];
|
||
var v2 = basis[1];
|
||
|
||
var c1 = v2.b.mul(k).divRound(this.n);
|
||
var c2 = v1.b.neg().mul(k).divRound(this.n);
|
||
|
||
var p1 = c1.mul(v1.a);
|
||
var p2 = c2.mul(v2.a);
|
||
var q1 = c1.mul(v1.b);
|
||
var q2 = c2.mul(v2.b);
|
||
|
||
// Calculate answer
|
||
var k1 = k.sub(p1).sub(p2);
|
||
var k2 = q1.add(q2).neg();
|
||
return { k1: k1, k2: k2 };
|
||
};
|
||
|
||
ShortCurve.prototype.pointFromX = function pointFromX(x, odd) {
|
||
x = new BN(x, 16);
|
||
if (!x.red)
|
||
x = x.toRed(this.red);
|
||
|
||
var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b);
|
||
var y = y2.redSqrt();
|
||
if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
|
||
throw new Error('invalid point');
|
||
|
||
// XXX Is there any way to tell if the number is odd without converting it
|
||
// to non-red form?
|
||
var isOdd = y.fromRed().isOdd();
|
||
if (odd && !isOdd || !odd && isOdd)
|
||
y = y.redNeg();
|
||
|
||
return this.point(x, y);
|
||
};
|
||
|
||
ShortCurve.prototype.validate = function validate(point) {
|
||
if (point.inf)
|
||
return true;
|
||
|
||
var x = point.x;
|
||
var y = point.y;
|
||
|
||
var ax = this.a.redMul(x);
|
||
var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b);
|
||
return y.redSqr().redISub(rhs).cmpn(0) === 0;
|
||
};
|
||
|
||
ShortCurve.prototype._endoWnafMulAdd =
|
||
function _endoWnafMulAdd(points, coeffs, jacobianResult) {
|
||
var npoints = this._endoWnafT1;
|
||
var ncoeffs = this._endoWnafT2;
|
||
for (var i = 0; i < points.length; i++) {
|
||
var split = this._endoSplit(coeffs[i]);
|
||
var p = points[i];
|
||
var beta = p._getBeta();
|
||
|
||
if (split.k1.negative) {
|
||
split.k1.ineg();
|
||
p = p.neg(true);
|
||
}
|
||
if (split.k2.negative) {
|
||
split.k2.ineg();
|
||
beta = beta.neg(true);
|
||
}
|
||
|
||
npoints[i * 2] = p;
|
||
npoints[i * 2 + 1] = beta;
|
||
ncoeffs[i * 2] = split.k1;
|
||
ncoeffs[i * 2 + 1] = split.k2;
|
||
}
|
||
var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2, jacobianResult);
|
||
|
||
// Clean-up references to points and coefficients
|
||
for (var j = 0; j < i * 2; j++) {
|
||
npoints[j] = null;
|
||
ncoeffs[j] = null;
|
||
}
|
||
return res;
|
||
};
|
||
|
||
function Point(curve, x, y, isRed) {
|
||
Base.BasePoint.call(this, curve, 'affine');
|
||
if (x === null && y === null) {
|
||
this.x = null;
|
||
this.y = null;
|
||
this.inf = true;
|
||
} else {
|
||
this.x = new BN(x, 16);
|
||
this.y = new BN(y, 16);
|
||
// Force redgomery representation when loading from JSON
|
||
if (isRed) {
|
||
this.x.forceRed(this.curve.red);
|
||
this.y.forceRed(this.curve.red);
|
||
}
|
||
if (!this.x.red)
|
||
this.x = this.x.toRed(this.curve.red);
|
||
if (!this.y.red)
|
||
this.y = this.y.toRed(this.curve.red);
|
||
this.inf = false;
|
||
}
|
||
}
|
||
inherits(Point, Base.BasePoint);
|
||
|
||
ShortCurve.prototype.point = function point(x, y, isRed) {
|
||
return new Point(this, x, y, isRed);
|
||
};
|
||
|
||
ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) {
|
||
return Point.fromJSON(this, obj, red);
|
||
};
|
||
|
||
Point.prototype._getBeta = function _getBeta() {
|
||
if (!this.curve.endo)
|
||
return;
|
||
|
||
var pre = this.precomputed;
|
||
if (pre && pre.beta)
|
||
return pre.beta;
|
||
|
||
var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y);
|
||
if (pre) {
|
||
var curve = this.curve;
|
||
var endoMul = function(p) {
|
||
return curve.point(p.x.redMul(curve.endo.beta), p.y);
|
||
};
|
||
pre.beta = beta;
|
||
beta.precomputed = {
|
||
beta: null,
|
||
naf: pre.naf && {
|
||
wnd: pre.naf.wnd,
|
||
points: pre.naf.points.map(endoMul)
|
||
},
|
||
doubles: pre.doubles && {
|
||
step: pre.doubles.step,
|
||
points: pre.doubles.points.map(endoMul)
|
||
}
|
||
};
|
||
}
|
||
return beta;
|
||
};
|
||
|
||
Point.prototype.toJSON = function toJSON() {
|
||
if (!this.precomputed)
|
||
return [ this.x, this.y ];
|
||
|
||
return [ this.x, this.y, this.precomputed && {
|
||
doubles: this.precomputed.doubles && {
|
||
step: this.precomputed.doubles.step,
|
||
points: this.precomputed.doubles.points.slice(1)
|
||
},
|
||
naf: this.precomputed.naf && {
|
||
wnd: this.precomputed.naf.wnd,
|
||
points: this.precomputed.naf.points.slice(1)
|
||
}
|
||
} ];
|
||
};
|
||
|
||
Point.fromJSON = function fromJSON(curve, obj, red) {
|
||
if (typeof obj === 'string')
|
||
obj = JSON.parse(obj);
|
||
var res = curve.point(obj[0], obj[1], red);
|
||
if (!obj[2])
|
||
return res;
|
||
|
||
function obj2point(obj) {
|
||
return curve.point(obj[0], obj[1], red);
|
||
}
|
||
|
||
var pre = obj[2];
|
||
res.precomputed = {
|
||
beta: null,
|
||
doubles: pre.doubles && {
|
||
step: pre.doubles.step,
|
||
points: [ res ].concat(pre.doubles.points.map(obj2point))
|
||
},
|
||
naf: pre.naf && {
|
||
wnd: pre.naf.wnd,
|
||
points: [ res ].concat(pre.naf.points.map(obj2point))
|
||
}
|
||
};
|
||
return res;
|
||
};
|
||
|
||
Point.prototype.inspect = function inspect() {
|
||
if (this.isInfinity())
|
||
return '<EC Point Infinity>';
|
||
return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
|
||
' y: ' + this.y.fromRed().toString(16, 2) + '>';
|
||
};
|
||
|
||
Point.prototype.isInfinity = function isInfinity() {
|
||
return this.inf;
|
||
};
|
||
|
||
Point.prototype.add = function add(p) {
|
||
// O + P = P
|
||
if (this.inf)
|
||
return p;
|
||
|
||
// P + O = P
|
||
if (p.inf)
|
||
return this;
|
||
|
||
// P + P = 2P
|
||
if (this.eq(p))
|
||
return this.dbl();
|
||
|
||
// P + (-P) = O
|
||
if (this.neg().eq(p))
|
||
return this.curve.point(null, null);
|
||
|
||
// P + Q = O
|
||
if (this.x.cmp(p.x) === 0)
|
||
return this.curve.point(null, null);
|
||
|
||
var c = this.y.redSub(p.y);
|
||
if (c.cmpn(0) !== 0)
|
||
c = c.redMul(this.x.redSub(p.x).redInvm());
|
||
var nx = c.redSqr().redISub(this.x).redISub(p.x);
|
||
var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
|
||
return this.curve.point(nx, ny);
|
||
};
|
||
|
||
Point.prototype.dbl = function dbl() {
|
||
if (this.inf)
|
||
return this;
|
||
|
||
// 2P = O
|
||
var ys1 = this.y.redAdd(this.y);
|
||
if (ys1.cmpn(0) === 0)
|
||
return this.curve.point(null, null);
|
||
|
||
var a = this.curve.a;
|
||
|
||
var x2 = this.x.redSqr();
|
||
var dyinv = ys1.redInvm();
|
||
var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv);
|
||
|
||
var nx = c.redSqr().redISub(this.x.redAdd(this.x));
|
||
var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
|
||
return this.curve.point(nx, ny);
|
||
};
|
||
|
||
Point.prototype.getX = function getX() {
|
||
return this.x.fromRed();
|
||
};
|
||
|
||
Point.prototype.getY = function getY() {
|
||
return this.y.fromRed();
|
||
};
|
||
|
||
Point.prototype.mul = function mul(k) {
|
||
k = new BN(k, 16);
|
||
if (this.isInfinity())
|
||
return this;
|
||
else if (this._hasDoubles(k))
|
||
return this.curve._fixedNafMul(this, k);
|
||
else if (this.curve.endo)
|
||
return this.curve._endoWnafMulAdd([ this ], [ k ]);
|
||
else
|
||
return this.curve._wnafMul(this, k);
|
||
};
|
||
|
||
Point.prototype.mulAdd = function mulAdd(k1, p2, k2) {
|
||
var points = [ this, p2 ];
|
||
var coeffs = [ k1, k2 ];
|
||
if (this.curve.endo)
|
||
return this.curve._endoWnafMulAdd(points, coeffs);
|
||
else
|
||
return this.curve._wnafMulAdd(1, points, coeffs, 2);
|
||
};
|
||
|
||
Point.prototype.jmulAdd = function jmulAdd(k1, p2, k2) {
|
||
var points = [ this, p2 ];
|
||
var coeffs = [ k1, k2 ];
|
||
if (this.curve.endo)
|
||
return this.curve._endoWnafMulAdd(points, coeffs, true);
|
||
else
|
||
return this.curve._wnafMulAdd(1, points, coeffs, 2, true);
|
||
};
|
||
|
||
Point.prototype.eq = function eq(p) {
|
||
return this === p ||
|
||
this.inf === p.inf &&
|
||
(this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0);
|
||
};
|
||
|
||
Point.prototype.neg = function neg(_precompute) {
|
||
if (this.inf)
|
||
return this;
|
||
|
||
var res = this.curve.point(this.x, this.y.redNeg());
|
||
if (_precompute && this.precomputed) {
|
||
var pre = this.precomputed;
|
||
var negate = function(p) {
|
||
return p.neg();
|
||
};
|
||
res.precomputed = {
|
||
naf: pre.naf && {
|
||
wnd: pre.naf.wnd,
|
||
points: pre.naf.points.map(negate)
|
||
},
|
||
doubles: pre.doubles && {
|
||
step: pre.doubles.step,
|
||
points: pre.doubles.points.map(negate)
|
||
}
|
||
};
|
||
}
|
||
return res;
|
||
};
|
||
|
||
Point.prototype.toJ = function toJ() {
|
||
if (this.inf)
|
||
return this.curve.jpoint(null, null, null);
|
||
|
||
var res = this.curve.jpoint(this.x, this.y, this.curve.one);
|
||
return res;
|
||
};
|
||
|
||
function JPoint(curve, x, y, z) {
|
||
Base.BasePoint.call(this, curve, 'jacobian');
|
||
if (x === null && y === null && z === null) {
|
||
this.x = this.curve.one;
|
||
this.y = this.curve.one;
|
||
this.z = new BN(0);
|
||
} else {
|
||
this.x = new BN(x, 16);
|
||
this.y = new BN(y, 16);
|
||
this.z = new BN(z, 16);
|
||
}
|
||
if (!this.x.red)
|
||
this.x = this.x.toRed(this.curve.red);
|
||
if (!this.y.red)
|
||
this.y = this.y.toRed(this.curve.red);
|
||
if (!this.z.red)
|
||
this.z = this.z.toRed(this.curve.red);
|
||
|
||
this.zOne = this.z === this.curve.one;
|
||
}
|
||
inherits(JPoint, Base.BasePoint);
|
||
|
||
ShortCurve.prototype.jpoint = function jpoint(x, y, z) {
|
||
return new JPoint(this, x, y, z);
|
||
};
|
||
|
||
JPoint.prototype.toP = function toP() {
|
||
if (this.isInfinity())
|
||
return this.curve.point(null, null);
|
||
|
||
var zinv = this.z.redInvm();
|
||
var zinv2 = zinv.redSqr();
|
||
var ax = this.x.redMul(zinv2);
|
||
var ay = this.y.redMul(zinv2).redMul(zinv);
|
||
|
||
return this.curve.point(ax, ay);
|
||
};
|
||
|
||
JPoint.prototype.neg = function neg() {
|
||
return this.curve.jpoint(this.x, this.y.redNeg(), this.z);
|
||
};
|
||
|
||
JPoint.prototype.add = function add(p) {
|
||
// O + P = P
|
||
if (this.isInfinity())
|
||
return p;
|
||
|
||
// P + O = P
|
||
if (p.isInfinity())
|
||
return this;
|
||
|
||
// 12M + 4S + 7A
|
||
var pz2 = p.z.redSqr();
|
||
var z2 = this.z.redSqr();
|
||
var u1 = this.x.redMul(pz2);
|
||
var u2 = p.x.redMul(z2);
|
||
var s1 = this.y.redMul(pz2.redMul(p.z));
|
||
var s2 = p.y.redMul(z2.redMul(this.z));
|
||
|
||
var h = u1.redSub(u2);
|
||
var r = s1.redSub(s2);
|
||
if (h.cmpn(0) === 0) {
|
||
if (r.cmpn(0) !== 0)
|
||
return this.curve.jpoint(null, null, null);
|
||
else
|
||
return this.dbl();
|
||
}
|
||
|
||
var h2 = h.redSqr();
|
||
var h3 = h2.redMul(h);
|
||
var v = u1.redMul(h2);
|
||
|
||
var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
|
||
var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
|
||
var nz = this.z.redMul(p.z).redMul(h);
|
||
|
||
return this.curve.jpoint(nx, ny, nz);
|
||
};
|
||
|
||
JPoint.prototype.mixedAdd = function mixedAdd(p) {
|
||
// O + P = P
|
||
if (this.isInfinity())
|
||
return p.toJ();
|
||
|
||
// P + O = P
|
||
if (p.isInfinity())
|
||
return this;
|
||
|
||
// 8M + 3S + 7A
|
||
var z2 = this.z.redSqr();
|
||
var u1 = this.x;
|
||
var u2 = p.x.redMul(z2);
|
||
var s1 = this.y;
|
||
var s2 = p.y.redMul(z2).redMul(this.z);
|
||
|
||
var h = u1.redSub(u2);
|
||
var r = s1.redSub(s2);
|
||
if (h.cmpn(0) === 0) {
|
||
if (r.cmpn(0) !== 0)
|
||
return this.curve.jpoint(null, null, null);
|
||
else
|
||
return this.dbl();
|
||
}
|
||
|
||
var h2 = h.redSqr();
|
||
var h3 = h2.redMul(h);
|
||
var v = u1.redMul(h2);
|
||
|
||
var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
|
||
var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
|
||
var nz = this.z.redMul(h);
|
||
|
||
return this.curve.jpoint(nx, ny, nz);
|
||
};
|
||
|
||
JPoint.prototype.dblp = function dblp(pow) {
|
||
if (pow === 0)
|
||
return this;
|
||
if (this.isInfinity())
|
||
return this;
|
||
if (!pow)
|
||
return this.dbl();
|
||
|
||
if (this.curve.zeroA || this.curve.threeA) {
|
||
var r = this;
|
||
for (var i = 0; i < pow; i++)
|
||
r = r.dbl();
|
||
return r;
|
||
}
|
||
|
||
// 1M + 2S + 1A + N * (4S + 5M + 8A)
|
||
// N = 1 => 6M + 6S + 9A
|
||
var a = this.curve.a;
|
||
var tinv = this.curve.tinv;
|
||
|
||
var jx = this.x;
|
||
var jy = this.y;
|
||
var jz = this.z;
|
||
var jz4 = jz.redSqr().redSqr();
|
||
|
||
// Reuse results
|
||
var jyd = jy.redAdd(jy);
|
||
for (var i = 0; i < pow; i++) {
|
||
var jx2 = jx.redSqr();
|
||
var jyd2 = jyd.redSqr();
|
||
var jyd4 = jyd2.redSqr();
|
||
var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
|
||
|
||
var t1 = jx.redMul(jyd2);
|
||
var nx = c.redSqr().redISub(t1.redAdd(t1));
|
||
var t2 = t1.redISub(nx);
|
||
var dny = c.redMul(t2);
|
||
dny = dny.redIAdd(dny).redISub(jyd4);
|
||
var nz = jyd.redMul(jz);
|
||
if (i + 1 < pow)
|
||
jz4 = jz4.redMul(jyd4);
|
||
|
||
jx = nx;
|
||
jz = nz;
|
||
jyd = dny;
|
||
}
|
||
|
||
return this.curve.jpoint(jx, jyd.redMul(tinv), jz);
|
||
};
|
||
|
||
JPoint.prototype.dbl = function dbl() {
|
||
if (this.isInfinity())
|
||
return this;
|
||
|
||
if (this.curve.zeroA)
|
||
return this._zeroDbl();
|
||
else if (this.curve.threeA)
|
||
return this._threeDbl();
|
||
else
|
||
return this._dbl();
|
||
};
|
||
|
||
JPoint.prototype._zeroDbl = function _zeroDbl() {
|
||
var nx;
|
||
var ny;
|
||
var nz;
|
||
// Z = 1
|
||
if (this.zOne) {
|
||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
|
||
// #doubling-mdbl-2007-bl
|
||
// 1M + 5S + 14A
|
||
|
||
// XX = X1^2
|
||
var xx = this.x.redSqr();
|
||
// YY = Y1^2
|
||
var yy = this.y.redSqr();
|
||
// YYYY = YY^2
|
||
var yyyy = yy.redSqr();
|
||
// S = 2 * ((X1 + YY)^2 - XX - YYYY)
|
||
var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
|
||
s = s.redIAdd(s);
|
||
// M = 3 * XX + a; a = 0
|
||
var m = xx.redAdd(xx).redIAdd(xx);
|
||
// T = M ^ 2 - 2*S
|
||
var t = m.redSqr().redISub(s).redISub(s);
|
||
|
||
// 8 * YYYY
|
||
var yyyy8 = yyyy.redIAdd(yyyy);
|
||
yyyy8 = yyyy8.redIAdd(yyyy8);
|
||
yyyy8 = yyyy8.redIAdd(yyyy8);
|
||
|
||
// X3 = T
|
||
nx = t;
|
||
// Y3 = M * (S - T) - 8 * YYYY
|
||
ny = m.redMul(s.redISub(t)).redISub(yyyy8);
|
||
// Z3 = 2*Y1
|
||
nz = this.y.redAdd(this.y);
|
||
} else {
|
||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
|
||
// #doubling-dbl-2009-l
|
||
// 2M + 5S + 13A
|
||
|
||
// A = X1^2
|
||
var a = this.x.redSqr();
|
||
// B = Y1^2
|
||
var b = this.y.redSqr();
|
||
// C = B^2
|
||
var c = b.redSqr();
|
||
// D = 2 * ((X1 + B)^2 - A - C)
|
||
var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c);
|
||
d = d.redIAdd(d);
|
||
// E = 3 * A
|
||
var e = a.redAdd(a).redIAdd(a);
|
||
// F = E^2
|
||
var f = e.redSqr();
|
||
|
||
// 8 * C
|
||
var c8 = c.redIAdd(c);
|
||
c8 = c8.redIAdd(c8);
|
||
c8 = c8.redIAdd(c8);
|
||
|
||
// X3 = F - 2 * D
|
||
nx = f.redISub(d).redISub(d);
|
||
// Y3 = E * (D - X3) - 8 * C
|
||
ny = e.redMul(d.redISub(nx)).redISub(c8);
|
||
// Z3 = 2 * Y1 * Z1
|
||
nz = this.y.redMul(this.z);
|
||
nz = nz.redIAdd(nz);
|
||
}
|
||
|
||
return this.curve.jpoint(nx, ny, nz);
|
||
};
|
||
|
||
JPoint.prototype._threeDbl = function _threeDbl() {
|
||
var nx;
|
||
var ny;
|
||
var nz;
|
||
// Z = 1
|
||
if (this.zOne) {
|
||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html
|
||
// #doubling-mdbl-2007-bl
|
||
// 1M + 5S + 15A
|
||
|
||
// XX = X1^2
|
||
var xx = this.x.redSqr();
|
||
// YY = Y1^2
|
||
var yy = this.y.redSqr();
|
||
// YYYY = YY^2
|
||
var yyyy = yy.redSqr();
|
||
// S = 2 * ((X1 + YY)^2 - XX - YYYY)
|
||
var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
|
||
s = s.redIAdd(s);
|
||
// M = 3 * XX + a
|
||
var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a);
|
||
// T = M^2 - 2 * S
|
||
var t = m.redSqr().redISub(s).redISub(s);
|
||
// X3 = T
|
||
nx = t;
|
||
// Y3 = M * (S - T) - 8 * YYYY
|
||
var yyyy8 = yyyy.redIAdd(yyyy);
|
||
yyyy8 = yyyy8.redIAdd(yyyy8);
|
||
yyyy8 = yyyy8.redIAdd(yyyy8);
|
||
ny = m.redMul(s.redISub(t)).redISub(yyyy8);
|
||
// Z3 = 2 * Y1
|
||
nz = this.y.redAdd(this.y);
|
||
} else {
|
||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
|
||
// 3M + 5S
|
||
|
||
// delta = Z1^2
|
||
var delta = this.z.redSqr();
|
||
// gamma = Y1^2
|
||
var gamma = this.y.redSqr();
|
||
// beta = X1 * gamma
|
||
var beta = this.x.redMul(gamma);
|
||
// alpha = 3 * (X1 - delta) * (X1 + delta)
|
||
var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta));
|
||
alpha = alpha.redAdd(alpha).redIAdd(alpha);
|
||
// X3 = alpha^2 - 8 * beta
|
||
var beta4 = beta.redIAdd(beta);
|
||
beta4 = beta4.redIAdd(beta4);
|
||
var beta8 = beta4.redAdd(beta4);
|
||
nx = alpha.redSqr().redISub(beta8);
|
||
// Z3 = (Y1 + Z1)^2 - gamma - delta
|
||
nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta);
|
||
// Y3 = alpha * (4 * beta - X3) - 8 * gamma^2
|
||
var ggamma8 = gamma.redSqr();
|
||
ggamma8 = ggamma8.redIAdd(ggamma8);
|
||
ggamma8 = ggamma8.redIAdd(ggamma8);
|
||
ggamma8 = ggamma8.redIAdd(ggamma8);
|
||
ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8);
|
||
}
|
||
|
||
return this.curve.jpoint(nx, ny, nz);
|
||
};
|
||
|
||
JPoint.prototype._dbl = function _dbl() {
|
||
var a = this.curve.a;
|
||
|
||
// 4M + 6S + 10A
|
||
var jx = this.x;
|
||
var jy = this.y;
|
||
var jz = this.z;
|
||
var jz4 = jz.redSqr().redSqr();
|
||
|
||
var jx2 = jx.redSqr();
|
||
var jy2 = jy.redSqr();
|
||
|
||
var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
|
||
|
||
var jxd4 = jx.redAdd(jx);
|
||
jxd4 = jxd4.redIAdd(jxd4);
|
||
var t1 = jxd4.redMul(jy2);
|
||
var nx = c.redSqr().redISub(t1.redAdd(t1));
|
||
var t2 = t1.redISub(nx);
|
||
|
||
var jyd8 = jy2.redSqr();
|
||
jyd8 = jyd8.redIAdd(jyd8);
|
||
jyd8 = jyd8.redIAdd(jyd8);
|
||
jyd8 = jyd8.redIAdd(jyd8);
|
||
var ny = c.redMul(t2).redISub(jyd8);
|
||
var nz = jy.redAdd(jy).redMul(jz);
|
||
|
||
return this.curve.jpoint(nx, ny, nz);
|
||
};
|
||
|
||
JPoint.prototype.trpl = function trpl() {
|
||
if (!this.curve.zeroA)
|
||
return this.dbl().add(this);
|
||
|
||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl
|
||
// 5M + 10S + ...
|
||
|
||
// XX = X1^2
|
||
var xx = this.x.redSqr();
|
||
// YY = Y1^2
|
||
var yy = this.y.redSqr();
|
||
// ZZ = Z1^2
|
||
var zz = this.z.redSqr();
|
||
// YYYY = YY^2
|
||
var yyyy = yy.redSqr();
|
||
// M = 3 * XX + a * ZZ2; a = 0
|
||
var m = xx.redAdd(xx).redIAdd(xx);
|
||
// MM = M^2
|
||
var mm = m.redSqr();
|
||
// E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM
|
||
var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
|
||
e = e.redIAdd(e);
|
||
e = e.redAdd(e).redIAdd(e);
|
||
e = e.redISub(mm);
|
||
// EE = E^2
|
||
var ee = e.redSqr();
|
||
// T = 16*YYYY
|
||
var t = yyyy.redIAdd(yyyy);
|
||
t = t.redIAdd(t);
|
||
t = t.redIAdd(t);
|
||
t = t.redIAdd(t);
|
||
// U = (M + E)^2 - MM - EE - T
|
||
var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t);
|
||
// X3 = 4 * (X1 * EE - 4 * YY * U)
|
||
var yyu4 = yy.redMul(u);
|
||
yyu4 = yyu4.redIAdd(yyu4);
|
||
yyu4 = yyu4.redIAdd(yyu4);
|
||
var nx = this.x.redMul(ee).redISub(yyu4);
|
||
nx = nx.redIAdd(nx);
|
||
nx = nx.redIAdd(nx);
|
||
// Y3 = 8 * Y1 * (U * (T - U) - E * EE)
|
||
var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee)));
|
||
ny = ny.redIAdd(ny);
|
||
ny = ny.redIAdd(ny);
|
||
ny = ny.redIAdd(ny);
|
||
// Z3 = (Z1 + E)^2 - ZZ - EE
|
||
var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee);
|
||
|
||
return this.curve.jpoint(nx, ny, nz);
|
||
};
|
||
|
||
JPoint.prototype.mul = function mul(k, kbase) {
|
||
k = new BN(k, kbase);
|
||
|
||
return this.curve._wnafMul(this, k);
|
||
};
|
||
|
||
JPoint.prototype.eq = function eq(p) {
|
||
if (p.type === 'affine')
|
||
return this.eq(p.toJ());
|
||
|
||
if (this === p)
|
||
return true;
|
||
|
||
// x1 * z2^2 == x2 * z1^2
|
||
var z2 = this.z.redSqr();
|
||
var pz2 = p.z.redSqr();
|
||
if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0)
|
||
return false;
|
||
|
||
// y1 * z2^3 == y2 * z1^3
|
||
var z3 = z2.redMul(this.z);
|
||
var pz3 = pz2.redMul(p.z);
|
||
return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0;
|
||
};
|
||
|
||
JPoint.prototype.eqXToP = function eqXToP(x) {
|
||
var zs = this.z.redSqr();
|
||
var rx = x.toRed(this.curve.red).redMul(zs);
|
||
if (this.x.cmp(rx) === 0)
|
||
return true;
|
||
|
||
var xc = x.clone();
|
||
var t = this.curve.redN.redMul(zs);
|
||
for (;;) {
|
||
xc.iadd(this.curve.n);
|
||
if (xc.cmp(this.curve.p) >= 0)
|
||
return false;
|
||
|
||
rx.redIAdd(t);
|
||
if (this.x.cmp(rx) === 0)
|
||
return true;
|
||
}
|
||
};
|
||
|
||
JPoint.prototype.inspect = function inspect() {
|
||
if (this.isInfinity())
|
||
return '<EC JPoint Infinity>';
|
||
return '<EC JPoint x: ' + this.x.toString(16, 2) +
|
||
' y: ' + this.y.toString(16, 2) +
|
||
' z: ' + this.z.toString(16, 2) + '>';
|
||
};
|
||
|
||
JPoint.prototype.isInfinity = function isInfinity() {
|
||
// XXX This code assumes that zero is always zero in red
|
||
return this.z.cmpn(0) === 0;
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/elliptic/lib/elliptic/curves.js":
|
||
/*!******************************************************!*\
|
||
!*** ./node_modules/elliptic/lib/elliptic/curves.js ***!
|
||
\******************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var curves = exports;
|
||
|
||
var hash = __webpack_require__(/*! hash.js */ "./node_modules/hash.js/lib/hash.js");
|
||
var curve = __webpack_require__(/*! ./curve */ "./node_modules/elliptic/lib/elliptic/curve/index.js");
|
||
var utils = __webpack_require__(/*! ./utils */ "./node_modules/elliptic/lib/elliptic/utils.js");
|
||
|
||
var assert = utils.assert;
|
||
|
||
function PresetCurve(options) {
|
||
if (options.type === 'short')
|
||
this.curve = new curve.short(options);
|
||
else if (options.type === 'edwards')
|
||
this.curve = new curve.edwards(options);
|
||
else
|
||
this.curve = new curve.mont(options);
|
||
this.g = this.curve.g;
|
||
this.n = this.curve.n;
|
||
this.hash = options.hash;
|
||
|
||
assert(this.g.validate(), 'Invalid curve');
|
||
assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N != O');
|
||
}
|
||
curves.PresetCurve = PresetCurve;
|
||
|
||
function defineCurve(name, options) {
|
||
Object.defineProperty(curves, name, {
|
||
configurable: true,
|
||
enumerable: true,
|
||
get: function() {
|
||
var curve = new PresetCurve(options);
|
||
Object.defineProperty(curves, name, {
|
||
configurable: true,
|
||
enumerable: true,
|
||
value: curve
|
||
});
|
||
return curve;
|
||
}
|
||
});
|
||
}
|
||
|
||
defineCurve('p192', {
|
||
type: 'short',
|
||
prime: 'p192',
|
||
p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff',
|
||
a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc',
|
||
b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1',
|
||
n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831',
|
||
hash: hash.sha256,
|
||
gRed: false,
|
||
g: [
|
||
'188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012',
|
||
'07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811'
|
||
]
|
||
});
|
||
|
||
defineCurve('p224', {
|
||
type: 'short',
|
||
prime: 'p224',
|
||
p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001',
|
||
a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe',
|
||
b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4',
|
||
n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d',
|
||
hash: hash.sha256,
|
||
gRed: false,
|
||
g: [
|
||
'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21',
|
||
'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34'
|
||
]
|
||
});
|
||
|
||
defineCurve('p256', {
|
||
type: 'short',
|
||
prime: null,
|
||
p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff',
|
||
a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc',
|
||
b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b',
|
||
n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551',
|
||
hash: hash.sha256,
|
||
gRed: false,
|
||
g: [
|
||
'6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296',
|
||
'4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5'
|
||
]
|
||
});
|
||
|
||
defineCurve('p384', {
|
||
type: 'short',
|
||
prime: null,
|
||
p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
||
'fffffffe ffffffff 00000000 00000000 ffffffff',
|
||
a: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
||
'fffffffe ffffffff 00000000 00000000 fffffffc',
|
||
b: 'b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f ' +
|
||
'5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef',
|
||
n: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 ' +
|
||
'f4372ddf 581a0db2 48b0a77a ecec196a ccc52973',
|
||
hash: hash.sha384,
|
||
gRed: false,
|
||
g: [
|
||
'aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 ' +
|
||
'5502f25d bf55296c 3a545e38 72760ab7',
|
||
'3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 ' +
|
||
'0a60b1ce 1d7e819d 7a431d7c 90ea0e5f'
|
||
]
|
||
});
|
||
|
||
defineCurve('p521', {
|
||
type: 'short',
|
||
prime: null,
|
||
p: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
||
'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
||
'ffffffff ffffffff ffffffff ffffffff ffffffff',
|
||
a: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
||
'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
||
'ffffffff ffffffff ffffffff ffffffff fffffffc',
|
||
b: '00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b ' +
|
||
'99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd ' +
|
||
'3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00',
|
||
n: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
||
'ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 ' +
|
||
'f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409',
|
||
hash: hash.sha512,
|
||
gRed: false,
|
||
g: [
|
||
'000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 ' +
|
||
'053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 ' +
|
||
'a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66',
|
||
'00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 ' +
|
||
'579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 ' +
|
||
'3fad0761 353c7086 a272c240 88be9476 9fd16650'
|
||
]
|
||
});
|
||
|
||
defineCurve('curve25519', {
|
||
type: 'mont',
|
||
prime: 'p25519',
|
||
p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
|
||
a: '76d06',
|
||
b: '1',
|
||
n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
|
||
hash: hash.sha256,
|
||
gRed: false,
|
||
g: [
|
||
'9'
|
||
]
|
||
});
|
||
|
||
defineCurve('ed25519', {
|
||
type: 'edwards',
|
||
prime: 'p25519',
|
||
p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
|
||
a: '-1',
|
||
c: '1',
|
||
// -121665 * (121666^(-1)) (mod P)
|
||
d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3',
|
||
n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
|
||
hash: hash.sha256,
|
||
gRed: false,
|
||
g: [
|
||
'216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a',
|
||
|
||
// 4/5
|
||
'6666666666666666666666666666666666666666666666666666666666666658'
|
||
]
|
||
});
|
||
|
||
var pre;
|
||
try {
|
||
pre = __webpack_require__(/*! ./precomputed/secp256k1 */ "./node_modules/elliptic/lib/elliptic/precomputed/secp256k1.js");
|
||
} catch (e) {
|
||
pre = undefined;
|
||
}
|
||
|
||
defineCurve('secp256k1', {
|
||
type: 'short',
|
||
prime: 'k256',
|
||
p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f',
|
||
a: '0',
|
||
b: '7',
|
||
n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141',
|
||
h: '1',
|
||
hash: hash.sha256,
|
||
|
||
// Precomputed endomorphism
|
||
beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee',
|
||
lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72',
|
||
basis: [
|
||
{
|
||
a: '3086d221a7d46bcde86c90e49284eb15',
|
||
b: '-e4437ed6010e88286f547fa90abfe4c3'
|
||
},
|
||
{
|
||
a: '114ca50f7a8e2f3f657c1108d9d44cfd8',
|
||
b: '3086d221a7d46bcde86c90e49284eb15'
|
||
}
|
||
],
|
||
|
||
gRed: false,
|
||
g: [
|
||
'79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
|
||
'483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8',
|
||
pre
|
||
]
|
||
});
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/elliptic/lib/elliptic/ec/index.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/elliptic/lib/elliptic/ec/index.js ***!
|
||
\********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var BN = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js");
|
||
var HmacDRBG = __webpack_require__(/*! hmac-drbg */ "./node_modules/hmac-drbg/lib/hmac-drbg.js");
|
||
var utils = __webpack_require__(/*! ../utils */ "./node_modules/elliptic/lib/elliptic/utils.js");
|
||
var curves = __webpack_require__(/*! ../curves */ "./node_modules/elliptic/lib/elliptic/curves.js");
|
||
var rand = __webpack_require__(/*! brorand */ "./node_modules/brorand/index.js");
|
||
var assert = utils.assert;
|
||
|
||
var KeyPair = __webpack_require__(/*! ./key */ "./node_modules/elliptic/lib/elliptic/ec/key.js");
|
||
var Signature = __webpack_require__(/*! ./signature */ "./node_modules/elliptic/lib/elliptic/ec/signature.js");
|
||
|
||
function EC(options) {
|
||
if (!(this instanceof EC))
|
||
return new EC(options);
|
||
|
||
// Shortcut `elliptic.ec(curve-name)`
|
||
if (typeof options === 'string') {
|
||
assert(curves.hasOwnProperty(options), 'Unknown curve ' + options);
|
||
|
||
options = curves[options];
|
||
}
|
||
|
||
// Shortcut for `elliptic.ec(elliptic.curves.curveName)`
|
||
if (options instanceof curves.PresetCurve)
|
||
options = { curve: options };
|
||
|
||
this.curve = options.curve.curve;
|
||
this.n = this.curve.n;
|
||
this.nh = this.n.ushrn(1);
|
||
this.g = this.curve.g;
|
||
|
||
// Point on curve
|
||
this.g = options.curve.g;
|
||
this.g.precompute(options.curve.n.bitLength() + 1);
|
||
|
||
// Hash for function for DRBG
|
||
this.hash = options.hash || options.curve.hash;
|
||
}
|
||
module.exports = EC;
|
||
|
||
EC.prototype.keyPair = function keyPair(options) {
|
||
return new KeyPair(this, options);
|
||
};
|
||
|
||
EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) {
|
||
return KeyPair.fromPrivate(this, priv, enc);
|
||
};
|
||
|
||
EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) {
|
||
return KeyPair.fromPublic(this, pub, enc);
|
||
};
|
||
|
||
EC.prototype.genKeyPair = function genKeyPair(options) {
|
||
if (!options)
|
||
options = {};
|
||
|
||
// Instantiate Hmac_DRBG
|
||
var drbg = new HmacDRBG({
|
||
hash: this.hash,
|
||
pers: options.pers,
|
||
persEnc: options.persEnc || 'utf8',
|
||
entropy: options.entropy || rand(this.hash.hmacStrength),
|
||
entropyEnc: options.entropy && options.entropyEnc || 'utf8',
|
||
nonce: this.n.toArray()
|
||
});
|
||
|
||
var bytes = this.n.byteLength();
|
||
var ns2 = this.n.sub(new BN(2));
|
||
do {
|
||
var priv = new BN(drbg.generate(bytes));
|
||
if (priv.cmp(ns2) > 0)
|
||
continue;
|
||
|
||
priv.iaddn(1);
|
||
return this.keyFromPrivate(priv);
|
||
} while (true);
|
||
};
|
||
|
||
EC.prototype._truncateToN = function truncateToN(msg, truncOnly) {
|
||
var delta = msg.byteLength() * 8 - this.n.bitLength();
|
||
if (delta > 0)
|
||
msg = msg.ushrn(delta);
|
||
if (!truncOnly && msg.cmp(this.n) >= 0)
|
||
return msg.sub(this.n);
|
||
else
|
||
return msg;
|
||
};
|
||
|
||
EC.prototype.sign = function sign(msg, key, enc, options) {
|
||
if (typeof enc === 'object') {
|
||
options = enc;
|
||
enc = null;
|
||
}
|
||
if (!options)
|
||
options = {};
|
||
|
||
key = this.keyFromPrivate(key, enc);
|
||
msg = this._truncateToN(new BN(msg, 16));
|
||
|
||
// Zero-extend key to provide enough entropy
|
||
var bytes = this.n.byteLength();
|
||
var bkey = key.getPrivate().toArray('be', bytes);
|
||
|
||
// Zero-extend nonce to have the same byte size as N
|
||
var nonce = msg.toArray('be', bytes);
|
||
|
||
// Instantiate Hmac_DRBG
|
||
var drbg = new HmacDRBG({
|
||
hash: this.hash,
|
||
entropy: bkey,
|
||
nonce: nonce,
|
||
pers: options.pers,
|
||
persEnc: options.persEnc || 'utf8'
|
||
});
|
||
|
||
// Number of bytes to generate
|
||
var ns1 = this.n.sub(new BN(1));
|
||
|
||
for (var iter = 0; true; iter++) {
|
||
var k = options.k ?
|
||
options.k(iter) :
|
||
new BN(drbg.generate(this.n.byteLength()));
|
||
k = this._truncateToN(k, true);
|
||
if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0)
|
||
continue;
|
||
|
||
var kp = this.g.mul(k);
|
||
if (kp.isInfinity())
|
||
continue;
|
||
|
||
var kpX = kp.getX();
|
||
var r = kpX.umod(this.n);
|
||
if (r.cmpn(0) === 0)
|
||
continue;
|
||
|
||
var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg));
|
||
s = s.umod(this.n);
|
||
if (s.cmpn(0) === 0)
|
||
continue;
|
||
|
||
var recoveryParam = (kp.getY().isOdd() ? 1 : 0) |
|
||
(kpX.cmp(r) !== 0 ? 2 : 0);
|
||
|
||
// Use complement of `s`, if it is > `n / 2`
|
||
if (options.canonical && s.cmp(this.nh) > 0) {
|
||
s = this.n.sub(s);
|
||
recoveryParam ^= 1;
|
||
}
|
||
|
||
return new Signature({ r: r, s: s, recoveryParam: recoveryParam });
|
||
}
|
||
};
|
||
|
||
EC.prototype.verify = function verify(msg, signature, key, enc) {
|
||
msg = this._truncateToN(new BN(msg, 16));
|
||
key = this.keyFromPublic(key, enc);
|
||
signature = new Signature(signature, 'hex');
|
||
|
||
// Perform primitive values validation
|
||
var r = signature.r;
|
||
var s = signature.s;
|
||
if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0)
|
||
return false;
|
||
if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0)
|
||
return false;
|
||
|
||
// Validate signature
|
||
var sinv = s.invm(this.n);
|
||
var u1 = sinv.mul(msg).umod(this.n);
|
||
var u2 = sinv.mul(r).umod(this.n);
|
||
|
||
if (!this.curve._maxwellTrick) {
|
||
var p = this.g.mulAdd(u1, key.getPublic(), u2);
|
||
if (p.isInfinity())
|
||
return false;
|
||
|
||
return p.getX().umod(this.n).cmp(r) === 0;
|
||
}
|
||
|
||
// NOTE: Greg Maxwell's trick, inspired by:
|
||
// https://git.io/vad3K
|
||
|
||
var p = this.g.jmulAdd(u1, key.getPublic(), u2);
|
||
if (p.isInfinity())
|
||
return false;
|
||
|
||
// Compare `p.x` of Jacobian point with `r`,
|
||
// this will do `p.x == r * p.z^2` instead of multiplying `p.x` by the
|
||
// inverse of `p.z^2`
|
||
return p.eqXToP(r);
|
||
};
|
||
|
||
EC.prototype.recoverPubKey = function(msg, signature, j, enc) {
|
||
assert((3 & j) === j, 'The recovery param is more than two bits');
|
||
signature = new Signature(signature, enc);
|
||
|
||
var n = this.n;
|
||
var e = new BN(msg);
|
||
var r = signature.r;
|
||
var s = signature.s;
|
||
|
||
// A set LSB signifies that the y-coordinate is odd
|
||
var isYOdd = j & 1;
|
||
var isSecondKey = j >> 1;
|
||
if (r.cmp(this.curve.p.umod(this.curve.n)) >= 0 && isSecondKey)
|
||
throw new Error('Unable to find sencond key candinate');
|
||
|
||
// 1.1. Let x = r + jn.
|
||
if (isSecondKey)
|
||
r = this.curve.pointFromX(r.add(this.curve.n), isYOdd);
|
||
else
|
||
r = this.curve.pointFromX(r, isYOdd);
|
||
|
||
var rInv = signature.r.invm(n);
|
||
var s1 = n.sub(e).mul(rInv).umod(n);
|
||
var s2 = s.mul(rInv).umod(n);
|
||
|
||
// 1.6.1 Compute Q = r^-1 (sR - eG)
|
||
// Q = r^-1 (sR + -eG)
|
||
return this.g.mulAdd(s1, r, s2);
|
||
};
|
||
|
||
EC.prototype.getKeyRecoveryParam = function(e, signature, Q, enc) {
|
||
signature = new Signature(signature, enc);
|
||
if (signature.recoveryParam !== null)
|
||
return signature.recoveryParam;
|
||
|
||
for (var i = 0; i < 4; i++) {
|
||
var Qprime;
|
||
try {
|
||
Qprime = this.recoverPubKey(e, signature, i);
|
||
} catch (e) {
|
||
continue;
|
||
}
|
||
|
||
if (Qprime.eq(Q))
|
||
return i;
|
||
}
|
||
throw new Error('Unable to find valid recovery factor');
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/elliptic/lib/elliptic/ec/key.js":
|
||
/*!******************************************************!*\
|
||
!*** ./node_modules/elliptic/lib/elliptic/ec/key.js ***!
|
||
\******************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var BN = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js");
|
||
var utils = __webpack_require__(/*! ../utils */ "./node_modules/elliptic/lib/elliptic/utils.js");
|
||
var assert = utils.assert;
|
||
|
||
function KeyPair(ec, options) {
|
||
this.ec = ec;
|
||
this.priv = null;
|
||
this.pub = null;
|
||
|
||
// KeyPair(ec, { priv: ..., pub: ... })
|
||
if (options.priv)
|
||
this._importPrivate(options.priv, options.privEnc);
|
||
if (options.pub)
|
||
this._importPublic(options.pub, options.pubEnc);
|
||
}
|
||
module.exports = KeyPair;
|
||
|
||
KeyPair.fromPublic = function fromPublic(ec, pub, enc) {
|
||
if (pub instanceof KeyPair)
|
||
return pub;
|
||
|
||
return new KeyPair(ec, {
|
||
pub: pub,
|
||
pubEnc: enc
|
||
});
|
||
};
|
||
|
||
KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) {
|
||
if (priv instanceof KeyPair)
|
||
return priv;
|
||
|
||
return new KeyPair(ec, {
|
||
priv: priv,
|
||
privEnc: enc
|
||
});
|
||
};
|
||
|
||
KeyPair.prototype.validate = function validate() {
|
||
var pub = this.getPublic();
|
||
|
||
if (pub.isInfinity())
|
||
return { result: false, reason: 'Invalid public key' };
|
||
if (!pub.validate())
|
||
return { result: false, reason: 'Public key is not a point' };
|
||
if (!pub.mul(this.ec.curve.n).isInfinity())
|
||
return { result: false, reason: 'Public key * N != O' };
|
||
|
||
return { result: true, reason: null };
|
||
};
|
||
|
||
KeyPair.prototype.getPublic = function getPublic(compact, enc) {
|
||
// compact is optional argument
|
||
if (typeof compact === 'string') {
|
||
enc = compact;
|
||
compact = null;
|
||
}
|
||
|
||
if (!this.pub)
|
||
this.pub = this.ec.g.mul(this.priv);
|
||
|
||
if (!enc)
|
||
return this.pub;
|
||
|
||
return this.pub.encode(enc, compact);
|
||
};
|
||
|
||
KeyPair.prototype.getPrivate = function getPrivate(enc) {
|
||
if (enc === 'hex')
|
||
return this.priv.toString(16, 2);
|
||
else
|
||
return this.priv;
|
||
};
|
||
|
||
KeyPair.prototype._importPrivate = function _importPrivate(key, enc) {
|
||
this.priv = new BN(key, enc || 16);
|
||
|
||
// Ensure that the priv won't be bigger than n, otherwise we may fail
|
||
// in fixed multiplication method
|
||
this.priv = this.priv.umod(this.ec.curve.n);
|
||
};
|
||
|
||
KeyPair.prototype._importPublic = function _importPublic(key, enc) {
|
||
if (key.x || key.y) {
|
||
// Montgomery points only have an `x` coordinate.
|
||
// Weierstrass/Edwards points on the other hand have both `x` and
|
||
// `y` coordinates.
|
||
if (this.ec.curve.type === 'mont') {
|
||
assert(key.x, 'Need x coordinate');
|
||
} else if (this.ec.curve.type === 'short' ||
|
||
this.ec.curve.type === 'edwards') {
|
||
assert(key.x && key.y, 'Need both x and y coordinate');
|
||
}
|
||
this.pub = this.ec.curve.point(key.x, key.y);
|
||
return;
|
||
}
|
||
this.pub = this.ec.curve.decodePoint(key, enc);
|
||
};
|
||
|
||
// ECDH
|
||
KeyPair.prototype.derive = function derive(pub) {
|
||
return pub.mul(this.priv).getX();
|
||
};
|
||
|
||
// ECDSA
|
||
KeyPair.prototype.sign = function sign(msg, enc, options) {
|
||
return this.ec.sign(msg, this, enc, options);
|
||
};
|
||
|
||
KeyPair.prototype.verify = function verify(msg, signature) {
|
||
return this.ec.verify(msg, signature, this);
|
||
};
|
||
|
||
KeyPair.prototype.inspect = function inspect() {
|
||
return '<Key priv: ' + (this.priv && this.priv.toString(16, 2)) +
|
||
' pub: ' + (this.pub && this.pub.inspect()) + ' >';
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/elliptic/lib/elliptic/ec/signature.js":
|
||
/*!************************************************************!*\
|
||
!*** ./node_modules/elliptic/lib/elliptic/ec/signature.js ***!
|
||
\************************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var BN = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js");
|
||
|
||
var utils = __webpack_require__(/*! ../utils */ "./node_modules/elliptic/lib/elliptic/utils.js");
|
||
var assert = utils.assert;
|
||
|
||
function Signature(options, enc) {
|
||
if (options instanceof Signature)
|
||
return options;
|
||
|
||
if (this._importDER(options, enc))
|
||
return;
|
||
|
||
assert(options.r && options.s, 'Signature without r or s');
|
||
this.r = new BN(options.r, 16);
|
||
this.s = new BN(options.s, 16);
|
||
if (options.recoveryParam === undefined)
|
||
this.recoveryParam = null;
|
||
else
|
||
this.recoveryParam = options.recoveryParam;
|
||
}
|
||
module.exports = Signature;
|
||
|
||
function Position() {
|
||
this.place = 0;
|
||
}
|
||
|
||
function getLength(buf, p) {
|
||
var initial = buf[p.place++];
|
||
if (!(initial & 0x80)) {
|
||
return initial;
|
||
}
|
||
var octetLen = initial & 0xf;
|
||
|
||
// Indefinite length or overflow
|
||
if (octetLen === 0 || octetLen > 4) {
|
||
return false;
|
||
}
|
||
|
||
var val = 0;
|
||
for (var i = 0, off = p.place; i < octetLen; i++, off++) {
|
||
val <<= 8;
|
||
val |= buf[off];
|
||
val >>>= 0;
|
||
}
|
||
|
||
// Leading zeroes
|
||
if (val <= 0x7f) {
|
||
return false;
|
||
}
|
||
|
||
p.place = off;
|
||
return val;
|
||
}
|
||
|
||
function rmPadding(buf) {
|
||
var i = 0;
|
||
var len = buf.length - 1;
|
||
while (!buf[i] && !(buf[i + 1] & 0x80) && i < len) {
|
||
i++;
|
||
}
|
||
if (i === 0) {
|
||
return buf;
|
||
}
|
||
return buf.slice(i);
|
||
}
|
||
|
||
Signature.prototype._importDER = function _importDER(data, enc) {
|
||
data = utils.toArray(data, enc);
|
||
var p = new Position();
|
||
if (data[p.place++] !== 0x30) {
|
||
return false;
|
||
}
|
||
var len = getLength(data, p);
|
||
if (len === false) {
|
||
return false;
|
||
}
|
||
if ((len + p.place) !== data.length) {
|
||
return false;
|
||
}
|
||
if (data[p.place++] !== 0x02) {
|
||
return false;
|
||
}
|
||
var rlen = getLength(data, p);
|
||
if (rlen === false) {
|
||
return false;
|
||
}
|
||
var r = data.slice(p.place, rlen + p.place);
|
||
p.place += rlen;
|
||
if (data[p.place++] !== 0x02) {
|
||
return false;
|
||
}
|
||
var slen = getLength(data, p);
|
||
if (slen === false) {
|
||
return false;
|
||
}
|
||
if (data.length !== slen + p.place) {
|
||
return false;
|
||
}
|
||
var s = data.slice(p.place, slen + p.place);
|
||
if (r[0] === 0) {
|
||
if (r[1] & 0x80) {
|
||
r = r.slice(1);
|
||
} else {
|
||
// Leading zeroes
|
||
return false;
|
||
}
|
||
}
|
||
if (s[0] === 0) {
|
||
if (s[1] & 0x80) {
|
||
s = s.slice(1);
|
||
} else {
|
||
// Leading zeroes
|
||
return false;
|
||
}
|
||
}
|
||
|
||
this.r = new BN(r);
|
||
this.s = new BN(s);
|
||
this.recoveryParam = null;
|
||
|
||
return true;
|
||
};
|
||
|
||
function constructLength(arr, len) {
|
||
if (len < 0x80) {
|
||
arr.push(len);
|
||
return;
|
||
}
|
||
var octets = 1 + (Math.log(len) / Math.LN2 >>> 3);
|
||
arr.push(octets | 0x80);
|
||
while (--octets) {
|
||
arr.push((len >>> (octets << 3)) & 0xff);
|
||
}
|
||
arr.push(len);
|
||
}
|
||
|
||
Signature.prototype.toDER = function toDER(enc) {
|
||
var r = this.r.toArray();
|
||
var s = this.s.toArray();
|
||
|
||
// Pad values
|
||
if (r[0] & 0x80)
|
||
r = [ 0 ].concat(r);
|
||
// Pad values
|
||
if (s[0] & 0x80)
|
||
s = [ 0 ].concat(s);
|
||
|
||
r = rmPadding(r);
|
||
s = rmPadding(s);
|
||
|
||
while (!s[0] && !(s[1] & 0x80)) {
|
||
s = s.slice(1);
|
||
}
|
||
var arr = [ 0x02 ];
|
||
constructLength(arr, r.length);
|
||
arr = arr.concat(r);
|
||
arr.push(0x02);
|
||
constructLength(arr, s.length);
|
||
var backHalf = arr.concat(s);
|
||
var res = [ 0x30 ];
|
||
constructLength(res, backHalf.length);
|
||
res = res.concat(backHalf);
|
||
return utils.encode(res, enc);
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/elliptic/lib/elliptic/eddsa/index.js":
|
||
/*!***********************************************************!*\
|
||
!*** ./node_modules/elliptic/lib/elliptic/eddsa/index.js ***!
|
||
\***********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var hash = __webpack_require__(/*! hash.js */ "./node_modules/hash.js/lib/hash.js");
|
||
var curves = __webpack_require__(/*! ../curves */ "./node_modules/elliptic/lib/elliptic/curves.js");
|
||
var utils = __webpack_require__(/*! ../utils */ "./node_modules/elliptic/lib/elliptic/utils.js");
|
||
var assert = utils.assert;
|
||
var parseBytes = utils.parseBytes;
|
||
var KeyPair = __webpack_require__(/*! ./key */ "./node_modules/elliptic/lib/elliptic/eddsa/key.js");
|
||
var Signature = __webpack_require__(/*! ./signature */ "./node_modules/elliptic/lib/elliptic/eddsa/signature.js");
|
||
|
||
function EDDSA(curve) {
|
||
assert(curve === 'ed25519', 'only tested with ed25519 so far');
|
||
|
||
if (!(this instanceof EDDSA))
|
||
return new EDDSA(curve);
|
||
|
||
var curve = curves[curve].curve;
|
||
this.curve = curve;
|
||
this.g = curve.g;
|
||
this.g.precompute(curve.n.bitLength() + 1);
|
||
|
||
this.pointClass = curve.point().constructor;
|
||
this.encodingLength = Math.ceil(curve.n.bitLength() / 8);
|
||
this.hash = hash.sha512;
|
||
}
|
||
|
||
module.exports = EDDSA;
|
||
|
||
/**
|
||
* @param {Array|String} message - message bytes
|
||
* @param {Array|String|KeyPair} secret - secret bytes or a keypair
|
||
* @returns {Signature} - signature
|
||
*/
|
||
EDDSA.prototype.sign = function sign(message, secret) {
|
||
message = parseBytes(message);
|
||
var key = this.keyFromSecret(secret);
|
||
var r = this.hashInt(key.messagePrefix(), message);
|
||
var R = this.g.mul(r);
|
||
var Rencoded = this.encodePoint(R);
|
||
var s_ = this.hashInt(Rencoded, key.pubBytes(), message)
|
||
.mul(key.priv());
|
||
var S = r.add(s_).umod(this.curve.n);
|
||
return this.makeSignature({ R: R, S: S, Rencoded: Rencoded });
|
||
};
|
||
|
||
/**
|
||
* @param {Array} message - message bytes
|
||
* @param {Array|String|Signature} sig - sig bytes
|
||
* @param {Array|String|Point|KeyPair} pub - public key
|
||
* @returns {Boolean} - true if public key matches sig of message
|
||
*/
|
||
EDDSA.prototype.verify = function verify(message, sig, pub) {
|
||
message = parseBytes(message);
|
||
sig = this.makeSignature(sig);
|
||
var key = this.keyFromPublic(pub);
|
||
var h = this.hashInt(sig.Rencoded(), key.pubBytes(), message);
|
||
var SG = this.g.mul(sig.S());
|
||
var RplusAh = sig.R().add(key.pub().mul(h));
|
||
return RplusAh.eq(SG);
|
||
};
|
||
|
||
EDDSA.prototype.hashInt = function hashInt() {
|
||
var hash = this.hash();
|
||
for (var i = 0; i < arguments.length; i++)
|
||
hash.update(arguments[i]);
|
||
return utils.intFromLE(hash.digest()).umod(this.curve.n);
|
||
};
|
||
|
||
EDDSA.prototype.keyFromPublic = function keyFromPublic(pub) {
|
||
return KeyPair.fromPublic(this, pub);
|
||
};
|
||
|
||
EDDSA.prototype.keyFromSecret = function keyFromSecret(secret) {
|
||
return KeyPair.fromSecret(this, secret);
|
||
};
|
||
|
||
EDDSA.prototype.makeSignature = function makeSignature(sig) {
|
||
if (sig instanceof Signature)
|
||
return sig;
|
||
return new Signature(this, sig);
|
||
};
|
||
|
||
/**
|
||
* * https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-5.2
|
||
*
|
||
* EDDSA defines methods for encoding and decoding points and integers. These are
|
||
* helper convenience methods, that pass along to utility functions implied
|
||
* parameters.
|
||
*
|
||
*/
|
||
EDDSA.prototype.encodePoint = function encodePoint(point) {
|
||
var enc = point.getY().toArray('le', this.encodingLength);
|
||
enc[this.encodingLength - 1] |= point.getX().isOdd() ? 0x80 : 0;
|
||
return enc;
|
||
};
|
||
|
||
EDDSA.prototype.decodePoint = function decodePoint(bytes) {
|
||
bytes = utils.parseBytes(bytes);
|
||
|
||
var lastIx = bytes.length - 1;
|
||
var normed = bytes.slice(0, lastIx).concat(bytes[lastIx] & ~0x80);
|
||
var xIsOdd = (bytes[lastIx] & 0x80) !== 0;
|
||
|
||
var y = utils.intFromLE(normed);
|
||
return this.curve.pointFromY(y, xIsOdd);
|
||
};
|
||
|
||
EDDSA.prototype.encodeInt = function encodeInt(num) {
|
||
return num.toArray('le', this.encodingLength);
|
||
};
|
||
|
||
EDDSA.prototype.decodeInt = function decodeInt(bytes) {
|
||
return utils.intFromLE(bytes);
|
||
};
|
||
|
||
EDDSA.prototype.isPoint = function isPoint(val) {
|
||
return val instanceof this.pointClass;
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/elliptic/lib/elliptic/eddsa/key.js":
|
||
/*!*********************************************************!*\
|
||
!*** ./node_modules/elliptic/lib/elliptic/eddsa/key.js ***!
|
||
\*********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var utils = __webpack_require__(/*! ../utils */ "./node_modules/elliptic/lib/elliptic/utils.js");
|
||
var assert = utils.assert;
|
||
var parseBytes = utils.parseBytes;
|
||
var cachedProperty = utils.cachedProperty;
|
||
|
||
/**
|
||
* @param {EDDSA} eddsa - instance
|
||
* @param {Object} params - public/private key parameters
|
||
*
|
||
* @param {Array<Byte>} [params.secret] - secret seed bytes
|
||
* @param {Point} [params.pub] - public key point (aka `A` in eddsa terms)
|
||
* @param {Array<Byte>} [params.pub] - public key point encoded as bytes
|
||
*
|
||
*/
|
||
function KeyPair(eddsa, params) {
|
||
this.eddsa = eddsa;
|
||
this._secret = parseBytes(params.secret);
|
||
if (eddsa.isPoint(params.pub))
|
||
this._pub = params.pub;
|
||
else
|
||
this._pubBytes = parseBytes(params.pub);
|
||
}
|
||
|
||
KeyPair.fromPublic = function fromPublic(eddsa, pub) {
|
||
if (pub instanceof KeyPair)
|
||
return pub;
|
||
return new KeyPair(eddsa, { pub: pub });
|
||
};
|
||
|
||
KeyPair.fromSecret = function fromSecret(eddsa, secret) {
|
||
if (secret instanceof KeyPair)
|
||
return secret;
|
||
return new KeyPair(eddsa, { secret: secret });
|
||
};
|
||
|
||
KeyPair.prototype.secret = function secret() {
|
||
return this._secret;
|
||
};
|
||
|
||
cachedProperty(KeyPair, 'pubBytes', function pubBytes() {
|
||
return this.eddsa.encodePoint(this.pub());
|
||
});
|
||
|
||
cachedProperty(KeyPair, 'pub', function pub() {
|
||
if (this._pubBytes)
|
||
return this.eddsa.decodePoint(this._pubBytes);
|
||
return this.eddsa.g.mul(this.priv());
|
||
});
|
||
|
||
cachedProperty(KeyPair, 'privBytes', function privBytes() {
|
||
var eddsa = this.eddsa;
|
||
var hash = this.hash();
|
||
var lastIx = eddsa.encodingLength - 1;
|
||
|
||
var a = hash.slice(0, eddsa.encodingLength);
|
||
a[0] &= 248;
|
||
a[lastIx] &= 127;
|
||
a[lastIx] |= 64;
|
||
|
||
return a;
|
||
});
|
||
|
||
cachedProperty(KeyPair, 'priv', function priv() {
|
||
return this.eddsa.decodeInt(this.privBytes());
|
||
});
|
||
|
||
cachedProperty(KeyPair, 'hash', function hash() {
|
||
return this.eddsa.hash().update(this.secret()).digest();
|
||
});
|
||
|
||
cachedProperty(KeyPair, 'messagePrefix', function messagePrefix() {
|
||
return this.hash().slice(this.eddsa.encodingLength);
|
||
});
|
||
|
||
KeyPair.prototype.sign = function sign(message) {
|
||
assert(this._secret, 'KeyPair can only verify');
|
||
return this.eddsa.sign(message, this);
|
||
};
|
||
|
||
KeyPair.prototype.verify = function verify(message, sig) {
|
||
return this.eddsa.verify(message, sig, this);
|
||
};
|
||
|
||
KeyPair.prototype.getSecret = function getSecret(enc) {
|
||
assert(this._secret, 'KeyPair is public only');
|
||
return utils.encode(this.secret(), enc);
|
||
};
|
||
|
||
KeyPair.prototype.getPublic = function getPublic(enc) {
|
||
return utils.encode(this.pubBytes(), enc);
|
||
};
|
||
|
||
module.exports = KeyPair;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/elliptic/lib/elliptic/eddsa/signature.js":
|
||
/*!***************************************************************!*\
|
||
!*** ./node_modules/elliptic/lib/elliptic/eddsa/signature.js ***!
|
||
\***************************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var BN = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js");
|
||
var utils = __webpack_require__(/*! ../utils */ "./node_modules/elliptic/lib/elliptic/utils.js");
|
||
var assert = utils.assert;
|
||
var cachedProperty = utils.cachedProperty;
|
||
var parseBytes = utils.parseBytes;
|
||
|
||
/**
|
||
* @param {EDDSA} eddsa - eddsa instance
|
||
* @param {Array<Bytes>|Object} sig -
|
||
* @param {Array<Bytes>|Point} [sig.R] - R point as Point or bytes
|
||
* @param {Array<Bytes>|bn} [sig.S] - S scalar as bn or bytes
|
||
* @param {Array<Bytes>} [sig.Rencoded] - R point encoded
|
||
* @param {Array<Bytes>} [sig.Sencoded] - S scalar encoded
|
||
*/
|
||
function Signature(eddsa, sig) {
|
||
this.eddsa = eddsa;
|
||
|
||
if (typeof sig !== 'object')
|
||
sig = parseBytes(sig);
|
||
|
||
if (Array.isArray(sig)) {
|
||
sig = {
|
||
R: sig.slice(0, eddsa.encodingLength),
|
||
S: sig.slice(eddsa.encodingLength)
|
||
};
|
||
}
|
||
|
||
assert(sig.R && sig.S, 'Signature without R or S');
|
||
|
||
if (eddsa.isPoint(sig.R))
|
||
this._R = sig.R;
|
||
if (sig.S instanceof BN)
|
||
this._S = sig.S;
|
||
|
||
this._Rencoded = Array.isArray(sig.R) ? sig.R : sig.Rencoded;
|
||
this._Sencoded = Array.isArray(sig.S) ? sig.S : sig.Sencoded;
|
||
}
|
||
|
||
cachedProperty(Signature, 'S', function S() {
|
||
return this.eddsa.decodeInt(this.Sencoded());
|
||
});
|
||
|
||
cachedProperty(Signature, 'R', function R() {
|
||
return this.eddsa.decodePoint(this.Rencoded());
|
||
});
|
||
|
||
cachedProperty(Signature, 'Rencoded', function Rencoded() {
|
||
return this.eddsa.encodePoint(this.R());
|
||
});
|
||
|
||
cachedProperty(Signature, 'Sencoded', function Sencoded() {
|
||
return this.eddsa.encodeInt(this.S());
|
||
});
|
||
|
||
Signature.prototype.toBytes = function toBytes() {
|
||
return this.Rencoded().concat(this.Sencoded());
|
||
};
|
||
|
||
Signature.prototype.toHex = function toHex() {
|
||
return utils.encode(this.toBytes(), 'hex').toUpperCase();
|
||
};
|
||
|
||
module.exports = Signature;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/elliptic/lib/elliptic/precomputed/secp256k1.js":
|
||
/*!*********************************************************************!*\
|
||
!*** ./node_modules/elliptic/lib/elliptic/precomputed/secp256k1.js ***!
|
||
\*********************************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
module.exports = {
|
||
doubles: {
|
||
step: 4,
|
||
points: [
|
||
[
|
||
'e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a',
|
||
'f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821'
|
||
],
|
||
[
|
||
'8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508',
|
||
'11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf'
|
||
],
|
||
[
|
||
'175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739',
|
||
'd3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695'
|
||
],
|
||
[
|
||
'363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640',
|
||
'4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9'
|
||
],
|
||
[
|
||
'8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c',
|
||
'4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36'
|
||
],
|
||
[
|
||
'723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda',
|
||
'96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f'
|
||
],
|
||
[
|
||
'eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa',
|
||
'5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999'
|
||
],
|
||
[
|
||
'100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0',
|
||
'cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09'
|
||
],
|
||
[
|
||
'e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d',
|
||
'9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d'
|
||
],
|
||
[
|
||
'feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d',
|
||
'e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088'
|
||
],
|
||
[
|
||
'da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1',
|
||
'9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d'
|
||
],
|
||
[
|
||
'53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0',
|
||
'5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8'
|
||
],
|
||
[
|
||
'8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047',
|
||
'10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a'
|
||
],
|
||
[
|
||
'385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862',
|
||
'283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453'
|
||
],
|
||
[
|
||
'6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7',
|
||
'7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160'
|
||
],
|
||
[
|
||
'3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd',
|
||
'56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0'
|
||
],
|
||
[
|
||
'85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83',
|
||
'7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6'
|
||
],
|
||
[
|
||
'948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a',
|
||
'53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589'
|
||
],
|
||
[
|
||
'6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8',
|
||
'bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17'
|
||
],
|
||
[
|
||
'e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d',
|
||
'4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda'
|
||
],
|
||
[
|
||
'e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725',
|
||
'7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd'
|
||
],
|
||
[
|
||
'213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754',
|
||
'4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2'
|
||
],
|
||
[
|
||
'4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c',
|
||
'17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6'
|
||
],
|
||
[
|
||
'fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6',
|
||
'6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f'
|
||
],
|
||
[
|
||
'76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39',
|
||
'c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01'
|
||
],
|
||
[
|
||
'c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891',
|
||
'893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3'
|
||
],
|
||
[
|
||
'd895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b',
|
||
'febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f'
|
||
],
|
||
[
|
||
'b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03',
|
||
'2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7'
|
||
],
|
||
[
|
||
'e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d',
|
||
'eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78'
|
||
],
|
||
[
|
||
'a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070',
|
||
'7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1'
|
||
],
|
||
[
|
||
'90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4',
|
||
'e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150'
|
||
],
|
||
[
|
||
'8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da',
|
||
'662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82'
|
||
],
|
||
[
|
||
'e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11',
|
||
'1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc'
|
||
],
|
||
[
|
||
'8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e',
|
||
'efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b'
|
||
],
|
||
[
|
||
'e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41',
|
||
'2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51'
|
||
],
|
||
[
|
||
'b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef',
|
||
'67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45'
|
||
],
|
||
[
|
||
'd68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8',
|
||
'db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120'
|
||
],
|
||
[
|
||
'324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d',
|
||
'648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84'
|
||
],
|
||
[
|
||
'4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96',
|
||
'35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d'
|
||
],
|
||
[
|
||
'9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd',
|
||
'ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d'
|
||
],
|
||
[
|
||
'6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5',
|
||
'9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8'
|
||
],
|
||
[
|
||
'a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266',
|
||
'40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8'
|
||
],
|
||
[
|
||
'7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71',
|
||
'34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac'
|
||
],
|
||
[
|
||
'928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac',
|
||
'c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f'
|
||
],
|
||
[
|
||
'85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751',
|
||
'1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962'
|
||
],
|
||
[
|
||
'ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e',
|
||
'493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907'
|
||
],
|
||
[
|
||
'827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241',
|
||
'c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec'
|
||
],
|
||
[
|
||
'eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3',
|
||
'be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d'
|
||
],
|
||
[
|
||
'e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f',
|
||
'4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414'
|
||
],
|
||
[
|
||
'1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19',
|
||
'aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd'
|
||
],
|
||
[
|
||
'146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be',
|
||
'b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0'
|
||
],
|
||
[
|
||
'fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9',
|
||
'6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811'
|
||
],
|
||
[
|
||
'da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2',
|
||
'8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1'
|
||
],
|
||
[
|
||
'a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13',
|
||
'7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c'
|
||
],
|
||
[
|
||
'174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c',
|
||
'ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73'
|
||
],
|
||
[
|
||
'959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba',
|
||
'2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd'
|
||
],
|
||
[
|
||
'd2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151',
|
||
'e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405'
|
||
],
|
||
[
|
||
'64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073',
|
||
'd99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589'
|
||
],
|
||
[
|
||
'8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458',
|
||
'38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e'
|
||
],
|
||
[
|
||
'13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b',
|
||
'69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27'
|
||
],
|
||
[
|
||
'bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366',
|
||
'd3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1'
|
||
],
|
||
[
|
||
'8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa',
|
||
'40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482'
|
||
],
|
||
[
|
||
'8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0',
|
||
'620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945'
|
||
],
|
||
[
|
||
'dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787',
|
||
'7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573'
|
||
],
|
||
[
|
||
'f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e',
|
||
'ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82'
|
||
]
|
||
]
|
||
},
|
||
naf: {
|
||
wnd: 7,
|
||
points: [
|
||
[
|
||
'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9',
|
||
'388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672'
|
||
],
|
||
[
|
||
'2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4',
|
||
'd8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6'
|
||
],
|
||
[
|
||
'5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc',
|
||
'6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da'
|
||
],
|
||
[
|
||
'acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe',
|
||
'cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37'
|
||
],
|
||
[
|
||
'774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb',
|
||
'd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b'
|
||
],
|
||
[
|
||
'f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8',
|
||
'ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81'
|
||
],
|
||
[
|
||
'd7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e',
|
||
'581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58'
|
||
],
|
||
[
|
||
'defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34',
|
||
'4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77'
|
||
],
|
||
[
|
||
'2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c',
|
||
'85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a'
|
||
],
|
||
[
|
||
'352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5',
|
||
'321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c'
|
||
],
|
||
[
|
||
'2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f',
|
||
'2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67'
|
||
],
|
||
[
|
||
'9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714',
|
||
'73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402'
|
||
],
|
||
[
|
||
'daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729',
|
||
'a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55'
|
||
],
|
||
[
|
||
'c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db',
|
||
'2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482'
|
||
],
|
||
[
|
||
'6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4',
|
||
'e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82'
|
||
],
|
||
[
|
||
'1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5',
|
||
'b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396'
|
||
],
|
||
[
|
||
'605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479',
|
||
'2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49'
|
||
],
|
||
[
|
||
'62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d',
|
||
'80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf'
|
||
],
|
||
[
|
||
'80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f',
|
||
'1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a'
|
||
],
|
||
[
|
||
'7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb',
|
||
'd0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7'
|
||
],
|
||
[
|
||
'd528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9',
|
||
'eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933'
|
||
],
|
||
[
|
||
'49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963',
|
||
'758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a'
|
||
],
|
||
[
|
||
'77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74',
|
||
'958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6'
|
||
],
|
||
[
|
||
'f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530',
|
||
'e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37'
|
||
],
|
||
[
|
||
'463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b',
|
||
'5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e'
|
||
],
|
||
[
|
||
'f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247',
|
||
'cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6'
|
||
],
|
||
[
|
||
'caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1',
|
||
'cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476'
|
||
],
|
||
[
|
||
'2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120',
|
||
'4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40'
|
||
],
|
||
[
|
||
'7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435',
|
||
'91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61'
|
||
],
|
||
[
|
||
'754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18',
|
||
'673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683'
|
||
],
|
||
[
|
||
'e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8',
|
||
'59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5'
|
||
],
|
||
[
|
||
'186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb',
|
||
'3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b'
|
||
],
|
||
[
|
||
'df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f',
|
||
'55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417'
|
||
],
|
||
[
|
||
'5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143',
|
||
'efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868'
|
||
],
|
||
[
|
||
'290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba',
|
||
'e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a'
|
||
],
|
||
[
|
||
'af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45',
|
||
'f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6'
|
||
],
|
||
[
|
||
'766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a',
|
||
'744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996'
|
||
],
|
||
[
|
||
'59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e',
|
||
'c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e'
|
||
],
|
||
[
|
||
'f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8',
|
||
'e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d'
|
||
],
|
||
[
|
||
'7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c',
|
||
'30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2'
|
||
],
|
||
[
|
||
'948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519',
|
||
'e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e'
|
||
],
|
||
[
|
||
'7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab',
|
||
'100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437'
|
||
],
|
||
[
|
||
'3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca',
|
||
'ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311'
|
||
],
|
||
[
|
||
'd3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf',
|
||
'8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4'
|
||
],
|
||
[
|
||
'1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610',
|
||
'68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575'
|
||
],
|
||
[
|
||
'733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4',
|
||
'f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d'
|
||
],
|
||
[
|
||
'15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c',
|
||
'd56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d'
|
||
],
|
||
[
|
||
'a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940',
|
||
'edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629'
|
||
],
|
||
[
|
||
'e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980',
|
||
'a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06'
|
||
],
|
||
[
|
||
'311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3',
|
||
'66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374'
|
||
],
|
||
[
|
||
'34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf',
|
||
'9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee'
|
||
],
|
||
[
|
||
'f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63',
|
||
'4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1'
|
||
],
|
||
[
|
||
'd7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448',
|
||
'fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b'
|
||
],
|
||
[
|
||
'32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf',
|
||
'5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661'
|
||
],
|
||
[
|
||
'7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5',
|
||
'8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6'
|
||
],
|
||
[
|
||
'ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6',
|
||
'8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e'
|
||
],
|
||
[
|
||
'16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5',
|
||
'5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d'
|
||
],
|
||
[
|
||
'eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99',
|
||
'f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc'
|
||
],
|
||
[
|
||
'78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51',
|
||
'f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4'
|
||
],
|
||
[
|
||
'494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5',
|
||
'42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c'
|
||
],
|
||
[
|
||
'a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5',
|
||
'204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b'
|
||
],
|
||
[
|
||
'c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997',
|
||
'4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913'
|
||
],
|
||
[
|
||
'841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881',
|
||
'73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154'
|
||
],
|
||
[
|
||
'5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5',
|
||
'39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865'
|
||
],
|
||
[
|
||
'36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66',
|
||
'd2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc'
|
||
],
|
||
[
|
||
'336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726',
|
||
'ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224'
|
||
],
|
||
[
|
||
'8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede',
|
||
'6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e'
|
||
],
|
||
[
|
||
'1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94',
|
||
'60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6'
|
||
],
|
||
[
|
||
'85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31',
|
||
'3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511'
|
||
],
|
||
[
|
||
'29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51',
|
||
'b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b'
|
||
],
|
||
[
|
||
'a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252',
|
||
'ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2'
|
||
],
|
||
[
|
||
'4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5',
|
||
'cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c'
|
||
],
|
||
[
|
||
'd24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b',
|
||
'6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3'
|
||
],
|
||
[
|
||
'ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4',
|
||
'322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d'
|
||
],
|
||
[
|
||
'af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f',
|
||
'6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700'
|
||
],
|
||
[
|
||
'e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889',
|
||
'2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4'
|
||
],
|
||
[
|
||
'591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246',
|
||
'b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196'
|
||
],
|
||
[
|
||
'11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984',
|
||
'998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4'
|
||
],
|
||
[
|
||
'3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a',
|
||
'b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257'
|
||
],
|
||
[
|
||
'cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030',
|
||
'bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13'
|
||
],
|
||
[
|
||
'c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197',
|
||
'6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096'
|
||
],
|
||
[
|
||
'c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593',
|
||
'c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38'
|
||
],
|
||
[
|
||
'a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef',
|
||
'21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f'
|
||
],
|
||
[
|
||
'347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38',
|
||
'60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448'
|
||
],
|
||
[
|
||
'da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a',
|
||
'49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a'
|
||
],
|
||
[
|
||
'c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111',
|
||
'5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4'
|
||
],
|
||
[
|
||
'4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502',
|
||
'7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437'
|
||
],
|
||
[
|
||
'3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea',
|
||
'be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7'
|
||
],
|
||
[
|
||
'cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26',
|
||
'8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d'
|
||
],
|
||
[
|
||
'b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986',
|
||
'39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a'
|
||
],
|
||
[
|
||
'd4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e',
|
||
'62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54'
|
||
],
|
||
[
|
||
'48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4',
|
||
'25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77'
|
||
],
|
||
[
|
||
'dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda',
|
||
'ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517'
|
||
],
|
||
[
|
||
'6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859',
|
||
'cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10'
|
||
],
|
||
[
|
||
'e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f',
|
||
'f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125'
|
||
],
|
||
[
|
||
'eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c',
|
||
'6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e'
|
||
],
|
||
[
|
||
'13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942',
|
||
'fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1'
|
||
],
|
||
[
|
||
'ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a',
|
||
'1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2'
|
||
],
|
||
[
|
||
'b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80',
|
||
'5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423'
|
||
],
|
||
[
|
||
'ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d',
|
||
'438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8'
|
||
],
|
||
[
|
||
'8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1',
|
||
'cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758'
|
||
],
|
||
[
|
||
'52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63',
|
||
'c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375'
|
||
],
|
||
[
|
||
'e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352',
|
||
'6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d'
|
||
],
|
||
[
|
||
'7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193',
|
||
'ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec'
|
||
],
|
||
[
|
||
'5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00',
|
||
'9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0'
|
||
],
|
||
[
|
||
'32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58',
|
||
'ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c'
|
||
],
|
||
[
|
||
'e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7',
|
||
'd3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4'
|
||
],
|
||
[
|
||
'8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8',
|
||
'c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f'
|
||
],
|
||
[
|
||
'4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e',
|
||
'67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649'
|
||
],
|
||
[
|
||
'3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d',
|
||
'cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826'
|
||
],
|
||
[
|
||
'674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b',
|
||
'299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5'
|
||
],
|
||
[
|
||
'd32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f',
|
||
'f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87'
|
||
],
|
||
[
|
||
'30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6',
|
||
'462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b'
|
||
],
|
||
[
|
||
'be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297',
|
||
'62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc'
|
||
],
|
||
[
|
||
'93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a',
|
||
'7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c'
|
||
],
|
||
[
|
||
'b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c',
|
||
'ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f'
|
||
],
|
||
[
|
||
'd5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52',
|
||
'4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a'
|
||
],
|
||
[
|
||
'd3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb',
|
||
'bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46'
|
||
],
|
||
[
|
||
'463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065',
|
||
'bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f'
|
||
],
|
||
[
|
||
'7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917',
|
||
'603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03'
|
||
],
|
||
[
|
||
'74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9',
|
||
'cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08'
|
||
],
|
||
[
|
||
'30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3',
|
||
'553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8'
|
||
],
|
||
[
|
||
'9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57',
|
||
'712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373'
|
||
],
|
||
[
|
||
'176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66',
|
||
'ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3'
|
||
],
|
||
[
|
||
'75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8',
|
||
'9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8'
|
||
],
|
||
[
|
||
'809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721',
|
||
'9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1'
|
||
],
|
||
[
|
||
'1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180',
|
||
'4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9'
|
||
]
|
||
]
|
||
}
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/elliptic/lib/elliptic/utils.js":
|
||
/*!*****************************************************!*\
|
||
!*** ./node_modules/elliptic/lib/elliptic/utils.js ***!
|
||
\*****************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var utils = exports;
|
||
var BN = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js");
|
||
var minAssert = __webpack_require__(/*! minimalistic-assert */ "./node_modules/minimalistic-assert/index.js");
|
||
var minUtils = __webpack_require__(/*! minimalistic-crypto-utils */ "./node_modules/minimalistic-crypto-utils/lib/utils.js");
|
||
|
||
utils.assert = minAssert;
|
||
utils.toArray = minUtils.toArray;
|
||
utils.zero2 = minUtils.zero2;
|
||
utils.toHex = minUtils.toHex;
|
||
utils.encode = minUtils.encode;
|
||
|
||
// Represent num in a w-NAF form
|
||
function getNAF(num, w, bits) {
|
||
var naf = new Array(Math.max(num.bitLength(), bits) + 1);
|
||
naf.fill(0);
|
||
|
||
var ws = 1 << (w + 1);
|
||
var k = num.clone();
|
||
|
||
for (var i = 0; i < naf.length; i++) {
|
||
var z;
|
||
var mod = k.andln(ws - 1);
|
||
if (k.isOdd()) {
|
||
if (mod > (ws >> 1) - 1)
|
||
z = (ws >> 1) - mod;
|
||
else
|
||
z = mod;
|
||
k.isubn(z);
|
||
} else {
|
||
z = 0;
|
||
}
|
||
|
||
naf[i] = z;
|
||
k.iushrn(1);
|
||
}
|
||
|
||
return naf;
|
||
}
|
||
utils.getNAF = getNAF;
|
||
|
||
// Represent k1, k2 in a Joint Sparse Form
|
||
function getJSF(k1, k2) {
|
||
var jsf = [
|
||
[],
|
||
[]
|
||
];
|
||
|
||
k1 = k1.clone();
|
||
k2 = k2.clone();
|
||
var d1 = 0;
|
||
var d2 = 0;
|
||
while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) {
|
||
|
||
// First phase
|
||
var m14 = (k1.andln(3) + d1) & 3;
|
||
var m24 = (k2.andln(3) + d2) & 3;
|
||
if (m14 === 3)
|
||
m14 = -1;
|
||
if (m24 === 3)
|
||
m24 = -1;
|
||
var u1;
|
||
if ((m14 & 1) === 0) {
|
||
u1 = 0;
|
||
} else {
|
||
var m8 = (k1.andln(7) + d1) & 7;
|
||
if ((m8 === 3 || m8 === 5) && m24 === 2)
|
||
u1 = -m14;
|
||
else
|
||
u1 = m14;
|
||
}
|
||
jsf[0].push(u1);
|
||
|
||
var u2;
|
||
if ((m24 & 1) === 0) {
|
||
u2 = 0;
|
||
} else {
|
||
var m8 = (k2.andln(7) + d2) & 7;
|
||
if ((m8 === 3 || m8 === 5) && m14 === 2)
|
||
u2 = -m24;
|
||
else
|
||
u2 = m24;
|
||
}
|
||
jsf[1].push(u2);
|
||
|
||
// Second phase
|
||
if (2 * d1 === u1 + 1)
|
||
d1 = 1 - d1;
|
||
if (2 * d2 === u2 + 1)
|
||
d2 = 1 - d2;
|
||
k1.iushrn(1);
|
||
k2.iushrn(1);
|
||
}
|
||
|
||
return jsf;
|
||
}
|
||
utils.getJSF = getJSF;
|
||
|
||
function cachedProperty(obj, name, computer) {
|
||
var key = '_' + name;
|
||
obj.prototype[name] = function cachedProperty() {
|
||
return this[key] !== undefined ? this[key] :
|
||
this[key] = computer.call(this);
|
||
};
|
||
}
|
||
utils.cachedProperty = cachedProperty;
|
||
|
||
function parseBytes(bytes) {
|
||
return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') :
|
||
bytes;
|
||
}
|
||
utils.parseBytes = parseBytes;
|
||
|
||
function intFromLE(bytes) {
|
||
return new BN(bytes, 'hex', 'le');
|
||
}
|
||
utils.intFromLE = intFromLE;
|
||
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/elliptic/package.json":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/elliptic/package.json ***!
|
||
\********************************************/
|
||
/*! exports provided: _args, _development, _from, _id, _inBundle, _integrity, _location, _phantomChildren, _requested, _requiredBy, _resolved, _spec, _where, author, bugs, dependencies, description, devDependencies, files, homepage, keywords, license, main, name, repository, scripts, version, default */
|
||
/***/ (function(module) {
|
||
|
||
module.exports = JSON.parse("{\"_args\":[[\"elliptic@6.5.3\",\"/home/highway/Projekte/pdfAnnotate\"]],\"_development\":true,\"_from\":\"elliptic@6.5.3\",\"_id\":\"elliptic@6.5.3\",\"_inBundle\":false,\"_integrity\":\"sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==\",\"_location\":\"/elliptic\",\"_phantomChildren\":{},\"_requested\":{\"type\":\"version\",\"registry\":true,\"raw\":\"elliptic@6.5.3\",\"name\":\"elliptic\",\"escapedName\":\"elliptic\",\"rawSpec\":\"6.5.3\",\"saveSpec\":null,\"fetchSpec\":\"6.5.3\"},\"_requiredBy\":[\"/browserify-sign\",\"/create-ecdh\"],\"_resolved\":\"https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz\",\"_spec\":\"6.5.3\",\"_where\":\"/home/highway/Projekte/pdfAnnotate\",\"author\":{\"name\":\"Fedor Indutny\",\"email\":\"fedor@indutny.com\"},\"bugs\":{\"url\":\"https://github.com/indutny/elliptic/issues\"},\"dependencies\":{\"bn.js\":\"^4.4.0\",\"brorand\":\"^1.0.1\",\"hash.js\":\"^1.0.0\",\"hmac-drbg\":\"^1.0.0\",\"inherits\":\"^2.0.1\",\"minimalistic-assert\":\"^1.0.0\",\"minimalistic-crypto-utils\":\"^1.0.0\"},\"description\":\"EC cryptography\",\"devDependencies\":{\"brfs\":\"^1.4.3\",\"coveralls\":\"^3.0.8\",\"grunt\":\"^1.0.4\",\"grunt-browserify\":\"^5.0.0\",\"grunt-cli\":\"^1.2.0\",\"grunt-contrib-connect\":\"^1.0.0\",\"grunt-contrib-copy\":\"^1.0.0\",\"grunt-contrib-uglify\":\"^1.0.1\",\"grunt-mocha-istanbul\":\"^3.0.1\",\"grunt-saucelabs\":\"^9.0.1\",\"istanbul\":\"^0.4.2\",\"jscs\":\"^3.0.7\",\"jshint\":\"^2.10.3\",\"mocha\":\"^6.2.2\"},\"files\":[\"lib\"],\"homepage\":\"https://github.com/indutny/elliptic\",\"keywords\":[\"EC\",\"Elliptic\",\"curve\",\"Cryptography\"],\"license\":\"MIT\",\"main\":\"lib/elliptic.js\",\"name\":\"elliptic\",\"repository\":{\"type\":\"git\",\"url\":\"git+ssh://git@github.com/indutny/elliptic.git\"},\"scripts\":{\"jscs\":\"jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js\",\"jshint\":\"jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js\",\"lint\":\"npm run jscs && npm run jshint\",\"test\":\"npm run lint && npm run unit\",\"unit\":\"istanbul test _mocha --reporter=spec test/index.js\",\"version\":\"grunt dist && git add dist/\"},\"version\":\"6.5.3\"}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/events/events.js":
|
||
/*!***************************************!*\
|
||
!*** ./node_modules/events/events.js ***!
|
||
\***************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
// Copyright Joyent, Inc. and other Node contributors.
|
||
//
|
||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||
// copy of this software and associated documentation files (the
|
||
// "Software"), to deal in the Software without restriction, including
|
||
// without limitation the rights to use, copy, modify, merge, publish,
|
||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||
// persons to whom the Software is furnished to do so, subject to the
|
||
// following conditions:
|
||
//
|
||
// The above copyright notice and this permission notice shall be included
|
||
// in all copies or substantial portions of the Software.
|
||
//
|
||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
||
|
||
|
||
var R = typeof Reflect === 'object' ? Reflect : null
|
||
var ReflectApply = R && typeof R.apply === 'function'
|
||
? R.apply
|
||
: function ReflectApply(target, receiver, args) {
|
||
return Function.prototype.apply.call(target, receiver, args);
|
||
}
|
||
|
||
var ReflectOwnKeys
|
||
if (R && typeof R.ownKeys === 'function') {
|
||
ReflectOwnKeys = R.ownKeys
|
||
} else if (Object.getOwnPropertySymbols) {
|
||
ReflectOwnKeys = function ReflectOwnKeys(target) {
|
||
return Object.getOwnPropertyNames(target)
|
||
.concat(Object.getOwnPropertySymbols(target));
|
||
};
|
||
} else {
|
||
ReflectOwnKeys = function ReflectOwnKeys(target) {
|
||
return Object.getOwnPropertyNames(target);
|
||
};
|
||
}
|
||
|
||
function ProcessEmitWarning(warning) {
|
||
if (console && console.warn) console.warn(warning);
|
||
}
|
||
|
||
var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
|
||
return value !== value;
|
||
}
|
||
|
||
function EventEmitter() {
|
||
EventEmitter.init.call(this);
|
||
}
|
||
module.exports = EventEmitter;
|
||
|
||
// Backwards-compat with node 0.10.x
|
||
EventEmitter.EventEmitter = EventEmitter;
|
||
|
||
EventEmitter.prototype._events = undefined;
|
||
EventEmitter.prototype._eventsCount = 0;
|
||
EventEmitter.prototype._maxListeners = undefined;
|
||
|
||
// By default EventEmitters will print a warning if more than 10 listeners are
|
||
// added to it. This is a useful default which helps finding memory leaks.
|
||
var defaultMaxListeners = 10;
|
||
|
||
Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
|
||
enumerable: true,
|
||
get: function() {
|
||
return defaultMaxListeners;
|
||
},
|
||
set: function(arg) {
|
||
if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
|
||
throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
|
||
}
|
||
defaultMaxListeners = arg;
|
||
}
|
||
});
|
||
|
||
EventEmitter.init = function() {
|
||
|
||
if (this._events === undefined ||
|
||
this._events === Object.getPrototypeOf(this)._events) {
|
||
this._events = Object.create(null);
|
||
this._eventsCount = 0;
|
||
}
|
||
|
||
this._maxListeners = this._maxListeners || undefined;
|
||
};
|
||
|
||
// Obviously not all Emitters should be limited to 10. This function allows
|
||
// that to be increased. Set to zero for unlimited.
|
||
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
|
||
if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
|
||
throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
|
||
}
|
||
this._maxListeners = n;
|
||
return this;
|
||
};
|
||
|
||
function $getMaxListeners(that) {
|
||
if (that._maxListeners === undefined)
|
||
return EventEmitter.defaultMaxListeners;
|
||
return that._maxListeners;
|
||
}
|
||
|
||
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
|
||
return $getMaxListeners(this);
|
||
};
|
||
|
||
EventEmitter.prototype.emit = function emit(type) {
|
||
var args = [];
|
||
for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
|
||
var doError = (type === 'error');
|
||
|
||
var events = this._events;
|
||
if (events !== undefined)
|
||
doError = (doError && events.error === undefined);
|
||
else if (!doError)
|
||
return false;
|
||
|
||
// If there is no 'error' event listener then throw.
|
||
if (doError) {
|
||
var er;
|
||
if (args.length > 0)
|
||
er = args[0];
|
||
if (er instanceof Error) {
|
||
// Note: The comments on the `throw` lines are intentional, they show
|
||
// up in Node's output if this results in an unhandled exception.
|
||
throw er; // Unhandled 'error' event
|
||
}
|
||
// At least give some kind of context to the user
|
||
var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
|
||
err.context = er;
|
||
throw err; // Unhandled 'error' event
|
||
}
|
||
|
||
var handler = events[type];
|
||
|
||
if (handler === undefined)
|
||
return false;
|
||
|
||
if (typeof handler === 'function') {
|
||
ReflectApply(handler, this, args);
|
||
} else {
|
||
var len = handler.length;
|
||
var listeners = arrayClone(handler, len);
|
||
for (var i = 0; i < len; ++i)
|
||
ReflectApply(listeners[i], this, args);
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
function _addListener(target, type, listener, prepend) {
|
||
var m;
|
||
var events;
|
||
var existing;
|
||
|
||
if (typeof listener !== 'function') {
|
||
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
|
||
}
|
||
|
||
events = target._events;
|
||
if (events === undefined) {
|
||
events = target._events = Object.create(null);
|
||
target._eventsCount = 0;
|
||
} else {
|
||
// To avoid recursion in the case that type === "newListener"! Before
|
||
// adding it to the listeners, first emit "newListener".
|
||
if (events.newListener !== undefined) {
|
||
target.emit('newListener', type,
|
||
listener.listener ? listener.listener : listener);
|
||
|
||
// Re-assign `events` because a newListener handler could have caused the
|
||
// this._events to be assigned to a new object
|
||
events = target._events;
|
||
}
|
||
existing = events[type];
|
||
}
|
||
|
||
if (existing === undefined) {
|
||
// Optimize the case of one listener. Don't need the extra array object.
|
||
existing = events[type] = listener;
|
||
++target._eventsCount;
|
||
} else {
|
||
if (typeof existing === 'function') {
|
||
// Adding the second element, need to change to array.
|
||
existing = events[type] =
|
||
prepend ? [listener, existing] : [existing, listener];
|
||
// If we've already got an array, just append.
|
||
} else if (prepend) {
|
||
existing.unshift(listener);
|
||
} else {
|
||
existing.push(listener);
|
||
}
|
||
|
||
// Check for listener leak
|
||
m = $getMaxListeners(target);
|
||
if (m > 0 && existing.length > m && !existing.warned) {
|
||
existing.warned = true;
|
||
// No error code for this since it is a Warning
|
||
// eslint-disable-next-line no-restricted-syntax
|
||
var w = new Error('Possible EventEmitter memory leak detected. ' +
|
||
existing.length + ' ' + String(type) + ' listeners ' +
|
||
'added. Use emitter.setMaxListeners() to ' +
|
||
'increase limit');
|
||
w.name = 'MaxListenersExceededWarning';
|
||
w.emitter = target;
|
||
w.type = type;
|
||
w.count = existing.length;
|
||
ProcessEmitWarning(w);
|
||
}
|
||
}
|
||
|
||
return target;
|
||
}
|
||
|
||
EventEmitter.prototype.addListener = function addListener(type, listener) {
|
||
return _addListener(this, type, listener, false);
|
||
};
|
||
|
||
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
|
||
|
||
EventEmitter.prototype.prependListener =
|
||
function prependListener(type, listener) {
|
||
return _addListener(this, type, listener, true);
|
||
};
|
||
|
||
function onceWrapper() {
|
||
var args = [];
|
||
for (var i = 0; i < arguments.length; i++) args.push(arguments[i]);
|
||
if (!this.fired) {
|
||
this.target.removeListener(this.type, this.wrapFn);
|
||
this.fired = true;
|
||
ReflectApply(this.listener, this.target, args);
|
||
}
|
||
}
|
||
|
||
function _onceWrap(target, type, listener) {
|
||
var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
|
||
var wrapped = onceWrapper.bind(state);
|
||
wrapped.listener = listener;
|
||
state.wrapFn = wrapped;
|
||
return wrapped;
|
||
}
|
||
|
||
EventEmitter.prototype.once = function once(type, listener) {
|
||
if (typeof listener !== 'function') {
|
||
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
|
||
}
|
||
this.on(type, _onceWrap(this, type, listener));
|
||
return this;
|
||
};
|
||
|
||
EventEmitter.prototype.prependOnceListener =
|
||
function prependOnceListener(type, listener) {
|
||
if (typeof listener !== 'function') {
|
||
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
|
||
}
|
||
this.prependListener(type, _onceWrap(this, type, listener));
|
||
return this;
|
||
};
|
||
|
||
// Emits a 'removeListener' event if and only if the listener was removed.
|
||
EventEmitter.prototype.removeListener =
|
||
function removeListener(type, listener) {
|
||
var list, events, position, i, originalListener;
|
||
|
||
if (typeof listener !== 'function') {
|
||
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
|
||
}
|
||
|
||
events = this._events;
|
||
if (events === undefined)
|
||
return this;
|
||
|
||
list = events[type];
|
||
if (list === undefined)
|
||
return this;
|
||
|
||
if (list === listener || list.listener === listener) {
|
||
if (--this._eventsCount === 0)
|
||
this._events = Object.create(null);
|
||
else {
|
||
delete events[type];
|
||
if (events.removeListener)
|
||
this.emit('removeListener', type, list.listener || listener);
|
||
}
|
||
} else if (typeof list !== 'function') {
|
||
position = -1;
|
||
|
||
for (i = list.length - 1; i >= 0; i--) {
|
||
if (list[i] === listener || list[i].listener === listener) {
|
||
originalListener = list[i].listener;
|
||
position = i;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (position < 0)
|
||
return this;
|
||
|
||
if (position === 0)
|
||
list.shift();
|
||
else {
|
||
spliceOne(list, position);
|
||
}
|
||
|
||
if (list.length === 1)
|
||
events[type] = list[0];
|
||
|
||
if (events.removeListener !== undefined)
|
||
this.emit('removeListener', type, originalListener || listener);
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
|
||
|
||
EventEmitter.prototype.removeAllListeners =
|
||
function removeAllListeners(type) {
|
||
var listeners, events, i;
|
||
|
||
events = this._events;
|
||
if (events === undefined)
|
||
return this;
|
||
|
||
// not listening for removeListener, no need to emit
|
||
if (events.removeListener === undefined) {
|
||
if (arguments.length === 0) {
|
||
this._events = Object.create(null);
|
||
this._eventsCount = 0;
|
||
} else if (events[type] !== undefined) {
|
||
if (--this._eventsCount === 0)
|
||
this._events = Object.create(null);
|
||
else
|
||
delete events[type];
|
||
}
|
||
return this;
|
||
}
|
||
|
||
// emit removeListener for all listeners on all events
|
||
if (arguments.length === 0) {
|
||
var keys = Object.keys(events);
|
||
var key;
|
||
for (i = 0; i < keys.length; ++i) {
|
||
key = keys[i];
|
||
if (key === 'removeListener') continue;
|
||
this.removeAllListeners(key);
|
||
}
|
||
this.removeAllListeners('removeListener');
|
||
this._events = Object.create(null);
|
||
this._eventsCount = 0;
|
||
return this;
|
||
}
|
||
|
||
listeners = events[type];
|
||
|
||
if (typeof listeners === 'function') {
|
||
this.removeListener(type, listeners);
|
||
} else if (listeners !== undefined) {
|
||
// LIFO order
|
||
for (i = listeners.length - 1; i >= 0; i--) {
|
||
this.removeListener(type, listeners[i]);
|
||
}
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
function _listeners(target, type, unwrap) {
|
||
var events = target._events;
|
||
|
||
if (events === undefined)
|
||
return [];
|
||
|
||
var evlistener = events[type];
|
||
if (evlistener === undefined)
|
||
return [];
|
||
|
||
if (typeof evlistener === 'function')
|
||
return unwrap ? [evlistener.listener || evlistener] : [evlistener];
|
||
|
||
return unwrap ?
|
||
unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
|
||
}
|
||
|
||
EventEmitter.prototype.listeners = function listeners(type) {
|
||
return _listeners(this, type, true);
|
||
};
|
||
|
||
EventEmitter.prototype.rawListeners = function rawListeners(type) {
|
||
return _listeners(this, type, false);
|
||
};
|
||
|
||
EventEmitter.listenerCount = function(emitter, type) {
|
||
if (typeof emitter.listenerCount === 'function') {
|
||
return emitter.listenerCount(type);
|
||
} else {
|
||
return listenerCount.call(emitter, type);
|
||
}
|
||
};
|
||
|
||
EventEmitter.prototype.listenerCount = listenerCount;
|
||
function listenerCount(type) {
|
||
var events = this._events;
|
||
|
||
if (events !== undefined) {
|
||
var evlistener = events[type];
|
||
|
||
if (typeof evlistener === 'function') {
|
||
return 1;
|
||
} else if (evlistener !== undefined) {
|
||
return evlistener.length;
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
EventEmitter.prototype.eventNames = function eventNames() {
|
||
return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
|
||
};
|
||
|
||
function arrayClone(arr, n) {
|
||
var copy = new Array(n);
|
||
for (var i = 0; i < n; ++i)
|
||
copy[i] = arr[i];
|
||
return copy;
|
||
}
|
||
|
||
function spliceOne(list, index) {
|
||
for (; index + 1 < list.length; index++)
|
||
list[index] = list[index + 1];
|
||
list.pop();
|
||
}
|
||
|
||
function unwrapListeners(arr) {
|
||
var ret = new Array(arr.length);
|
||
for (var i = 0; i < ret.length; ++i) {
|
||
ret[i] = arr[i].listener || arr[i];
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/evp_bytestokey/index.js":
|
||
/*!**********************************************!*\
|
||
!*** ./node_modules/evp_bytestokey/index.js ***!
|
||
\**********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
var MD5 = __webpack_require__(/*! md5.js */ "./node_modules/md5.js/index.js")
|
||
|
||
/* eslint-disable camelcase */
|
||
function EVP_BytesToKey (password, salt, keyBits, ivLen) {
|
||
if (!Buffer.isBuffer(password)) password = Buffer.from(password, 'binary')
|
||
if (salt) {
|
||
if (!Buffer.isBuffer(salt)) salt = Buffer.from(salt, 'binary')
|
||
if (salt.length !== 8) throw new RangeError('salt should be Buffer with 8 byte length')
|
||
}
|
||
|
||
var keyLen = keyBits / 8
|
||
var key = Buffer.alloc(keyLen)
|
||
var iv = Buffer.alloc(ivLen || 0)
|
||
var tmp = Buffer.alloc(0)
|
||
|
||
while (keyLen > 0 || ivLen > 0) {
|
||
var hash = new MD5()
|
||
hash.update(tmp)
|
||
hash.update(password)
|
||
if (salt) hash.update(salt)
|
||
tmp = hash.digest()
|
||
|
||
var used = 0
|
||
|
||
if (keyLen > 0) {
|
||
var keyStart = key.length - keyLen
|
||
used = Math.min(keyLen, tmp.length)
|
||
tmp.copy(key, keyStart, 0, used)
|
||
keyLen -= used
|
||
}
|
||
|
||
if (used < tmp.length && ivLen > 0) {
|
||
var ivStart = iv.length - ivLen
|
||
var length = Math.min(ivLen, tmp.length - used)
|
||
tmp.copy(iv, ivStart, used, used + length)
|
||
ivLen -= length
|
||
}
|
||
}
|
||
|
||
tmp.fill(0)
|
||
return { key: key, iv: iv }
|
||
}
|
||
|
||
module.exports = EVP_BytesToKey
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/hash-base/index.js":
|
||
/*!*****************************************!*\
|
||
!*** ./node_modules/hash-base/index.js ***!
|
||
\*****************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
var Transform = __webpack_require__(/*! stream */ "./node_modules/stream-browserify/index.js").Transform
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
|
||
function throwIfNotStringOrBuffer (val, prefix) {
|
||
if (!Buffer.isBuffer(val) && typeof val !== 'string') {
|
||
throw new TypeError(prefix + ' must be a string or a buffer')
|
||
}
|
||
}
|
||
|
||
function HashBase (blockSize) {
|
||
Transform.call(this)
|
||
|
||
this._block = Buffer.allocUnsafe(blockSize)
|
||
this._blockSize = blockSize
|
||
this._blockOffset = 0
|
||
this._length = [0, 0, 0, 0]
|
||
|
||
this._finalized = false
|
||
}
|
||
|
||
inherits(HashBase, Transform)
|
||
|
||
HashBase.prototype._transform = function (chunk, encoding, callback) {
|
||
var error = null
|
||
try {
|
||
this.update(chunk, encoding)
|
||
} catch (err) {
|
||
error = err
|
||
}
|
||
|
||
callback(error)
|
||
}
|
||
|
||
HashBase.prototype._flush = function (callback) {
|
||
var error = null
|
||
try {
|
||
this.push(this.digest())
|
||
} catch (err) {
|
||
error = err
|
||
}
|
||
|
||
callback(error)
|
||
}
|
||
|
||
HashBase.prototype.update = function (data, encoding) {
|
||
throwIfNotStringOrBuffer(data, 'Data')
|
||
if (this._finalized) throw new Error('Digest already called')
|
||
if (!Buffer.isBuffer(data)) data = Buffer.from(data, encoding)
|
||
|
||
// consume data
|
||
var block = this._block
|
||
var offset = 0
|
||
while (this._blockOffset + data.length - offset >= this._blockSize) {
|
||
for (var i = this._blockOffset; i < this._blockSize;) block[i++] = data[offset++]
|
||
this._update()
|
||
this._blockOffset = 0
|
||
}
|
||
while (offset < data.length) block[this._blockOffset++] = data[offset++]
|
||
|
||
// update length
|
||
for (var j = 0, carry = data.length * 8; carry > 0; ++j) {
|
||
this._length[j] += carry
|
||
carry = (this._length[j] / 0x0100000000) | 0
|
||
if (carry > 0) this._length[j] -= 0x0100000000 * carry
|
||
}
|
||
|
||
return this
|
||
}
|
||
|
||
HashBase.prototype._update = function () {
|
||
throw new Error('_update is not implemented')
|
||
}
|
||
|
||
HashBase.prototype.digest = function (encoding) {
|
||
if (this._finalized) throw new Error('Digest already called')
|
||
this._finalized = true
|
||
|
||
var digest = this._digest()
|
||
if (encoding !== undefined) digest = digest.toString(encoding)
|
||
|
||
// reset state
|
||
this._block.fill(0)
|
||
this._blockOffset = 0
|
||
for (var i = 0; i < 4; ++i) this._length[i] = 0
|
||
|
||
return digest
|
||
}
|
||
|
||
HashBase.prototype._digest = function () {
|
||
throw new Error('_digest is not implemented')
|
||
}
|
||
|
||
module.exports = HashBase
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/hash.js/lib/hash.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/hash.js/lib/hash.js ***!
|
||
\******************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var hash = exports;
|
||
|
||
hash.utils = __webpack_require__(/*! ./hash/utils */ "./node_modules/hash.js/lib/hash/utils.js");
|
||
hash.common = __webpack_require__(/*! ./hash/common */ "./node_modules/hash.js/lib/hash/common.js");
|
||
hash.sha = __webpack_require__(/*! ./hash/sha */ "./node_modules/hash.js/lib/hash/sha.js");
|
||
hash.ripemd = __webpack_require__(/*! ./hash/ripemd */ "./node_modules/hash.js/lib/hash/ripemd.js");
|
||
hash.hmac = __webpack_require__(/*! ./hash/hmac */ "./node_modules/hash.js/lib/hash/hmac.js");
|
||
|
||
// Proxy hash functions to the main object
|
||
hash.sha1 = hash.sha.sha1;
|
||
hash.sha256 = hash.sha.sha256;
|
||
hash.sha224 = hash.sha.sha224;
|
||
hash.sha384 = hash.sha.sha384;
|
||
hash.sha512 = hash.sha.sha512;
|
||
hash.ripemd160 = hash.ripemd.ripemd160;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/hash.js/lib/hash/common.js":
|
||
/*!*************************************************!*\
|
||
!*** ./node_modules/hash.js/lib/hash/common.js ***!
|
||
\*************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var utils = __webpack_require__(/*! ./utils */ "./node_modules/hash.js/lib/hash/utils.js");
|
||
var assert = __webpack_require__(/*! minimalistic-assert */ "./node_modules/minimalistic-assert/index.js");
|
||
|
||
function BlockHash() {
|
||
this.pending = null;
|
||
this.pendingTotal = 0;
|
||
this.blockSize = this.constructor.blockSize;
|
||
this.outSize = this.constructor.outSize;
|
||
this.hmacStrength = this.constructor.hmacStrength;
|
||
this.padLength = this.constructor.padLength / 8;
|
||
this.endian = 'big';
|
||
|
||
this._delta8 = this.blockSize / 8;
|
||
this._delta32 = this.blockSize / 32;
|
||
}
|
||
exports.BlockHash = BlockHash;
|
||
|
||
BlockHash.prototype.update = function update(msg, enc) {
|
||
// Convert message to array, pad it, and join into 32bit blocks
|
||
msg = utils.toArray(msg, enc);
|
||
if (!this.pending)
|
||
this.pending = msg;
|
||
else
|
||
this.pending = this.pending.concat(msg);
|
||
this.pendingTotal += msg.length;
|
||
|
||
// Enough data, try updating
|
||
if (this.pending.length >= this._delta8) {
|
||
msg = this.pending;
|
||
|
||
// Process pending data in blocks
|
||
var r = msg.length % this._delta8;
|
||
this.pending = msg.slice(msg.length - r, msg.length);
|
||
if (this.pending.length === 0)
|
||
this.pending = null;
|
||
|
||
msg = utils.join32(msg, 0, msg.length - r, this.endian);
|
||
for (var i = 0; i < msg.length; i += this._delta32)
|
||
this._update(msg, i, i + this._delta32);
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
BlockHash.prototype.digest = function digest(enc) {
|
||
this.update(this._pad());
|
||
assert(this.pending === null);
|
||
|
||
return this._digest(enc);
|
||
};
|
||
|
||
BlockHash.prototype._pad = function pad() {
|
||
var len = this.pendingTotal;
|
||
var bytes = this._delta8;
|
||
var k = bytes - ((len + this.padLength) % bytes);
|
||
var res = new Array(k + this.padLength);
|
||
res[0] = 0x80;
|
||
for (var i = 1; i < k; i++)
|
||
res[i] = 0;
|
||
|
||
// Append length
|
||
len <<= 3;
|
||
if (this.endian === 'big') {
|
||
for (var t = 8; t < this.padLength; t++)
|
||
res[i++] = 0;
|
||
|
||
res[i++] = 0;
|
||
res[i++] = 0;
|
||
res[i++] = 0;
|
||
res[i++] = 0;
|
||
res[i++] = (len >>> 24) & 0xff;
|
||
res[i++] = (len >>> 16) & 0xff;
|
||
res[i++] = (len >>> 8) & 0xff;
|
||
res[i++] = len & 0xff;
|
||
} else {
|
||
res[i++] = len & 0xff;
|
||
res[i++] = (len >>> 8) & 0xff;
|
||
res[i++] = (len >>> 16) & 0xff;
|
||
res[i++] = (len >>> 24) & 0xff;
|
||
res[i++] = 0;
|
||
res[i++] = 0;
|
||
res[i++] = 0;
|
||
res[i++] = 0;
|
||
|
||
for (t = 8; t < this.padLength; t++)
|
||
res[i++] = 0;
|
||
}
|
||
|
||
return res;
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/hash.js/lib/hash/hmac.js":
|
||
/*!***********************************************!*\
|
||
!*** ./node_modules/hash.js/lib/hash/hmac.js ***!
|
||
\***********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var utils = __webpack_require__(/*! ./utils */ "./node_modules/hash.js/lib/hash/utils.js");
|
||
var assert = __webpack_require__(/*! minimalistic-assert */ "./node_modules/minimalistic-assert/index.js");
|
||
|
||
function Hmac(hash, key, enc) {
|
||
if (!(this instanceof Hmac))
|
||
return new Hmac(hash, key, enc);
|
||
this.Hash = hash;
|
||
this.blockSize = hash.blockSize / 8;
|
||
this.outSize = hash.outSize / 8;
|
||
this.inner = null;
|
||
this.outer = null;
|
||
|
||
this._init(utils.toArray(key, enc));
|
||
}
|
||
module.exports = Hmac;
|
||
|
||
Hmac.prototype._init = function init(key) {
|
||
// Shorten key, if needed
|
||
if (key.length > this.blockSize)
|
||
key = new this.Hash().update(key).digest();
|
||
assert(key.length <= this.blockSize);
|
||
|
||
// Add padding to key
|
||
for (var i = key.length; i < this.blockSize; i++)
|
||
key.push(0);
|
||
|
||
for (i = 0; i < key.length; i++)
|
||
key[i] ^= 0x36;
|
||
this.inner = new this.Hash().update(key);
|
||
|
||
// 0x36 ^ 0x5c = 0x6a
|
||
for (i = 0; i < key.length; i++)
|
||
key[i] ^= 0x6a;
|
||
this.outer = new this.Hash().update(key);
|
||
};
|
||
|
||
Hmac.prototype.update = function update(msg, enc) {
|
||
this.inner.update(msg, enc);
|
||
return this;
|
||
};
|
||
|
||
Hmac.prototype.digest = function digest(enc) {
|
||
this.outer.update(this.inner.digest());
|
||
return this.outer.digest(enc);
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/hash.js/lib/hash/ripemd.js":
|
||
/*!*************************************************!*\
|
||
!*** ./node_modules/hash.js/lib/hash/ripemd.js ***!
|
||
\*************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var utils = __webpack_require__(/*! ./utils */ "./node_modules/hash.js/lib/hash/utils.js");
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/hash.js/lib/hash/common.js");
|
||
|
||
var rotl32 = utils.rotl32;
|
||
var sum32 = utils.sum32;
|
||
var sum32_3 = utils.sum32_3;
|
||
var sum32_4 = utils.sum32_4;
|
||
var BlockHash = common.BlockHash;
|
||
|
||
function RIPEMD160() {
|
||
if (!(this instanceof RIPEMD160))
|
||
return new RIPEMD160();
|
||
|
||
BlockHash.call(this);
|
||
|
||
this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];
|
||
this.endian = 'little';
|
||
}
|
||
utils.inherits(RIPEMD160, BlockHash);
|
||
exports.ripemd160 = RIPEMD160;
|
||
|
||
RIPEMD160.blockSize = 512;
|
||
RIPEMD160.outSize = 160;
|
||
RIPEMD160.hmacStrength = 192;
|
||
RIPEMD160.padLength = 64;
|
||
|
||
RIPEMD160.prototype._update = function update(msg, start) {
|
||
var A = this.h[0];
|
||
var B = this.h[1];
|
||
var C = this.h[2];
|
||
var D = this.h[3];
|
||
var E = this.h[4];
|
||
var Ah = A;
|
||
var Bh = B;
|
||
var Ch = C;
|
||
var Dh = D;
|
||
var Eh = E;
|
||
for (var j = 0; j < 80; j++) {
|
||
var T = sum32(
|
||
rotl32(
|
||
sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)),
|
||
s[j]),
|
||
E);
|
||
A = E;
|
||
E = D;
|
||
D = rotl32(C, 10);
|
||
C = B;
|
||
B = T;
|
||
T = sum32(
|
||
rotl32(
|
||
sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)),
|
||
sh[j]),
|
||
Eh);
|
||
Ah = Eh;
|
||
Eh = Dh;
|
||
Dh = rotl32(Ch, 10);
|
||
Ch = Bh;
|
||
Bh = T;
|
||
}
|
||
T = sum32_3(this.h[1], C, Dh);
|
||
this.h[1] = sum32_3(this.h[2], D, Eh);
|
||
this.h[2] = sum32_3(this.h[3], E, Ah);
|
||
this.h[3] = sum32_3(this.h[4], A, Bh);
|
||
this.h[4] = sum32_3(this.h[0], B, Ch);
|
||
this.h[0] = T;
|
||
};
|
||
|
||
RIPEMD160.prototype._digest = function digest(enc) {
|
||
if (enc === 'hex')
|
||
return utils.toHex32(this.h, 'little');
|
||
else
|
||
return utils.split32(this.h, 'little');
|
||
};
|
||
|
||
function f(j, x, y, z) {
|
||
if (j <= 15)
|
||
return x ^ y ^ z;
|
||
else if (j <= 31)
|
||
return (x & y) | ((~x) & z);
|
||
else if (j <= 47)
|
||
return (x | (~y)) ^ z;
|
||
else if (j <= 63)
|
||
return (x & z) | (y & (~z));
|
||
else
|
||
return x ^ (y | (~z));
|
||
}
|
||
|
||
function K(j) {
|
||
if (j <= 15)
|
||
return 0x00000000;
|
||
else if (j <= 31)
|
||
return 0x5a827999;
|
||
else if (j <= 47)
|
||
return 0x6ed9eba1;
|
||
else if (j <= 63)
|
||
return 0x8f1bbcdc;
|
||
else
|
||
return 0xa953fd4e;
|
||
}
|
||
|
||
function Kh(j) {
|
||
if (j <= 15)
|
||
return 0x50a28be6;
|
||
else if (j <= 31)
|
||
return 0x5c4dd124;
|
||
else if (j <= 47)
|
||
return 0x6d703ef3;
|
||
else if (j <= 63)
|
||
return 0x7a6d76e9;
|
||
else
|
||
return 0x00000000;
|
||
}
|
||
|
||
var r = [
|
||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||
7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
|
||
3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
|
||
1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
|
||
4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
|
||
];
|
||
|
||
var rh = [
|
||
5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
|
||
6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
|
||
15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
|
||
8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
|
||
12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
|
||
];
|
||
|
||
var s = [
|
||
11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
|
||
7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
|
||
11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
|
||
11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
|
||
9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
|
||
];
|
||
|
||
var sh = [
|
||
8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
|
||
9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
|
||
9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
|
||
15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
|
||
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
|
||
];
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/hash.js/lib/hash/sha.js":
|
||
/*!**********************************************!*\
|
||
!*** ./node_modules/hash.js/lib/hash/sha.js ***!
|
||
\**********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
exports.sha1 = __webpack_require__(/*! ./sha/1 */ "./node_modules/hash.js/lib/hash/sha/1.js");
|
||
exports.sha224 = __webpack_require__(/*! ./sha/224 */ "./node_modules/hash.js/lib/hash/sha/224.js");
|
||
exports.sha256 = __webpack_require__(/*! ./sha/256 */ "./node_modules/hash.js/lib/hash/sha/256.js");
|
||
exports.sha384 = __webpack_require__(/*! ./sha/384 */ "./node_modules/hash.js/lib/hash/sha/384.js");
|
||
exports.sha512 = __webpack_require__(/*! ./sha/512 */ "./node_modules/hash.js/lib/hash/sha/512.js");
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/hash.js/lib/hash/sha/1.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/hash.js/lib/hash/sha/1.js ***!
|
||
\************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var utils = __webpack_require__(/*! ../utils */ "./node_modules/hash.js/lib/hash/utils.js");
|
||
var common = __webpack_require__(/*! ../common */ "./node_modules/hash.js/lib/hash/common.js");
|
||
var shaCommon = __webpack_require__(/*! ./common */ "./node_modules/hash.js/lib/hash/sha/common.js");
|
||
|
||
var rotl32 = utils.rotl32;
|
||
var sum32 = utils.sum32;
|
||
var sum32_5 = utils.sum32_5;
|
||
var ft_1 = shaCommon.ft_1;
|
||
var BlockHash = common.BlockHash;
|
||
|
||
var sha1_K = [
|
||
0x5A827999, 0x6ED9EBA1,
|
||
0x8F1BBCDC, 0xCA62C1D6
|
||
];
|
||
|
||
function SHA1() {
|
||
if (!(this instanceof SHA1))
|
||
return new SHA1();
|
||
|
||
BlockHash.call(this);
|
||
this.h = [
|
||
0x67452301, 0xefcdab89, 0x98badcfe,
|
||
0x10325476, 0xc3d2e1f0 ];
|
||
this.W = new Array(80);
|
||
}
|
||
|
||
utils.inherits(SHA1, BlockHash);
|
||
module.exports = SHA1;
|
||
|
||
SHA1.blockSize = 512;
|
||
SHA1.outSize = 160;
|
||
SHA1.hmacStrength = 80;
|
||
SHA1.padLength = 64;
|
||
|
||
SHA1.prototype._update = function _update(msg, start) {
|
||
var W = this.W;
|
||
|
||
for (var i = 0; i < 16; i++)
|
||
W[i] = msg[start + i];
|
||
|
||
for(; i < W.length; i++)
|
||
W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
|
||
|
||
var a = this.h[0];
|
||
var b = this.h[1];
|
||
var c = this.h[2];
|
||
var d = this.h[3];
|
||
var e = this.h[4];
|
||
|
||
for (i = 0; i < W.length; i++) {
|
||
var s = ~~(i / 20);
|
||
var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]);
|
||
e = d;
|
||
d = c;
|
||
c = rotl32(b, 30);
|
||
b = a;
|
||
a = t;
|
||
}
|
||
|
||
this.h[0] = sum32(this.h[0], a);
|
||
this.h[1] = sum32(this.h[1], b);
|
||
this.h[2] = sum32(this.h[2], c);
|
||
this.h[3] = sum32(this.h[3], d);
|
||
this.h[4] = sum32(this.h[4], e);
|
||
};
|
||
|
||
SHA1.prototype._digest = function digest(enc) {
|
||
if (enc === 'hex')
|
||
return utils.toHex32(this.h, 'big');
|
||
else
|
||
return utils.split32(this.h, 'big');
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/hash.js/lib/hash/sha/224.js":
|
||
/*!**************************************************!*\
|
||
!*** ./node_modules/hash.js/lib/hash/sha/224.js ***!
|
||
\**************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var utils = __webpack_require__(/*! ../utils */ "./node_modules/hash.js/lib/hash/utils.js");
|
||
var SHA256 = __webpack_require__(/*! ./256 */ "./node_modules/hash.js/lib/hash/sha/256.js");
|
||
|
||
function SHA224() {
|
||
if (!(this instanceof SHA224))
|
||
return new SHA224();
|
||
|
||
SHA256.call(this);
|
||
this.h = [
|
||
0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
|
||
0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];
|
||
}
|
||
utils.inherits(SHA224, SHA256);
|
||
module.exports = SHA224;
|
||
|
||
SHA224.blockSize = 512;
|
||
SHA224.outSize = 224;
|
||
SHA224.hmacStrength = 192;
|
||
SHA224.padLength = 64;
|
||
|
||
SHA224.prototype._digest = function digest(enc) {
|
||
// Just truncate output
|
||
if (enc === 'hex')
|
||
return utils.toHex32(this.h.slice(0, 7), 'big');
|
||
else
|
||
return utils.split32(this.h.slice(0, 7), 'big');
|
||
};
|
||
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/hash.js/lib/hash/sha/256.js":
|
||
/*!**************************************************!*\
|
||
!*** ./node_modules/hash.js/lib/hash/sha/256.js ***!
|
||
\**************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var utils = __webpack_require__(/*! ../utils */ "./node_modules/hash.js/lib/hash/utils.js");
|
||
var common = __webpack_require__(/*! ../common */ "./node_modules/hash.js/lib/hash/common.js");
|
||
var shaCommon = __webpack_require__(/*! ./common */ "./node_modules/hash.js/lib/hash/sha/common.js");
|
||
var assert = __webpack_require__(/*! minimalistic-assert */ "./node_modules/minimalistic-assert/index.js");
|
||
|
||
var sum32 = utils.sum32;
|
||
var sum32_4 = utils.sum32_4;
|
||
var sum32_5 = utils.sum32_5;
|
||
var ch32 = shaCommon.ch32;
|
||
var maj32 = shaCommon.maj32;
|
||
var s0_256 = shaCommon.s0_256;
|
||
var s1_256 = shaCommon.s1_256;
|
||
var g0_256 = shaCommon.g0_256;
|
||
var g1_256 = shaCommon.g1_256;
|
||
|
||
var BlockHash = common.BlockHash;
|
||
|
||
var sha256_K = [
|
||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||
];
|
||
|
||
function SHA256() {
|
||
if (!(this instanceof SHA256))
|
||
return new SHA256();
|
||
|
||
BlockHash.call(this);
|
||
this.h = [
|
||
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
|
||
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
||
];
|
||
this.k = sha256_K;
|
||
this.W = new Array(64);
|
||
}
|
||
utils.inherits(SHA256, BlockHash);
|
||
module.exports = SHA256;
|
||
|
||
SHA256.blockSize = 512;
|
||
SHA256.outSize = 256;
|
||
SHA256.hmacStrength = 192;
|
||
SHA256.padLength = 64;
|
||
|
||
SHA256.prototype._update = function _update(msg, start) {
|
||
var W = this.W;
|
||
|
||
for (var i = 0; i < 16; i++)
|
||
W[i] = msg[start + i];
|
||
for (; i < W.length; i++)
|
||
W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);
|
||
|
||
var a = this.h[0];
|
||
var b = this.h[1];
|
||
var c = this.h[2];
|
||
var d = this.h[3];
|
||
var e = this.h[4];
|
||
var f = this.h[5];
|
||
var g = this.h[6];
|
||
var h = this.h[7];
|
||
|
||
assert(this.k.length === W.length);
|
||
for (i = 0; i < W.length; i++) {
|
||
var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);
|
||
var T2 = sum32(s0_256(a), maj32(a, b, c));
|
||
h = g;
|
||
g = f;
|
||
f = e;
|
||
e = sum32(d, T1);
|
||
d = c;
|
||
c = b;
|
||
b = a;
|
||
a = sum32(T1, T2);
|
||
}
|
||
|
||
this.h[0] = sum32(this.h[0], a);
|
||
this.h[1] = sum32(this.h[1], b);
|
||
this.h[2] = sum32(this.h[2], c);
|
||
this.h[3] = sum32(this.h[3], d);
|
||
this.h[4] = sum32(this.h[4], e);
|
||
this.h[5] = sum32(this.h[5], f);
|
||
this.h[6] = sum32(this.h[6], g);
|
||
this.h[7] = sum32(this.h[7], h);
|
||
};
|
||
|
||
SHA256.prototype._digest = function digest(enc) {
|
||
if (enc === 'hex')
|
||
return utils.toHex32(this.h, 'big');
|
||
else
|
||
return utils.split32(this.h, 'big');
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/hash.js/lib/hash/sha/384.js":
|
||
/*!**************************************************!*\
|
||
!*** ./node_modules/hash.js/lib/hash/sha/384.js ***!
|
||
\**************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var utils = __webpack_require__(/*! ../utils */ "./node_modules/hash.js/lib/hash/utils.js");
|
||
|
||
var SHA512 = __webpack_require__(/*! ./512 */ "./node_modules/hash.js/lib/hash/sha/512.js");
|
||
|
||
function SHA384() {
|
||
if (!(this instanceof SHA384))
|
||
return new SHA384();
|
||
|
||
SHA512.call(this);
|
||
this.h = [
|
||
0xcbbb9d5d, 0xc1059ed8,
|
||
0x629a292a, 0x367cd507,
|
||
0x9159015a, 0x3070dd17,
|
||
0x152fecd8, 0xf70e5939,
|
||
0x67332667, 0xffc00b31,
|
||
0x8eb44a87, 0x68581511,
|
||
0xdb0c2e0d, 0x64f98fa7,
|
||
0x47b5481d, 0xbefa4fa4 ];
|
||
}
|
||
utils.inherits(SHA384, SHA512);
|
||
module.exports = SHA384;
|
||
|
||
SHA384.blockSize = 1024;
|
||
SHA384.outSize = 384;
|
||
SHA384.hmacStrength = 192;
|
||
SHA384.padLength = 128;
|
||
|
||
SHA384.prototype._digest = function digest(enc) {
|
||
if (enc === 'hex')
|
||
return utils.toHex32(this.h.slice(0, 12), 'big');
|
||
else
|
||
return utils.split32(this.h.slice(0, 12), 'big');
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/hash.js/lib/hash/sha/512.js":
|
||
/*!**************************************************!*\
|
||
!*** ./node_modules/hash.js/lib/hash/sha/512.js ***!
|
||
\**************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var utils = __webpack_require__(/*! ../utils */ "./node_modules/hash.js/lib/hash/utils.js");
|
||
var common = __webpack_require__(/*! ../common */ "./node_modules/hash.js/lib/hash/common.js");
|
||
var assert = __webpack_require__(/*! minimalistic-assert */ "./node_modules/minimalistic-assert/index.js");
|
||
|
||
var rotr64_hi = utils.rotr64_hi;
|
||
var rotr64_lo = utils.rotr64_lo;
|
||
var shr64_hi = utils.shr64_hi;
|
||
var shr64_lo = utils.shr64_lo;
|
||
var sum64 = utils.sum64;
|
||
var sum64_hi = utils.sum64_hi;
|
||
var sum64_lo = utils.sum64_lo;
|
||
var sum64_4_hi = utils.sum64_4_hi;
|
||
var sum64_4_lo = utils.sum64_4_lo;
|
||
var sum64_5_hi = utils.sum64_5_hi;
|
||
var sum64_5_lo = utils.sum64_5_lo;
|
||
|
||
var BlockHash = common.BlockHash;
|
||
|
||
var sha512_K = [
|
||
0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
|
||
0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
|
||
0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
|
||
0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
|
||
0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
|
||
0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
|
||
0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
|
||
0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
|
||
0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
|
||
0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
|
||
0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
|
||
0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
|
||
0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
|
||
0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
|
||
0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
|
||
0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
|
||
0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
|
||
0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
|
||
0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
|
||
0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
|
||
0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
|
||
0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
|
||
0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
|
||
0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
|
||
0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
|
||
0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
|
||
0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
|
||
0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
|
||
0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
|
||
0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
|
||
0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
|
||
0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
|
||
0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
|
||
0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
|
||
0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
|
||
0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
|
||
0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
|
||
0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
|
||
0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
|
||
0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
|
||
];
|
||
|
||
function SHA512() {
|
||
if (!(this instanceof SHA512))
|
||
return new SHA512();
|
||
|
||
BlockHash.call(this);
|
||
this.h = [
|
||
0x6a09e667, 0xf3bcc908,
|
||
0xbb67ae85, 0x84caa73b,
|
||
0x3c6ef372, 0xfe94f82b,
|
||
0xa54ff53a, 0x5f1d36f1,
|
||
0x510e527f, 0xade682d1,
|
||
0x9b05688c, 0x2b3e6c1f,
|
||
0x1f83d9ab, 0xfb41bd6b,
|
||
0x5be0cd19, 0x137e2179 ];
|
||
this.k = sha512_K;
|
||
this.W = new Array(160);
|
||
}
|
||
utils.inherits(SHA512, BlockHash);
|
||
module.exports = SHA512;
|
||
|
||
SHA512.blockSize = 1024;
|
||
SHA512.outSize = 512;
|
||
SHA512.hmacStrength = 192;
|
||
SHA512.padLength = 128;
|
||
|
||
SHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {
|
||
var W = this.W;
|
||
|
||
// 32 x 32bit words
|
||
for (var i = 0; i < 32; i++)
|
||
W[i] = msg[start + i];
|
||
for (; i < W.length; i += 2) {
|
||
var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2
|
||
var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);
|
||
var c1_hi = W[i - 14]; // i - 7
|
||
var c1_lo = W[i - 13];
|
||
var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15
|
||
var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);
|
||
var c3_hi = W[i - 32]; // i - 16
|
||
var c3_lo = W[i - 31];
|
||
|
||
W[i] = sum64_4_hi(
|
||
c0_hi, c0_lo,
|
||
c1_hi, c1_lo,
|
||
c2_hi, c2_lo,
|
||
c3_hi, c3_lo);
|
||
W[i + 1] = sum64_4_lo(
|
||
c0_hi, c0_lo,
|
||
c1_hi, c1_lo,
|
||
c2_hi, c2_lo,
|
||
c3_hi, c3_lo);
|
||
}
|
||
};
|
||
|
||
SHA512.prototype._update = function _update(msg, start) {
|
||
this._prepareBlock(msg, start);
|
||
|
||
var W = this.W;
|
||
|
||
var ah = this.h[0];
|
||
var al = this.h[1];
|
||
var bh = this.h[2];
|
||
var bl = this.h[3];
|
||
var ch = this.h[4];
|
||
var cl = this.h[5];
|
||
var dh = this.h[6];
|
||
var dl = this.h[7];
|
||
var eh = this.h[8];
|
||
var el = this.h[9];
|
||
var fh = this.h[10];
|
||
var fl = this.h[11];
|
||
var gh = this.h[12];
|
||
var gl = this.h[13];
|
||
var hh = this.h[14];
|
||
var hl = this.h[15];
|
||
|
||
assert(this.k.length === W.length);
|
||
for (var i = 0; i < W.length; i += 2) {
|
||
var c0_hi = hh;
|
||
var c0_lo = hl;
|
||
var c1_hi = s1_512_hi(eh, el);
|
||
var c1_lo = s1_512_lo(eh, el);
|
||
var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl);
|
||
var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);
|
||
var c3_hi = this.k[i];
|
||
var c3_lo = this.k[i + 1];
|
||
var c4_hi = W[i];
|
||
var c4_lo = W[i + 1];
|
||
|
||
var T1_hi = sum64_5_hi(
|
||
c0_hi, c0_lo,
|
||
c1_hi, c1_lo,
|
||
c2_hi, c2_lo,
|
||
c3_hi, c3_lo,
|
||
c4_hi, c4_lo);
|
||
var T1_lo = sum64_5_lo(
|
||
c0_hi, c0_lo,
|
||
c1_hi, c1_lo,
|
||
c2_hi, c2_lo,
|
||
c3_hi, c3_lo,
|
||
c4_hi, c4_lo);
|
||
|
||
c0_hi = s0_512_hi(ah, al);
|
||
c0_lo = s0_512_lo(ah, al);
|
||
c1_hi = maj64_hi(ah, al, bh, bl, ch, cl);
|
||
c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);
|
||
|
||
var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo);
|
||
var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo);
|
||
|
||
hh = gh;
|
||
hl = gl;
|
||
|
||
gh = fh;
|
||
gl = fl;
|
||
|
||
fh = eh;
|
||
fl = el;
|
||
|
||
eh = sum64_hi(dh, dl, T1_hi, T1_lo);
|
||
el = sum64_lo(dl, dl, T1_hi, T1_lo);
|
||
|
||
dh = ch;
|
||
dl = cl;
|
||
|
||
ch = bh;
|
||
cl = bl;
|
||
|
||
bh = ah;
|
||
bl = al;
|
||
|
||
ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo);
|
||
al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo);
|
||
}
|
||
|
||
sum64(this.h, 0, ah, al);
|
||
sum64(this.h, 2, bh, bl);
|
||
sum64(this.h, 4, ch, cl);
|
||
sum64(this.h, 6, dh, dl);
|
||
sum64(this.h, 8, eh, el);
|
||
sum64(this.h, 10, fh, fl);
|
||
sum64(this.h, 12, gh, gl);
|
||
sum64(this.h, 14, hh, hl);
|
||
};
|
||
|
||
SHA512.prototype._digest = function digest(enc) {
|
||
if (enc === 'hex')
|
||
return utils.toHex32(this.h, 'big');
|
||
else
|
||
return utils.split32(this.h, 'big');
|
||
};
|
||
|
||
function ch64_hi(xh, xl, yh, yl, zh) {
|
||
var r = (xh & yh) ^ ((~xh) & zh);
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function ch64_lo(xh, xl, yh, yl, zh, zl) {
|
||
var r = (xl & yl) ^ ((~xl) & zl);
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function maj64_hi(xh, xl, yh, yl, zh) {
|
||
var r = (xh & yh) ^ (xh & zh) ^ (yh & zh);
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function maj64_lo(xh, xl, yh, yl, zh, zl) {
|
||
var r = (xl & yl) ^ (xl & zl) ^ (yl & zl);
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function s0_512_hi(xh, xl) {
|
||
var c0_hi = rotr64_hi(xh, xl, 28);
|
||
var c1_hi = rotr64_hi(xl, xh, 2); // 34
|
||
var c2_hi = rotr64_hi(xl, xh, 7); // 39
|
||
|
||
var r = c0_hi ^ c1_hi ^ c2_hi;
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function s0_512_lo(xh, xl) {
|
||
var c0_lo = rotr64_lo(xh, xl, 28);
|
||
var c1_lo = rotr64_lo(xl, xh, 2); // 34
|
||
var c2_lo = rotr64_lo(xl, xh, 7); // 39
|
||
|
||
var r = c0_lo ^ c1_lo ^ c2_lo;
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function s1_512_hi(xh, xl) {
|
||
var c0_hi = rotr64_hi(xh, xl, 14);
|
||
var c1_hi = rotr64_hi(xh, xl, 18);
|
||
var c2_hi = rotr64_hi(xl, xh, 9); // 41
|
||
|
||
var r = c0_hi ^ c1_hi ^ c2_hi;
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function s1_512_lo(xh, xl) {
|
||
var c0_lo = rotr64_lo(xh, xl, 14);
|
||
var c1_lo = rotr64_lo(xh, xl, 18);
|
||
var c2_lo = rotr64_lo(xl, xh, 9); // 41
|
||
|
||
var r = c0_lo ^ c1_lo ^ c2_lo;
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function g0_512_hi(xh, xl) {
|
||
var c0_hi = rotr64_hi(xh, xl, 1);
|
||
var c1_hi = rotr64_hi(xh, xl, 8);
|
||
var c2_hi = shr64_hi(xh, xl, 7);
|
||
|
||
var r = c0_hi ^ c1_hi ^ c2_hi;
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function g0_512_lo(xh, xl) {
|
||
var c0_lo = rotr64_lo(xh, xl, 1);
|
||
var c1_lo = rotr64_lo(xh, xl, 8);
|
||
var c2_lo = shr64_lo(xh, xl, 7);
|
||
|
||
var r = c0_lo ^ c1_lo ^ c2_lo;
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function g1_512_hi(xh, xl) {
|
||
var c0_hi = rotr64_hi(xh, xl, 19);
|
||
var c1_hi = rotr64_hi(xl, xh, 29); // 61
|
||
var c2_hi = shr64_hi(xh, xl, 6);
|
||
|
||
var r = c0_hi ^ c1_hi ^ c2_hi;
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function g1_512_lo(xh, xl) {
|
||
var c0_lo = rotr64_lo(xh, xl, 19);
|
||
var c1_lo = rotr64_lo(xl, xh, 29); // 61
|
||
var c2_lo = shr64_lo(xh, xl, 6);
|
||
|
||
var r = c0_lo ^ c1_lo ^ c2_lo;
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/hash.js/lib/hash/sha/common.js":
|
||
/*!*****************************************************!*\
|
||
!*** ./node_modules/hash.js/lib/hash/sha/common.js ***!
|
||
\*****************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var utils = __webpack_require__(/*! ../utils */ "./node_modules/hash.js/lib/hash/utils.js");
|
||
var rotr32 = utils.rotr32;
|
||
|
||
function ft_1(s, x, y, z) {
|
||
if (s === 0)
|
||
return ch32(x, y, z);
|
||
if (s === 1 || s === 3)
|
||
return p32(x, y, z);
|
||
if (s === 2)
|
||
return maj32(x, y, z);
|
||
}
|
||
exports.ft_1 = ft_1;
|
||
|
||
function ch32(x, y, z) {
|
||
return (x & y) ^ ((~x) & z);
|
||
}
|
||
exports.ch32 = ch32;
|
||
|
||
function maj32(x, y, z) {
|
||
return (x & y) ^ (x & z) ^ (y & z);
|
||
}
|
||
exports.maj32 = maj32;
|
||
|
||
function p32(x, y, z) {
|
||
return x ^ y ^ z;
|
||
}
|
||
exports.p32 = p32;
|
||
|
||
function s0_256(x) {
|
||
return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);
|
||
}
|
||
exports.s0_256 = s0_256;
|
||
|
||
function s1_256(x) {
|
||
return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);
|
||
}
|
||
exports.s1_256 = s1_256;
|
||
|
||
function g0_256(x) {
|
||
return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3);
|
||
}
|
||
exports.g0_256 = g0_256;
|
||
|
||
function g1_256(x) {
|
||
return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10);
|
||
}
|
||
exports.g1_256 = g1_256;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/hash.js/lib/hash/utils.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/hash.js/lib/hash/utils.js ***!
|
||
\************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var assert = __webpack_require__(/*! minimalistic-assert */ "./node_modules/minimalistic-assert/index.js");
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
|
||
exports.inherits = inherits;
|
||
|
||
function isSurrogatePair(msg, i) {
|
||
if ((msg.charCodeAt(i) & 0xFC00) !== 0xD800) {
|
||
return false;
|
||
}
|
||
if (i < 0 || i + 1 >= msg.length) {
|
||
return false;
|
||
}
|
||
return (msg.charCodeAt(i + 1) & 0xFC00) === 0xDC00;
|
||
}
|
||
|
||
function toArray(msg, enc) {
|
||
if (Array.isArray(msg))
|
||
return msg.slice();
|
||
if (!msg)
|
||
return [];
|
||
var res = [];
|
||
if (typeof msg === 'string') {
|
||
if (!enc) {
|
||
// Inspired by stringToUtf8ByteArray() in closure-library by Google
|
||
// https://github.com/google/closure-library/blob/8598d87242af59aac233270742c8984e2b2bdbe0/closure/goog/crypt/crypt.js#L117-L143
|
||
// Apache License 2.0
|
||
// https://github.com/google/closure-library/blob/master/LICENSE
|
||
var p = 0;
|
||
for (var i = 0; i < msg.length; i++) {
|
||
var c = msg.charCodeAt(i);
|
||
if (c < 128) {
|
||
res[p++] = c;
|
||
} else if (c < 2048) {
|
||
res[p++] = (c >> 6) | 192;
|
||
res[p++] = (c & 63) | 128;
|
||
} else if (isSurrogatePair(msg, i)) {
|
||
c = 0x10000 + ((c & 0x03FF) << 10) + (msg.charCodeAt(++i) & 0x03FF);
|
||
res[p++] = (c >> 18) | 240;
|
||
res[p++] = ((c >> 12) & 63) | 128;
|
||
res[p++] = ((c >> 6) & 63) | 128;
|
||
res[p++] = (c & 63) | 128;
|
||
} else {
|
||
res[p++] = (c >> 12) | 224;
|
||
res[p++] = ((c >> 6) & 63) | 128;
|
||
res[p++] = (c & 63) | 128;
|
||
}
|
||
}
|
||
} else if (enc === 'hex') {
|
||
msg = msg.replace(/[^a-z0-9]+/ig, '');
|
||
if (msg.length % 2 !== 0)
|
||
msg = '0' + msg;
|
||
for (i = 0; i < msg.length; i += 2)
|
||
res.push(parseInt(msg[i] + msg[i + 1], 16));
|
||
}
|
||
} else {
|
||
for (i = 0; i < msg.length; i++)
|
||
res[i] = msg[i] | 0;
|
||
}
|
||
return res;
|
||
}
|
||
exports.toArray = toArray;
|
||
|
||
function toHex(msg) {
|
||
var res = '';
|
||
for (var i = 0; i < msg.length; i++)
|
||
res += zero2(msg[i].toString(16));
|
||
return res;
|
||
}
|
||
exports.toHex = toHex;
|
||
|
||
function htonl(w) {
|
||
var res = (w >>> 24) |
|
||
((w >>> 8) & 0xff00) |
|
||
((w << 8) & 0xff0000) |
|
||
((w & 0xff) << 24);
|
||
return res >>> 0;
|
||
}
|
||
exports.htonl = htonl;
|
||
|
||
function toHex32(msg, endian) {
|
||
var res = '';
|
||
for (var i = 0; i < msg.length; i++) {
|
||
var w = msg[i];
|
||
if (endian === 'little')
|
||
w = htonl(w);
|
||
res += zero8(w.toString(16));
|
||
}
|
||
return res;
|
||
}
|
||
exports.toHex32 = toHex32;
|
||
|
||
function zero2(word) {
|
||
if (word.length === 1)
|
||
return '0' + word;
|
||
else
|
||
return word;
|
||
}
|
||
exports.zero2 = zero2;
|
||
|
||
function zero8(word) {
|
||
if (word.length === 7)
|
||
return '0' + word;
|
||
else if (word.length === 6)
|
||
return '00' + word;
|
||
else if (word.length === 5)
|
||
return '000' + word;
|
||
else if (word.length === 4)
|
||
return '0000' + word;
|
||
else if (word.length === 3)
|
||
return '00000' + word;
|
||
else if (word.length === 2)
|
||
return '000000' + word;
|
||
else if (word.length === 1)
|
||
return '0000000' + word;
|
||
else
|
||
return word;
|
||
}
|
||
exports.zero8 = zero8;
|
||
|
||
function join32(msg, start, end, endian) {
|
||
var len = end - start;
|
||
assert(len % 4 === 0);
|
||
var res = new Array(len / 4);
|
||
for (var i = 0, k = start; i < res.length; i++, k += 4) {
|
||
var w;
|
||
if (endian === 'big')
|
||
w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];
|
||
else
|
||
w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];
|
||
res[i] = w >>> 0;
|
||
}
|
||
return res;
|
||
}
|
||
exports.join32 = join32;
|
||
|
||
function split32(msg, endian) {
|
||
var res = new Array(msg.length * 4);
|
||
for (var i = 0, k = 0; i < msg.length; i++, k += 4) {
|
||
var m = msg[i];
|
||
if (endian === 'big') {
|
||
res[k] = m >>> 24;
|
||
res[k + 1] = (m >>> 16) & 0xff;
|
||
res[k + 2] = (m >>> 8) & 0xff;
|
||
res[k + 3] = m & 0xff;
|
||
} else {
|
||
res[k + 3] = m >>> 24;
|
||
res[k + 2] = (m >>> 16) & 0xff;
|
||
res[k + 1] = (m >>> 8) & 0xff;
|
||
res[k] = m & 0xff;
|
||
}
|
||
}
|
||
return res;
|
||
}
|
||
exports.split32 = split32;
|
||
|
||
function rotr32(w, b) {
|
||
return (w >>> b) | (w << (32 - b));
|
||
}
|
||
exports.rotr32 = rotr32;
|
||
|
||
function rotl32(w, b) {
|
||
return (w << b) | (w >>> (32 - b));
|
||
}
|
||
exports.rotl32 = rotl32;
|
||
|
||
function sum32(a, b) {
|
||
return (a + b) >>> 0;
|
||
}
|
||
exports.sum32 = sum32;
|
||
|
||
function sum32_3(a, b, c) {
|
||
return (a + b + c) >>> 0;
|
||
}
|
||
exports.sum32_3 = sum32_3;
|
||
|
||
function sum32_4(a, b, c, d) {
|
||
return (a + b + c + d) >>> 0;
|
||
}
|
||
exports.sum32_4 = sum32_4;
|
||
|
||
function sum32_5(a, b, c, d, e) {
|
||
return (a + b + c + d + e) >>> 0;
|
||
}
|
||
exports.sum32_5 = sum32_5;
|
||
|
||
function sum64(buf, pos, ah, al) {
|
||
var bh = buf[pos];
|
||
var bl = buf[pos + 1];
|
||
|
||
var lo = (al + bl) >>> 0;
|
||
var hi = (lo < al ? 1 : 0) + ah + bh;
|
||
buf[pos] = hi >>> 0;
|
||
buf[pos + 1] = lo;
|
||
}
|
||
exports.sum64 = sum64;
|
||
|
||
function sum64_hi(ah, al, bh, bl) {
|
||
var lo = (al + bl) >>> 0;
|
||
var hi = (lo < al ? 1 : 0) + ah + bh;
|
||
return hi >>> 0;
|
||
}
|
||
exports.sum64_hi = sum64_hi;
|
||
|
||
function sum64_lo(ah, al, bh, bl) {
|
||
var lo = al + bl;
|
||
return lo >>> 0;
|
||
}
|
||
exports.sum64_lo = sum64_lo;
|
||
|
||
function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {
|
||
var carry = 0;
|
||
var lo = al;
|
||
lo = (lo + bl) >>> 0;
|
||
carry += lo < al ? 1 : 0;
|
||
lo = (lo + cl) >>> 0;
|
||
carry += lo < cl ? 1 : 0;
|
||
lo = (lo + dl) >>> 0;
|
||
carry += lo < dl ? 1 : 0;
|
||
|
||
var hi = ah + bh + ch + dh + carry;
|
||
return hi >>> 0;
|
||
}
|
||
exports.sum64_4_hi = sum64_4_hi;
|
||
|
||
function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {
|
||
var lo = al + bl + cl + dl;
|
||
return lo >>> 0;
|
||
}
|
||
exports.sum64_4_lo = sum64_4_lo;
|
||
|
||
function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
|
||
var carry = 0;
|
||
var lo = al;
|
||
lo = (lo + bl) >>> 0;
|
||
carry += lo < al ? 1 : 0;
|
||
lo = (lo + cl) >>> 0;
|
||
carry += lo < cl ? 1 : 0;
|
||
lo = (lo + dl) >>> 0;
|
||
carry += lo < dl ? 1 : 0;
|
||
lo = (lo + el) >>> 0;
|
||
carry += lo < el ? 1 : 0;
|
||
|
||
var hi = ah + bh + ch + dh + eh + carry;
|
||
return hi >>> 0;
|
||
}
|
||
exports.sum64_5_hi = sum64_5_hi;
|
||
|
||
function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
|
||
var lo = al + bl + cl + dl + el;
|
||
|
||
return lo >>> 0;
|
||
}
|
||
exports.sum64_5_lo = sum64_5_lo;
|
||
|
||
function rotr64_hi(ah, al, num) {
|
||
var r = (al << (32 - num)) | (ah >>> num);
|
||
return r >>> 0;
|
||
}
|
||
exports.rotr64_hi = rotr64_hi;
|
||
|
||
function rotr64_lo(ah, al, num) {
|
||
var r = (ah << (32 - num)) | (al >>> num);
|
||
return r >>> 0;
|
||
}
|
||
exports.rotr64_lo = rotr64_lo;
|
||
|
||
function shr64_hi(ah, al, num) {
|
||
return ah >>> num;
|
||
}
|
||
exports.shr64_hi = shr64_hi;
|
||
|
||
function shr64_lo(ah, al, num) {
|
||
var r = (ah << (32 - num)) | (al >>> num);
|
||
return r >>> 0;
|
||
}
|
||
exports.shr64_lo = shr64_lo;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/hmac-drbg/lib/hmac-drbg.js":
|
||
/*!*************************************************!*\
|
||
!*** ./node_modules/hmac-drbg/lib/hmac-drbg.js ***!
|
||
\*************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var hash = __webpack_require__(/*! hash.js */ "./node_modules/hash.js/lib/hash.js");
|
||
var utils = __webpack_require__(/*! minimalistic-crypto-utils */ "./node_modules/minimalistic-crypto-utils/lib/utils.js");
|
||
var assert = __webpack_require__(/*! minimalistic-assert */ "./node_modules/minimalistic-assert/index.js");
|
||
|
||
function HmacDRBG(options) {
|
||
if (!(this instanceof HmacDRBG))
|
||
return new HmacDRBG(options);
|
||
this.hash = options.hash;
|
||
this.predResist = !!options.predResist;
|
||
|
||
this.outLen = this.hash.outSize;
|
||
this.minEntropy = options.minEntropy || this.hash.hmacStrength;
|
||
|
||
this._reseed = null;
|
||
this.reseedInterval = null;
|
||
this.K = null;
|
||
this.V = null;
|
||
|
||
var entropy = utils.toArray(options.entropy, options.entropyEnc || 'hex');
|
||
var nonce = utils.toArray(options.nonce, options.nonceEnc || 'hex');
|
||
var pers = utils.toArray(options.pers, options.persEnc || 'hex');
|
||
assert(entropy.length >= (this.minEntropy / 8),
|
||
'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
|
||
this._init(entropy, nonce, pers);
|
||
}
|
||
module.exports = HmacDRBG;
|
||
|
||
HmacDRBG.prototype._init = function init(entropy, nonce, pers) {
|
||
var seed = entropy.concat(nonce).concat(pers);
|
||
|
||
this.K = new Array(this.outLen / 8);
|
||
this.V = new Array(this.outLen / 8);
|
||
for (var i = 0; i < this.V.length; i++) {
|
||
this.K[i] = 0x00;
|
||
this.V[i] = 0x01;
|
||
}
|
||
|
||
this._update(seed);
|
||
this._reseed = 1;
|
||
this.reseedInterval = 0x1000000000000; // 2^48
|
||
};
|
||
|
||
HmacDRBG.prototype._hmac = function hmac() {
|
||
return new hash.hmac(this.hash, this.K);
|
||
};
|
||
|
||
HmacDRBG.prototype._update = function update(seed) {
|
||
var kmac = this._hmac()
|
||
.update(this.V)
|
||
.update([ 0x00 ]);
|
||
if (seed)
|
||
kmac = kmac.update(seed);
|
||
this.K = kmac.digest();
|
||
this.V = this._hmac().update(this.V).digest();
|
||
if (!seed)
|
||
return;
|
||
|
||
this.K = this._hmac()
|
||
.update(this.V)
|
||
.update([ 0x01 ])
|
||
.update(seed)
|
||
.digest();
|
||
this.V = this._hmac().update(this.V).digest();
|
||
};
|
||
|
||
HmacDRBG.prototype.reseed = function reseed(entropy, entropyEnc, add, addEnc) {
|
||
// Optional entropy enc
|
||
if (typeof entropyEnc !== 'string') {
|
||
addEnc = add;
|
||
add = entropyEnc;
|
||
entropyEnc = null;
|
||
}
|
||
|
||
entropy = utils.toArray(entropy, entropyEnc);
|
||
add = utils.toArray(add, addEnc);
|
||
|
||
assert(entropy.length >= (this.minEntropy / 8),
|
||
'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
|
||
|
||
this._update(entropy.concat(add || []));
|
||
this._reseed = 1;
|
||
};
|
||
|
||
HmacDRBG.prototype.generate = function generate(len, enc, add, addEnc) {
|
||
if (this._reseed > this.reseedInterval)
|
||
throw new Error('Reseed is required');
|
||
|
||
// Optional encoding
|
||
if (typeof enc !== 'string') {
|
||
addEnc = add;
|
||
add = enc;
|
||
enc = null;
|
||
}
|
||
|
||
// Optional additional data
|
||
if (add) {
|
||
add = utils.toArray(add, addEnc || 'hex');
|
||
this._update(add);
|
||
}
|
||
|
||
var temp = [];
|
||
while (temp.length < len) {
|
||
this.V = this._hmac().update(this.V).digest();
|
||
temp = temp.concat(this.V);
|
||
}
|
||
|
||
var res = temp.slice(0, len);
|
||
this._update(add);
|
||
this._reseed++;
|
||
return utils.encode(res, enc);
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/ieee754/index.js":
|
||
/*!***************************************!*\
|
||
!*** ./node_modules/ieee754/index.js ***!
|
||
\***************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
|
||
var e, m
|
||
var eLen = (nBytes * 8) - mLen - 1
|
||
var eMax = (1 << eLen) - 1
|
||
var eBias = eMax >> 1
|
||
var nBits = -7
|
||
var i = isLE ? (nBytes - 1) : 0
|
||
var d = isLE ? -1 : 1
|
||
var s = buffer[offset + i]
|
||
|
||
i += d
|
||
|
||
e = s & ((1 << (-nBits)) - 1)
|
||
s >>= (-nBits)
|
||
nBits += eLen
|
||
for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
|
||
|
||
m = e & ((1 << (-nBits)) - 1)
|
||
e >>= (-nBits)
|
||
nBits += mLen
|
||
for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}
|
||
|
||
if (e === 0) {
|
||
e = 1 - eBias
|
||
} else if (e === eMax) {
|
||
return m ? NaN : ((s ? -1 : 1) * Infinity)
|
||
} else {
|
||
m = m + Math.pow(2, mLen)
|
||
e = e - eBias
|
||
}
|
||
return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
|
||
}
|
||
|
||
exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
|
||
var e, m, c
|
||
var eLen = (nBytes * 8) - mLen - 1
|
||
var eMax = (1 << eLen) - 1
|
||
var eBias = eMax >> 1
|
||
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
|
||
var i = isLE ? 0 : (nBytes - 1)
|
||
var d = isLE ? 1 : -1
|
||
var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
|
||
|
||
value = Math.abs(value)
|
||
|
||
if (isNaN(value) || value === Infinity) {
|
||
m = isNaN(value) ? 1 : 0
|
||
e = eMax
|
||
} else {
|
||
e = Math.floor(Math.log(value) / Math.LN2)
|
||
if (value * (c = Math.pow(2, -e)) < 1) {
|
||
e--
|
||
c *= 2
|
||
}
|
||
if (e + eBias >= 1) {
|
||
value += rt / c
|
||
} else {
|
||
value += rt * Math.pow(2, 1 - eBias)
|
||
}
|
||
if (value * c >= 2) {
|
||
e++
|
||
c /= 2
|
||
}
|
||
|
||
if (e + eBias >= eMax) {
|
||
m = 0
|
||
e = eMax
|
||
} else if (e + eBias >= 1) {
|
||
m = ((value * c) - 1) * Math.pow(2, mLen)
|
||
e = e + eBias
|
||
} else {
|
||
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
|
||
e = 0
|
||
}
|
||
}
|
||
|
||
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
|
||
|
||
e = (e << mLen) | m
|
||
eLen += mLen
|
||
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
|
||
|
||
buffer[offset + i - d] |= s * 128
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inherits/inherits_browser.js":
|
||
/*!***************************************************!*\
|
||
!*** ./node_modules/inherits/inherits_browser.js ***!
|
||
\***************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
if (typeof Object.create === 'function') {
|
||
// implementation from standard node.js 'util' module
|
||
module.exports = function inherits(ctor, superCtor) {
|
||
ctor.super_ = superCtor
|
||
ctor.prototype = Object.create(superCtor.prototype, {
|
||
constructor: {
|
||
value: ctor,
|
||
enumerable: false,
|
||
writable: true,
|
||
configurable: true
|
||
}
|
||
});
|
||
};
|
||
} else {
|
||
// old school shim for old browsers
|
||
module.exports = function inherits(ctor, superCtor) {
|
||
ctor.super_ = superCtor
|
||
var TempCtor = function () {}
|
||
TempCtor.prototype = superCtor.prototype
|
||
ctor.prototype = new TempCtor()
|
||
ctor.prototype.constructor = ctor
|
||
}
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/isarray/index.js":
|
||
/*!***************************************!*\
|
||
!*** ./node_modules/isarray/index.js ***!
|
||
\***************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
var toString = {}.toString;
|
||
|
||
module.exports = Array.isArray || function (arr) {
|
||
return toString.call(arr) == '[object Array]';
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/md5.js/index.js":
|
||
/*!**************************************!*\
|
||
!*** ./node_modules/md5.js/index.js ***!
|
||
\**************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
var HashBase = __webpack_require__(/*! hash-base */ "./node_modules/hash-base/index.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
var ARRAY16 = new Array(16)
|
||
|
||
function MD5 () {
|
||
HashBase.call(this, 64)
|
||
|
||
// state
|
||
this._a = 0x67452301
|
||
this._b = 0xefcdab89
|
||
this._c = 0x98badcfe
|
||
this._d = 0x10325476
|
||
}
|
||
|
||
inherits(MD5, HashBase)
|
||
|
||
MD5.prototype._update = function () {
|
||
var M = ARRAY16
|
||
for (var i = 0; i < 16; ++i) M[i] = this._block.readInt32LE(i * 4)
|
||
|
||
var a = this._a
|
||
var b = this._b
|
||
var c = this._c
|
||
var d = this._d
|
||
|
||
a = fnF(a, b, c, d, M[0], 0xd76aa478, 7)
|
||
d = fnF(d, a, b, c, M[1], 0xe8c7b756, 12)
|
||
c = fnF(c, d, a, b, M[2], 0x242070db, 17)
|
||
b = fnF(b, c, d, a, M[3], 0xc1bdceee, 22)
|
||
a = fnF(a, b, c, d, M[4], 0xf57c0faf, 7)
|
||
d = fnF(d, a, b, c, M[5], 0x4787c62a, 12)
|
||
c = fnF(c, d, a, b, M[6], 0xa8304613, 17)
|
||
b = fnF(b, c, d, a, M[7], 0xfd469501, 22)
|
||
a = fnF(a, b, c, d, M[8], 0x698098d8, 7)
|
||
d = fnF(d, a, b, c, M[9], 0x8b44f7af, 12)
|
||
c = fnF(c, d, a, b, M[10], 0xffff5bb1, 17)
|
||
b = fnF(b, c, d, a, M[11], 0x895cd7be, 22)
|
||
a = fnF(a, b, c, d, M[12], 0x6b901122, 7)
|
||
d = fnF(d, a, b, c, M[13], 0xfd987193, 12)
|
||
c = fnF(c, d, a, b, M[14], 0xa679438e, 17)
|
||
b = fnF(b, c, d, a, M[15], 0x49b40821, 22)
|
||
|
||
a = fnG(a, b, c, d, M[1], 0xf61e2562, 5)
|
||
d = fnG(d, a, b, c, M[6], 0xc040b340, 9)
|
||
c = fnG(c, d, a, b, M[11], 0x265e5a51, 14)
|
||
b = fnG(b, c, d, a, M[0], 0xe9b6c7aa, 20)
|
||
a = fnG(a, b, c, d, M[5], 0xd62f105d, 5)
|
||
d = fnG(d, a, b, c, M[10], 0x02441453, 9)
|
||
c = fnG(c, d, a, b, M[15], 0xd8a1e681, 14)
|
||
b = fnG(b, c, d, a, M[4], 0xe7d3fbc8, 20)
|
||
a = fnG(a, b, c, d, M[9], 0x21e1cde6, 5)
|
||
d = fnG(d, a, b, c, M[14], 0xc33707d6, 9)
|
||
c = fnG(c, d, a, b, M[3], 0xf4d50d87, 14)
|
||
b = fnG(b, c, d, a, M[8], 0x455a14ed, 20)
|
||
a = fnG(a, b, c, d, M[13], 0xa9e3e905, 5)
|
||
d = fnG(d, a, b, c, M[2], 0xfcefa3f8, 9)
|
||
c = fnG(c, d, a, b, M[7], 0x676f02d9, 14)
|
||
b = fnG(b, c, d, a, M[12], 0x8d2a4c8a, 20)
|
||
|
||
a = fnH(a, b, c, d, M[5], 0xfffa3942, 4)
|
||
d = fnH(d, a, b, c, M[8], 0x8771f681, 11)
|
||
c = fnH(c, d, a, b, M[11], 0x6d9d6122, 16)
|
||
b = fnH(b, c, d, a, M[14], 0xfde5380c, 23)
|
||
a = fnH(a, b, c, d, M[1], 0xa4beea44, 4)
|
||
d = fnH(d, a, b, c, M[4], 0x4bdecfa9, 11)
|
||
c = fnH(c, d, a, b, M[7], 0xf6bb4b60, 16)
|
||
b = fnH(b, c, d, a, M[10], 0xbebfbc70, 23)
|
||
a = fnH(a, b, c, d, M[13], 0x289b7ec6, 4)
|
||
d = fnH(d, a, b, c, M[0], 0xeaa127fa, 11)
|
||
c = fnH(c, d, a, b, M[3], 0xd4ef3085, 16)
|
||
b = fnH(b, c, d, a, M[6], 0x04881d05, 23)
|
||
a = fnH(a, b, c, d, M[9], 0xd9d4d039, 4)
|
||
d = fnH(d, a, b, c, M[12], 0xe6db99e5, 11)
|
||
c = fnH(c, d, a, b, M[15], 0x1fa27cf8, 16)
|
||
b = fnH(b, c, d, a, M[2], 0xc4ac5665, 23)
|
||
|
||
a = fnI(a, b, c, d, M[0], 0xf4292244, 6)
|
||
d = fnI(d, a, b, c, M[7], 0x432aff97, 10)
|
||
c = fnI(c, d, a, b, M[14], 0xab9423a7, 15)
|
||
b = fnI(b, c, d, a, M[5], 0xfc93a039, 21)
|
||
a = fnI(a, b, c, d, M[12], 0x655b59c3, 6)
|
||
d = fnI(d, a, b, c, M[3], 0x8f0ccc92, 10)
|
||
c = fnI(c, d, a, b, M[10], 0xffeff47d, 15)
|
||
b = fnI(b, c, d, a, M[1], 0x85845dd1, 21)
|
||
a = fnI(a, b, c, d, M[8], 0x6fa87e4f, 6)
|
||
d = fnI(d, a, b, c, M[15], 0xfe2ce6e0, 10)
|
||
c = fnI(c, d, a, b, M[6], 0xa3014314, 15)
|
||
b = fnI(b, c, d, a, M[13], 0x4e0811a1, 21)
|
||
a = fnI(a, b, c, d, M[4], 0xf7537e82, 6)
|
||
d = fnI(d, a, b, c, M[11], 0xbd3af235, 10)
|
||
c = fnI(c, d, a, b, M[2], 0x2ad7d2bb, 15)
|
||
b = fnI(b, c, d, a, M[9], 0xeb86d391, 21)
|
||
|
||
this._a = (this._a + a) | 0
|
||
this._b = (this._b + b) | 0
|
||
this._c = (this._c + c) | 0
|
||
this._d = (this._d + d) | 0
|
||
}
|
||
|
||
MD5.prototype._digest = function () {
|
||
// create padding and handle blocks
|
||
this._block[this._blockOffset++] = 0x80
|
||
if (this._blockOffset > 56) {
|
||
this._block.fill(0, this._blockOffset, 64)
|
||
this._update()
|
||
this._blockOffset = 0
|
||
}
|
||
|
||
this._block.fill(0, this._blockOffset, 56)
|
||
this._block.writeUInt32LE(this._length[0], 56)
|
||
this._block.writeUInt32LE(this._length[1], 60)
|
||
this._update()
|
||
|
||
// produce result
|
||
var buffer = Buffer.allocUnsafe(16)
|
||
buffer.writeInt32LE(this._a, 0)
|
||
buffer.writeInt32LE(this._b, 4)
|
||
buffer.writeInt32LE(this._c, 8)
|
||
buffer.writeInt32LE(this._d, 12)
|
||
return buffer
|
||
}
|
||
|
||
function rotl (x, n) {
|
||
return (x << n) | (x >>> (32 - n))
|
||
}
|
||
|
||
function fnF (a, b, c, d, m, k, s) {
|
||
return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + b) | 0
|
||
}
|
||
|
||
function fnG (a, b, c, d, m, k, s) {
|
||
return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + b) | 0
|
||
}
|
||
|
||
function fnH (a, b, c, d, m, k, s) {
|
||
return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + b) | 0
|
||
}
|
||
|
||
function fnI (a, b, c, d, m, k, s) {
|
||
return (rotl((a + ((c ^ (b | (~d)))) + m + k) | 0, s) + b) | 0
|
||
}
|
||
|
||
module.exports = MD5
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/miller-rabin/lib/mr.js":
|
||
/*!*********************************************!*\
|
||
!*** ./node_modules/miller-rabin/lib/mr.js ***!
|
||
\*********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var bn = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js");
|
||
var brorand = __webpack_require__(/*! brorand */ "./node_modules/brorand/index.js");
|
||
|
||
function MillerRabin(rand) {
|
||
this.rand = rand || new brorand.Rand();
|
||
}
|
||
module.exports = MillerRabin;
|
||
|
||
MillerRabin.create = function create(rand) {
|
||
return new MillerRabin(rand);
|
||
};
|
||
|
||
MillerRabin.prototype._randbelow = function _randbelow(n) {
|
||
var len = n.bitLength();
|
||
var min_bytes = Math.ceil(len / 8);
|
||
|
||
// Generage random bytes until a number less than n is found.
|
||
// This ensures that 0..n-1 have an equal probability of being selected.
|
||
do
|
||
var a = new bn(this.rand.generate(min_bytes));
|
||
while (a.cmp(n) >= 0);
|
||
|
||
return a;
|
||
};
|
||
|
||
MillerRabin.prototype._randrange = function _randrange(start, stop) {
|
||
// Generate a random number greater than or equal to start and less than stop.
|
||
var size = stop.sub(start);
|
||
return start.add(this._randbelow(size));
|
||
};
|
||
|
||
MillerRabin.prototype.test = function test(n, k, cb) {
|
||
var len = n.bitLength();
|
||
var red = bn.mont(n);
|
||
var rone = new bn(1).toRed(red);
|
||
|
||
if (!k)
|
||
k = Math.max(1, (len / 48) | 0);
|
||
|
||
// Find d and s, (n - 1) = (2 ^ s) * d;
|
||
var n1 = n.subn(1);
|
||
for (var s = 0; !n1.testn(s); s++) {}
|
||
var d = n.shrn(s);
|
||
|
||
var rn1 = n1.toRed(red);
|
||
|
||
var prime = true;
|
||
for (; k > 0; k--) {
|
||
var a = this._randrange(new bn(2), n1);
|
||
if (cb)
|
||
cb(a);
|
||
|
||
var x = a.toRed(red).redPow(d);
|
||
if (x.cmp(rone) === 0 || x.cmp(rn1) === 0)
|
||
continue;
|
||
|
||
for (var i = 1; i < s; i++) {
|
||
x = x.redSqr();
|
||
|
||
if (x.cmp(rone) === 0)
|
||
return false;
|
||
if (x.cmp(rn1) === 0)
|
||
break;
|
||
}
|
||
|
||
if (i === s)
|
||
return false;
|
||
}
|
||
|
||
return prime;
|
||
};
|
||
|
||
MillerRabin.prototype.getDivisor = function getDivisor(n, k) {
|
||
var len = n.bitLength();
|
||
var red = bn.mont(n);
|
||
var rone = new bn(1).toRed(red);
|
||
|
||
if (!k)
|
||
k = Math.max(1, (len / 48) | 0);
|
||
|
||
// Find d and s, (n - 1) = (2 ^ s) * d;
|
||
var n1 = n.subn(1);
|
||
for (var s = 0; !n1.testn(s); s++) {}
|
||
var d = n.shrn(s);
|
||
|
||
var rn1 = n1.toRed(red);
|
||
|
||
for (; k > 0; k--) {
|
||
var a = this._randrange(new bn(2), n1);
|
||
|
||
var g = n.gcd(a);
|
||
if (g.cmpn(1) !== 0)
|
||
return g;
|
||
|
||
var x = a.toRed(red).redPow(d);
|
||
if (x.cmp(rone) === 0 || x.cmp(rn1) === 0)
|
||
continue;
|
||
|
||
for (var i = 1; i < s; i++) {
|
||
x = x.redSqr();
|
||
|
||
if (x.cmp(rone) === 0)
|
||
return x.fromRed().subn(1).gcd(n);
|
||
if (x.cmp(rn1) === 0)
|
||
break;
|
||
}
|
||
|
||
if (i === s) {
|
||
x = x.redSqr();
|
||
return x.fromRed().subn(1).gcd(n);
|
||
}
|
||
}
|
||
|
||
return false;
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/minimalistic-assert/index.js":
|
||
/*!***************************************************!*\
|
||
!*** ./node_modules/minimalistic-assert/index.js ***!
|
||
\***************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
module.exports = assert;
|
||
|
||
function assert(val, msg) {
|
||
if (!val)
|
||
throw new Error(msg || 'Assertion failed');
|
||
}
|
||
|
||
assert.equal = function assertEqual(l, r, msg) {
|
||
if (l != r)
|
||
throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r));
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/minimalistic-crypto-utils/lib/utils.js":
|
||
/*!*************************************************************!*\
|
||
!*** ./node_modules/minimalistic-crypto-utils/lib/utils.js ***!
|
||
\*************************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var utils = exports;
|
||
|
||
function toArray(msg, enc) {
|
||
if (Array.isArray(msg))
|
||
return msg.slice();
|
||
if (!msg)
|
||
return [];
|
||
var res = [];
|
||
if (typeof msg !== 'string') {
|
||
for (var i = 0; i < msg.length; i++)
|
||
res[i] = msg[i] | 0;
|
||
return res;
|
||
}
|
||
if (enc === 'hex') {
|
||
msg = msg.replace(/[^a-z0-9]+/ig, '');
|
||
if (msg.length % 2 !== 0)
|
||
msg = '0' + msg;
|
||
for (var i = 0; i < msg.length; i += 2)
|
||
res.push(parseInt(msg[i] + msg[i + 1], 16));
|
||
} else {
|
||
for (var i = 0; i < msg.length; i++) {
|
||
var c = msg.charCodeAt(i);
|
||
var hi = c >> 8;
|
||
var lo = c & 0xff;
|
||
if (hi)
|
||
res.push(hi, lo);
|
||
else
|
||
res.push(lo);
|
||
}
|
||
}
|
||
return res;
|
||
}
|
||
utils.toArray = toArray;
|
||
|
||
function zero2(word) {
|
||
if (word.length === 1)
|
||
return '0' + word;
|
||
else
|
||
return word;
|
||
}
|
||
utils.zero2 = zero2;
|
||
|
||
function toHex(msg) {
|
||
var res = '';
|
||
for (var i = 0; i < msg.length; i++)
|
||
res += zero2(msg[i].toString(16));
|
||
return res;
|
||
}
|
||
utils.toHex = toHex;
|
||
|
||
utils.encode = function encode(arr, enc) {
|
||
if (enc === 'hex')
|
||
return toHex(arr);
|
||
else
|
||
return arr;
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/node-libs-browser/mock/empty.js":
|
||
/*!******************************************************!*\
|
||
!*** ./node_modules/node-libs-browser/mock/empty.js ***!
|
||
\******************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pako/index.js":
|
||
/*!************************************!*\
|
||
!*** ./node_modules/pako/index.js ***!
|
||
\************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
// Top level file is just a mixin of submodules & constants
|
||
|
||
|
||
var assign = __webpack_require__(/*! ./lib/utils/common */ "./node_modules/pako/lib/utils/common.js").assign;
|
||
|
||
var deflate = __webpack_require__(/*! ./lib/deflate */ "./node_modules/pako/lib/deflate.js");
|
||
var inflate = __webpack_require__(/*! ./lib/inflate */ "./node_modules/pako/lib/inflate.js");
|
||
var constants = __webpack_require__(/*! ./lib/zlib/constants */ "./node_modules/pako/lib/zlib/constants.js");
|
||
|
||
var pako = {};
|
||
|
||
assign(pako, deflate, inflate, constants);
|
||
|
||
module.exports = pako;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pako/lib/deflate.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/pako/lib/deflate.js ***!
|
||
\******************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
|
||
var zlib_deflate = __webpack_require__(/*! ./zlib/deflate */ "./node_modules/pako/lib/zlib/deflate.js");
|
||
var utils = __webpack_require__(/*! ./utils/common */ "./node_modules/pako/lib/utils/common.js");
|
||
var strings = __webpack_require__(/*! ./utils/strings */ "./node_modules/pako/lib/utils/strings.js");
|
||
var msg = __webpack_require__(/*! ./zlib/messages */ "./node_modules/pako/lib/zlib/messages.js");
|
||
var ZStream = __webpack_require__(/*! ./zlib/zstream */ "./node_modules/pako/lib/zlib/zstream.js");
|
||
|
||
var toString = Object.prototype.toString;
|
||
|
||
/* Public constants ==========================================================*/
|
||
/* ===========================================================================*/
|
||
|
||
var Z_NO_FLUSH = 0;
|
||
var Z_FINISH = 4;
|
||
|
||
var Z_OK = 0;
|
||
var Z_STREAM_END = 1;
|
||
var Z_SYNC_FLUSH = 2;
|
||
|
||
var Z_DEFAULT_COMPRESSION = -1;
|
||
|
||
var Z_DEFAULT_STRATEGY = 0;
|
||
|
||
var Z_DEFLATED = 8;
|
||
|
||
/* ===========================================================================*/
|
||
|
||
|
||
/**
|
||
* class Deflate
|
||
*
|
||
* Generic JS-style wrapper for zlib calls. If you don't need
|
||
* streaming behaviour - use more simple functions: [[deflate]],
|
||
* [[deflateRaw]] and [[gzip]].
|
||
**/
|
||
|
||
/* internal
|
||
* Deflate.chunks -> Array
|
||
*
|
||
* Chunks of output data, if [[Deflate#onData]] not overridden.
|
||
**/
|
||
|
||
/**
|
||
* Deflate.result -> Uint8Array|Array
|
||
*
|
||
* Compressed result, generated by default [[Deflate#onData]]
|
||
* and [[Deflate#onEnd]] handlers. Filled after you push last chunk
|
||
* (call [[Deflate#push]] with `Z_FINISH` / `true` param) or if you
|
||
* push a chunk with explicit flush (call [[Deflate#push]] with
|
||
* `Z_SYNC_FLUSH` param).
|
||
**/
|
||
|
||
/**
|
||
* Deflate.err -> Number
|
||
*
|
||
* Error code after deflate finished. 0 (Z_OK) on success.
|
||
* You will not need it in real life, because deflate errors
|
||
* are possible only on wrong options or bad `onData` / `onEnd`
|
||
* custom handlers.
|
||
**/
|
||
|
||
/**
|
||
* Deflate.msg -> String
|
||
*
|
||
* Error message, if [[Deflate.err]] != 0
|
||
**/
|
||
|
||
|
||
/**
|
||
* new Deflate(options)
|
||
* - options (Object): zlib deflate options.
|
||
*
|
||
* Creates new deflator instance with specified params. Throws exception
|
||
* on bad params. Supported options:
|
||
*
|
||
* - `level`
|
||
* - `windowBits`
|
||
* - `memLevel`
|
||
* - `strategy`
|
||
* - `dictionary`
|
||
*
|
||
* [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
|
||
* for more information on these.
|
||
*
|
||
* Additional options, for internal needs:
|
||
*
|
||
* - `chunkSize` - size of generated data chunks (16K by default)
|
||
* - `raw` (Boolean) - do raw deflate
|
||
* - `gzip` (Boolean) - create gzip wrapper
|
||
* - `to` (String) - if equal to 'string', then result will be "binary string"
|
||
* (each char code [0..255])
|
||
* - `header` (Object) - custom header for gzip
|
||
* - `text` (Boolean) - true if compressed data believed to be text
|
||
* - `time` (Number) - modification time, unix timestamp
|
||
* - `os` (Number) - operation system code
|
||
* - `extra` (Array) - array of bytes with extra data (max 65536)
|
||
* - `name` (String) - file name (binary string)
|
||
* - `comment` (String) - comment (binary string)
|
||
* - `hcrc` (Boolean) - true if header crc should be added
|
||
*
|
||
* ##### Example:
|
||
*
|
||
* ```javascript
|
||
* var pako = require('pako')
|
||
* , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
|
||
* , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
|
||
*
|
||
* var deflate = new pako.Deflate({ level: 3});
|
||
*
|
||
* deflate.push(chunk1, false);
|
||
* deflate.push(chunk2, true); // true -> last chunk
|
||
*
|
||
* if (deflate.err) { throw new Error(deflate.err); }
|
||
*
|
||
* console.log(deflate.result);
|
||
* ```
|
||
**/
|
||
function Deflate(options) {
|
||
if (!(this instanceof Deflate)) return new Deflate(options);
|
||
|
||
this.options = utils.assign({
|
||
level: Z_DEFAULT_COMPRESSION,
|
||
method: Z_DEFLATED,
|
||
chunkSize: 16384,
|
||
windowBits: 15,
|
||
memLevel: 8,
|
||
strategy: Z_DEFAULT_STRATEGY,
|
||
to: ''
|
||
}, options || {});
|
||
|
||
var opt = this.options;
|
||
|
||
if (opt.raw && (opt.windowBits > 0)) {
|
||
opt.windowBits = -opt.windowBits;
|
||
}
|
||
|
||
else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) {
|
||
opt.windowBits += 16;
|
||
}
|
||
|
||
this.err = 0; // error code, if happens (0 = Z_OK)
|
||
this.msg = ''; // error message
|
||
this.ended = false; // used to avoid multiple onEnd() calls
|
||
this.chunks = []; // chunks of compressed data
|
||
|
||
this.strm = new ZStream();
|
||
this.strm.avail_out = 0;
|
||
|
||
var status = zlib_deflate.deflateInit2(
|
||
this.strm,
|
||
opt.level,
|
||
opt.method,
|
||
opt.windowBits,
|
||
opt.memLevel,
|
||
opt.strategy
|
||
);
|
||
|
||
if (status !== Z_OK) {
|
||
throw new Error(msg[status]);
|
||
}
|
||
|
||
if (opt.header) {
|
||
zlib_deflate.deflateSetHeader(this.strm, opt.header);
|
||
}
|
||
|
||
if (opt.dictionary) {
|
||
var dict;
|
||
// Convert data if needed
|
||
if (typeof opt.dictionary === 'string') {
|
||
// If we need to compress text, change encoding to utf8.
|
||
dict = strings.string2buf(opt.dictionary);
|
||
} else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') {
|
||
dict = new Uint8Array(opt.dictionary);
|
||
} else {
|
||
dict = opt.dictionary;
|
||
}
|
||
|
||
status = zlib_deflate.deflateSetDictionary(this.strm, dict);
|
||
|
||
if (status !== Z_OK) {
|
||
throw new Error(msg[status]);
|
||
}
|
||
|
||
this._dict_set = true;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Deflate#push(data[, mode]) -> Boolean
|
||
* - data (Uint8Array|Array|ArrayBuffer|String): input data. Strings will be
|
||
* converted to utf8 byte sequence.
|
||
* - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
|
||
* See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.
|
||
*
|
||
* Sends input data to deflate pipe, generating [[Deflate#onData]] calls with
|
||
* new compressed chunks. Returns `true` on success. The last data block must have
|
||
* mode Z_FINISH (or `true`). That will flush internal pending buffers and call
|
||
* [[Deflate#onEnd]]. For interim explicit flushes (without ending the stream) you
|
||
* can use mode Z_SYNC_FLUSH, keeping the compression context.
|
||
*
|
||
* On fail call [[Deflate#onEnd]] with error code and return false.
|
||
*
|
||
* We strongly recommend to use `Uint8Array` on input for best speed (output
|
||
* array format is detected automatically). Also, don't skip last param and always
|
||
* use the same type in your code (boolean or number). That will improve JS speed.
|
||
*
|
||
* For regular `Array`-s make sure all elements are [0..255].
|
||
*
|
||
* ##### Example
|
||
*
|
||
* ```javascript
|
||
* push(chunk, false); // push one of data chunks
|
||
* ...
|
||
* push(chunk, true); // push last chunk
|
||
* ```
|
||
**/
|
||
Deflate.prototype.push = function (data, mode) {
|
||
var strm = this.strm;
|
||
var chunkSize = this.options.chunkSize;
|
||
var status, _mode;
|
||
|
||
if (this.ended) { return false; }
|
||
|
||
_mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH);
|
||
|
||
// Convert data if needed
|
||
if (typeof data === 'string') {
|
||
// If we need to compress text, change encoding to utf8.
|
||
strm.input = strings.string2buf(data);
|
||
} else if (toString.call(data) === '[object ArrayBuffer]') {
|
||
strm.input = new Uint8Array(data);
|
||
} else {
|
||
strm.input = data;
|
||
}
|
||
|
||
strm.next_in = 0;
|
||
strm.avail_in = strm.input.length;
|
||
|
||
do {
|
||
if (strm.avail_out === 0) {
|
||
strm.output = new utils.Buf8(chunkSize);
|
||
strm.next_out = 0;
|
||
strm.avail_out = chunkSize;
|
||
}
|
||
status = zlib_deflate.deflate(strm, _mode); /* no bad return value */
|
||
|
||
if (status !== Z_STREAM_END && status !== Z_OK) {
|
||
this.onEnd(status);
|
||
this.ended = true;
|
||
return false;
|
||
}
|
||
if (strm.avail_out === 0 || (strm.avail_in === 0 && (_mode === Z_FINISH || _mode === Z_SYNC_FLUSH))) {
|
||
if (this.options.to === 'string') {
|
||
this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out)));
|
||
} else {
|
||
this.onData(utils.shrinkBuf(strm.output, strm.next_out));
|
||
}
|
||
}
|
||
} while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END);
|
||
|
||
// Finalize on the last chunk.
|
||
if (_mode === Z_FINISH) {
|
||
status = zlib_deflate.deflateEnd(this.strm);
|
||
this.onEnd(status);
|
||
this.ended = true;
|
||
return status === Z_OK;
|
||
}
|
||
|
||
// callback interim results if Z_SYNC_FLUSH.
|
||
if (_mode === Z_SYNC_FLUSH) {
|
||
this.onEnd(Z_OK);
|
||
strm.avail_out = 0;
|
||
return true;
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
|
||
/**
|
||
* Deflate#onData(chunk) -> Void
|
||
* - chunk (Uint8Array|Array|String): output data. Type of array depends
|
||
* on js engine support. When string output requested, each chunk
|
||
* will be string.
|
||
*
|
||
* By default, stores data blocks in `chunks[]` property and glue
|
||
* those in `onEnd`. Override this handler, if you need another behaviour.
|
||
**/
|
||
Deflate.prototype.onData = function (chunk) {
|
||
this.chunks.push(chunk);
|
||
};
|
||
|
||
|
||
/**
|
||
* Deflate#onEnd(status) -> Void
|
||
* - status (Number): deflate status. 0 (Z_OK) on success,
|
||
* other if not.
|
||
*
|
||
* Called once after you tell deflate that the input stream is
|
||
* complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)
|
||
* or if an error happened. By default - join collected chunks,
|
||
* free memory and fill `results` / `err` properties.
|
||
**/
|
||
Deflate.prototype.onEnd = function (status) {
|
||
// On success - join
|
||
if (status === Z_OK) {
|
||
if (this.options.to === 'string') {
|
||
this.result = this.chunks.join('');
|
||
} else {
|
||
this.result = utils.flattenChunks(this.chunks);
|
||
}
|
||
}
|
||
this.chunks = [];
|
||
this.err = status;
|
||
this.msg = this.strm.msg;
|
||
};
|
||
|
||
|
||
/**
|
||
* deflate(data[, options]) -> Uint8Array|Array|String
|
||
* - data (Uint8Array|Array|String): input data to compress.
|
||
* - options (Object): zlib deflate options.
|
||
*
|
||
* Compress `data` with deflate algorithm and `options`.
|
||
*
|
||
* Supported options are:
|
||
*
|
||
* - level
|
||
* - windowBits
|
||
* - memLevel
|
||
* - strategy
|
||
* - dictionary
|
||
*
|
||
* [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
|
||
* for more information on these.
|
||
*
|
||
* Sugar (options):
|
||
*
|
||
* - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify
|
||
* negative windowBits implicitly.
|
||
* - `to` (String) - if equal to 'string', then result will be "binary string"
|
||
* (each char code [0..255])
|
||
*
|
||
* ##### Example:
|
||
*
|
||
* ```javascript
|
||
* var pako = require('pako')
|
||
* , data = Uint8Array([1,2,3,4,5,6,7,8,9]);
|
||
*
|
||
* console.log(pako.deflate(data));
|
||
* ```
|
||
**/
|
||
function deflate(input, options) {
|
||
var deflator = new Deflate(options);
|
||
|
||
deflator.push(input, true);
|
||
|
||
// That will never happens, if you don't cheat with options :)
|
||
if (deflator.err) { throw deflator.msg || msg[deflator.err]; }
|
||
|
||
return deflator.result;
|
||
}
|
||
|
||
|
||
/**
|
||
* deflateRaw(data[, options]) -> Uint8Array|Array|String
|
||
* - data (Uint8Array|Array|String): input data to compress.
|
||
* - options (Object): zlib deflate options.
|
||
*
|
||
* The same as [[deflate]], but creates raw data, without wrapper
|
||
* (header and adler32 crc).
|
||
**/
|
||
function deflateRaw(input, options) {
|
||
options = options || {};
|
||
options.raw = true;
|
||
return deflate(input, options);
|
||
}
|
||
|
||
|
||
/**
|
||
* gzip(data[, options]) -> Uint8Array|Array|String
|
||
* - data (Uint8Array|Array|String): input data to compress.
|
||
* - options (Object): zlib deflate options.
|
||
*
|
||
* The same as [[deflate]], but create gzip wrapper instead of
|
||
* deflate one.
|
||
**/
|
||
function gzip(input, options) {
|
||
options = options || {};
|
||
options.gzip = true;
|
||
return deflate(input, options);
|
||
}
|
||
|
||
|
||
exports.Deflate = Deflate;
|
||
exports.deflate = deflate;
|
||
exports.deflateRaw = deflateRaw;
|
||
exports.gzip = gzip;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pako/lib/inflate.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/pako/lib/inflate.js ***!
|
||
\******************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
|
||
var zlib_inflate = __webpack_require__(/*! ./zlib/inflate */ "./node_modules/pako/lib/zlib/inflate.js");
|
||
var utils = __webpack_require__(/*! ./utils/common */ "./node_modules/pako/lib/utils/common.js");
|
||
var strings = __webpack_require__(/*! ./utils/strings */ "./node_modules/pako/lib/utils/strings.js");
|
||
var c = __webpack_require__(/*! ./zlib/constants */ "./node_modules/pako/lib/zlib/constants.js");
|
||
var msg = __webpack_require__(/*! ./zlib/messages */ "./node_modules/pako/lib/zlib/messages.js");
|
||
var ZStream = __webpack_require__(/*! ./zlib/zstream */ "./node_modules/pako/lib/zlib/zstream.js");
|
||
var GZheader = __webpack_require__(/*! ./zlib/gzheader */ "./node_modules/pako/lib/zlib/gzheader.js");
|
||
|
||
var toString = Object.prototype.toString;
|
||
|
||
/**
|
||
* class Inflate
|
||
*
|
||
* Generic JS-style wrapper for zlib calls. If you don't need
|
||
* streaming behaviour - use more simple functions: [[inflate]]
|
||
* and [[inflateRaw]].
|
||
**/
|
||
|
||
/* internal
|
||
* inflate.chunks -> Array
|
||
*
|
||
* Chunks of output data, if [[Inflate#onData]] not overridden.
|
||
**/
|
||
|
||
/**
|
||
* Inflate.result -> Uint8Array|Array|String
|
||
*
|
||
* Uncompressed result, generated by default [[Inflate#onData]]
|
||
* and [[Inflate#onEnd]] handlers. Filled after you push last chunk
|
||
* (call [[Inflate#push]] with `Z_FINISH` / `true` param) or if you
|
||
* push a chunk with explicit flush (call [[Inflate#push]] with
|
||
* `Z_SYNC_FLUSH` param).
|
||
**/
|
||
|
||
/**
|
||
* Inflate.err -> Number
|
||
*
|
||
* Error code after inflate finished. 0 (Z_OK) on success.
|
||
* Should be checked if broken data possible.
|
||
**/
|
||
|
||
/**
|
||
* Inflate.msg -> String
|
||
*
|
||
* Error message, if [[Inflate.err]] != 0
|
||
**/
|
||
|
||
|
||
/**
|
||
* new Inflate(options)
|
||
* - options (Object): zlib inflate options.
|
||
*
|
||
* Creates new inflator instance with specified params. Throws exception
|
||
* on bad params. Supported options:
|
||
*
|
||
* - `windowBits`
|
||
* - `dictionary`
|
||
*
|
||
* [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
|
||
* for more information on these.
|
||
*
|
||
* Additional options, for internal needs:
|
||
*
|
||
* - `chunkSize` - size of generated data chunks (16K by default)
|
||
* - `raw` (Boolean) - do raw inflate
|
||
* - `to` (String) - if equal to 'string', then result will be converted
|
||
* from utf8 to utf16 (javascript) string. When string output requested,
|
||
* chunk length can differ from `chunkSize`, depending on content.
|
||
*
|
||
* By default, when no options set, autodetect deflate/gzip data format via
|
||
* wrapper header.
|
||
*
|
||
* ##### Example:
|
||
*
|
||
* ```javascript
|
||
* var pako = require('pako')
|
||
* , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
|
||
* , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
|
||
*
|
||
* var inflate = new pako.Inflate({ level: 3});
|
||
*
|
||
* inflate.push(chunk1, false);
|
||
* inflate.push(chunk2, true); // true -> last chunk
|
||
*
|
||
* if (inflate.err) { throw new Error(inflate.err); }
|
||
*
|
||
* console.log(inflate.result);
|
||
* ```
|
||
**/
|
||
function Inflate(options) {
|
||
if (!(this instanceof Inflate)) return new Inflate(options);
|
||
|
||
this.options = utils.assign({
|
||
chunkSize: 16384,
|
||
windowBits: 0,
|
||
to: ''
|
||
}, options || {});
|
||
|
||
var opt = this.options;
|
||
|
||
// Force window size for `raw` data, if not set directly,
|
||
// because we have no header for autodetect.
|
||
if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) {
|
||
opt.windowBits = -opt.windowBits;
|
||
if (opt.windowBits === 0) { opt.windowBits = -15; }
|
||
}
|
||
|
||
// If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate
|
||
if ((opt.windowBits >= 0) && (opt.windowBits < 16) &&
|
||
!(options && options.windowBits)) {
|
||
opt.windowBits += 32;
|
||
}
|
||
|
||
// Gzip header has no info about windows size, we can do autodetect only
|
||
// for deflate. So, if window size not set, force it to max when gzip possible
|
||
if ((opt.windowBits > 15) && (opt.windowBits < 48)) {
|
||
// bit 3 (16) -> gzipped data
|
||
// bit 4 (32) -> autodetect gzip/deflate
|
||
if ((opt.windowBits & 15) === 0) {
|
||
opt.windowBits |= 15;
|
||
}
|
||
}
|
||
|
||
this.err = 0; // error code, if happens (0 = Z_OK)
|
||
this.msg = ''; // error message
|
||
this.ended = false; // used to avoid multiple onEnd() calls
|
||
this.chunks = []; // chunks of compressed data
|
||
|
||
this.strm = new ZStream();
|
||
this.strm.avail_out = 0;
|
||
|
||
var status = zlib_inflate.inflateInit2(
|
||
this.strm,
|
||
opt.windowBits
|
||
);
|
||
|
||
if (status !== c.Z_OK) {
|
||
throw new Error(msg[status]);
|
||
}
|
||
|
||
this.header = new GZheader();
|
||
|
||
zlib_inflate.inflateGetHeader(this.strm, this.header);
|
||
|
||
// Setup dictionary
|
||
if (opt.dictionary) {
|
||
// Convert data if needed
|
||
if (typeof opt.dictionary === 'string') {
|
||
opt.dictionary = strings.string2buf(opt.dictionary);
|
||
} else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') {
|
||
opt.dictionary = new Uint8Array(opt.dictionary);
|
||
}
|
||
if (opt.raw) { //In raw mode we need to set the dictionary early
|
||
status = zlib_inflate.inflateSetDictionary(this.strm, opt.dictionary);
|
||
if (status !== c.Z_OK) {
|
||
throw new Error(msg[status]);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Inflate#push(data[, mode]) -> Boolean
|
||
* - data (Uint8Array|Array|ArrayBuffer|String): input data
|
||
* - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
|
||
* See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.
|
||
*
|
||
* Sends input data to inflate pipe, generating [[Inflate#onData]] calls with
|
||
* new output chunks. Returns `true` on success. The last data block must have
|
||
* mode Z_FINISH (or `true`). That will flush internal pending buffers and call
|
||
* [[Inflate#onEnd]]. For interim explicit flushes (without ending the stream) you
|
||
* can use mode Z_SYNC_FLUSH, keeping the decompression context.
|
||
*
|
||
* On fail call [[Inflate#onEnd]] with error code and return false.
|
||
*
|
||
* We strongly recommend to use `Uint8Array` on input for best speed (output
|
||
* format is detected automatically). Also, don't skip last param and always
|
||
* use the same type in your code (boolean or number). That will improve JS speed.
|
||
*
|
||
* For regular `Array`-s make sure all elements are [0..255].
|
||
*
|
||
* ##### Example
|
||
*
|
||
* ```javascript
|
||
* push(chunk, false); // push one of data chunks
|
||
* ...
|
||
* push(chunk, true); // push last chunk
|
||
* ```
|
||
**/
|
||
Inflate.prototype.push = function (data, mode) {
|
||
var strm = this.strm;
|
||
var chunkSize = this.options.chunkSize;
|
||
var dictionary = this.options.dictionary;
|
||
var status, _mode;
|
||
var next_out_utf8, tail, utf8str;
|
||
|
||
// Flag to properly process Z_BUF_ERROR on testing inflate call
|
||
// when we check that all output data was flushed.
|
||
var allowBufError = false;
|
||
|
||
if (this.ended) { return false; }
|
||
_mode = (mode === ~~mode) ? mode : ((mode === true) ? c.Z_FINISH : c.Z_NO_FLUSH);
|
||
|
||
// Convert data if needed
|
||
if (typeof data === 'string') {
|
||
// Only binary strings can be decompressed on practice
|
||
strm.input = strings.binstring2buf(data);
|
||
} else if (toString.call(data) === '[object ArrayBuffer]') {
|
||
strm.input = new Uint8Array(data);
|
||
} else {
|
||
strm.input = data;
|
||
}
|
||
|
||
strm.next_in = 0;
|
||
strm.avail_in = strm.input.length;
|
||
|
||
do {
|
||
if (strm.avail_out === 0) {
|
||
strm.output = new utils.Buf8(chunkSize);
|
||
strm.next_out = 0;
|
||
strm.avail_out = chunkSize;
|
||
}
|
||
|
||
status = zlib_inflate.inflate(strm, c.Z_NO_FLUSH); /* no bad return value */
|
||
|
||
if (status === c.Z_NEED_DICT && dictionary) {
|
||
status = zlib_inflate.inflateSetDictionary(this.strm, dictionary);
|
||
}
|
||
|
||
if (status === c.Z_BUF_ERROR && allowBufError === true) {
|
||
status = c.Z_OK;
|
||
allowBufError = false;
|
||
}
|
||
|
||
if (status !== c.Z_STREAM_END && status !== c.Z_OK) {
|
||
this.onEnd(status);
|
||
this.ended = true;
|
||
return false;
|
||
}
|
||
|
||
if (strm.next_out) {
|
||
if (strm.avail_out === 0 || status === c.Z_STREAM_END || (strm.avail_in === 0 && (_mode === c.Z_FINISH || _mode === c.Z_SYNC_FLUSH))) {
|
||
|
||
if (this.options.to === 'string') {
|
||
|
||
next_out_utf8 = strings.utf8border(strm.output, strm.next_out);
|
||
|
||
tail = strm.next_out - next_out_utf8;
|
||
utf8str = strings.buf2string(strm.output, next_out_utf8);
|
||
|
||
// move tail
|
||
strm.next_out = tail;
|
||
strm.avail_out = chunkSize - tail;
|
||
if (tail) { utils.arraySet(strm.output, strm.output, next_out_utf8, tail, 0); }
|
||
|
||
this.onData(utf8str);
|
||
|
||
} else {
|
||
this.onData(utils.shrinkBuf(strm.output, strm.next_out));
|
||
}
|
||
}
|
||
}
|
||
|
||
// When no more input data, we should check that internal inflate buffers
|
||
// are flushed. The only way to do it when avail_out = 0 - run one more
|
||
// inflate pass. But if output data not exists, inflate return Z_BUF_ERROR.
|
||
// Here we set flag to process this error properly.
|
||
//
|
||
// NOTE. Deflate does not return error in this case and does not needs such
|
||
// logic.
|
||
if (strm.avail_in === 0 && strm.avail_out === 0) {
|
||
allowBufError = true;
|
||
}
|
||
|
||
} while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== c.Z_STREAM_END);
|
||
|
||
if (status === c.Z_STREAM_END) {
|
||
_mode = c.Z_FINISH;
|
||
}
|
||
|
||
// Finalize on the last chunk.
|
||
if (_mode === c.Z_FINISH) {
|
||
status = zlib_inflate.inflateEnd(this.strm);
|
||
this.onEnd(status);
|
||
this.ended = true;
|
||
return status === c.Z_OK;
|
||
}
|
||
|
||
// callback interim results if Z_SYNC_FLUSH.
|
||
if (_mode === c.Z_SYNC_FLUSH) {
|
||
this.onEnd(c.Z_OK);
|
||
strm.avail_out = 0;
|
||
return true;
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
|
||
/**
|
||
* Inflate#onData(chunk) -> Void
|
||
* - chunk (Uint8Array|Array|String): output data. Type of array depends
|
||
* on js engine support. When string output requested, each chunk
|
||
* will be string.
|
||
*
|
||
* By default, stores data blocks in `chunks[]` property and glue
|
||
* those in `onEnd`. Override this handler, if you need another behaviour.
|
||
**/
|
||
Inflate.prototype.onData = function (chunk) {
|
||
this.chunks.push(chunk);
|
||
};
|
||
|
||
|
||
/**
|
||
* Inflate#onEnd(status) -> Void
|
||
* - status (Number): inflate status. 0 (Z_OK) on success,
|
||
* other if not.
|
||
*
|
||
* Called either after you tell inflate that the input stream is
|
||
* complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)
|
||
* or if an error happened. By default - join collected chunks,
|
||
* free memory and fill `results` / `err` properties.
|
||
**/
|
||
Inflate.prototype.onEnd = function (status) {
|
||
// On success - join
|
||
if (status === c.Z_OK) {
|
||
if (this.options.to === 'string') {
|
||
// Glue & convert here, until we teach pako to send
|
||
// utf8 aligned strings to onData
|
||
this.result = this.chunks.join('');
|
||
} else {
|
||
this.result = utils.flattenChunks(this.chunks);
|
||
}
|
||
}
|
||
this.chunks = [];
|
||
this.err = status;
|
||
this.msg = this.strm.msg;
|
||
};
|
||
|
||
|
||
/**
|
||
* inflate(data[, options]) -> Uint8Array|Array|String
|
||
* - data (Uint8Array|Array|String): input data to decompress.
|
||
* - options (Object): zlib inflate options.
|
||
*
|
||
* Decompress `data` with inflate/ungzip and `options`. Autodetect
|
||
* format via wrapper header by default. That's why we don't provide
|
||
* separate `ungzip` method.
|
||
*
|
||
* Supported options are:
|
||
*
|
||
* - windowBits
|
||
*
|
||
* [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
|
||
* for more information.
|
||
*
|
||
* Sugar (options):
|
||
*
|
||
* - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify
|
||
* negative windowBits implicitly.
|
||
* - `to` (String) - if equal to 'string', then result will be converted
|
||
* from utf8 to utf16 (javascript) string. When string output requested,
|
||
* chunk length can differ from `chunkSize`, depending on content.
|
||
*
|
||
*
|
||
* ##### Example:
|
||
*
|
||
* ```javascript
|
||
* var pako = require('pako')
|
||
* , input = pako.deflate([1,2,3,4,5,6,7,8,9])
|
||
* , output;
|
||
*
|
||
* try {
|
||
* output = pako.inflate(input);
|
||
* } catch (err)
|
||
* console.log(err);
|
||
* }
|
||
* ```
|
||
**/
|
||
function inflate(input, options) {
|
||
var inflator = new Inflate(options);
|
||
|
||
inflator.push(input, true);
|
||
|
||
// That will never happens, if you don't cheat with options :)
|
||
if (inflator.err) { throw inflator.msg || msg[inflator.err]; }
|
||
|
||
return inflator.result;
|
||
}
|
||
|
||
|
||
/**
|
||
* inflateRaw(data[, options]) -> Uint8Array|Array|String
|
||
* - data (Uint8Array|Array|String): input data to decompress.
|
||
* - options (Object): zlib inflate options.
|
||
*
|
||
* The same as [[inflate]], but creates raw data, without wrapper
|
||
* (header and adler32 crc).
|
||
**/
|
||
function inflateRaw(input, options) {
|
||
options = options || {};
|
||
options.raw = true;
|
||
return inflate(input, options);
|
||
}
|
||
|
||
|
||
/**
|
||
* ungzip(data[, options]) -> Uint8Array|Array|String
|
||
* - data (Uint8Array|Array|String): input data to decompress.
|
||
* - options (Object): zlib inflate options.
|
||
*
|
||
* Just shortcut to [[inflate]], because it autodetects format
|
||
* by header.content. Done for convenience.
|
||
**/
|
||
|
||
|
||
exports.Inflate = Inflate;
|
||
exports.inflate = inflate;
|
||
exports.inflateRaw = inflateRaw;
|
||
exports.ungzip = inflate;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pako/lib/utils/common.js":
|
||
/*!***********************************************!*\
|
||
!*** ./node_modules/pako/lib/utils/common.js ***!
|
||
\***********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
|
||
var TYPED_OK = (typeof Uint8Array !== 'undefined') &&
|
||
(typeof Uint16Array !== 'undefined') &&
|
||
(typeof Int32Array !== 'undefined');
|
||
|
||
function _has(obj, key) {
|
||
return Object.prototype.hasOwnProperty.call(obj, key);
|
||
}
|
||
|
||
exports.assign = function (obj /*from1, from2, from3, ...*/) {
|
||
var sources = Array.prototype.slice.call(arguments, 1);
|
||
while (sources.length) {
|
||
var source = sources.shift();
|
||
if (!source) { continue; }
|
||
|
||
if (typeof source !== 'object') {
|
||
throw new TypeError(source + 'must be non-object');
|
||
}
|
||
|
||
for (var p in source) {
|
||
if (_has(source, p)) {
|
||
obj[p] = source[p];
|
||
}
|
||
}
|
||
}
|
||
|
||
return obj;
|
||
};
|
||
|
||
|
||
// reduce buffer size, avoiding mem copy
|
||
exports.shrinkBuf = function (buf, size) {
|
||
if (buf.length === size) { return buf; }
|
||
if (buf.subarray) { return buf.subarray(0, size); }
|
||
buf.length = size;
|
||
return buf;
|
||
};
|
||
|
||
|
||
var fnTyped = {
|
||
arraySet: function (dest, src, src_offs, len, dest_offs) {
|
||
if (src.subarray && dest.subarray) {
|
||
dest.set(src.subarray(src_offs, src_offs + len), dest_offs);
|
||
return;
|
||
}
|
||
// Fallback to ordinary array
|
||
for (var i = 0; i < len; i++) {
|
||
dest[dest_offs + i] = src[src_offs + i];
|
||
}
|
||
},
|
||
// Join array of chunks to single array.
|
||
flattenChunks: function (chunks) {
|
||
var i, l, len, pos, chunk, result;
|
||
|
||
// calculate data length
|
||
len = 0;
|
||
for (i = 0, l = chunks.length; i < l; i++) {
|
||
len += chunks[i].length;
|
||
}
|
||
|
||
// join chunks
|
||
result = new Uint8Array(len);
|
||
pos = 0;
|
||
for (i = 0, l = chunks.length; i < l; i++) {
|
||
chunk = chunks[i];
|
||
result.set(chunk, pos);
|
||
pos += chunk.length;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
};
|
||
|
||
var fnUntyped = {
|
||
arraySet: function (dest, src, src_offs, len, dest_offs) {
|
||
for (var i = 0; i < len; i++) {
|
||
dest[dest_offs + i] = src[src_offs + i];
|
||
}
|
||
},
|
||
// Join array of chunks to single array.
|
||
flattenChunks: function (chunks) {
|
||
return [].concat.apply([], chunks);
|
||
}
|
||
};
|
||
|
||
|
||
// Enable/Disable typed arrays use, for testing
|
||
//
|
||
exports.setTyped = function (on) {
|
||
if (on) {
|
||
exports.Buf8 = Uint8Array;
|
||
exports.Buf16 = Uint16Array;
|
||
exports.Buf32 = Int32Array;
|
||
exports.assign(exports, fnTyped);
|
||
} else {
|
||
exports.Buf8 = Array;
|
||
exports.Buf16 = Array;
|
||
exports.Buf32 = Array;
|
||
exports.assign(exports, fnUntyped);
|
||
}
|
||
};
|
||
|
||
exports.setTyped(TYPED_OK);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pako/lib/utils/strings.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/pako/lib/utils/strings.js ***!
|
||
\************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
// String encode/decode helpers
|
||
|
||
|
||
|
||
var utils = __webpack_require__(/*! ./common */ "./node_modules/pako/lib/utils/common.js");
|
||
|
||
|
||
// Quick check if we can use fast array to bin string conversion
|
||
//
|
||
// - apply(Array) can fail on Android 2.2
|
||
// - apply(Uint8Array) can fail on iOS 5.1 Safari
|
||
//
|
||
var STR_APPLY_OK = true;
|
||
var STR_APPLY_UIA_OK = true;
|
||
|
||
try { String.fromCharCode.apply(null, [ 0 ]); } catch (__) { STR_APPLY_OK = false; }
|
||
try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (__) { STR_APPLY_UIA_OK = false; }
|
||
|
||
|
||
// Table with utf8 lengths (calculated by first byte of sequence)
|
||
// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,
|
||
// because max possible codepoint is 0x10ffff
|
||
var _utf8len = new utils.Buf8(256);
|
||
for (var q = 0; q < 256; q++) {
|
||
_utf8len[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1);
|
||
}
|
||
_utf8len[254] = _utf8len[254] = 1; // Invalid sequence start
|
||
|
||
|
||
// convert string to array (typed, when possible)
|
||
exports.string2buf = function (str) {
|
||
var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0;
|
||
|
||
// count binary size
|
||
for (m_pos = 0; m_pos < str_len; m_pos++) {
|
||
c = str.charCodeAt(m_pos);
|
||
if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) {
|
||
c2 = str.charCodeAt(m_pos + 1);
|
||
if ((c2 & 0xfc00) === 0xdc00) {
|
||
c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);
|
||
m_pos++;
|
||
}
|
||
}
|
||
buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4;
|
||
}
|
||
|
||
// allocate buffer
|
||
buf = new utils.Buf8(buf_len);
|
||
|
||
// convert
|
||
for (i = 0, m_pos = 0; i < buf_len; m_pos++) {
|
||
c = str.charCodeAt(m_pos);
|
||
if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) {
|
||
c2 = str.charCodeAt(m_pos + 1);
|
||
if ((c2 & 0xfc00) === 0xdc00) {
|
||
c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);
|
||
m_pos++;
|
||
}
|
||
}
|
||
if (c < 0x80) {
|
||
/* one byte */
|
||
buf[i++] = c;
|
||
} else if (c < 0x800) {
|
||
/* two bytes */
|
||
buf[i++] = 0xC0 | (c >>> 6);
|
||
buf[i++] = 0x80 | (c & 0x3f);
|
||
} else if (c < 0x10000) {
|
||
/* three bytes */
|
||
buf[i++] = 0xE0 | (c >>> 12);
|
||
buf[i++] = 0x80 | (c >>> 6 & 0x3f);
|
||
buf[i++] = 0x80 | (c & 0x3f);
|
||
} else {
|
||
/* four bytes */
|
||
buf[i++] = 0xf0 | (c >>> 18);
|
||
buf[i++] = 0x80 | (c >>> 12 & 0x3f);
|
||
buf[i++] = 0x80 | (c >>> 6 & 0x3f);
|
||
buf[i++] = 0x80 | (c & 0x3f);
|
||
}
|
||
}
|
||
|
||
return buf;
|
||
};
|
||
|
||
// Helper (used in 2 places)
|
||
function buf2binstring(buf, len) {
|
||
// On Chrome, the arguments in a function call that are allowed is `65534`.
|
||
// If the length of the buffer is smaller than that, we can use this optimization,
|
||
// otherwise we will take a slower path.
|
||
if (len < 65534) {
|
||
if ((buf.subarray && STR_APPLY_UIA_OK) || (!buf.subarray && STR_APPLY_OK)) {
|
||
return String.fromCharCode.apply(null, utils.shrinkBuf(buf, len));
|
||
}
|
||
}
|
||
|
||
var result = '';
|
||
for (var i = 0; i < len; i++) {
|
||
result += String.fromCharCode(buf[i]);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
|
||
// Convert byte array to binary string
|
||
exports.buf2binstring = function (buf) {
|
||
return buf2binstring(buf, buf.length);
|
||
};
|
||
|
||
|
||
// Convert binary string (typed, when possible)
|
||
exports.binstring2buf = function (str) {
|
||
var buf = new utils.Buf8(str.length);
|
||
for (var i = 0, len = buf.length; i < len; i++) {
|
||
buf[i] = str.charCodeAt(i);
|
||
}
|
||
return buf;
|
||
};
|
||
|
||
|
||
// convert array to string
|
||
exports.buf2string = function (buf, max) {
|
||
var i, out, c, c_len;
|
||
var len = max || buf.length;
|
||
|
||
// Reserve max possible length (2 words per char)
|
||
// NB: by unknown reasons, Array is significantly faster for
|
||
// String.fromCharCode.apply than Uint16Array.
|
||
var utf16buf = new Array(len * 2);
|
||
|
||
for (out = 0, i = 0; i < len;) {
|
||
c = buf[i++];
|
||
// quick process ascii
|
||
if (c < 0x80) { utf16buf[out++] = c; continue; }
|
||
|
||
c_len = _utf8len[c];
|
||
// skip 5 & 6 byte codes
|
||
if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; }
|
||
|
||
// apply mask on first byte
|
||
c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07;
|
||
// join the rest
|
||
while (c_len > 1 && i < len) {
|
||
c = (c << 6) | (buf[i++] & 0x3f);
|
||
c_len--;
|
||
}
|
||
|
||
// terminated by end of string?
|
||
if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; }
|
||
|
||
if (c < 0x10000) {
|
||
utf16buf[out++] = c;
|
||
} else {
|
||
c -= 0x10000;
|
||
utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff);
|
||
utf16buf[out++] = 0xdc00 | (c & 0x3ff);
|
||
}
|
||
}
|
||
|
||
return buf2binstring(utf16buf, out);
|
||
};
|
||
|
||
|
||
// Calculate max possible position in utf8 buffer,
|
||
// that will not break sequence. If that's not possible
|
||
// - (very small limits) return max size as is.
|
||
//
|
||
// buf[] - utf8 bytes array
|
||
// max - length limit (mandatory);
|
||
exports.utf8border = function (buf, max) {
|
||
var pos;
|
||
|
||
max = max || buf.length;
|
||
if (max > buf.length) { max = buf.length; }
|
||
|
||
// go back from last position, until start of sequence found
|
||
pos = max - 1;
|
||
while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; }
|
||
|
||
// Very small and broken sequence,
|
||
// return max, because we should return something anyway.
|
||
if (pos < 0) { return max; }
|
||
|
||
// If we came to start of buffer - that means buffer is too small,
|
||
// return max too.
|
||
if (pos === 0) { return max; }
|
||
|
||
return (pos + _utf8len[buf[pos]] > max) ? pos : max;
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pako/lib/zlib/adler32.js":
|
||
/*!***********************************************!*\
|
||
!*** ./node_modules/pako/lib/zlib/adler32.js ***!
|
||
\***********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
// Note: adler32 takes 12% for level 0 and 2% for level 6.
|
||
// It isn't worth it to make additional optimizations as in original.
|
||
// Small size is preferable.
|
||
|
||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||
//
|
||
// This software is provided 'as-is', without any express or implied
|
||
// warranty. In no event will the authors be held liable for any damages
|
||
// arising from the use of this software.
|
||
//
|
||
// Permission is granted to anyone to use this software for any purpose,
|
||
// including commercial applications, and to alter it and redistribute it
|
||
// freely, subject to the following restrictions:
|
||
//
|
||
// 1. The origin of this software must not be misrepresented; you must not
|
||
// claim that you wrote the original software. If you use this software
|
||
// in a product, an acknowledgment in the product documentation would be
|
||
// appreciated but is not required.
|
||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||
// misrepresented as being the original software.
|
||
// 3. This notice may not be removed or altered from any source distribution.
|
||
|
||
function adler32(adler, buf, len, pos) {
|
||
var s1 = (adler & 0xffff) |0,
|
||
s2 = ((adler >>> 16) & 0xffff) |0,
|
||
n = 0;
|
||
|
||
while (len !== 0) {
|
||
// Set limit ~ twice less than 5552, to keep
|
||
// s2 in 31-bits, because we force signed ints.
|
||
// in other case %= will fail.
|
||
n = len > 2000 ? 2000 : len;
|
||
len -= n;
|
||
|
||
do {
|
||
s1 = (s1 + buf[pos++]) |0;
|
||
s2 = (s2 + s1) |0;
|
||
} while (--n);
|
||
|
||
s1 %= 65521;
|
||
s2 %= 65521;
|
||
}
|
||
|
||
return (s1 | (s2 << 16)) |0;
|
||
}
|
||
|
||
|
||
module.exports = adler32;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pako/lib/zlib/constants.js":
|
||
/*!*************************************************!*\
|
||
!*** ./node_modules/pako/lib/zlib/constants.js ***!
|
||
\*************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||
//
|
||
// This software is provided 'as-is', without any express or implied
|
||
// warranty. In no event will the authors be held liable for any damages
|
||
// arising from the use of this software.
|
||
//
|
||
// Permission is granted to anyone to use this software for any purpose,
|
||
// including commercial applications, and to alter it and redistribute it
|
||
// freely, subject to the following restrictions:
|
||
//
|
||
// 1. The origin of this software must not be misrepresented; you must not
|
||
// claim that you wrote the original software. If you use this software
|
||
// in a product, an acknowledgment in the product documentation would be
|
||
// appreciated but is not required.
|
||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||
// misrepresented as being the original software.
|
||
// 3. This notice may not be removed or altered from any source distribution.
|
||
|
||
module.exports = {
|
||
|
||
/* Allowed flush values; see deflate() and inflate() below for details */
|
||
Z_NO_FLUSH: 0,
|
||
Z_PARTIAL_FLUSH: 1,
|
||
Z_SYNC_FLUSH: 2,
|
||
Z_FULL_FLUSH: 3,
|
||
Z_FINISH: 4,
|
||
Z_BLOCK: 5,
|
||
Z_TREES: 6,
|
||
|
||
/* Return codes for the compression/decompression functions. Negative values
|
||
* are errors, positive values are used for special but normal events.
|
||
*/
|
||
Z_OK: 0,
|
||
Z_STREAM_END: 1,
|
||
Z_NEED_DICT: 2,
|
||
Z_ERRNO: -1,
|
||
Z_STREAM_ERROR: -2,
|
||
Z_DATA_ERROR: -3,
|
||
//Z_MEM_ERROR: -4,
|
||
Z_BUF_ERROR: -5,
|
||
//Z_VERSION_ERROR: -6,
|
||
|
||
/* compression levels */
|
||
Z_NO_COMPRESSION: 0,
|
||
Z_BEST_SPEED: 1,
|
||
Z_BEST_COMPRESSION: 9,
|
||
Z_DEFAULT_COMPRESSION: -1,
|
||
|
||
|
||
Z_FILTERED: 1,
|
||
Z_HUFFMAN_ONLY: 2,
|
||
Z_RLE: 3,
|
||
Z_FIXED: 4,
|
||
Z_DEFAULT_STRATEGY: 0,
|
||
|
||
/* Possible values of the data_type field (though see inflate()) */
|
||
Z_BINARY: 0,
|
||
Z_TEXT: 1,
|
||
//Z_ASCII: 1, // = Z_TEXT (deprecated)
|
||
Z_UNKNOWN: 2,
|
||
|
||
/* The deflate compression method */
|
||
Z_DEFLATED: 8
|
||
//Z_NULL: null // Use -1 or null inline, depending on var type
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pako/lib/zlib/crc32.js":
|
||
/*!*********************************************!*\
|
||
!*** ./node_modules/pako/lib/zlib/crc32.js ***!
|
||
\*********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
// Note: we can't get significant speed boost here.
|
||
// So write code to minimize size - no pregenerated tables
|
||
// and array tools dependencies.
|
||
|
||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||
//
|
||
// This software is provided 'as-is', without any express or implied
|
||
// warranty. In no event will the authors be held liable for any damages
|
||
// arising from the use of this software.
|
||
//
|
||
// Permission is granted to anyone to use this software for any purpose,
|
||
// including commercial applications, and to alter it and redistribute it
|
||
// freely, subject to the following restrictions:
|
||
//
|
||
// 1. The origin of this software must not be misrepresented; you must not
|
||
// claim that you wrote the original software. If you use this software
|
||
// in a product, an acknowledgment in the product documentation would be
|
||
// appreciated but is not required.
|
||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||
// misrepresented as being the original software.
|
||
// 3. This notice may not be removed or altered from any source distribution.
|
||
|
||
// Use ordinary array, since untyped makes no boost here
|
||
function makeTable() {
|
||
var c, table = [];
|
||
|
||
for (var n = 0; n < 256; n++) {
|
||
c = n;
|
||
for (var k = 0; k < 8; k++) {
|
||
c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
|
||
}
|
||
table[n] = c;
|
||
}
|
||
|
||
return table;
|
||
}
|
||
|
||
// Create table on load. Just 255 signed longs. Not a problem.
|
||
var crcTable = makeTable();
|
||
|
||
|
||
function crc32(crc, buf, len, pos) {
|
||
var t = crcTable,
|
||
end = pos + len;
|
||
|
||
crc ^= -1;
|
||
|
||
for (var i = pos; i < end; i++) {
|
||
crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF];
|
||
}
|
||
|
||
return (crc ^ (-1)); // >>> 0;
|
||
}
|
||
|
||
|
||
module.exports = crc32;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pako/lib/zlib/deflate.js":
|
||
/*!***********************************************!*\
|
||
!*** ./node_modules/pako/lib/zlib/deflate.js ***!
|
||
\***********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||
//
|
||
// This software is provided 'as-is', without any express or implied
|
||
// warranty. In no event will the authors be held liable for any damages
|
||
// arising from the use of this software.
|
||
//
|
||
// Permission is granted to anyone to use this software for any purpose,
|
||
// including commercial applications, and to alter it and redistribute it
|
||
// freely, subject to the following restrictions:
|
||
//
|
||
// 1. The origin of this software must not be misrepresented; you must not
|
||
// claim that you wrote the original software. If you use this software
|
||
// in a product, an acknowledgment in the product documentation would be
|
||
// appreciated but is not required.
|
||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||
// misrepresented as being the original software.
|
||
// 3. This notice may not be removed or altered from any source distribution.
|
||
|
||
var utils = __webpack_require__(/*! ../utils/common */ "./node_modules/pako/lib/utils/common.js");
|
||
var trees = __webpack_require__(/*! ./trees */ "./node_modules/pako/lib/zlib/trees.js");
|
||
var adler32 = __webpack_require__(/*! ./adler32 */ "./node_modules/pako/lib/zlib/adler32.js");
|
||
var crc32 = __webpack_require__(/*! ./crc32 */ "./node_modules/pako/lib/zlib/crc32.js");
|
||
var msg = __webpack_require__(/*! ./messages */ "./node_modules/pako/lib/zlib/messages.js");
|
||
|
||
/* Public constants ==========================================================*/
|
||
/* ===========================================================================*/
|
||
|
||
|
||
/* Allowed flush values; see deflate() and inflate() below for details */
|
||
var Z_NO_FLUSH = 0;
|
||
var Z_PARTIAL_FLUSH = 1;
|
||
//var Z_SYNC_FLUSH = 2;
|
||
var Z_FULL_FLUSH = 3;
|
||
var Z_FINISH = 4;
|
||
var Z_BLOCK = 5;
|
||
//var Z_TREES = 6;
|
||
|
||
|
||
/* Return codes for the compression/decompression functions. Negative values
|
||
* are errors, positive values are used for special but normal events.
|
||
*/
|
||
var Z_OK = 0;
|
||
var Z_STREAM_END = 1;
|
||
//var Z_NEED_DICT = 2;
|
||
//var Z_ERRNO = -1;
|
||
var Z_STREAM_ERROR = -2;
|
||
var Z_DATA_ERROR = -3;
|
||
//var Z_MEM_ERROR = -4;
|
||
var Z_BUF_ERROR = -5;
|
||
//var Z_VERSION_ERROR = -6;
|
||
|
||
|
||
/* compression levels */
|
||
//var Z_NO_COMPRESSION = 0;
|
||
//var Z_BEST_SPEED = 1;
|
||
//var Z_BEST_COMPRESSION = 9;
|
||
var Z_DEFAULT_COMPRESSION = -1;
|
||
|
||
|
||
var Z_FILTERED = 1;
|
||
var Z_HUFFMAN_ONLY = 2;
|
||
var Z_RLE = 3;
|
||
var Z_FIXED = 4;
|
||
var Z_DEFAULT_STRATEGY = 0;
|
||
|
||
/* Possible values of the data_type field (though see inflate()) */
|
||
//var Z_BINARY = 0;
|
||
//var Z_TEXT = 1;
|
||
//var Z_ASCII = 1; // = Z_TEXT
|
||
var Z_UNKNOWN = 2;
|
||
|
||
|
||
/* The deflate compression method */
|
||
var Z_DEFLATED = 8;
|
||
|
||
/*============================================================================*/
|
||
|
||
|
||
var MAX_MEM_LEVEL = 9;
|
||
/* Maximum value for memLevel in deflateInit2 */
|
||
var MAX_WBITS = 15;
|
||
/* 32K LZ77 window */
|
||
var DEF_MEM_LEVEL = 8;
|
||
|
||
|
||
var LENGTH_CODES = 29;
|
||
/* number of length codes, not counting the special END_BLOCK code */
|
||
var LITERALS = 256;
|
||
/* number of literal bytes 0..255 */
|
||
var L_CODES = LITERALS + 1 + LENGTH_CODES;
|
||
/* number of Literal or Length codes, including the END_BLOCK code */
|
||
var D_CODES = 30;
|
||
/* number of distance codes */
|
||
var BL_CODES = 19;
|
||
/* number of codes used to transfer the bit lengths */
|
||
var HEAP_SIZE = 2 * L_CODES + 1;
|
||
/* maximum heap size */
|
||
var MAX_BITS = 15;
|
||
/* All codes must not exceed MAX_BITS bits */
|
||
|
||
var MIN_MATCH = 3;
|
||
var MAX_MATCH = 258;
|
||
var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);
|
||
|
||
var PRESET_DICT = 0x20;
|
||
|
||
var INIT_STATE = 42;
|
||
var EXTRA_STATE = 69;
|
||
var NAME_STATE = 73;
|
||
var COMMENT_STATE = 91;
|
||
var HCRC_STATE = 103;
|
||
var BUSY_STATE = 113;
|
||
var FINISH_STATE = 666;
|
||
|
||
var BS_NEED_MORE = 1; /* block not completed, need more input or more output */
|
||
var BS_BLOCK_DONE = 2; /* block flush performed */
|
||
var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */
|
||
var BS_FINISH_DONE = 4; /* finish done, accept no more input or output */
|
||
|
||
var OS_CODE = 0x03; // Unix :) . Don't detect, use this default.
|
||
|
||
function err(strm, errorCode) {
|
||
strm.msg = msg[errorCode];
|
||
return errorCode;
|
||
}
|
||
|
||
function rank(f) {
|
||
return ((f) << 1) - ((f) > 4 ? 9 : 0);
|
||
}
|
||
|
||
function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } }
|
||
|
||
|
||
/* =========================================================================
|
||
* Flush as much pending output as possible. All deflate() output goes
|
||
* through this function so some applications may wish to modify it
|
||
* to avoid allocating a large strm->output buffer and copying into it.
|
||
* (See also read_buf()).
|
||
*/
|
||
function flush_pending(strm) {
|
||
var s = strm.state;
|
||
|
||
//_tr_flush_bits(s);
|
||
var len = s.pending;
|
||
if (len > strm.avail_out) {
|
||
len = strm.avail_out;
|
||
}
|
||
if (len === 0) { return; }
|
||
|
||
utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out);
|
||
strm.next_out += len;
|
||
s.pending_out += len;
|
||
strm.total_out += len;
|
||
strm.avail_out -= len;
|
||
s.pending -= len;
|
||
if (s.pending === 0) {
|
||
s.pending_out = 0;
|
||
}
|
||
}
|
||
|
||
|
||
function flush_block_only(s, last) {
|
||
trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last);
|
||
s.block_start = s.strstart;
|
||
flush_pending(s.strm);
|
||
}
|
||
|
||
|
||
function put_byte(s, b) {
|
||
s.pending_buf[s.pending++] = b;
|
||
}
|
||
|
||
|
||
/* =========================================================================
|
||
* Put a short in the pending buffer. The 16-bit value is put in MSB order.
|
||
* IN assertion: the stream state is correct and there is enough room in
|
||
* pending_buf.
|
||
*/
|
||
function putShortMSB(s, b) {
|
||
// put_byte(s, (Byte)(b >> 8));
|
||
// put_byte(s, (Byte)(b & 0xff));
|
||
s.pending_buf[s.pending++] = (b >>> 8) & 0xff;
|
||
s.pending_buf[s.pending++] = b & 0xff;
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Read a new buffer from the current input stream, update the adler32
|
||
* and total number of bytes read. All deflate() input goes through
|
||
* this function so some applications may wish to modify it to avoid
|
||
* allocating a large strm->input buffer and copying from it.
|
||
* (See also flush_pending()).
|
||
*/
|
||
function read_buf(strm, buf, start, size) {
|
||
var len = strm.avail_in;
|
||
|
||
if (len > size) { len = size; }
|
||
if (len === 0) { return 0; }
|
||
|
||
strm.avail_in -= len;
|
||
|
||
// zmemcpy(buf, strm->next_in, len);
|
||
utils.arraySet(buf, strm.input, strm.next_in, len, start);
|
||
if (strm.state.wrap === 1) {
|
||
strm.adler = adler32(strm.adler, buf, len, start);
|
||
}
|
||
|
||
else if (strm.state.wrap === 2) {
|
||
strm.adler = crc32(strm.adler, buf, len, start);
|
||
}
|
||
|
||
strm.next_in += len;
|
||
strm.total_in += len;
|
||
|
||
return len;
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Set match_start to the longest match starting at the given string and
|
||
* return its length. Matches shorter or equal to prev_length are discarded,
|
||
* in which case the result is equal to prev_length and match_start is
|
||
* garbage.
|
||
* IN assertions: cur_match is the head of the hash chain for the current
|
||
* string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
|
||
* OUT assertion: the match length is not greater than s->lookahead.
|
||
*/
|
||
function longest_match(s, cur_match) {
|
||
var chain_length = s.max_chain_length; /* max hash chain length */
|
||
var scan = s.strstart; /* current string */
|
||
var match; /* matched string */
|
||
var len; /* length of current match */
|
||
var best_len = s.prev_length; /* best match length so far */
|
||
var nice_match = s.nice_match; /* stop if match long enough */
|
||
var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ?
|
||
s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/;
|
||
|
||
var _win = s.window; // shortcut
|
||
|
||
var wmask = s.w_mask;
|
||
var prev = s.prev;
|
||
|
||
/* Stop when cur_match becomes <= limit. To simplify the code,
|
||
* we prevent matches with the string of window index 0.
|
||
*/
|
||
|
||
var strend = s.strstart + MAX_MATCH;
|
||
var scan_end1 = _win[scan + best_len - 1];
|
||
var scan_end = _win[scan + best_len];
|
||
|
||
/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
|
||
* It is easy to get rid of this optimization if necessary.
|
||
*/
|
||
// Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
|
||
|
||
/* Do not waste too much time if we already have a good match: */
|
||
if (s.prev_length >= s.good_match) {
|
||
chain_length >>= 2;
|
||
}
|
||
/* Do not look for matches beyond the end of the input. This is necessary
|
||
* to make deflate deterministic.
|
||
*/
|
||
if (nice_match > s.lookahead) { nice_match = s.lookahead; }
|
||
|
||
// Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
|
||
|
||
do {
|
||
// Assert(cur_match < s->strstart, "no future");
|
||
match = cur_match;
|
||
|
||
/* Skip to next match if the match length cannot increase
|
||
* or if the match length is less than 2. Note that the checks below
|
||
* for insufficient lookahead only occur occasionally for performance
|
||
* reasons. Therefore uninitialized memory will be accessed, and
|
||
* conditional jumps will be made that depend on those values.
|
||
* However the length of the match is limited to the lookahead, so
|
||
* the output of deflate is not affected by the uninitialized values.
|
||
*/
|
||
|
||
if (_win[match + best_len] !== scan_end ||
|
||
_win[match + best_len - 1] !== scan_end1 ||
|
||
_win[match] !== _win[scan] ||
|
||
_win[++match] !== _win[scan + 1]) {
|
||
continue;
|
||
}
|
||
|
||
/* The check at best_len-1 can be removed because it will be made
|
||
* again later. (This heuristic is not always a win.)
|
||
* It is not necessary to compare scan[2] and match[2] since they
|
||
* are always equal when the other bytes match, given that
|
||
* the hash keys are equal and that HASH_BITS >= 8.
|
||
*/
|
||
scan += 2;
|
||
match++;
|
||
// Assert(*scan == *match, "match[2]?");
|
||
|
||
/* We check for insufficient lookahead only every 8th comparison;
|
||
* the 256th check will be made at strstart+258.
|
||
*/
|
||
do {
|
||
/*jshint noempty:false*/
|
||
} while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
|
||
_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
|
||
_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
|
||
_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
|
||
scan < strend);
|
||
|
||
// Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
|
||
|
||
len = MAX_MATCH - (strend - scan);
|
||
scan = strend - MAX_MATCH;
|
||
|
||
if (len > best_len) {
|
||
s.match_start = cur_match;
|
||
best_len = len;
|
||
if (len >= nice_match) {
|
||
break;
|
||
}
|
||
scan_end1 = _win[scan + best_len - 1];
|
||
scan_end = _win[scan + best_len];
|
||
}
|
||
} while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0);
|
||
|
||
if (best_len <= s.lookahead) {
|
||
return best_len;
|
||
}
|
||
return s.lookahead;
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Fill the window when the lookahead becomes insufficient.
|
||
* Updates strstart and lookahead.
|
||
*
|
||
* IN assertion: lookahead < MIN_LOOKAHEAD
|
||
* OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
|
||
* At least one byte has been read, or avail_in == 0; reads are
|
||
* performed for at least two bytes (required for the zip translate_eol
|
||
* option -- not supported here).
|
||
*/
|
||
function fill_window(s) {
|
||
var _w_size = s.w_size;
|
||
var p, n, m, more, str;
|
||
|
||
//Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
|
||
|
||
do {
|
||
more = s.window_size - s.lookahead - s.strstart;
|
||
|
||
// JS ints have 32 bit, block below not needed
|
||
/* Deal with !@#$% 64K limit: */
|
||
//if (sizeof(int) <= 2) {
|
||
// if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
|
||
// more = wsize;
|
||
//
|
||
// } else if (more == (unsigned)(-1)) {
|
||
// /* Very unlikely, but possible on 16 bit machine if
|
||
// * strstart == 0 && lookahead == 1 (input done a byte at time)
|
||
// */
|
||
// more--;
|
||
// }
|
||
//}
|
||
|
||
|
||
/* If the window is almost full and there is insufficient lookahead,
|
||
* move the upper half to the lower one to make room in the upper half.
|
||
*/
|
||
if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {
|
||
|
||
utils.arraySet(s.window, s.window, _w_size, _w_size, 0);
|
||
s.match_start -= _w_size;
|
||
s.strstart -= _w_size;
|
||
/* we now have strstart >= MAX_DIST */
|
||
s.block_start -= _w_size;
|
||
|
||
/* Slide the hash table (could be avoided with 32 bit values
|
||
at the expense of memory usage). We slide even when level == 0
|
||
to keep the hash table consistent if we switch back to level > 0
|
||
later. (Using level 0 permanently is not an optimal usage of
|
||
zlib, so we don't care about this pathological case.)
|
||
*/
|
||
|
||
n = s.hash_size;
|
||
p = n;
|
||
do {
|
||
m = s.head[--p];
|
||
s.head[p] = (m >= _w_size ? m - _w_size : 0);
|
||
} while (--n);
|
||
|
||
n = _w_size;
|
||
p = n;
|
||
do {
|
||
m = s.prev[--p];
|
||
s.prev[p] = (m >= _w_size ? m - _w_size : 0);
|
||
/* If n is not on any hash chain, prev[n] is garbage but
|
||
* its value will never be used.
|
||
*/
|
||
} while (--n);
|
||
|
||
more += _w_size;
|
||
}
|
||
if (s.strm.avail_in === 0) {
|
||
break;
|
||
}
|
||
|
||
/* If there was no sliding:
|
||
* strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
|
||
* more == window_size - lookahead - strstart
|
||
* => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
|
||
* => more >= window_size - 2*WSIZE + 2
|
||
* In the BIG_MEM or MMAP case (not yet supported),
|
||
* window_size == input_size + MIN_LOOKAHEAD &&
|
||
* strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
|
||
* Otherwise, window_size == 2*WSIZE so more >= 2.
|
||
* If there was sliding, more >= WSIZE. So in all cases, more >= 2.
|
||
*/
|
||
//Assert(more >= 2, "more < 2");
|
||
n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);
|
||
s.lookahead += n;
|
||
|
||
/* Initialize the hash value now that we have some input: */
|
||
if (s.lookahead + s.insert >= MIN_MATCH) {
|
||
str = s.strstart - s.insert;
|
||
s.ins_h = s.window[str];
|
||
|
||
/* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */
|
||
s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask;
|
||
//#if MIN_MATCH != 3
|
||
// Call update_hash() MIN_MATCH-3 more times
|
||
//#endif
|
||
while (s.insert) {
|
||
/* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
|
||
s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
|
||
|
||
s.prev[str & s.w_mask] = s.head[s.ins_h];
|
||
s.head[s.ins_h] = str;
|
||
str++;
|
||
s.insert--;
|
||
if (s.lookahead + s.insert < MIN_MATCH) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
/* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
|
||
* but this is not important since only literal bytes will be emitted.
|
||
*/
|
||
|
||
} while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0);
|
||
|
||
/* If the WIN_INIT bytes after the end of the current data have never been
|
||
* written, then zero those bytes in order to avoid memory check reports of
|
||
* the use of uninitialized (or uninitialised as Julian writes) bytes by
|
||
* the longest match routines. Update the high water mark for the next
|
||
* time through here. WIN_INIT is set to MAX_MATCH since the longest match
|
||
* routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
|
||
*/
|
||
// if (s.high_water < s.window_size) {
|
||
// var curr = s.strstart + s.lookahead;
|
||
// var init = 0;
|
||
//
|
||
// if (s.high_water < curr) {
|
||
// /* Previous high water mark below current data -- zero WIN_INIT
|
||
// * bytes or up to end of window, whichever is less.
|
||
// */
|
||
// init = s.window_size - curr;
|
||
// if (init > WIN_INIT)
|
||
// init = WIN_INIT;
|
||
// zmemzero(s->window + curr, (unsigned)init);
|
||
// s->high_water = curr + init;
|
||
// }
|
||
// else if (s->high_water < (ulg)curr + WIN_INIT) {
|
||
// /* High water mark at or above current data, but below current data
|
||
// * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
|
||
// * to end of window, whichever is less.
|
||
// */
|
||
// init = (ulg)curr + WIN_INIT - s->high_water;
|
||
// if (init > s->window_size - s->high_water)
|
||
// init = s->window_size - s->high_water;
|
||
// zmemzero(s->window + s->high_water, (unsigned)init);
|
||
// s->high_water += init;
|
||
// }
|
||
// }
|
||
//
|
||
// Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
|
||
// "not enough room for search");
|
||
}
|
||
|
||
/* ===========================================================================
|
||
* Copy without compression as much as possible from the input stream, return
|
||
* the current block state.
|
||
* This function does not insert new strings in the dictionary since
|
||
* uncompressible data is probably not useful. This function is used
|
||
* only for the level=0 compression option.
|
||
* NOTE: this function should be optimized to avoid extra copying from
|
||
* window to pending_buf.
|
||
*/
|
||
function deflate_stored(s, flush) {
|
||
/* Stored blocks are limited to 0xffff bytes, pending_buf is limited
|
||
* to pending_buf_size, and each stored block has a 5 byte header:
|
||
*/
|
||
var max_block_size = 0xffff;
|
||
|
||
if (max_block_size > s.pending_buf_size - 5) {
|
||
max_block_size = s.pending_buf_size - 5;
|
||
}
|
||
|
||
/* Copy as much as possible from input to output: */
|
||
for (;;) {
|
||
/* Fill the window as much as possible: */
|
||
if (s.lookahead <= 1) {
|
||
|
||
//Assert(s->strstart < s->w_size+MAX_DIST(s) ||
|
||
// s->block_start >= (long)s->w_size, "slide too late");
|
||
// if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) ||
|
||
// s.block_start >= s.w_size)) {
|
||
// throw new Error("slide too late");
|
||
// }
|
||
|
||
fill_window(s);
|
||
if (s.lookahead === 0 && flush === Z_NO_FLUSH) {
|
||
return BS_NEED_MORE;
|
||
}
|
||
|
||
if (s.lookahead === 0) {
|
||
break;
|
||
}
|
||
/* flush the current block */
|
||
}
|
||
//Assert(s->block_start >= 0L, "block gone");
|
||
// if (s.block_start < 0) throw new Error("block gone");
|
||
|
||
s.strstart += s.lookahead;
|
||
s.lookahead = 0;
|
||
|
||
/* Emit a stored block if pending_buf will be full: */
|
||
var max_start = s.block_start + max_block_size;
|
||
|
||
if (s.strstart === 0 || s.strstart >= max_start) {
|
||
/* strstart == 0 is possible when wraparound on 16-bit machine */
|
||
s.lookahead = s.strstart - max_start;
|
||
s.strstart = max_start;
|
||
/*** FLUSH_BLOCK(s, 0); ***/
|
||
flush_block_only(s, false);
|
||
if (s.strm.avail_out === 0) {
|
||
return BS_NEED_MORE;
|
||
}
|
||
/***/
|
||
|
||
|
||
}
|
||
/* Flush if we may have to slide, otherwise block_start may become
|
||
* negative and the data will be gone:
|
||
*/
|
||
if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) {
|
||
/*** FLUSH_BLOCK(s, 0); ***/
|
||
flush_block_only(s, false);
|
||
if (s.strm.avail_out === 0) {
|
||
return BS_NEED_MORE;
|
||
}
|
||
/***/
|
||
}
|
||
}
|
||
|
||
s.insert = 0;
|
||
|
||
if (flush === Z_FINISH) {
|
||
/*** FLUSH_BLOCK(s, 1); ***/
|
||
flush_block_only(s, true);
|
||
if (s.strm.avail_out === 0) {
|
||
return BS_FINISH_STARTED;
|
||
}
|
||
/***/
|
||
return BS_FINISH_DONE;
|
||
}
|
||
|
||
if (s.strstart > s.block_start) {
|
||
/*** FLUSH_BLOCK(s, 0); ***/
|
||
flush_block_only(s, false);
|
||
if (s.strm.avail_out === 0) {
|
||
return BS_NEED_MORE;
|
||
}
|
||
/***/
|
||
}
|
||
|
||
return BS_NEED_MORE;
|
||
}
|
||
|
||
/* ===========================================================================
|
||
* Compress as much as possible from the input stream, return the current
|
||
* block state.
|
||
* This function does not perform lazy evaluation of matches and inserts
|
||
* new strings in the dictionary only for unmatched strings or for short
|
||
* matches. It is used only for the fast compression options.
|
||
*/
|
||
function deflate_fast(s, flush) {
|
||
var hash_head; /* head of the hash chain */
|
||
var bflush; /* set if current block must be flushed */
|
||
|
||
for (;;) {
|
||
/* Make sure that we always have enough lookahead, except
|
||
* at the end of the input file. We need MAX_MATCH bytes
|
||
* for the next match, plus MIN_MATCH bytes to insert the
|
||
* string following the next match.
|
||
*/
|
||
if (s.lookahead < MIN_LOOKAHEAD) {
|
||
fill_window(s);
|
||
if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
|
||
return BS_NEED_MORE;
|
||
}
|
||
if (s.lookahead === 0) {
|
||
break; /* flush the current block */
|
||
}
|
||
}
|
||
|
||
/* Insert the string window[strstart .. strstart+2] in the
|
||
* dictionary, and set hash_head to the head of the hash chain:
|
||
*/
|
||
hash_head = 0/*NIL*/;
|
||
if (s.lookahead >= MIN_MATCH) {
|
||
/*** INSERT_STRING(s, s.strstart, hash_head); ***/
|
||
s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
|
||
hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
|
||
s.head[s.ins_h] = s.strstart;
|
||
/***/
|
||
}
|
||
|
||
/* Find the longest match, discarding those <= prev_length.
|
||
* At this point we have always match_length < MIN_MATCH
|
||
*/
|
||
if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) {
|
||
/* To simplify the code, we prevent matches with the string
|
||
* of window index 0 (in particular we have to avoid a match
|
||
* of the string with itself at the start of the input file).
|
||
*/
|
||
s.match_length = longest_match(s, hash_head);
|
||
/* longest_match() sets match_start */
|
||
}
|
||
if (s.match_length >= MIN_MATCH) {
|
||
// check_match(s, s.strstart, s.match_start, s.match_length); // for debug only
|
||
|
||
/*** _tr_tally_dist(s, s.strstart - s.match_start,
|
||
s.match_length - MIN_MATCH, bflush); ***/
|
||
bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH);
|
||
|
||
s.lookahead -= s.match_length;
|
||
|
||
/* Insert new strings in the hash table only if the match length
|
||
* is not too large. This saves time but degrades compression.
|
||
*/
|
||
if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) {
|
||
s.match_length--; /* string at strstart already in table */
|
||
do {
|
||
s.strstart++;
|
||
/*** INSERT_STRING(s, s.strstart, hash_head); ***/
|
||
s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
|
||
hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
|
||
s.head[s.ins_h] = s.strstart;
|
||
/***/
|
||
/* strstart never exceeds WSIZE-MAX_MATCH, so there are
|
||
* always MIN_MATCH bytes ahead.
|
||
*/
|
||
} while (--s.match_length !== 0);
|
||
s.strstart++;
|
||
} else
|
||
{
|
||
s.strstart += s.match_length;
|
||
s.match_length = 0;
|
||
s.ins_h = s.window[s.strstart];
|
||
/* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */
|
||
s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask;
|
||
|
||
//#if MIN_MATCH != 3
|
||
// Call UPDATE_HASH() MIN_MATCH-3 more times
|
||
//#endif
|
||
/* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
|
||
* matter since it will be recomputed at next deflate call.
|
||
*/
|
||
}
|
||
} else {
|
||
/* No match, output a literal byte */
|
||
//Tracevv((stderr,"%c", s.window[s.strstart]));
|
||
/*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
|
||
bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
|
||
|
||
s.lookahead--;
|
||
s.strstart++;
|
||
}
|
||
if (bflush) {
|
||
/*** FLUSH_BLOCK(s, 0); ***/
|
||
flush_block_only(s, false);
|
||
if (s.strm.avail_out === 0) {
|
||
return BS_NEED_MORE;
|
||
}
|
||
/***/
|
||
}
|
||
}
|
||
s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1);
|
||
if (flush === Z_FINISH) {
|
||
/*** FLUSH_BLOCK(s, 1); ***/
|
||
flush_block_only(s, true);
|
||
if (s.strm.avail_out === 0) {
|
||
return BS_FINISH_STARTED;
|
||
}
|
||
/***/
|
||
return BS_FINISH_DONE;
|
||
}
|
||
if (s.last_lit) {
|
||
/*** FLUSH_BLOCK(s, 0); ***/
|
||
flush_block_only(s, false);
|
||
if (s.strm.avail_out === 0) {
|
||
return BS_NEED_MORE;
|
||
}
|
||
/***/
|
||
}
|
||
return BS_BLOCK_DONE;
|
||
}
|
||
|
||
/* ===========================================================================
|
||
* Same as above, but achieves better compression. We use a lazy
|
||
* evaluation for matches: a match is finally adopted only if there is
|
||
* no better match at the next window position.
|
||
*/
|
||
function deflate_slow(s, flush) {
|
||
var hash_head; /* head of hash chain */
|
||
var bflush; /* set if current block must be flushed */
|
||
|
||
var max_insert;
|
||
|
||
/* Process the input block. */
|
||
for (;;) {
|
||
/* Make sure that we always have enough lookahead, except
|
||
* at the end of the input file. We need MAX_MATCH bytes
|
||
* for the next match, plus MIN_MATCH bytes to insert the
|
||
* string following the next match.
|
||
*/
|
||
if (s.lookahead < MIN_LOOKAHEAD) {
|
||
fill_window(s);
|
||
if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
|
||
return BS_NEED_MORE;
|
||
}
|
||
if (s.lookahead === 0) { break; } /* flush the current block */
|
||
}
|
||
|
||
/* Insert the string window[strstart .. strstart+2] in the
|
||
* dictionary, and set hash_head to the head of the hash chain:
|
||
*/
|
||
hash_head = 0/*NIL*/;
|
||
if (s.lookahead >= MIN_MATCH) {
|
||
/*** INSERT_STRING(s, s.strstart, hash_head); ***/
|
||
s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
|
||
hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
|
||
s.head[s.ins_h] = s.strstart;
|
||
/***/
|
||
}
|
||
|
||
/* Find the longest match, discarding those <= prev_length.
|
||
*/
|
||
s.prev_length = s.match_length;
|
||
s.prev_match = s.match_start;
|
||
s.match_length = MIN_MATCH - 1;
|
||
|
||
if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match &&
|
||
s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) {
|
||
/* To simplify the code, we prevent matches with the string
|
||
* of window index 0 (in particular we have to avoid a match
|
||
* of the string with itself at the start of the input file).
|
||
*/
|
||
s.match_length = longest_match(s, hash_head);
|
||
/* longest_match() sets match_start */
|
||
|
||
if (s.match_length <= 5 &&
|
||
(s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) {
|
||
|
||
/* If prev_match is also MIN_MATCH, match_start is garbage
|
||
* but we will ignore the current match anyway.
|
||
*/
|
||
s.match_length = MIN_MATCH - 1;
|
||
}
|
||
}
|
||
/* If there was a match at the previous step and the current
|
||
* match is not better, output the previous match:
|
||
*/
|
||
if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) {
|
||
max_insert = s.strstart + s.lookahead - MIN_MATCH;
|
||
/* Do not insert strings in hash table beyond this. */
|
||
|
||
//check_match(s, s.strstart-1, s.prev_match, s.prev_length);
|
||
|
||
/***_tr_tally_dist(s, s.strstart - 1 - s.prev_match,
|
||
s.prev_length - MIN_MATCH, bflush);***/
|
||
bflush = trees._tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH);
|
||
/* Insert in hash table all strings up to the end of the match.
|
||
* strstart-1 and strstart are already inserted. If there is not
|
||
* enough lookahead, the last two strings are not inserted in
|
||
* the hash table.
|
||
*/
|
||
s.lookahead -= s.prev_length - 1;
|
||
s.prev_length -= 2;
|
||
do {
|
||
if (++s.strstart <= max_insert) {
|
||
/*** INSERT_STRING(s, s.strstart, hash_head); ***/
|
||
s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
|
||
hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
|
||
s.head[s.ins_h] = s.strstart;
|
||
/***/
|
||
}
|
||
} while (--s.prev_length !== 0);
|
||
s.match_available = 0;
|
||
s.match_length = MIN_MATCH - 1;
|
||
s.strstart++;
|
||
|
||
if (bflush) {
|
||
/*** FLUSH_BLOCK(s, 0); ***/
|
||
flush_block_only(s, false);
|
||
if (s.strm.avail_out === 0) {
|
||
return BS_NEED_MORE;
|
||
}
|
||
/***/
|
||
}
|
||
|
||
} else if (s.match_available) {
|
||
/* If there was no match at the previous position, output a
|
||
* single literal. If there was a match but the current match
|
||
* is longer, truncate the previous match to a single literal.
|
||
*/
|
||
//Tracevv((stderr,"%c", s->window[s->strstart-1]));
|
||
/*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
|
||
bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);
|
||
|
||
if (bflush) {
|
||
/*** FLUSH_BLOCK_ONLY(s, 0) ***/
|
||
flush_block_only(s, false);
|
||
/***/
|
||
}
|
||
s.strstart++;
|
||
s.lookahead--;
|
||
if (s.strm.avail_out === 0) {
|
||
return BS_NEED_MORE;
|
||
}
|
||
} else {
|
||
/* There is no previous match to compare with, wait for
|
||
* the next step to decide.
|
||
*/
|
||
s.match_available = 1;
|
||
s.strstart++;
|
||
s.lookahead--;
|
||
}
|
||
}
|
||
//Assert (flush != Z_NO_FLUSH, "no flush?");
|
||
if (s.match_available) {
|
||
//Tracevv((stderr,"%c", s->window[s->strstart-1]));
|
||
/*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
|
||
bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);
|
||
|
||
s.match_available = 0;
|
||
}
|
||
s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1;
|
||
if (flush === Z_FINISH) {
|
||
/*** FLUSH_BLOCK(s, 1); ***/
|
||
flush_block_only(s, true);
|
||
if (s.strm.avail_out === 0) {
|
||
return BS_FINISH_STARTED;
|
||
}
|
||
/***/
|
||
return BS_FINISH_DONE;
|
||
}
|
||
if (s.last_lit) {
|
||
/*** FLUSH_BLOCK(s, 0); ***/
|
||
flush_block_only(s, false);
|
||
if (s.strm.avail_out === 0) {
|
||
return BS_NEED_MORE;
|
||
}
|
||
/***/
|
||
}
|
||
|
||
return BS_BLOCK_DONE;
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* For Z_RLE, simply look for runs of bytes, generate matches only of distance
|
||
* one. Do not maintain a hash table. (It will be regenerated if this run of
|
||
* deflate switches away from Z_RLE.)
|
||
*/
|
||
function deflate_rle(s, flush) {
|
||
var bflush; /* set if current block must be flushed */
|
||
var prev; /* byte at distance one to match */
|
||
var scan, strend; /* scan goes up to strend for length of run */
|
||
|
||
var _win = s.window;
|
||
|
||
for (;;) {
|
||
/* Make sure that we always have enough lookahead, except
|
||
* at the end of the input file. We need MAX_MATCH bytes
|
||
* for the longest run, plus one for the unrolled loop.
|
||
*/
|
||
if (s.lookahead <= MAX_MATCH) {
|
||
fill_window(s);
|
||
if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) {
|
||
return BS_NEED_MORE;
|
||
}
|
||
if (s.lookahead === 0) { break; } /* flush the current block */
|
||
}
|
||
|
||
/* See how many times the previous byte repeats */
|
||
s.match_length = 0;
|
||
if (s.lookahead >= MIN_MATCH && s.strstart > 0) {
|
||
scan = s.strstart - 1;
|
||
prev = _win[scan];
|
||
if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) {
|
||
strend = s.strstart + MAX_MATCH;
|
||
do {
|
||
/*jshint noempty:false*/
|
||
} while (prev === _win[++scan] && prev === _win[++scan] &&
|
||
prev === _win[++scan] && prev === _win[++scan] &&
|
||
prev === _win[++scan] && prev === _win[++scan] &&
|
||
prev === _win[++scan] && prev === _win[++scan] &&
|
||
scan < strend);
|
||
s.match_length = MAX_MATCH - (strend - scan);
|
||
if (s.match_length > s.lookahead) {
|
||
s.match_length = s.lookahead;
|
||
}
|
||
}
|
||
//Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
|
||
}
|
||
|
||
/* Emit match if have run of MIN_MATCH or longer, else emit literal */
|
||
if (s.match_length >= MIN_MATCH) {
|
||
//check_match(s, s.strstart, s.strstart - 1, s.match_length);
|
||
|
||
/*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/
|
||
bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH);
|
||
|
||
s.lookahead -= s.match_length;
|
||
s.strstart += s.match_length;
|
||
s.match_length = 0;
|
||
} else {
|
||
/* No match, output a literal byte */
|
||
//Tracevv((stderr,"%c", s->window[s->strstart]));
|
||
/*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
|
||
bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
|
||
|
||
s.lookahead--;
|
||
s.strstart++;
|
||
}
|
||
if (bflush) {
|
||
/*** FLUSH_BLOCK(s, 0); ***/
|
||
flush_block_only(s, false);
|
||
if (s.strm.avail_out === 0) {
|
||
return BS_NEED_MORE;
|
||
}
|
||
/***/
|
||
}
|
||
}
|
||
s.insert = 0;
|
||
if (flush === Z_FINISH) {
|
||
/*** FLUSH_BLOCK(s, 1); ***/
|
||
flush_block_only(s, true);
|
||
if (s.strm.avail_out === 0) {
|
||
return BS_FINISH_STARTED;
|
||
}
|
||
/***/
|
||
return BS_FINISH_DONE;
|
||
}
|
||
if (s.last_lit) {
|
||
/*** FLUSH_BLOCK(s, 0); ***/
|
||
flush_block_only(s, false);
|
||
if (s.strm.avail_out === 0) {
|
||
return BS_NEED_MORE;
|
||
}
|
||
/***/
|
||
}
|
||
return BS_BLOCK_DONE;
|
||
}
|
||
|
||
/* ===========================================================================
|
||
* For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table.
|
||
* (It will be regenerated if this run of deflate switches away from Huffman.)
|
||
*/
|
||
function deflate_huff(s, flush) {
|
||
var bflush; /* set if current block must be flushed */
|
||
|
||
for (;;) {
|
||
/* Make sure that we have a literal to write. */
|
||
if (s.lookahead === 0) {
|
||
fill_window(s);
|
||
if (s.lookahead === 0) {
|
||
if (flush === Z_NO_FLUSH) {
|
||
return BS_NEED_MORE;
|
||
}
|
||
break; /* flush the current block */
|
||
}
|
||
}
|
||
|
||
/* Output a literal byte */
|
||
s.match_length = 0;
|
||
//Tracevv((stderr,"%c", s->window[s->strstart]));
|
||
/*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
|
||
bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
|
||
s.lookahead--;
|
||
s.strstart++;
|
||
if (bflush) {
|
||
/*** FLUSH_BLOCK(s, 0); ***/
|
||
flush_block_only(s, false);
|
||
if (s.strm.avail_out === 0) {
|
||
return BS_NEED_MORE;
|
||
}
|
||
/***/
|
||
}
|
||
}
|
||
s.insert = 0;
|
||
if (flush === Z_FINISH) {
|
||
/*** FLUSH_BLOCK(s, 1); ***/
|
||
flush_block_only(s, true);
|
||
if (s.strm.avail_out === 0) {
|
||
return BS_FINISH_STARTED;
|
||
}
|
||
/***/
|
||
return BS_FINISH_DONE;
|
||
}
|
||
if (s.last_lit) {
|
||
/*** FLUSH_BLOCK(s, 0); ***/
|
||
flush_block_only(s, false);
|
||
if (s.strm.avail_out === 0) {
|
||
return BS_NEED_MORE;
|
||
}
|
||
/***/
|
||
}
|
||
return BS_BLOCK_DONE;
|
||
}
|
||
|
||
/* Values for max_lazy_match, good_match and max_chain_length, depending on
|
||
* the desired pack level (0..9). The values given below have been tuned to
|
||
* exclude worst case performance for pathological files. Better values may be
|
||
* found for specific files.
|
||
*/
|
||
function Config(good_length, max_lazy, nice_length, max_chain, func) {
|
||
this.good_length = good_length;
|
||
this.max_lazy = max_lazy;
|
||
this.nice_length = nice_length;
|
||
this.max_chain = max_chain;
|
||
this.func = func;
|
||
}
|
||
|
||
var configuration_table;
|
||
|
||
configuration_table = [
|
||
/* good lazy nice chain */
|
||
new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */
|
||
new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */
|
||
new Config(4, 5, 16, 8, deflate_fast), /* 2 */
|
||
new Config(4, 6, 32, 32, deflate_fast), /* 3 */
|
||
|
||
new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */
|
||
new Config(8, 16, 32, 32, deflate_slow), /* 5 */
|
||
new Config(8, 16, 128, 128, deflate_slow), /* 6 */
|
||
new Config(8, 32, 128, 256, deflate_slow), /* 7 */
|
||
new Config(32, 128, 258, 1024, deflate_slow), /* 8 */
|
||
new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */
|
||
];
|
||
|
||
|
||
/* ===========================================================================
|
||
* Initialize the "longest match" routines for a new zlib stream
|
||
*/
|
||
function lm_init(s) {
|
||
s.window_size = 2 * s.w_size;
|
||
|
||
/*** CLEAR_HASH(s); ***/
|
||
zero(s.head); // Fill with NIL (= 0);
|
||
|
||
/* Set the default configuration parameters:
|
||
*/
|
||
s.max_lazy_match = configuration_table[s.level].max_lazy;
|
||
s.good_match = configuration_table[s.level].good_length;
|
||
s.nice_match = configuration_table[s.level].nice_length;
|
||
s.max_chain_length = configuration_table[s.level].max_chain;
|
||
|
||
s.strstart = 0;
|
||
s.block_start = 0;
|
||
s.lookahead = 0;
|
||
s.insert = 0;
|
||
s.match_length = s.prev_length = MIN_MATCH - 1;
|
||
s.match_available = 0;
|
||
s.ins_h = 0;
|
||
}
|
||
|
||
|
||
function DeflateState() {
|
||
this.strm = null; /* pointer back to this zlib stream */
|
||
this.status = 0; /* as the name implies */
|
||
this.pending_buf = null; /* output still pending */
|
||
this.pending_buf_size = 0; /* size of pending_buf */
|
||
this.pending_out = 0; /* next pending byte to output to the stream */
|
||
this.pending = 0; /* nb of bytes in the pending buffer */
|
||
this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */
|
||
this.gzhead = null; /* gzip header information to write */
|
||
this.gzindex = 0; /* where in extra, name, or comment */
|
||
this.method = Z_DEFLATED; /* can only be DEFLATED */
|
||
this.last_flush = -1; /* value of flush param for previous deflate call */
|
||
|
||
this.w_size = 0; /* LZ77 window size (32K by default) */
|
||
this.w_bits = 0; /* log2(w_size) (8..16) */
|
||
this.w_mask = 0; /* w_size - 1 */
|
||
|
||
this.window = null;
|
||
/* Sliding window. Input bytes are read into the second half of the window,
|
||
* and move to the first half later to keep a dictionary of at least wSize
|
||
* bytes. With this organization, matches are limited to a distance of
|
||
* wSize-MAX_MATCH bytes, but this ensures that IO is always
|
||
* performed with a length multiple of the block size.
|
||
*/
|
||
|
||
this.window_size = 0;
|
||
/* Actual size of window: 2*wSize, except when the user input buffer
|
||
* is directly used as sliding window.
|
||
*/
|
||
|
||
this.prev = null;
|
||
/* Link to older string with same hash index. To limit the size of this
|
||
* array to 64K, this link is maintained only for the last 32K strings.
|
||
* An index in this array is thus a window index modulo 32K.
|
||
*/
|
||
|
||
this.head = null; /* Heads of the hash chains or NIL. */
|
||
|
||
this.ins_h = 0; /* hash index of string to be inserted */
|
||
this.hash_size = 0; /* number of elements in hash table */
|
||
this.hash_bits = 0; /* log2(hash_size) */
|
||
this.hash_mask = 0; /* hash_size-1 */
|
||
|
||
this.hash_shift = 0;
|
||
/* Number of bits by which ins_h must be shifted at each input
|
||
* step. It must be such that after MIN_MATCH steps, the oldest
|
||
* byte no longer takes part in the hash key, that is:
|
||
* hash_shift * MIN_MATCH >= hash_bits
|
||
*/
|
||
|
||
this.block_start = 0;
|
||
/* Window position at the beginning of the current output block. Gets
|
||
* negative when the window is moved backwards.
|
||
*/
|
||
|
||
this.match_length = 0; /* length of best match */
|
||
this.prev_match = 0; /* previous match */
|
||
this.match_available = 0; /* set if previous match exists */
|
||
this.strstart = 0; /* start of string to insert */
|
||
this.match_start = 0; /* start of matching string */
|
||
this.lookahead = 0; /* number of valid bytes ahead in window */
|
||
|
||
this.prev_length = 0;
|
||
/* Length of the best match at previous step. Matches not greater than this
|
||
* are discarded. This is used in the lazy match evaluation.
|
||
*/
|
||
|
||
this.max_chain_length = 0;
|
||
/* To speed up deflation, hash chains are never searched beyond this
|
||
* length. A higher limit improves compression ratio but degrades the
|
||
* speed.
|
||
*/
|
||
|
||
this.max_lazy_match = 0;
|
||
/* Attempt to find a better match only when the current match is strictly
|
||
* smaller than this value. This mechanism is used only for compression
|
||
* levels >= 4.
|
||
*/
|
||
// That's alias to max_lazy_match, don't use directly
|
||
//this.max_insert_length = 0;
|
||
/* Insert new strings in the hash table only if the match length is not
|
||
* greater than this length. This saves time but degrades compression.
|
||
* max_insert_length is used only for compression levels <= 3.
|
||
*/
|
||
|
||
this.level = 0; /* compression level (1..9) */
|
||
this.strategy = 0; /* favor or force Huffman coding*/
|
||
|
||
this.good_match = 0;
|
||
/* Use a faster search when the previous match is longer than this */
|
||
|
||
this.nice_match = 0; /* Stop searching when current match exceeds this */
|
||
|
||
/* used by trees.c: */
|
||
|
||
/* Didn't use ct_data typedef below to suppress compiler warning */
|
||
|
||
// struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
|
||
// struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
|
||
// struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
|
||
|
||
// Use flat array of DOUBLE size, with interleaved fata,
|
||
// because JS does not support effective
|
||
this.dyn_ltree = new utils.Buf16(HEAP_SIZE * 2);
|
||
this.dyn_dtree = new utils.Buf16((2 * D_CODES + 1) * 2);
|
||
this.bl_tree = new utils.Buf16((2 * BL_CODES + 1) * 2);
|
||
zero(this.dyn_ltree);
|
||
zero(this.dyn_dtree);
|
||
zero(this.bl_tree);
|
||
|
||
this.l_desc = null; /* desc. for literal tree */
|
||
this.d_desc = null; /* desc. for distance tree */
|
||
this.bl_desc = null; /* desc. for bit length tree */
|
||
|
||
//ush bl_count[MAX_BITS+1];
|
||
this.bl_count = new utils.Buf16(MAX_BITS + 1);
|
||
/* number of codes at each bit length for an optimal tree */
|
||
|
||
//int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
|
||
this.heap = new utils.Buf16(2 * L_CODES + 1); /* heap used to build the Huffman trees */
|
||
zero(this.heap);
|
||
|
||
this.heap_len = 0; /* number of elements in the heap */
|
||
this.heap_max = 0; /* element of largest frequency */
|
||
/* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
|
||
* The same heap array is used to build all trees.
|
||
*/
|
||
|
||
this.depth = new utils.Buf16(2 * L_CODES + 1); //uch depth[2*L_CODES+1];
|
||
zero(this.depth);
|
||
/* Depth of each subtree used as tie breaker for trees of equal frequency
|
||
*/
|
||
|
||
this.l_buf = 0; /* buffer index for literals or lengths */
|
||
|
||
this.lit_bufsize = 0;
|
||
/* Size of match buffer for literals/lengths. There are 4 reasons for
|
||
* limiting lit_bufsize to 64K:
|
||
* - frequencies can be kept in 16 bit counters
|
||
* - if compression is not successful for the first block, all input
|
||
* data is still in the window so we can still emit a stored block even
|
||
* when input comes from standard input. (This can also be done for
|
||
* all blocks if lit_bufsize is not greater than 32K.)
|
||
* - if compression is not successful for a file smaller than 64K, we can
|
||
* even emit a stored file instead of a stored block (saving 5 bytes).
|
||
* This is applicable only for zip (not gzip or zlib).
|
||
* - creating new Huffman trees less frequently may not provide fast
|
||
* adaptation to changes in the input data statistics. (Take for
|
||
* example a binary file with poorly compressible code followed by
|
||
* a highly compressible string table.) Smaller buffer sizes give
|
||
* fast adaptation but have of course the overhead of transmitting
|
||
* trees more frequently.
|
||
* - I can't count above 4
|
||
*/
|
||
|
||
this.last_lit = 0; /* running index in l_buf */
|
||
|
||
this.d_buf = 0;
|
||
/* Buffer index for distances. To simplify the code, d_buf and l_buf have
|
||
* the same number of elements. To use different lengths, an extra flag
|
||
* array would be necessary.
|
||
*/
|
||
|
||
this.opt_len = 0; /* bit length of current block with optimal trees */
|
||
this.static_len = 0; /* bit length of current block with static trees */
|
||
this.matches = 0; /* number of string matches in current block */
|
||
this.insert = 0; /* bytes at end of window left to insert */
|
||
|
||
|
||
this.bi_buf = 0;
|
||
/* Output buffer. bits are inserted starting at the bottom (least
|
||
* significant bits).
|
||
*/
|
||
this.bi_valid = 0;
|
||
/* Number of valid bits in bi_buf. All bits above the last valid bit
|
||
* are always zero.
|
||
*/
|
||
|
||
// Used for window memory init. We safely ignore it for JS. That makes
|
||
// sense only for pointers and memory check tools.
|
||
//this.high_water = 0;
|
||
/* High water mark offset in window for initialized bytes -- bytes above
|
||
* this are set to zero in order to avoid memory check warnings when
|
||
* longest match routines access bytes past the input. This is then
|
||
* updated to the new high water mark.
|
||
*/
|
||
}
|
||
|
||
|
||
function deflateResetKeep(strm) {
|
||
var s;
|
||
|
||
if (!strm || !strm.state) {
|
||
return err(strm, Z_STREAM_ERROR);
|
||
}
|
||
|
||
strm.total_in = strm.total_out = 0;
|
||
strm.data_type = Z_UNKNOWN;
|
||
|
||
s = strm.state;
|
||
s.pending = 0;
|
||
s.pending_out = 0;
|
||
|
||
if (s.wrap < 0) {
|
||
s.wrap = -s.wrap;
|
||
/* was made negative by deflate(..., Z_FINISH); */
|
||
}
|
||
s.status = (s.wrap ? INIT_STATE : BUSY_STATE);
|
||
strm.adler = (s.wrap === 2) ?
|
||
0 // crc32(0, Z_NULL, 0)
|
||
:
|
||
1; // adler32(0, Z_NULL, 0)
|
||
s.last_flush = Z_NO_FLUSH;
|
||
trees._tr_init(s);
|
||
return Z_OK;
|
||
}
|
||
|
||
|
||
function deflateReset(strm) {
|
||
var ret = deflateResetKeep(strm);
|
||
if (ret === Z_OK) {
|
||
lm_init(strm.state);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
|
||
function deflateSetHeader(strm, head) {
|
||
if (!strm || !strm.state) { return Z_STREAM_ERROR; }
|
||
if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; }
|
||
strm.state.gzhead = head;
|
||
return Z_OK;
|
||
}
|
||
|
||
|
||
function deflateInit2(strm, level, method, windowBits, memLevel, strategy) {
|
||
if (!strm) { // === Z_NULL
|
||
return Z_STREAM_ERROR;
|
||
}
|
||
var wrap = 1;
|
||
|
||
if (level === Z_DEFAULT_COMPRESSION) {
|
||
level = 6;
|
||
}
|
||
|
||
if (windowBits < 0) { /* suppress zlib wrapper */
|
||
wrap = 0;
|
||
windowBits = -windowBits;
|
||
}
|
||
|
||
else if (windowBits > 15) {
|
||
wrap = 2; /* write gzip wrapper instead */
|
||
windowBits -= 16;
|
||
}
|
||
|
||
|
||
if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED ||
|
||
windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
|
||
strategy < 0 || strategy > Z_FIXED) {
|
||
return err(strm, Z_STREAM_ERROR);
|
||
}
|
||
|
||
|
||
if (windowBits === 8) {
|
||
windowBits = 9;
|
||
}
|
||
/* until 256-byte window bug fixed */
|
||
|
||
var s = new DeflateState();
|
||
|
||
strm.state = s;
|
||
s.strm = strm;
|
||
|
||
s.wrap = wrap;
|
||
s.gzhead = null;
|
||
s.w_bits = windowBits;
|
||
s.w_size = 1 << s.w_bits;
|
||
s.w_mask = s.w_size - 1;
|
||
|
||
s.hash_bits = memLevel + 7;
|
||
s.hash_size = 1 << s.hash_bits;
|
||
s.hash_mask = s.hash_size - 1;
|
||
s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH);
|
||
|
||
s.window = new utils.Buf8(s.w_size * 2);
|
||
s.head = new utils.Buf16(s.hash_size);
|
||
s.prev = new utils.Buf16(s.w_size);
|
||
|
||
// Don't need mem init magic for JS.
|
||
//s.high_water = 0; /* nothing written to s->window yet */
|
||
|
||
s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
|
||
|
||
s.pending_buf_size = s.lit_bufsize * 4;
|
||
|
||
//overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
|
||
//s->pending_buf = (uchf *) overlay;
|
||
s.pending_buf = new utils.Buf8(s.pending_buf_size);
|
||
|
||
// It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`)
|
||
//s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
|
||
s.d_buf = 1 * s.lit_bufsize;
|
||
|
||
//s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
|
||
s.l_buf = (1 + 2) * s.lit_bufsize;
|
||
|
||
s.level = level;
|
||
s.strategy = strategy;
|
||
s.method = method;
|
||
|
||
return deflateReset(strm);
|
||
}
|
||
|
||
function deflateInit(strm, level) {
|
||
return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
|
||
}
|
||
|
||
|
||
function deflate(strm, flush) {
|
||
var old_flush, s;
|
||
var beg, val; // for gzip header write only
|
||
|
||
if (!strm || !strm.state ||
|
||
flush > Z_BLOCK || flush < 0) {
|
||
return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR;
|
||
}
|
||
|
||
s = strm.state;
|
||
|
||
if (!strm.output ||
|
||
(!strm.input && strm.avail_in !== 0) ||
|
||
(s.status === FINISH_STATE && flush !== Z_FINISH)) {
|
||
return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR);
|
||
}
|
||
|
||
s.strm = strm; /* just in case */
|
||
old_flush = s.last_flush;
|
||
s.last_flush = flush;
|
||
|
||
/* Write the header */
|
||
if (s.status === INIT_STATE) {
|
||
|
||
if (s.wrap === 2) { // GZIP header
|
||
strm.adler = 0; //crc32(0L, Z_NULL, 0);
|
||
put_byte(s, 31);
|
||
put_byte(s, 139);
|
||
put_byte(s, 8);
|
||
if (!s.gzhead) { // s->gzhead == Z_NULL
|
||
put_byte(s, 0);
|
||
put_byte(s, 0);
|
||
put_byte(s, 0);
|
||
put_byte(s, 0);
|
||
put_byte(s, 0);
|
||
put_byte(s, s.level === 9 ? 2 :
|
||
(s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?
|
||
4 : 0));
|
||
put_byte(s, OS_CODE);
|
||
s.status = BUSY_STATE;
|
||
}
|
||
else {
|
||
put_byte(s, (s.gzhead.text ? 1 : 0) +
|
||
(s.gzhead.hcrc ? 2 : 0) +
|
||
(!s.gzhead.extra ? 0 : 4) +
|
||
(!s.gzhead.name ? 0 : 8) +
|
||
(!s.gzhead.comment ? 0 : 16)
|
||
);
|
||
put_byte(s, s.gzhead.time & 0xff);
|
||
put_byte(s, (s.gzhead.time >> 8) & 0xff);
|
||
put_byte(s, (s.gzhead.time >> 16) & 0xff);
|
||
put_byte(s, (s.gzhead.time >> 24) & 0xff);
|
||
put_byte(s, s.level === 9 ? 2 :
|
||
(s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?
|
||
4 : 0));
|
||
put_byte(s, s.gzhead.os & 0xff);
|
||
if (s.gzhead.extra && s.gzhead.extra.length) {
|
||
put_byte(s, s.gzhead.extra.length & 0xff);
|
||
put_byte(s, (s.gzhead.extra.length >> 8) & 0xff);
|
||
}
|
||
if (s.gzhead.hcrc) {
|
||
strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0);
|
||
}
|
||
s.gzindex = 0;
|
||
s.status = EXTRA_STATE;
|
||
}
|
||
}
|
||
else // DEFLATE header
|
||
{
|
||
var header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8;
|
||
var level_flags = -1;
|
||
|
||
if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) {
|
||
level_flags = 0;
|
||
} else if (s.level < 6) {
|
||
level_flags = 1;
|
||
} else if (s.level === 6) {
|
||
level_flags = 2;
|
||
} else {
|
||
level_flags = 3;
|
||
}
|
||
header |= (level_flags << 6);
|
||
if (s.strstart !== 0) { header |= PRESET_DICT; }
|
||
header += 31 - (header % 31);
|
||
|
||
s.status = BUSY_STATE;
|
||
putShortMSB(s, header);
|
||
|
||
/* Save the adler32 of the preset dictionary: */
|
||
if (s.strstart !== 0) {
|
||
putShortMSB(s, strm.adler >>> 16);
|
||
putShortMSB(s, strm.adler & 0xffff);
|
||
}
|
||
strm.adler = 1; // adler32(0L, Z_NULL, 0);
|
||
}
|
||
}
|
||
|
||
//#ifdef GZIP
|
||
if (s.status === EXTRA_STATE) {
|
||
if (s.gzhead.extra/* != Z_NULL*/) {
|
||
beg = s.pending; /* start of bytes to update crc */
|
||
|
||
while (s.gzindex < (s.gzhead.extra.length & 0xffff)) {
|
||
if (s.pending === s.pending_buf_size) {
|
||
if (s.gzhead.hcrc && s.pending > beg) {
|
||
strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
|
||
}
|
||
flush_pending(strm);
|
||
beg = s.pending;
|
||
if (s.pending === s.pending_buf_size) {
|
||
break;
|
||
}
|
||
}
|
||
put_byte(s, s.gzhead.extra[s.gzindex] & 0xff);
|
||
s.gzindex++;
|
||
}
|
||
if (s.gzhead.hcrc && s.pending > beg) {
|
||
strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
|
||
}
|
||
if (s.gzindex === s.gzhead.extra.length) {
|
||
s.gzindex = 0;
|
||
s.status = NAME_STATE;
|
||
}
|
||
}
|
||
else {
|
||
s.status = NAME_STATE;
|
||
}
|
||
}
|
||
if (s.status === NAME_STATE) {
|
||
if (s.gzhead.name/* != Z_NULL*/) {
|
||
beg = s.pending; /* start of bytes to update crc */
|
||
//int val;
|
||
|
||
do {
|
||
if (s.pending === s.pending_buf_size) {
|
||
if (s.gzhead.hcrc && s.pending > beg) {
|
||
strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
|
||
}
|
||
flush_pending(strm);
|
||
beg = s.pending;
|
||
if (s.pending === s.pending_buf_size) {
|
||
val = 1;
|
||
break;
|
||
}
|
||
}
|
||
// JS specific: little magic to add zero terminator to end of string
|
||
if (s.gzindex < s.gzhead.name.length) {
|
||
val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff;
|
||
} else {
|
||
val = 0;
|
||
}
|
||
put_byte(s, val);
|
||
} while (val !== 0);
|
||
|
||
if (s.gzhead.hcrc && s.pending > beg) {
|
||
strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
|
||
}
|
||
if (val === 0) {
|
||
s.gzindex = 0;
|
||
s.status = COMMENT_STATE;
|
||
}
|
||
}
|
||
else {
|
||
s.status = COMMENT_STATE;
|
||
}
|
||
}
|
||
if (s.status === COMMENT_STATE) {
|
||
if (s.gzhead.comment/* != Z_NULL*/) {
|
||
beg = s.pending; /* start of bytes to update crc */
|
||
//int val;
|
||
|
||
do {
|
||
if (s.pending === s.pending_buf_size) {
|
||
if (s.gzhead.hcrc && s.pending > beg) {
|
||
strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
|
||
}
|
||
flush_pending(strm);
|
||
beg = s.pending;
|
||
if (s.pending === s.pending_buf_size) {
|
||
val = 1;
|
||
break;
|
||
}
|
||
}
|
||
// JS specific: little magic to add zero terminator to end of string
|
||
if (s.gzindex < s.gzhead.comment.length) {
|
||
val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff;
|
||
} else {
|
||
val = 0;
|
||
}
|
||
put_byte(s, val);
|
||
} while (val !== 0);
|
||
|
||
if (s.gzhead.hcrc && s.pending > beg) {
|
||
strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
|
||
}
|
||
if (val === 0) {
|
||
s.status = HCRC_STATE;
|
||
}
|
||
}
|
||
else {
|
||
s.status = HCRC_STATE;
|
||
}
|
||
}
|
||
if (s.status === HCRC_STATE) {
|
||
if (s.gzhead.hcrc) {
|
||
if (s.pending + 2 > s.pending_buf_size) {
|
||
flush_pending(strm);
|
||
}
|
||
if (s.pending + 2 <= s.pending_buf_size) {
|
||
put_byte(s, strm.adler & 0xff);
|
||
put_byte(s, (strm.adler >> 8) & 0xff);
|
||
strm.adler = 0; //crc32(0L, Z_NULL, 0);
|
||
s.status = BUSY_STATE;
|
||
}
|
||
}
|
||
else {
|
||
s.status = BUSY_STATE;
|
||
}
|
||
}
|
||
//#endif
|
||
|
||
/* Flush as much pending output as possible */
|
||
if (s.pending !== 0) {
|
||
flush_pending(strm);
|
||
if (strm.avail_out === 0) {
|
||
/* Since avail_out is 0, deflate will be called again with
|
||
* more output space, but possibly with both pending and
|
||
* avail_in equal to zero. There won't be anything to do,
|
||
* but this is not an error situation so make sure we
|
||
* return OK instead of BUF_ERROR at next call of deflate:
|
||
*/
|
||
s.last_flush = -1;
|
||
return Z_OK;
|
||
}
|
||
|
||
/* Make sure there is something to do and avoid duplicate consecutive
|
||
* flushes. For repeated and useless calls with Z_FINISH, we keep
|
||
* returning Z_STREAM_END instead of Z_BUF_ERROR.
|
||
*/
|
||
} else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) &&
|
||
flush !== Z_FINISH) {
|
||
return err(strm, Z_BUF_ERROR);
|
||
}
|
||
|
||
/* User must not provide more input after the first FINISH: */
|
||
if (s.status === FINISH_STATE && strm.avail_in !== 0) {
|
||
return err(strm, Z_BUF_ERROR);
|
||
}
|
||
|
||
/* Start a new block or continue the current one.
|
||
*/
|
||
if (strm.avail_in !== 0 || s.lookahead !== 0 ||
|
||
(flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) {
|
||
var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) :
|
||
(s.strategy === Z_RLE ? deflate_rle(s, flush) :
|
||
configuration_table[s.level].func(s, flush));
|
||
|
||
if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) {
|
||
s.status = FINISH_STATE;
|
||
}
|
||
if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) {
|
||
if (strm.avail_out === 0) {
|
||
s.last_flush = -1;
|
||
/* avoid BUF_ERROR next call, see above */
|
||
}
|
||
return Z_OK;
|
||
/* If flush != Z_NO_FLUSH && avail_out == 0, the next call
|
||
* of deflate should use the same flush parameter to make sure
|
||
* that the flush is complete. So we don't have to output an
|
||
* empty block here, this will be done at next call. This also
|
||
* ensures that for a very small output buffer, we emit at most
|
||
* one empty block.
|
||
*/
|
||
}
|
||
if (bstate === BS_BLOCK_DONE) {
|
||
if (flush === Z_PARTIAL_FLUSH) {
|
||
trees._tr_align(s);
|
||
}
|
||
else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
|
||
|
||
trees._tr_stored_block(s, 0, 0, false);
|
||
/* For a full flush, this empty block will be recognized
|
||
* as a special marker by inflate_sync().
|
||
*/
|
||
if (flush === Z_FULL_FLUSH) {
|
||
/*** CLEAR_HASH(s); ***/ /* forget history */
|
||
zero(s.head); // Fill with NIL (= 0);
|
||
|
||
if (s.lookahead === 0) {
|
||
s.strstart = 0;
|
||
s.block_start = 0;
|
||
s.insert = 0;
|
||
}
|
||
}
|
||
}
|
||
flush_pending(strm);
|
||
if (strm.avail_out === 0) {
|
||
s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */
|
||
return Z_OK;
|
||
}
|
||
}
|
||
}
|
||
//Assert(strm->avail_out > 0, "bug2");
|
||
//if (strm.avail_out <= 0) { throw new Error("bug2");}
|
||
|
||
if (flush !== Z_FINISH) { return Z_OK; }
|
||
if (s.wrap <= 0) { return Z_STREAM_END; }
|
||
|
||
/* Write the trailer */
|
||
if (s.wrap === 2) {
|
||
put_byte(s, strm.adler & 0xff);
|
||
put_byte(s, (strm.adler >> 8) & 0xff);
|
||
put_byte(s, (strm.adler >> 16) & 0xff);
|
||
put_byte(s, (strm.adler >> 24) & 0xff);
|
||
put_byte(s, strm.total_in & 0xff);
|
||
put_byte(s, (strm.total_in >> 8) & 0xff);
|
||
put_byte(s, (strm.total_in >> 16) & 0xff);
|
||
put_byte(s, (strm.total_in >> 24) & 0xff);
|
||
}
|
||
else
|
||
{
|
||
putShortMSB(s, strm.adler >>> 16);
|
||
putShortMSB(s, strm.adler & 0xffff);
|
||
}
|
||
|
||
flush_pending(strm);
|
||
/* If avail_out is zero, the application will call deflate again
|
||
* to flush the rest.
|
||
*/
|
||
if (s.wrap > 0) { s.wrap = -s.wrap; }
|
||
/* write the trailer only once! */
|
||
return s.pending !== 0 ? Z_OK : Z_STREAM_END;
|
||
}
|
||
|
||
function deflateEnd(strm) {
|
||
var status;
|
||
|
||
if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {
|
||
return Z_STREAM_ERROR;
|
||
}
|
||
|
||
status = strm.state.status;
|
||
if (status !== INIT_STATE &&
|
||
status !== EXTRA_STATE &&
|
||
status !== NAME_STATE &&
|
||
status !== COMMENT_STATE &&
|
||
status !== HCRC_STATE &&
|
||
status !== BUSY_STATE &&
|
||
status !== FINISH_STATE
|
||
) {
|
||
return err(strm, Z_STREAM_ERROR);
|
||
}
|
||
|
||
strm.state = null;
|
||
|
||
return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK;
|
||
}
|
||
|
||
|
||
/* =========================================================================
|
||
* Initializes the compression dictionary from the given byte
|
||
* sequence without producing any compressed output.
|
||
*/
|
||
function deflateSetDictionary(strm, dictionary) {
|
||
var dictLength = dictionary.length;
|
||
|
||
var s;
|
||
var str, n;
|
||
var wrap;
|
||
var avail;
|
||
var next;
|
||
var input;
|
||
var tmpDict;
|
||
|
||
if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {
|
||
return Z_STREAM_ERROR;
|
||
}
|
||
|
||
s = strm.state;
|
||
wrap = s.wrap;
|
||
|
||
if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) {
|
||
return Z_STREAM_ERROR;
|
||
}
|
||
|
||
/* when using zlib wrappers, compute Adler-32 for provided dictionary */
|
||
if (wrap === 1) {
|
||
/* adler32(strm->adler, dictionary, dictLength); */
|
||
strm.adler = adler32(strm.adler, dictionary, dictLength, 0);
|
||
}
|
||
|
||
s.wrap = 0; /* avoid computing Adler-32 in read_buf */
|
||
|
||
/* if dictionary would fill window, just replace the history */
|
||
if (dictLength >= s.w_size) {
|
||
if (wrap === 0) { /* already empty otherwise */
|
||
/*** CLEAR_HASH(s); ***/
|
||
zero(s.head); // Fill with NIL (= 0);
|
||
s.strstart = 0;
|
||
s.block_start = 0;
|
||
s.insert = 0;
|
||
}
|
||
/* use the tail */
|
||
// dictionary = dictionary.slice(dictLength - s.w_size);
|
||
tmpDict = new utils.Buf8(s.w_size);
|
||
utils.arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0);
|
||
dictionary = tmpDict;
|
||
dictLength = s.w_size;
|
||
}
|
||
/* insert dictionary into window and hash */
|
||
avail = strm.avail_in;
|
||
next = strm.next_in;
|
||
input = strm.input;
|
||
strm.avail_in = dictLength;
|
||
strm.next_in = 0;
|
||
strm.input = dictionary;
|
||
fill_window(s);
|
||
while (s.lookahead >= MIN_MATCH) {
|
||
str = s.strstart;
|
||
n = s.lookahead - (MIN_MATCH - 1);
|
||
do {
|
||
/* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
|
||
s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
|
||
|
||
s.prev[str & s.w_mask] = s.head[s.ins_h];
|
||
|
||
s.head[s.ins_h] = str;
|
||
str++;
|
||
} while (--n);
|
||
s.strstart = str;
|
||
s.lookahead = MIN_MATCH - 1;
|
||
fill_window(s);
|
||
}
|
||
s.strstart += s.lookahead;
|
||
s.block_start = s.strstart;
|
||
s.insert = s.lookahead;
|
||
s.lookahead = 0;
|
||
s.match_length = s.prev_length = MIN_MATCH - 1;
|
||
s.match_available = 0;
|
||
strm.next_in = next;
|
||
strm.input = input;
|
||
strm.avail_in = avail;
|
||
s.wrap = wrap;
|
||
return Z_OK;
|
||
}
|
||
|
||
|
||
exports.deflateInit = deflateInit;
|
||
exports.deflateInit2 = deflateInit2;
|
||
exports.deflateReset = deflateReset;
|
||
exports.deflateResetKeep = deflateResetKeep;
|
||
exports.deflateSetHeader = deflateSetHeader;
|
||
exports.deflate = deflate;
|
||
exports.deflateEnd = deflateEnd;
|
||
exports.deflateSetDictionary = deflateSetDictionary;
|
||
exports.deflateInfo = 'pako deflate (from Nodeca project)';
|
||
|
||
/* Not implemented
|
||
exports.deflateBound = deflateBound;
|
||
exports.deflateCopy = deflateCopy;
|
||
exports.deflateParams = deflateParams;
|
||
exports.deflatePending = deflatePending;
|
||
exports.deflatePrime = deflatePrime;
|
||
exports.deflateTune = deflateTune;
|
||
*/
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pako/lib/zlib/gzheader.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/pako/lib/zlib/gzheader.js ***!
|
||
\************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||
//
|
||
// This software is provided 'as-is', without any express or implied
|
||
// warranty. In no event will the authors be held liable for any damages
|
||
// arising from the use of this software.
|
||
//
|
||
// Permission is granted to anyone to use this software for any purpose,
|
||
// including commercial applications, and to alter it and redistribute it
|
||
// freely, subject to the following restrictions:
|
||
//
|
||
// 1. The origin of this software must not be misrepresented; you must not
|
||
// claim that you wrote the original software. If you use this software
|
||
// in a product, an acknowledgment in the product documentation would be
|
||
// appreciated but is not required.
|
||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||
// misrepresented as being the original software.
|
||
// 3. This notice may not be removed or altered from any source distribution.
|
||
|
||
function GZheader() {
|
||
/* true if compressed data believed to be text */
|
||
this.text = 0;
|
||
/* modification time */
|
||
this.time = 0;
|
||
/* extra flags (not used when writing a gzip file) */
|
||
this.xflags = 0;
|
||
/* operating system */
|
||
this.os = 0;
|
||
/* pointer to extra field or Z_NULL if none */
|
||
this.extra = null;
|
||
/* extra field length (valid if extra != Z_NULL) */
|
||
this.extra_len = 0; // Actually, we don't need it in JS,
|
||
// but leave for few code modifications
|
||
|
||
//
|
||
// Setup limits is not necessary because in js we should not preallocate memory
|
||
// for inflate use constant limit in 65536 bytes
|
||
//
|
||
|
||
/* space at extra (only when reading header) */
|
||
// this.extra_max = 0;
|
||
/* pointer to zero-terminated file name or Z_NULL */
|
||
this.name = '';
|
||
/* space at name (only when reading header) */
|
||
// this.name_max = 0;
|
||
/* pointer to zero-terminated comment or Z_NULL */
|
||
this.comment = '';
|
||
/* space at comment (only when reading header) */
|
||
// this.comm_max = 0;
|
||
/* true if there was or will be a header crc */
|
||
this.hcrc = 0;
|
||
/* true when done reading gzip header (not used when writing a gzip file) */
|
||
this.done = false;
|
||
}
|
||
|
||
module.exports = GZheader;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pako/lib/zlib/inffast.js":
|
||
/*!***********************************************!*\
|
||
!*** ./node_modules/pako/lib/zlib/inffast.js ***!
|
||
\***********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||
//
|
||
// This software is provided 'as-is', without any express or implied
|
||
// warranty. In no event will the authors be held liable for any damages
|
||
// arising from the use of this software.
|
||
//
|
||
// Permission is granted to anyone to use this software for any purpose,
|
||
// including commercial applications, and to alter it and redistribute it
|
||
// freely, subject to the following restrictions:
|
||
//
|
||
// 1. The origin of this software must not be misrepresented; you must not
|
||
// claim that you wrote the original software. If you use this software
|
||
// in a product, an acknowledgment in the product documentation would be
|
||
// appreciated but is not required.
|
||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||
// misrepresented as being the original software.
|
||
// 3. This notice may not be removed or altered from any source distribution.
|
||
|
||
// See state defs from inflate.js
|
||
var BAD = 30; /* got a data error -- remain here until reset */
|
||
var TYPE = 12; /* i: waiting for type bits, including last-flag bit */
|
||
|
||
/*
|
||
Decode literal, length, and distance codes and write out the resulting
|
||
literal and match bytes until either not enough input or output is
|
||
available, an end-of-block is encountered, or a data error is encountered.
|
||
When large enough input and output buffers are supplied to inflate(), for
|
||
example, a 16K input buffer and a 64K output buffer, more than 95% of the
|
||
inflate execution time is spent in this routine.
|
||
|
||
Entry assumptions:
|
||
|
||
state.mode === LEN
|
||
strm.avail_in >= 6
|
||
strm.avail_out >= 258
|
||
start >= strm.avail_out
|
||
state.bits < 8
|
||
|
||
On return, state.mode is one of:
|
||
|
||
LEN -- ran out of enough output space or enough available input
|
||
TYPE -- reached end of block code, inflate() to interpret next block
|
||
BAD -- error in block data
|
||
|
||
Notes:
|
||
|
||
- The maximum input bits used by a length/distance pair is 15 bits for the
|
||
length code, 5 bits for the length extra, 15 bits for the distance code,
|
||
and 13 bits for the distance extra. This totals 48 bits, or six bytes.
|
||
Therefore if strm.avail_in >= 6, then there is enough input to avoid
|
||
checking for available input while decoding.
|
||
|
||
- The maximum bytes that a single length/distance pair can output is 258
|
||
bytes, which is the maximum length that can be coded. inflate_fast()
|
||
requires strm.avail_out >= 258 for each loop to avoid checking for
|
||
output space.
|
||
*/
|
||
module.exports = function inflate_fast(strm, start) {
|
||
var state;
|
||
var _in; /* local strm.input */
|
||
var last; /* have enough input while in < last */
|
||
var _out; /* local strm.output */
|
||
var beg; /* inflate()'s initial strm.output */
|
||
var end; /* while out < end, enough space available */
|
||
//#ifdef INFLATE_STRICT
|
||
var dmax; /* maximum distance from zlib header */
|
||
//#endif
|
||
var wsize; /* window size or zero if not using window */
|
||
var whave; /* valid bytes in the window */
|
||
var wnext; /* window write index */
|
||
// Use `s_window` instead `window`, avoid conflict with instrumentation tools
|
||
var s_window; /* allocated sliding window, if wsize != 0 */
|
||
var hold; /* local strm.hold */
|
||
var bits; /* local strm.bits */
|
||
var lcode; /* local strm.lencode */
|
||
var dcode; /* local strm.distcode */
|
||
var lmask; /* mask for first level of length codes */
|
||
var dmask; /* mask for first level of distance codes */
|
||
var here; /* retrieved table entry */
|
||
var op; /* code bits, operation, extra bits, or */
|
||
/* window position, window bytes to copy */
|
||
var len; /* match length, unused bytes */
|
||
var dist; /* match distance */
|
||
var from; /* where to copy match from */
|
||
var from_source;
|
||
|
||
|
||
var input, output; // JS specific, because we have no pointers
|
||
|
||
/* copy state to local variables */
|
||
state = strm.state;
|
||
//here = state.here;
|
||
_in = strm.next_in;
|
||
input = strm.input;
|
||
last = _in + (strm.avail_in - 5);
|
||
_out = strm.next_out;
|
||
output = strm.output;
|
||
beg = _out - (start - strm.avail_out);
|
||
end = _out + (strm.avail_out - 257);
|
||
//#ifdef INFLATE_STRICT
|
||
dmax = state.dmax;
|
||
//#endif
|
||
wsize = state.wsize;
|
||
whave = state.whave;
|
||
wnext = state.wnext;
|
||
s_window = state.window;
|
||
hold = state.hold;
|
||
bits = state.bits;
|
||
lcode = state.lencode;
|
||
dcode = state.distcode;
|
||
lmask = (1 << state.lenbits) - 1;
|
||
dmask = (1 << state.distbits) - 1;
|
||
|
||
|
||
/* decode literals and length/distances until end-of-block or not enough
|
||
input data or output space */
|
||
|
||
top:
|
||
do {
|
||
if (bits < 15) {
|
||
hold += input[_in++] << bits;
|
||
bits += 8;
|
||
hold += input[_in++] << bits;
|
||
bits += 8;
|
||
}
|
||
|
||
here = lcode[hold & lmask];
|
||
|
||
dolen:
|
||
for (;;) { // Goto emulation
|
||
op = here >>> 24/*here.bits*/;
|
||
hold >>>= op;
|
||
bits -= op;
|
||
op = (here >>> 16) & 0xff/*here.op*/;
|
||
if (op === 0) { /* literal */
|
||
//Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
|
||
// "inflate: literal '%c'\n" :
|
||
// "inflate: literal 0x%02x\n", here.val));
|
||
output[_out++] = here & 0xffff/*here.val*/;
|
||
}
|
||
else if (op & 16) { /* length base */
|
||
len = here & 0xffff/*here.val*/;
|
||
op &= 15; /* number of extra bits */
|
||
if (op) {
|
||
if (bits < op) {
|
||
hold += input[_in++] << bits;
|
||
bits += 8;
|
||
}
|
||
len += hold & ((1 << op) - 1);
|
||
hold >>>= op;
|
||
bits -= op;
|
||
}
|
||
//Tracevv((stderr, "inflate: length %u\n", len));
|
||
if (bits < 15) {
|
||
hold += input[_in++] << bits;
|
||
bits += 8;
|
||
hold += input[_in++] << bits;
|
||
bits += 8;
|
||
}
|
||
here = dcode[hold & dmask];
|
||
|
||
dodist:
|
||
for (;;) { // goto emulation
|
||
op = here >>> 24/*here.bits*/;
|
||
hold >>>= op;
|
||
bits -= op;
|
||
op = (here >>> 16) & 0xff/*here.op*/;
|
||
|
||
if (op & 16) { /* distance base */
|
||
dist = here & 0xffff/*here.val*/;
|
||
op &= 15; /* number of extra bits */
|
||
if (bits < op) {
|
||
hold += input[_in++] << bits;
|
||
bits += 8;
|
||
if (bits < op) {
|
||
hold += input[_in++] << bits;
|
||
bits += 8;
|
||
}
|
||
}
|
||
dist += hold & ((1 << op) - 1);
|
||
//#ifdef INFLATE_STRICT
|
||
if (dist > dmax) {
|
||
strm.msg = 'invalid distance too far back';
|
||
state.mode = BAD;
|
||
break top;
|
||
}
|
||
//#endif
|
||
hold >>>= op;
|
||
bits -= op;
|
||
//Tracevv((stderr, "inflate: distance %u\n", dist));
|
||
op = _out - beg; /* max distance in output */
|
||
if (dist > op) { /* see if copy from window */
|
||
op = dist - op; /* distance back in window */
|
||
if (op > whave) {
|
||
if (state.sane) {
|
||
strm.msg = 'invalid distance too far back';
|
||
state.mode = BAD;
|
||
break top;
|
||
}
|
||
|
||
// (!) This block is disabled in zlib defaults,
|
||
// don't enable it for binary compatibility
|
||
//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
|
||
// if (len <= op - whave) {
|
||
// do {
|
||
// output[_out++] = 0;
|
||
// } while (--len);
|
||
// continue top;
|
||
// }
|
||
// len -= op - whave;
|
||
// do {
|
||
// output[_out++] = 0;
|
||
// } while (--op > whave);
|
||
// if (op === 0) {
|
||
// from = _out - dist;
|
||
// do {
|
||
// output[_out++] = output[from++];
|
||
// } while (--len);
|
||
// continue top;
|
||
// }
|
||
//#endif
|
||
}
|
||
from = 0; // window index
|
||
from_source = s_window;
|
||
if (wnext === 0) { /* very common case */
|
||
from += wsize - op;
|
||
if (op < len) { /* some from window */
|
||
len -= op;
|
||
do {
|
||
output[_out++] = s_window[from++];
|
||
} while (--op);
|
||
from = _out - dist; /* rest from output */
|
||
from_source = output;
|
||
}
|
||
}
|
||
else if (wnext < op) { /* wrap around window */
|
||
from += wsize + wnext - op;
|
||
op -= wnext;
|
||
if (op < len) { /* some from end of window */
|
||
len -= op;
|
||
do {
|
||
output[_out++] = s_window[from++];
|
||
} while (--op);
|
||
from = 0;
|
||
if (wnext < len) { /* some from start of window */
|
||
op = wnext;
|
||
len -= op;
|
||
do {
|
||
output[_out++] = s_window[from++];
|
||
} while (--op);
|
||
from = _out - dist; /* rest from output */
|
||
from_source = output;
|
||
}
|
||
}
|
||
}
|
||
else { /* contiguous in window */
|
||
from += wnext - op;
|
||
if (op < len) { /* some from window */
|
||
len -= op;
|
||
do {
|
||
output[_out++] = s_window[from++];
|
||
} while (--op);
|
||
from = _out - dist; /* rest from output */
|
||
from_source = output;
|
||
}
|
||
}
|
||
while (len > 2) {
|
||
output[_out++] = from_source[from++];
|
||
output[_out++] = from_source[from++];
|
||
output[_out++] = from_source[from++];
|
||
len -= 3;
|
||
}
|
||
if (len) {
|
||
output[_out++] = from_source[from++];
|
||
if (len > 1) {
|
||
output[_out++] = from_source[from++];
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
from = _out - dist; /* copy direct from output */
|
||
do { /* minimum length is three */
|
||
output[_out++] = output[from++];
|
||
output[_out++] = output[from++];
|
||
output[_out++] = output[from++];
|
||
len -= 3;
|
||
} while (len > 2);
|
||
if (len) {
|
||
output[_out++] = output[from++];
|
||
if (len > 1) {
|
||
output[_out++] = output[from++];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if ((op & 64) === 0) { /* 2nd level distance code */
|
||
here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];
|
||
continue dodist;
|
||
}
|
||
else {
|
||
strm.msg = 'invalid distance code';
|
||
state.mode = BAD;
|
||
break top;
|
||
}
|
||
|
||
break; // need to emulate goto via "continue"
|
||
}
|
||
}
|
||
else if ((op & 64) === 0) { /* 2nd level length code */
|
||
here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];
|
||
continue dolen;
|
||
}
|
||
else if (op & 32) { /* end-of-block */
|
||
//Tracevv((stderr, "inflate: end of block\n"));
|
||
state.mode = TYPE;
|
||
break top;
|
||
}
|
||
else {
|
||
strm.msg = 'invalid literal/length code';
|
||
state.mode = BAD;
|
||
break top;
|
||
}
|
||
|
||
break; // need to emulate goto via "continue"
|
||
}
|
||
} while (_in < last && _out < end);
|
||
|
||
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
|
||
len = bits >> 3;
|
||
_in -= len;
|
||
bits -= len << 3;
|
||
hold &= (1 << bits) - 1;
|
||
|
||
/* update state and return */
|
||
strm.next_in = _in;
|
||
strm.next_out = _out;
|
||
strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last));
|
||
strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end));
|
||
state.hold = hold;
|
||
state.bits = bits;
|
||
return;
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pako/lib/zlib/inflate.js":
|
||
/*!***********************************************!*\
|
||
!*** ./node_modules/pako/lib/zlib/inflate.js ***!
|
||
\***********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||
//
|
||
// This software is provided 'as-is', without any express or implied
|
||
// warranty. In no event will the authors be held liable for any damages
|
||
// arising from the use of this software.
|
||
//
|
||
// Permission is granted to anyone to use this software for any purpose,
|
||
// including commercial applications, and to alter it and redistribute it
|
||
// freely, subject to the following restrictions:
|
||
//
|
||
// 1. The origin of this software must not be misrepresented; you must not
|
||
// claim that you wrote the original software. If you use this software
|
||
// in a product, an acknowledgment in the product documentation would be
|
||
// appreciated but is not required.
|
||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||
// misrepresented as being the original software.
|
||
// 3. This notice may not be removed or altered from any source distribution.
|
||
|
||
var utils = __webpack_require__(/*! ../utils/common */ "./node_modules/pako/lib/utils/common.js");
|
||
var adler32 = __webpack_require__(/*! ./adler32 */ "./node_modules/pako/lib/zlib/adler32.js");
|
||
var crc32 = __webpack_require__(/*! ./crc32 */ "./node_modules/pako/lib/zlib/crc32.js");
|
||
var inflate_fast = __webpack_require__(/*! ./inffast */ "./node_modules/pako/lib/zlib/inffast.js");
|
||
var inflate_table = __webpack_require__(/*! ./inftrees */ "./node_modules/pako/lib/zlib/inftrees.js");
|
||
|
||
var CODES = 0;
|
||
var LENS = 1;
|
||
var DISTS = 2;
|
||
|
||
/* Public constants ==========================================================*/
|
||
/* ===========================================================================*/
|
||
|
||
|
||
/* Allowed flush values; see deflate() and inflate() below for details */
|
||
//var Z_NO_FLUSH = 0;
|
||
//var Z_PARTIAL_FLUSH = 1;
|
||
//var Z_SYNC_FLUSH = 2;
|
||
//var Z_FULL_FLUSH = 3;
|
||
var Z_FINISH = 4;
|
||
var Z_BLOCK = 5;
|
||
var Z_TREES = 6;
|
||
|
||
|
||
/* Return codes for the compression/decompression functions. Negative values
|
||
* are errors, positive values are used for special but normal events.
|
||
*/
|
||
var Z_OK = 0;
|
||
var Z_STREAM_END = 1;
|
||
var Z_NEED_DICT = 2;
|
||
//var Z_ERRNO = -1;
|
||
var Z_STREAM_ERROR = -2;
|
||
var Z_DATA_ERROR = -3;
|
||
var Z_MEM_ERROR = -4;
|
||
var Z_BUF_ERROR = -5;
|
||
//var Z_VERSION_ERROR = -6;
|
||
|
||
/* The deflate compression method */
|
||
var Z_DEFLATED = 8;
|
||
|
||
|
||
/* STATES ====================================================================*/
|
||
/* ===========================================================================*/
|
||
|
||
|
||
var HEAD = 1; /* i: waiting for magic header */
|
||
var FLAGS = 2; /* i: waiting for method and flags (gzip) */
|
||
var TIME = 3; /* i: waiting for modification time (gzip) */
|
||
var OS = 4; /* i: waiting for extra flags and operating system (gzip) */
|
||
var EXLEN = 5; /* i: waiting for extra length (gzip) */
|
||
var EXTRA = 6; /* i: waiting for extra bytes (gzip) */
|
||
var NAME = 7; /* i: waiting for end of file name (gzip) */
|
||
var COMMENT = 8; /* i: waiting for end of comment (gzip) */
|
||
var HCRC = 9; /* i: waiting for header crc (gzip) */
|
||
var DICTID = 10; /* i: waiting for dictionary check value */
|
||
var DICT = 11; /* waiting for inflateSetDictionary() call */
|
||
var TYPE = 12; /* i: waiting for type bits, including last-flag bit */
|
||
var TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */
|
||
var STORED = 14; /* i: waiting for stored size (length and complement) */
|
||
var COPY_ = 15; /* i/o: same as COPY below, but only first time in */
|
||
var COPY = 16; /* i/o: waiting for input or output to copy stored block */
|
||
var TABLE = 17; /* i: waiting for dynamic block table lengths */
|
||
var LENLENS = 18; /* i: waiting for code length code lengths */
|
||
var CODELENS = 19; /* i: waiting for length/lit and distance code lengths */
|
||
var LEN_ = 20; /* i: same as LEN below, but only first time in */
|
||
var LEN = 21; /* i: waiting for length/lit/eob code */
|
||
var LENEXT = 22; /* i: waiting for length extra bits */
|
||
var DIST = 23; /* i: waiting for distance code */
|
||
var DISTEXT = 24; /* i: waiting for distance extra bits */
|
||
var MATCH = 25; /* o: waiting for output space to copy string */
|
||
var LIT = 26; /* o: waiting for output space to write literal */
|
||
var CHECK = 27; /* i: waiting for 32-bit check value */
|
||
var LENGTH = 28; /* i: waiting for 32-bit length (gzip) */
|
||
var DONE = 29; /* finished check, done -- remain here until reset */
|
||
var BAD = 30; /* got a data error -- remain here until reset */
|
||
var MEM = 31; /* got an inflate() memory error -- remain here until reset */
|
||
var SYNC = 32; /* looking for synchronization bytes to restart inflate() */
|
||
|
||
/* ===========================================================================*/
|
||
|
||
|
||
|
||
var ENOUGH_LENS = 852;
|
||
var ENOUGH_DISTS = 592;
|
||
//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
|
||
|
||
var MAX_WBITS = 15;
|
||
/* 32K LZ77 window */
|
||
var DEF_WBITS = MAX_WBITS;
|
||
|
||
|
||
function zswap32(q) {
|
||
return (((q >>> 24) & 0xff) +
|
||
((q >>> 8) & 0xff00) +
|
||
((q & 0xff00) << 8) +
|
||
((q & 0xff) << 24));
|
||
}
|
||
|
||
|
||
function InflateState() {
|
||
this.mode = 0; /* current inflate mode */
|
||
this.last = false; /* true if processing last block */
|
||
this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */
|
||
this.havedict = false; /* true if dictionary provided */
|
||
this.flags = 0; /* gzip header method and flags (0 if zlib) */
|
||
this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */
|
||
this.check = 0; /* protected copy of check value */
|
||
this.total = 0; /* protected copy of output count */
|
||
// TODO: may be {}
|
||
this.head = null; /* where to save gzip header information */
|
||
|
||
/* sliding window */
|
||
this.wbits = 0; /* log base 2 of requested window size */
|
||
this.wsize = 0; /* window size or zero if not using window */
|
||
this.whave = 0; /* valid bytes in the window */
|
||
this.wnext = 0; /* window write index */
|
||
this.window = null; /* allocated sliding window, if needed */
|
||
|
||
/* bit accumulator */
|
||
this.hold = 0; /* input bit accumulator */
|
||
this.bits = 0; /* number of bits in "in" */
|
||
|
||
/* for string and stored block copying */
|
||
this.length = 0; /* literal or length of data to copy */
|
||
this.offset = 0; /* distance back to copy string from */
|
||
|
||
/* for table and code decoding */
|
||
this.extra = 0; /* extra bits needed */
|
||
|
||
/* fixed and dynamic code tables */
|
||
this.lencode = null; /* starting table for length/literal codes */
|
||
this.distcode = null; /* starting table for distance codes */
|
||
this.lenbits = 0; /* index bits for lencode */
|
||
this.distbits = 0; /* index bits for distcode */
|
||
|
||
/* dynamic table building */
|
||
this.ncode = 0; /* number of code length code lengths */
|
||
this.nlen = 0; /* number of length code lengths */
|
||
this.ndist = 0; /* number of distance code lengths */
|
||
this.have = 0; /* number of code lengths in lens[] */
|
||
this.next = null; /* next available space in codes[] */
|
||
|
||
this.lens = new utils.Buf16(320); /* temporary storage for code lengths */
|
||
this.work = new utils.Buf16(288); /* work area for code table building */
|
||
|
||
/*
|
||
because we don't have pointers in js, we use lencode and distcode directly
|
||
as buffers so we don't need codes
|
||
*/
|
||
//this.codes = new utils.Buf32(ENOUGH); /* space for code tables */
|
||
this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */
|
||
this.distdyn = null; /* dynamic table for distance codes (JS specific) */
|
||
this.sane = 0; /* if false, allow invalid distance too far */
|
||
this.back = 0; /* bits back of last unprocessed length/lit */
|
||
this.was = 0; /* initial length of match */
|
||
}
|
||
|
||
function inflateResetKeep(strm) {
|
||
var state;
|
||
|
||
if (!strm || !strm.state) { return Z_STREAM_ERROR; }
|
||
state = strm.state;
|
||
strm.total_in = strm.total_out = state.total = 0;
|
||
strm.msg = ''; /*Z_NULL*/
|
||
if (state.wrap) { /* to support ill-conceived Java test suite */
|
||
strm.adler = state.wrap & 1;
|
||
}
|
||
state.mode = HEAD;
|
||
state.last = 0;
|
||
state.havedict = 0;
|
||
state.dmax = 32768;
|
||
state.head = null/*Z_NULL*/;
|
||
state.hold = 0;
|
||
state.bits = 0;
|
||
//state.lencode = state.distcode = state.next = state.codes;
|
||
state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS);
|
||
state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS);
|
||
|
||
state.sane = 1;
|
||
state.back = -1;
|
||
//Tracev((stderr, "inflate: reset\n"));
|
||
return Z_OK;
|
||
}
|
||
|
||
function inflateReset(strm) {
|
||
var state;
|
||
|
||
if (!strm || !strm.state) { return Z_STREAM_ERROR; }
|
||
state = strm.state;
|
||
state.wsize = 0;
|
||
state.whave = 0;
|
||
state.wnext = 0;
|
||
return inflateResetKeep(strm);
|
||
|
||
}
|
||
|
||
function inflateReset2(strm, windowBits) {
|
||
var wrap;
|
||
var state;
|
||
|
||
/* get the state */
|
||
if (!strm || !strm.state) { return Z_STREAM_ERROR; }
|
||
state = strm.state;
|
||
|
||
/* extract wrap request from windowBits parameter */
|
||
if (windowBits < 0) {
|
||
wrap = 0;
|
||
windowBits = -windowBits;
|
||
}
|
||
else {
|
||
wrap = (windowBits >> 4) + 1;
|
||
if (windowBits < 48) {
|
||
windowBits &= 15;
|
||
}
|
||
}
|
||
|
||
/* set number of window bits, free window if different */
|
||
if (windowBits && (windowBits < 8 || windowBits > 15)) {
|
||
return Z_STREAM_ERROR;
|
||
}
|
||
if (state.window !== null && state.wbits !== windowBits) {
|
||
state.window = null;
|
||
}
|
||
|
||
/* update state and reset the rest of it */
|
||
state.wrap = wrap;
|
||
state.wbits = windowBits;
|
||
return inflateReset(strm);
|
||
}
|
||
|
||
function inflateInit2(strm, windowBits) {
|
||
var ret;
|
||
var state;
|
||
|
||
if (!strm) { return Z_STREAM_ERROR; }
|
||
//strm.msg = Z_NULL; /* in case we return an error */
|
||
|
||
state = new InflateState();
|
||
|
||
//if (state === Z_NULL) return Z_MEM_ERROR;
|
||
//Tracev((stderr, "inflate: allocated\n"));
|
||
strm.state = state;
|
||
state.window = null/*Z_NULL*/;
|
||
ret = inflateReset2(strm, windowBits);
|
||
if (ret !== Z_OK) {
|
||
strm.state = null/*Z_NULL*/;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
function inflateInit(strm) {
|
||
return inflateInit2(strm, DEF_WBITS);
|
||
}
|
||
|
||
|
||
/*
|
||
Return state with length and distance decoding tables and index sizes set to
|
||
fixed code decoding. Normally this returns fixed tables from inffixed.h.
|
||
If BUILDFIXED is defined, then instead this routine builds the tables the
|
||
first time it's called, and returns those tables the first time and
|
||
thereafter. This reduces the size of the code by about 2K bytes, in
|
||
exchange for a little execution time. However, BUILDFIXED should not be
|
||
used for threaded applications, since the rewriting of the tables and virgin
|
||
may not be thread-safe.
|
||
*/
|
||
var virgin = true;
|
||
|
||
var lenfix, distfix; // We have no pointers in JS, so keep tables separate
|
||
|
||
function fixedtables(state) {
|
||
/* build fixed huffman tables if first call (may not be thread safe) */
|
||
if (virgin) {
|
||
var sym;
|
||
|
||
lenfix = new utils.Buf32(512);
|
||
distfix = new utils.Buf32(32);
|
||
|
||
/* literal/length table */
|
||
sym = 0;
|
||
while (sym < 144) { state.lens[sym++] = 8; }
|
||
while (sym < 256) { state.lens[sym++] = 9; }
|
||
while (sym < 280) { state.lens[sym++] = 7; }
|
||
while (sym < 288) { state.lens[sym++] = 8; }
|
||
|
||
inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 });
|
||
|
||
/* distance table */
|
||
sym = 0;
|
||
while (sym < 32) { state.lens[sym++] = 5; }
|
||
|
||
inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 });
|
||
|
||
/* do this just once */
|
||
virgin = false;
|
||
}
|
||
|
||
state.lencode = lenfix;
|
||
state.lenbits = 9;
|
||
state.distcode = distfix;
|
||
state.distbits = 5;
|
||
}
|
||
|
||
|
||
/*
|
||
Update the window with the last wsize (normally 32K) bytes written before
|
||
returning. If window does not exist yet, create it. This is only called
|
||
when a window is already in use, or when output has been written during this
|
||
inflate call, but the end of the deflate stream has not been reached yet.
|
||
It is also called to create a window for dictionary data when a dictionary
|
||
is loaded.
|
||
|
||
Providing output buffers larger than 32K to inflate() should provide a speed
|
||
advantage, since only the last 32K of output is copied to the sliding window
|
||
upon return from inflate(), and since all distances after the first 32K of
|
||
output will fall in the output data, making match copies simpler and faster.
|
||
The advantage may be dependent on the size of the processor's data caches.
|
||
*/
|
||
function updatewindow(strm, src, end, copy) {
|
||
var dist;
|
||
var state = strm.state;
|
||
|
||
/* if it hasn't been done already, allocate space for the window */
|
||
if (state.window === null) {
|
||
state.wsize = 1 << state.wbits;
|
||
state.wnext = 0;
|
||
state.whave = 0;
|
||
|
||
state.window = new utils.Buf8(state.wsize);
|
||
}
|
||
|
||
/* copy state->wsize or less output bytes into the circular window */
|
||
if (copy >= state.wsize) {
|
||
utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0);
|
||
state.wnext = 0;
|
||
state.whave = state.wsize;
|
||
}
|
||
else {
|
||
dist = state.wsize - state.wnext;
|
||
if (dist > copy) {
|
||
dist = copy;
|
||
}
|
||
//zmemcpy(state->window + state->wnext, end - copy, dist);
|
||
utils.arraySet(state.window, src, end - copy, dist, state.wnext);
|
||
copy -= dist;
|
||
if (copy) {
|
||
//zmemcpy(state->window, end - copy, copy);
|
||
utils.arraySet(state.window, src, end - copy, copy, 0);
|
||
state.wnext = copy;
|
||
state.whave = state.wsize;
|
||
}
|
||
else {
|
||
state.wnext += dist;
|
||
if (state.wnext === state.wsize) { state.wnext = 0; }
|
||
if (state.whave < state.wsize) { state.whave += dist; }
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
function inflate(strm, flush) {
|
||
var state;
|
||
var input, output; // input/output buffers
|
||
var next; /* next input INDEX */
|
||
var put; /* next output INDEX */
|
||
var have, left; /* available input and output */
|
||
var hold; /* bit buffer */
|
||
var bits; /* bits in bit buffer */
|
||
var _in, _out; /* save starting available input and output */
|
||
var copy; /* number of stored or match bytes to copy */
|
||
var from; /* where to copy match bytes from */
|
||
var from_source;
|
||
var here = 0; /* current decoding table entry */
|
||
var here_bits, here_op, here_val; // paked "here" denormalized (JS specific)
|
||
//var last; /* parent table entry */
|
||
var last_bits, last_op, last_val; // paked "last" denormalized (JS specific)
|
||
var len; /* length to copy for repeats, bits to drop */
|
||
var ret; /* return code */
|
||
var hbuf = new utils.Buf8(4); /* buffer for gzip header crc calculation */
|
||
var opts;
|
||
|
||
var n; // temporary var for NEED_BITS
|
||
|
||
var order = /* permutation of code lengths */
|
||
[ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
|
||
|
||
|
||
if (!strm || !strm.state || !strm.output ||
|
||
(!strm.input && strm.avail_in !== 0)) {
|
||
return Z_STREAM_ERROR;
|
||
}
|
||
|
||
state = strm.state;
|
||
if (state.mode === TYPE) { state.mode = TYPEDO; } /* skip check */
|
||
|
||
|
||
//--- LOAD() ---
|
||
put = strm.next_out;
|
||
output = strm.output;
|
||
left = strm.avail_out;
|
||
next = strm.next_in;
|
||
input = strm.input;
|
||
have = strm.avail_in;
|
||
hold = state.hold;
|
||
bits = state.bits;
|
||
//---
|
||
|
||
_in = have;
|
||
_out = left;
|
||
ret = Z_OK;
|
||
|
||
inf_leave: // goto emulation
|
||
for (;;) {
|
||
switch (state.mode) {
|
||
case HEAD:
|
||
if (state.wrap === 0) {
|
||
state.mode = TYPEDO;
|
||
break;
|
||
}
|
||
//=== NEEDBITS(16);
|
||
while (bits < 16) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */
|
||
state.check = 0/*crc32(0L, Z_NULL, 0)*/;
|
||
//=== CRC2(state.check, hold);
|
||
hbuf[0] = hold & 0xff;
|
||
hbuf[1] = (hold >>> 8) & 0xff;
|
||
state.check = crc32(state.check, hbuf, 2, 0);
|
||
//===//
|
||
|
||
//=== INITBITS();
|
||
hold = 0;
|
||
bits = 0;
|
||
//===//
|
||
state.mode = FLAGS;
|
||
break;
|
||
}
|
||
state.flags = 0; /* expect zlib header */
|
||
if (state.head) {
|
||
state.head.done = false;
|
||
}
|
||
if (!(state.wrap & 1) || /* check if zlib header allowed */
|
||
(((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) {
|
||
strm.msg = 'incorrect header check';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) {
|
||
strm.msg = 'unknown compression method';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
//--- DROPBITS(4) ---//
|
||
hold >>>= 4;
|
||
bits -= 4;
|
||
//---//
|
||
len = (hold & 0x0f)/*BITS(4)*/ + 8;
|
||
if (state.wbits === 0) {
|
||
state.wbits = len;
|
||
}
|
||
else if (len > state.wbits) {
|
||
strm.msg = 'invalid window size';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
state.dmax = 1 << len;
|
||
//Tracev((stderr, "inflate: zlib header ok\n"));
|
||
strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;
|
||
state.mode = hold & 0x200 ? DICTID : TYPE;
|
||
//=== INITBITS();
|
||
hold = 0;
|
||
bits = 0;
|
||
//===//
|
||
break;
|
||
case FLAGS:
|
||
//=== NEEDBITS(16); */
|
||
while (bits < 16) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
state.flags = hold;
|
||
if ((state.flags & 0xff) !== Z_DEFLATED) {
|
||
strm.msg = 'unknown compression method';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
if (state.flags & 0xe000) {
|
||
strm.msg = 'unknown header flags set';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
if (state.head) {
|
||
state.head.text = ((hold >> 8) & 1);
|
||
}
|
||
if (state.flags & 0x0200) {
|
||
//=== CRC2(state.check, hold);
|
||
hbuf[0] = hold & 0xff;
|
||
hbuf[1] = (hold >>> 8) & 0xff;
|
||
state.check = crc32(state.check, hbuf, 2, 0);
|
||
//===//
|
||
}
|
||
//=== INITBITS();
|
||
hold = 0;
|
||
bits = 0;
|
||
//===//
|
||
state.mode = TIME;
|
||
/* falls through */
|
||
case TIME:
|
||
//=== NEEDBITS(32); */
|
||
while (bits < 32) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
if (state.head) {
|
||
state.head.time = hold;
|
||
}
|
||
if (state.flags & 0x0200) {
|
||
//=== CRC4(state.check, hold)
|
||
hbuf[0] = hold & 0xff;
|
||
hbuf[1] = (hold >>> 8) & 0xff;
|
||
hbuf[2] = (hold >>> 16) & 0xff;
|
||
hbuf[3] = (hold >>> 24) & 0xff;
|
||
state.check = crc32(state.check, hbuf, 4, 0);
|
||
//===
|
||
}
|
||
//=== INITBITS();
|
||
hold = 0;
|
||
bits = 0;
|
||
//===//
|
||
state.mode = OS;
|
||
/* falls through */
|
||
case OS:
|
||
//=== NEEDBITS(16); */
|
||
while (bits < 16) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
if (state.head) {
|
||
state.head.xflags = (hold & 0xff);
|
||
state.head.os = (hold >> 8);
|
||
}
|
||
if (state.flags & 0x0200) {
|
||
//=== CRC2(state.check, hold);
|
||
hbuf[0] = hold & 0xff;
|
||
hbuf[1] = (hold >>> 8) & 0xff;
|
||
state.check = crc32(state.check, hbuf, 2, 0);
|
||
//===//
|
||
}
|
||
//=== INITBITS();
|
||
hold = 0;
|
||
bits = 0;
|
||
//===//
|
||
state.mode = EXLEN;
|
||
/* falls through */
|
||
case EXLEN:
|
||
if (state.flags & 0x0400) {
|
||
//=== NEEDBITS(16); */
|
||
while (bits < 16) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
state.length = hold;
|
||
if (state.head) {
|
||
state.head.extra_len = hold;
|
||
}
|
||
if (state.flags & 0x0200) {
|
||
//=== CRC2(state.check, hold);
|
||
hbuf[0] = hold & 0xff;
|
||
hbuf[1] = (hold >>> 8) & 0xff;
|
||
state.check = crc32(state.check, hbuf, 2, 0);
|
||
//===//
|
||
}
|
||
//=== INITBITS();
|
||
hold = 0;
|
||
bits = 0;
|
||
//===//
|
||
}
|
||
else if (state.head) {
|
||
state.head.extra = null/*Z_NULL*/;
|
||
}
|
||
state.mode = EXTRA;
|
||
/* falls through */
|
||
case EXTRA:
|
||
if (state.flags & 0x0400) {
|
||
copy = state.length;
|
||
if (copy > have) { copy = have; }
|
||
if (copy) {
|
||
if (state.head) {
|
||
len = state.head.extra_len - state.length;
|
||
if (!state.head.extra) {
|
||
// Use untyped array for more convenient processing later
|
||
state.head.extra = new Array(state.head.extra_len);
|
||
}
|
||
utils.arraySet(
|
||
state.head.extra,
|
||
input,
|
||
next,
|
||
// extra field is limited to 65536 bytes
|
||
// - no need for additional size check
|
||
copy,
|
||
/*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/
|
||
len
|
||
);
|
||
//zmemcpy(state.head.extra + len, next,
|
||
// len + copy > state.head.extra_max ?
|
||
// state.head.extra_max - len : copy);
|
||
}
|
||
if (state.flags & 0x0200) {
|
||
state.check = crc32(state.check, input, copy, next);
|
||
}
|
||
have -= copy;
|
||
next += copy;
|
||
state.length -= copy;
|
||
}
|
||
if (state.length) { break inf_leave; }
|
||
}
|
||
state.length = 0;
|
||
state.mode = NAME;
|
||
/* falls through */
|
||
case NAME:
|
||
if (state.flags & 0x0800) {
|
||
if (have === 0) { break inf_leave; }
|
||
copy = 0;
|
||
do {
|
||
// TODO: 2 or 1 bytes?
|
||
len = input[next + copy++];
|
||
/* use constant limit because in js we should not preallocate memory */
|
||
if (state.head && len &&
|
||
(state.length < 65536 /*state.head.name_max*/)) {
|
||
state.head.name += String.fromCharCode(len);
|
||
}
|
||
} while (len && copy < have);
|
||
|
||
if (state.flags & 0x0200) {
|
||
state.check = crc32(state.check, input, copy, next);
|
||
}
|
||
have -= copy;
|
||
next += copy;
|
||
if (len) { break inf_leave; }
|
||
}
|
||
else if (state.head) {
|
||
state.head.name = null;
|
||
}
|
||
state.length = 0;
|
||
state.mode = COMMENT;
|
||
/* falls through */
|
||
case COMMENT:
|
||
if (state.flags & 0x1000) {
|
||
if (have === 0) { break inf_leave; }
|
||
copy = 0;
|
||
do {
|
||
len = input[next + copy++];
|
||
/* use constant limit because in js we should not preallocate memory */
|
||
if (state.head && len &&
|
||
(state.length < 65536 /*state.head.comm_max*/)) {
|
||
state.head.comment += String.fromCharCode(len);
|
||
}
|
||
} while (len && copy < have);
|
||
if (state.flags & 0x0200) {
|
||
state.check = crc32(state.check, input, copy, next);
|
||
}
|
||
have -= copy;
|
||
next += copy;
|
||
if (len) { break inf_leave; }
|
||
}
|
||
else if (state.head) {
|
||
state.head.comment = null;
|
||
}
|
||
state.mode = HCRC;
|
||
/* falls through */
|
||
case HCRC:
|
||
if (state.flags & 0x0200) {
|
||
//=== NEEDBITS(16); */
|
||
while (bits < 16) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
if (hold !== (state.check & 0xffff)) {
|
||
strm.msg = 'header crc mismatch';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
//=== INITBITS();
|
||
hold = 0;
|
||
bits = 0;
|
||
//===//
|
||
}
|
||
if (state.head) {
|
||
state.head.hcrc = ((state.flags >> 9) & 1);
|
||
state.head.done = true;
|
||
}
|
||
strm.adler = state.check = 0;
|
||
state.mode = TYPE;
|
||
break;
|
||
case DICTID:
|
||
//=== NEEDBITS(32); */
|
||
while (bits < 32) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
strm.adler = state.check = zswap32(hold);
|
||
//=== INITBITS();
|
||
hold = 0;
|
||
bits = 0;
|
||
//===//
|
||
state.mode = DICT;
|
||
/* falls through */
|
||
case DICT:
|
||
if (state.havedict === 0) {
|
||
//--- RESTORE() ---
|
||
strm.next_out = put;
|
||
strm.avail_out = left;
|
||
strm.next_in = next;
|
||
strm.avail_in = have;
|
||
state.hold = hold;
|
||
state.bits = bits;
|
||
//---
|
||
return Z_NEED_DICT;
|
||
}
|
||
strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;
|
||
state.mode = TYPE;
|
||
/* falls through */
|
||
case TYPE:
|
||
if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; }
|
||
/* falls through */
|
||
case TYPEDO:
|
||
if (state.last) {
|
||
//--- BYTEBITS() ---//
|
||
hold >>>= bits & 7;
|
||
bits -= bits & 7;
|
||
//---//
|
||
state.mode = CHECK;
|
||
break;
|
||
}
|
||
//=== NEEDBITS(3); */
|
||
while (bits < 3) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
state.last = (hold & 0x01)/*BITS(1)*/;
|
||
//--- DROPBITS(1) ---//
|
||
hold >>>= 1;
|
||
bits -= 1;
|
||
//---//
|
||
|
||
switch ((hold & 0x03)/*BITS(2)*/) {
|
||
case 0: /* stored block */
|
||
//Tracev((stderr, "inflate: stored block%s\n",
|
||
// state.last ? " (last)" : ""));
|
||
state.mode = STORED;
|
||
break;
|
||
case 1: /* fixed block */
|
||
fixedtables(state);
|
||
//Tracev((stderr, "inflate: fixed codes block%s\n",
|
||
// state.last ? " (last)" : ""));
|
||
state.mode = LEN_; /* decode codes */
|
||
if (flush === Z_TREES) {
|
||
//--- DROPBITS(2) ---//
|
||
hold >>>= 2;
|
||
bits -= 2;
|
||
//---//
|
||
break inf_leave;
|
||
}
|
||
break;
|
||
case 2: /* dynamic block */
|
||
//Tracev((stderr, "inflate: dynamic codes block%s\n",
|
||
// state.last ? " (last)" : ""));
|
||
state.mode = TABLE;
|
||
break;
|
||
case 3:
|
||
strm.msg = 'invalid block type';
|
||
state.mode = BAD;
|
||
}
|
||
//--- DROPBITS(2) ---//
|
||
hold >>>= 2;
|
||
bits -= 2;
|
||
//---//
|
||
break;
|
||
case STORED:
|
||
//--- BYTEBITS() ---// /* go to byte boundary */
|
||
hold >>>= bits & 7;
|
||
bits -= bits & 7;
|
||
//---//
|
||
//=== NEEDBITS(32); */
|
||
while (bits < 32) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) {
|
||
strm.msg = 'invalid stored block lengths';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
state.length = hold & 0xffff;
|
||
//Tracev((stderr, "inflate: stored length %u\n",
|
||
// state.length));
|
||
//=== INITBITS();
|
||
hold = 0;
|
||
bits = 0;
|
||
//===//
|
||
state.mode = COPY_;
|
||
if (flush === Z_TREES) { break inf_leave; }
|
||
/* falls through */
|
||
case COPY_:
|
||
state.mode = COPY;
|
||
/* falls through */
|
||
case COPY:
|
||
copy = state.length;
|
||
if (copy) {
|
||
if (copy > have) { copy = have; }
|
||
if (copy > left) { copy = left; }
|
||
if (copy === 0) { break inf_leave; }
|
||
//--- zmemcpy(put, next, copy); ---
|
||
utils.arraySet(output, input, next, copy, put);
|
||
//---//
|
||
have -= copy;
|
||
next += copy;
|
||
left -= copy;
|
||
put += copy;
|
||
state.length -= copy;
|
||
break;
|
||
}
|
||
//Tracev((stderr, "inflate: stored end\n"));
|
||
state.mode = TYPE;
|
||
break;
|
||
case TABLE:
|
||
//=== NEEDBITS(14); */
|
||
while (bits < 14) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257;
|
||
//--- DROPBITS(5) ---//
|
||
hold >>>= 5;
|
||
bits -= 5;
|
||
//---//
|
||
state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1;
|
||
//--- DROPBITS(5) ---//
|
||
hold >>>= 5;
|
||
bits -= 5;
|
||
//---//
|
||
state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4;
|
||
//--- DROPBITS(4) ---//
|
||
hold >>>= 4;
|
||
bits -= 4;
|
||
//---//
|
||
//#ifndef PKZIP_BUG_WORKAROUND
|
||
if (state.nlen > 286 || state.ndist > 30) {
|
||
strm.msg = 'too many length or distance symbols';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
//#endif
|
||
//Tracev((stderr, "inflate: table sizes ok\n"));
|
||
state.have = 0;
|
||
state.mode = LENLENS;
|
||
/* falls through */
|
||
case LENLENS:
|
||
while (state.have < state.ncode) {
|
||
//=== NEEDBITS(3);
|
||
while (bits < 3) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
state.lens[order[state.have++]] = (hold & 0x07);//BITS(3);
|
||
//--- DROPBITS(3) ---//
|
||
hold >>>= 3;
|
||
bits -= 3;
|
||
//---//
|
||
}
|
||
while (state.have < 19) {
|
||
state.lens[order[state.have++]] = 0;
|
||
}
|
||
// We have separate tables & no pointers. 2 commented lines below not needed.
|
||
//state.next = state.codes;
|
||
//state.lencode = state.next;
|
||
// Switch to use dynamic table
|
||
state.lencode = state.lendyn;
|
||
state.lenbits = 7;
|
||
|
||
opts = { bits: state.lenbits };
|
||
ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts);
|
||
state.lenbits = opts.bits;
|
||
|
||
if (ret) {
|
||
strm.msg = 'invalid code lengths set';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
//Tracev((stderr, "inflate: code lengths ok\n"));
|
||
state.have = 0;
|
||
state.mode = CODELENS;
|
||
/* falls through */
|
||
case CODELENS:
|
||
while (state.have < state.nlen + state.ndist) {
|
||
for (;;) {
|
||
here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/
|
||
here_bits = here >>> 24;
|
||
here_op = (here >>> 16) & 0xff;
|
||
here_val = here & 0xffff;
|
||
|
||
if ((here_bits) <= bits) { break; }
|
||
//--- PULLBYTE() ---//
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
//---//
|
||
}
|
||
if (here_val < 16) {
|
||
//--- DROPBITS(here.bits) ---//
|
||
hold >>>= here_bits;
|
||
bits -= here_bits;
|
||
//---//
|
||
state.lens[state.have++] = here_val;
|
||
}
|
||
else {
|
||
if (here_val === 16) {
|
||
//=== NEEDBITS(here.bits + 2);
|
||
n = here_bits + 2;
|
||
while (bits < n) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
//--- DROPBITS(here.bits) ---//
|
||
hold >>>= here_bits;
|
||
bits -= here_bits;
|
||
//---//
|
||
if (state.have === 0) {
|
||
strm.msg = 'invalid bit length repeat';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
len = state.lens[state.have - 1];
|
||
copy = 3 + (hold & 0x03);//BITS(2);
|
||
//--- DROPBITS(2) ---//
|
||
hold >>>= 2;
|
||
bits -= 2;
|
||
//---//
|
||
}
|
||
else if (here_val === 17) {
|
||
//=== NEEDBITS(here.bits + 3);
|
||
n = here_bits + 3;
|
||
while (bits < n) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
//--- DROPBITS(here.bits) ---//
|
||
hold >>>= here_bits;
|
||
bits -= here_bits;
|
||
//---//
|
||
len = 0;
|
||
copy = 3 + (hold & 0x07);//BITS(3);
|
||
//--- DROPBITS(3) ---//
|
||
hold >>>= 3;
|
||
bits -= 3;
|
||
//---//
|
||
}
|
||
else {
|
||
//=== NEEDBITS(here.bits + 7);
|
||
n = here_bits + 7;
|
||
while (bits < n) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
//--- DROPBITS(here.bits) ---//
|
||
hold >>>= here_bits;
|
||
bits -= here_bits;
|
||
//---//
|
||
len = 0;
|
||
copy = 11 + (hold & 0x7f);//BITS(7);
|
||
//--- DROPBITS(7) ---//
|
||
hold >>>= 7;
|
||
bits -= 7;
|
||
//---//
|
||
}
|
||
if (state.have + copy > state.nlen + state.ndist) {
|
||
strm.msg = 'invalid bit length repeat';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
while (copy--) {
|
||
state.lens[state.have++] = len;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* handle error breaks in while */
|
||
if (state.mode === BAD) { break; }
|
||
|
||
/* check for end-of-block code (better have one) */
|
||
if (state.lens[256] === 0) {
|
||
strm.msg = 'invalid code -- missing end-of-block';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
|
||
/* build code tables -- note: do not change the lenbits or distbits
|
||
values here (9 and 6) without reading the comments in inftrees.h
|
||
concerning the ENOUGH constants, which depend on those values */
|
||
state.lenbits = 9;
|
||
|
||
opts = { bits: state.lenbits };
|
||
ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts);
|
||
// We have separate tables & no pointers. 2 commented lines below not needed.
|
||
// state.next_index = opts.table_index;
|
||
state.lenbits = opts.bits;
|
||
// state.lencode = state.next;
|
||
|
||
if (ret) {
|
||
strm.msg = 'invalid literal/lengths set';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
|
||
state.distbits = 6;
|
||
//state.distcode.copy(state.codes);
|
||
// Switch to use dynamic table
|
||
state.distcode = state.distdyn;
|
||
opts = { bits: state.distbits };
|
||
ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts);
|
||
// We have separate tables & no pointers. 2 commented lines below not needed.
|
||
// state.next_index = opts.table_index;
|
||
state.distbits = opts.bits;
|
||
// state.distcode = state.next;
|
||
|
||
if (ret) {
|
||
strm.msg = 'invalid distances set';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
//Tracev((stderr, 'inflate: codes ok\n'));
|
||
state.mode = LEN_;
|
||
if (flush === Z_TREES) { break inf_leave; }
|
||
/* falls through */
|
||
case LEN_:
|
||
state.mode = LEN;
|
||
/* falls through */
|
||
case LEN:
|
||
if (have >= 6 && left >= 258) {
|
||
//--- RESTORE() ---
|
||
strm.next_out = put;
|
||
strm.avail_out = left;
|
||
strm.next_in = next;
|
||
strm.avail_in = have;
|
||
state.hold = hold;
|
||
state.bits = bits;
|
||
//---
|
||
inflate_fast(strm, _out);
|
||
//--- LOAD() ---
|
||
put = strm.next_out;
|
||
output = strm.output;
|
||
left = strm.avail_out;
|
||
next = strm.next_in;
|
||
input = strm.input;
|
||
have = strm.avail_in;
|
||
hold = state.hold;
|
||
bits = state.bits;
|
||
//---
|
||
|
||
if (state.mode === TYPE) {
|
||
state.back = -1;
|
||
}
|
||
break;
|
||
}
|
||
state.back = 0;
|
||
for (;;) {
|
||
here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/
|
||
here_bits = here >>> 24;
|
||
here_op = (here >>> 16) & 0xff;
|
||
here_val = here & 0xffff;
|
||
|
||
if (here_bits <= bits) { break; }
|
||
//--- PULLBYTE() ---//
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
//---//
|
||
}
|
||
if (here_op && (here_op & 0xf0) === 0) {
|
||
last_bits = here_bits;
|
||
last_op = here_op;
|
||
last_val = here_val;
|
||
for (;;) {
|
||
here = state.lencode[last_val +
|
||
((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];
|
||
here_bits = here >>> 24;
|
||
here_op = (here >>> 16) & 0xff;
|
||
here_val = here & 0xffff;
|
||
|
||
if ((last_bits + here_bits) <= bits) { break; }
|
||
//--- PULLBYTE() ---//
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
//---//
|
||
}
|
||
//--- DROPBITS(last.bits) ---//
|
||
hold >>>= last_bits;
|
||
bits -= last_bits;
|
||
//---//
|
||
state.back += last_bits;
|
||
}
|
||
//--- DROPBITS(here.bits) ---//
|
||
hold >>>= here_bits;
|
||
bits -= here_bits;
|
||
//---//
|
||
state.back += here_bits;
|
||
state.length = here_val;
|
||
if (here_op === 0) {
|
||
//Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
|
||
// "inflate: literal '%c'\n" :
|
||
// "inflate: literal 0x%02x\n", here.val));
|
||
state.mode = LIT;
|
||
break;
|
||
}
|
||
if (here_op & 32) {
|
||
//Tracevv((stderr, "inflate: end of block\n"));
|
||
state.back = -1;
|
||
state.mode = TYPE;
|
||
break;
|
||
}
|
||
if (here_op & 64) {
|
||
strm.msg = 'invalid literal/length code';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
state.extra = here_op & 15;
|
||
state.mode = LENEXT;
|
||
/* falls through */
|
||
case LENEXT:
|
||
if (state.extra) {
|
||
//=== NEEDBITS(state.extra);
|
||
n = state.extra;
|
||
while (bits < n) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;
|
||
//--- DROPBITS(state.extra) ---//
|
||
hold >>>= state.extra;
|
||
bits -= state.extra;
|
||
//---//
|
||
state.back += state.extra;
|
||
}
|
||
//Tracevv((stderr, "inflate: length %u\n", state.length));
|
||
state.was = state.length;
|
||
state.mode = DIST;
|
||
/* falls through */
|
||
case DIST:
|
||
for (;;) {
|
||
here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/
|
||
here_bits = here >>> 24;
|
||
here_op = (here >>> 16) & 0xff;
|
||
here_val = here & 0xffff;
|
||
|
||
if ((here_bits) <= bits) { break; }
|
||
//--- PULLBYTE() ---//
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
//---//
|
||
}
|
||
if ((here_op & 0xf0) === 0) {
|
||
last_bits = here_bits;
|
||
last_op = here_op;
|
||
last_val = here_val;
|
||
for (;;) {
|
||
here = state.distcode[last_val +
|
||
((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];
|
||
here_bits = here >>> 24;
|
||
here_op = (here >>> 16) & 0xff;
|
||
here_val = here & 0xffff;
|
||
|
||
if ((last_bits + here_bits) <= bits) { break; }
|
||
//--- PULLBYTE() ---//
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
//---//
|
||
}
|
||
//--- DROPBITS(last.bits) ---//
|
||
hold >>>= last_bits;
|
||
bits -= last_bits;
|
||
//---//
|
||
state.back += last_bits;
|
||
}
|
||
//--- DROPBITS(here.bits) ---//
|
||
hold >>>= here_bits;
|
||
bits -= here_bits;
|
||
//---//
|
||
state.back += here_bits;
|
||
if (here_op & 64) {
|
||
strm.msg = 'invalid distance code';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
state.offset = here_val;
|
||
state.extra = (here_op) & 15;
|
||
state.mode = DISTEXT;
|
||
/* falls through */
|
||
case DISTEXT:
|
||
if (state.extra) {
|
||
//=== NEEDBITS(state.extra);
|
||
n = state.extra;
|
||
while (bits < n) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;
|
||
//--- DROPBITS(state.extra) ---//
|
||
hold >>>= state.extra;
|
||
bits -= state.extra;
|
||
//---//
|
||
state.back += state.extra;
|
||
}
|
||
//#ifdef INFLATE_STRICT
|
||
if (state.offset > state.dmax) {
|
||
strm.msg = 'invalid distance too far back';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
//#endif
|
||
//Tracevv((stderr, "inflate: distance %u\n", state.offset));
|
||
state.mode = MATCH;
|
||
/* falls through */
|
||
case MATCH:
|
||
if (left === 0) { break inf_leave; }
|
||
copy = _out - left;
|
||
if (state.offset > copy) { /* copy from window */
|
||
copy = state.offset - copy;
|
||
if (copy > state.whave) {
|
||
if (state.sane) {
|
||
strm.msg = 'invalid distance too far back';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
// (!) This block is disabled in zlib defaults,
|
||
// don't enable it for binary compatibility
|
||
//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
|
||
// Trace((stderr, "inflate.c too far\n"));
|
||
// copy -= state.whave;
|
||
// if (copy > state.length) { copy = state.length; }
|
||
// if (copy > left) { copy = left; }
|
||
// left -= copy;
|
||
// state.length -= copy;
|
||
// do {
|
||
// output[put++] = 0;
|
||
// } while (--copy);
|
||
// if (state.length === 0) { state.mode = LEN; }
|
||
// break;
|
||
//#endif
|
||
}
|
||
if (copy > state.wnext) {
|
||
copy -= state.wnext;
|
||
from = state.wsize - copy;
|
||
}
|
||
else {
|
||
from = state.wnext - copy;
|
||
}
|
||
if (copy > state.length) { copy = state.length; }
|
||
from_source = state.window;
|
||
}
|
||
else { /* copy from output */
|
||
from_source = output;
|
||
from = put - state.offset;
|
||
copy = state.length;
|
||
}
|
||
if (copy > left) { copy = left; }
|
||
left -= copy;
|
||
state.length -= copy;
|
||
do {
|
||
output[put++] = from_source[from++];
|
||
} while (--copy);
|
||
if (state.length === 0) { state.mode = LEN; }
|
||
break;
|
||
case LIT:
|
||
if (left === 0) { break inf_leave; }
|
||
output[put++] = state.length;
|
||
left--;
|
||
state.mode = LEN;
|
||
break;
|
||
case CHECK:
|
||
if (state.wrap) {
|
||
//=== NEEDBITS(32);
|
||
while (bits < 32) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
// Use '|' instead of '+' to make sure that result is signed
|
||
hold |= input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
_out -= left;
|
||
strm.total_out += _out;
|
||
state.total += _out;
|
||
if (_out) {
|
||
strm.adler = state.check =
|
||
/*UPDATE(state.check, put - _out, _out);*/
|
||
(state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out));
|
||
|
||
}
|
||
_out = left;
|
||
// NB: crc32 stored as signed 32-bit int, zswap32 returns signed too
|
||
if ((state.flags ? hold : zswap32(hold)) !== state.check) {
|
||
strm.msg = 'incorrect data check';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
//=== INITBITS();
|
||
hold = 0;
|
||
bits = 0;
|
||
//===//
|
||
//Tracev((stderr, "inflate: check matches trailer\n"));
|
||
}
|
||
state.mode = LENGTH;
|
||
/* falls through */
|
||
case LENGTH:
|
||
if (state.wrap && state.flags) {
|
||
//=== NEEDBITS(32);
|
||
while (bits < 32) {
|
||
if (have === 0) { break inf_leave; }
|
||
have--;
|
||
hold += input[next++] << bits;
|
||
bits += 8;
|
||
}
|
||
//===//
|
||
if (hold !== (state.total & 0xffffffff)) {
|
||
strm.msg = 'incorrect length check';
|
||
state.mode = BAD;
|
||
break;
|
||
}
|
||
//=== INITBITS();
|
||
hold = 0;
|
||
bits = 0;
|
||
//===//
|
||
//Tracev((stderr, "inflate: length matches trailer\n"));
|
||
}
|
||
state.mode = DONE;
|
||
/* falls through */
|
||
case DONE:
|
||
ret = Z_STREAM_END;
|
||
break inf_leave;
|
||
case BAD:
|
||
ret = Z_DATA_ERROR;
|
||
break inf_leave;
|
||
case MEM:
|
||
return Z_MEM_ERROR;
|
||
case SYNC:
|
||
/* falls through */
|
||
default:
|
||
return Z_STREAM_ERROR;
|
||
}
|
||
}
|
||
|
||
// inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave"
|
||
|
||
/*
|
||
Return from inflate(), updating the total counts and the check value.
|
||
If there was no progress during the inflate() call, return a buffer
|
||
error. Call updatewindow() to create and/or update the window state.
|
||
Note: a memory error from inflate() is non-recoverable.
|
||
*/
|
||
|
||
//--- RESTORE() ---
|
||
strm.next_out = put;
|
||
strm.avail_out = left;
|
||
strm.next_in = next;
|
||
strm.avail_in = have;
|
||
state.hold = hold;
|
||
state.bits = bits;
|
||
//---
|
||
|
||
if (state.wsize || (_out !== strm.avail_out && state.mode < BAD &&
|
||
(state.mode < CHECK || flush !== Z_FINISH))) {
|
||
if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) {
|
||
state.mode = MEM;
|
||
return Z_MEM_ERROR;
|
||
}
|
||
}
|
||
_in -= strm.avail_in;
|
||
_out -= strm.avail_out;
|
||
strm.total_in += _in;
|
||
strm.total_out += _out;
|
||
state.total += _out;
|
||
if (state.wrap && _out) {
|
||
strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/
|
||
(state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out));
|
||
}
|
||
strm.data_type = state.bits + (state.last ? 64 : 0) +
|
||
(state.mode === TYPE ? 128 : 0) +
|
||
(state.mode === LEN_ || state.mode === COPY_ ? 256 : 0);
|
||
if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) {
|
||
ret = Z_BUF_ERROR;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
function inflateEnd(strm) {
|
||
|
||
if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) {
|
||
return Z_STREAM_ERROR;
|
||
}
|
||
|
||
var state = strm.state;
|
||
if (state.window) {
|
||
state.window = null;
|
||
}
|
||
strm.state = null;
|
||
return Z_OK;
|
||
}
|
||
|
||
function inflateGetHeader(strm, head) {
|
||
var state;
|
||
|
||
/* check state */
|
||
if (!strm || !strm.state) { return Z_STREAM_ERROR; }
|
||
state = strm.state;
|
||
if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; }
|
||
|
||
/* save header structure */
|
||
state.head = head;
|
||
head.done = false;
|
||
return Z_OK;
|
||
}
|
||
|
||
function inflateSetDictionary(strm, dictionary) {
|
||
var dictLength = dictionary.length;
|
||
|
||
var state;
|
||
var dictid;
|
||
var ret;
|
||
|
||
/* check state */
|
||
if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; }
|
||
state = strm.state;
|
||
|
||
if (state.wrap !== 0 && state.mode !== DICT) {
|
||
return Z_STREAM_ERROR;
|
||
}
|
||
|
||
/* check for correct dictionary identifier */
|
||
if (state.mode === DICT) {
|
||
dictid = 1; /* adler32(0, null, 0)*/
|
||
/* dictid = adler32(dictid, dictionary, dictLength); */
|
||
dictid = adler32(dictid, dictionary, dictLength, 0);
|
||
if (dictid !== state.check) {
|
||
return Z_DATA_ERROR;
|
||
}
|
||
}
|
||
/* copy dictionary to window using updatewindow(), which will amend the
|
||
existing dictionary if appropriate */
|
||
ret = updatewindow(strm, dictionary, dictLength, dictLength);
|
||
if (ret) {
|
||
state.mode = MEM;
|
||
return Z_MEM_ERROR;
|
||
}
|
||
state.havedict = 1;
|
||
// Tracev((stderr, "inflate: dictionary set\n"));
|
||
return Z_OK;
|
||
}
|
||
|
||
exports.inflateReset = inflateReset;
|
||
exports.inflateReset2 = inflateReset2;
|
||
exports.inflateResetKeep = inflateResetKeep;
|
||
exports.inflateInit = inflateInit;
|
||
exports.inflateInit2 = inflateInit2;
|
||
exports.inflate = inflate;
|
||
exports.inflateEnd = inflateEnd;
|
||
exports.inflateGetHeader = inflateGetHeader;
|
||
exports.inflateSetDictionary = inflateSetDictionary;
|
||
exports.inflateInfo = 'pako inflate (from Nodeca project)';
|
||
|
||
/* Not implemented
|
||
exports.inflateCopy = inflateCopy;
|
||
exports.inflateGetDictionary = inflateGetDictionary;
|
||
exports.inflateMark = inflateMark;
|
||
exports.inflatePrime = inflatePrime;
|
||
exports.inflateSync = inflateSync;
|
||
exports.inflateSyncPoint = inflateSyncPoint;
|
||
exports.inflateUndermine = inflateUndermine;
|
||
*/
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pako/lib/zlib/inftrees.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/pako/lib/zlib/inftrees.js ***!
|
||
\************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||
//
|
||
// This software is provided 'as-is', without any express or implied
|
||
// warranty. In no event will the authors be held liable for any damages
|
||
// arising from the use of this software.
|
||
//
|
||
// Permission is granted to anyone to use this software for any purpose,
|
||
// including commercial applications, and to alter it and redistribute it
|
||
// freely, subject to the following restrictions:
|
||
//
|
||
// 1. The origin of this software must not be misrepresented; you must not
|
||
// claim that you wrote the original software. If you use this software
|
||
// in a product, an acknowledgment in the product documentation would be
|
||
// appreciated but is not required.
|
||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||
// misrepresented as being the original software.
|
||
// 3. This notice may not be removed or altered from any source distribution.
|
||
|
||
var utils = __webpack_require__(/*! ../utils/common */ "./node_modules/pako/lib/utils/common.js");
|
||
|
||
var MAXBITS = 15;
|
||
var ENOUGH_LENS = 852;
|
||
var ENOUGH_DISTS = 592;
|
||
//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
|
||
|
||
var CODES = 0;
|
||
var LENS = 1;
|
||
var DISTS = 2;
|
||
|
||
var lbase = [ /* Length codes 257..285 base */
|
||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
|
||
];
|
||
|
||
var lext = [ /* Length codes 257..285 extra */
|
||
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
|
||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78
|
||
];
|
||
|
||
var dbase = [ /* Distance codes 0..29 base */
|
||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||
8193, 12289, 16385, 24577, 0, 0
|
||
];
|
||
|
||
var dext = [ /* Distance codes 0..29 extra */
|
||
16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
|
||
23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
|
||
28, 28, 29, 29, 64, 64
|
||
];
|
||
|
||
module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts)
|
||
{
|
||
var bits = opts.bits;
|
||
//here = opts.here; /* table entry for duplication */
|
||
|
||
var len = 0; /* a code's length in bits */
|
||
var sym = 0; /* index of code symbols */
|
||
var min = 0, max = 0; /* minimum and maximum code lengths */
|
||
var root = 0; /* number of index bits for root table */
|
||
var curr = 0; /* number of index bits for current table */
|
||
var drop = 0; /* code bits to drop for sub-table */
|
||
var left = 0; /* number of prefix codes available */
|
||
var used = 0; /* code entries in table used */
|
||
var huff = 0; /* Huffman code */
|
||
var incr; /* for incrementing code, index */
|
||
var fill; /* index for replicating entries */
|
||
var low; /* low bits for current root entry */
|
||
var mask; /* mask for low root bits */
|
||
var next; /* next available space in table */
|
||
var base = null; /* base value table to use */
|
||
var base_index = 0;
|
||
// var shoextra; /* extra bits table to use */
|
||
var end; /* use base and extra for symbol > end */
|
||
var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */
|
||
var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */
|
||
var extra = null;
|
||
var extra_index = 0;
|
||
|
||
var here_bits, here_op, here_val;
|
||
|
||
/*
|
||
Process a set of code lengths to create a canonical Huffman code. The
|
||
code lengths are lens[0..codes-1]. Each length corresponds to the
|
||
symbols 0..codes-1. The Huffman code is generated by first sorting the
|
||
symbols by length from short to long, and retaining the symbol order
|
||
for codes with equal lengths. Then the code starts with all zero bits
|
||
for the first code of the shortest length, and the codes are integer
|
||
increments for the same length, and zeros are appended as the length
|
||
increases. For the deflate format, these bits are stored backwards
|
||
from their more natural integer increment ordering, and so when the
|
||
decoding tables are built in the large loop below, the integer codes
|
||
are incremented backwards.
|
||
|
||
This routine assumes, but does not check, that all of the entries in
|
||
lens[] are in the range 0..MAXBITS. The caller must assure this.
|
||
1..MAXBITS is interpreted as that code length. zero means that that
|
||
symbol does not occur in this code.
|
||
|
||
The codes are sorted by computing a count of codes for each length,
|
||
creating from that a table of starting indices for each length in the
|
||
sorted table, and then entering the symbols in order in the sorted
|
||
table. The sorted table is work[], with that space being provided by
|
||
the caller.
|
||
|
||
The length counts are used for other purposes as well, i.e. finding
|
||
the minimum and maximum length codes, determining if there are any
|
||
codes at all, checking for a valid set of lengths, and looking ahead
|
||
at length counts to determine sub-table sizes when building the
|
||
decoding tables.
|
||
*/
|
||
|
||
/* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
|
||
for (len = 0; len <= MAXBITS; len++) {
|
||
count[len] = 0;
|
||
}
|
||
for (sym = 0; sym < codes; sym++) {
|
||
count[lens[lens_index + sym]]++;
|
||
}
|
||
|
||
/* bound code lengths, force root to be within code lengths */
|
||
root = bits;
|
||
for (max = MAXBITS; max >= 1; max--) {
|
||
if (count[max] !== 0) { break; }
|
||
}
|
||
if (root > max) {
|
||
root = max;
|
||
}
|
||
if (max === 0) { /* no symbols to code at all */
|
||
//table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */
|
||
//table.bits[opts.table_index] = 1; //here.bits = (var char)1;
|
||
//table.val[opts.table_index++] = 0; //here.val = (var short)0;
|
||
table[table_index++] = (1 << 24) | (64 << 16) | 0;
|
||
|
||
|
||
//table.op[opts.table_index] = 64;
|
||
//table.bits[opts.table_index] = 1;
|
||
//table.val[opts.table_index++] = 0;
|
||
table[table_index++] = (1 << 24) | (64 << 16) | 0;
|
||
|
||
opts.bits = 1;
|
||
return 0; /* no symbols, but wait for decoding to report error */
|
||
}
|
||
for (min = 1; min < max; min++) {
|
||
if (count[min] !== 0) { break; }
|
||
}
|
||
if (root < min) {
|
||
root = min;
|
||
}
|
||
|
||
/* check for an over-subscribed or incomplete set of lengths */
|
||
left = 1;
|
||
for (len = 1; len <= MAXBITS; len++) {
|
||
left <<= 1;
|
||
left -= count[len];
|
||
if (left < 0) {
|
||
return -1;
|
||
} /* over-subscribed */
|
||
}
|
||
if (left > 0 && (type === CODES || max !== 1)) {
|
||
return -1; /* incomplete set */
|
||
}
|
||
|
||
/* generate offsets into symbol table for each length for sorting */
|
||
offs[1] = 0;
|
||
for (len = 1; len < MAXBITS; len++) {
|
||
offs[len + 1] = offs[len] + count[len];
|
||
}
|
||
|
||
/* sort symbols by length, by symbol order within each length */
|
||
for (sym = 0; sym < codes; sym++) {
|
||
if (lens[lens_index + sym] !== 0) {
|
||
work[offs[lens[lens_index + sym]]++] = sym;
|
||
}
|
||
}
|
||
|
||
/*
|
||
Create and fill in decoding tables. In this loop, the table being
|
||
filled is at next and has curr index bits. The code being used is huff
|
||
with length len. That code is converted to an index by dropping drop
|
||
bits off of the bottom. For codes where len is less than drop + curr,
|
||
those top drop + curr - len bits are incremented through all values to
|
||
fill the table with replicated entries.
|
||
|
||
root is the number of index bits for the root table. When len exceeds
|
||
root, sub-tables are created pointed to by the root entry with an index
|
||
of the low root bits of huff. This is saved in low to check for when a
|
||
new sub-table should be started. drop is zero when the root table is
|
||
being filled, and drop is root when sub-tables are being filled.
|
||
|
||
When a new sub-table is needed, it is necessary to look ahead in the
|
||
code lengths to determine what size sub-table is needed. The length
|
||
counts are used for this, and so count[] is decremented as codes are
|
||
entered in the tables.
|
||
|
||
used keeps track of how many table entries have been allocated from the
|
||
provided *table space. It is checked for LENS and DIST tables against
|
||
the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
|
||
the initial root table size constants. See the comments in inftrees.h
|
||
for more information.
|
||
|
||
sym increments through all symbols, and the loop terminates when
|
||
all codes of length max, i.e. all codes, have been processed. This
|
||
routine permits incomplete codes, so another loop after this one fills
|
||
in the rest of the decoding tables with invalid code markers.
|
||
*/
|
||
|
||
/* set up for code type */
|
||
// poor man optimization - use if-else instead of switch,
|
||
// to avoid deopts in old v8
|
||
if (type === CODES) {
|
||
base = extra = work; /* dummy value--not used */
|
||
end = 19;
|
||
|
||
} else if (type === LENS) {
|
||
base = lbase;
|
||
base_index -= 257;
|
||
extra = lext;
|
||
extra_index -= 257;
|
||
end = 256;
|
||
|
||
} else { /* DISTS */
|
||
base = dbase;
|
||
extra = dext;
|
||
end = -1;
|
||
}
|
||
|
||
/* initialize opts for loop */
|
||
huff = 0; /* starting code */
|
||
sym = 0; /* starting code symbol */
|
||
len = min; /* starting code length */
|
||
next = table_index; /* current table to fill in */
|
||
curr = root; /* current table index bits */
|
||
drop = 0; /* current bits to drop from code for index */
|
||
low = -1; /* trigger new sub-table when len > root */
|
||
used = 1 << root; /* use root table entries */
|
||
mask = used - 1; /* mask for comparing low */
|
||
|
||
/* check available table space */
|
||
if ((type === LENS && used > ENOUGH_LENS) ||
|
||
(type === DISTS && used > ENOUGH_DISTS)) {
|
||
return 1;
|
||
}
|
||
|
||
/* process all codes and make table entries */
|
||
for (;;) {
|
||
/* create table entry */
|
||
here_bits = len - drop;
|
||
if (work[sym] < end) {
|
||
here_op = 0;
|
||
here_val = work[sym];
|
||
}
|
||
else if (work[sym] > end) {
|
||
here_op = extra[extra_index + work[sym]];
|
||
here_val = base[base_index + work[sym]];
|
||
}
|
||
else {
|
||
here_op = 32 + 64; /* end of block */
|
||
here_val = 0;
|
||
}
|
||
|
||
/* replicate for those indices with low len bits equal to huff */
|
||
incr = 1 << (len - drop);
|
||
fill = 1 << curr;
|
||
min = fill; /* save offset to next table */
|
||
do {
|
||
fill -= incr;
|
||
table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0;
|
||
} while (fill !== 0);
|
||
|
||
/* backwards increment the len-bit code huff */
|
||
incr = 1 << (len - 1);
|
||
while (huff & incr) {
|
||
incr >>= 1;
|
||
}
|
||
if (incr !== 0) {
|
||
huff &= incr - 1;
|
||
huff += incr;
|
||
} else {
|
||
huff = 0;
|
||
}
|
||
|
||
/* go to next symbol, update count, len */
|
||
sym++;
|
||
if (--count[len] === 0) {
|
||
if (len === max) { break; }
|
||
len = lens[lens_index + work[sym]];
|
||
}
|
||
|
||
/* create new sub-table if needed */
|
||
if (len > root && (huff & mask) !== low) {
|
||
/* if first time, transition to sub-tables */
|
||
if (drop === 0) {
|
||
drop = root;
|
||
}
|
||
|
||
/* increment past last table */
|
||
next += min; /* here min is 1 << curr */
|
||
|
||
/* determine length of next table */
|
||
curr = len - drop;
|
||
left = 1 << curr;
|
||
while (curr + drop < max) {
|
||
left -= count[curr + drop];
|
||
if (left <= 0) { break; }
|
||
curr++;
|
||
left <<= 1;
|
||
}
|
||
|
||
/* check for enough space */
|
||
used += 1 << curr;
|
||
if ((type === LENS && used > ENOUGH_LENS) ||
|
||
(type === DISTS && used > ENOUGH_DISTS)) {
|
||
return 1;
|
||
}
|
||
|
||
/* point entry in root table to sub-table */
|
||
low = huff & mask;
|
||
/*table.op[low] = curr;
|
||
table.bits[low] = root;
|
||
table.val[low] = next - opts.table_index;*/
|
||
table[low] = (root << 24) | (curr << 16) | (next - table_index) |0;
|
||
}
|
||
}
|
||
|
||
/* fill in remaining table entry if code is incomplete (guaranteed to have
|
||
at most one remaining entry, since if the code is incomplete, the
|
||
maximum code length that was allowed to get this far is one bit) */
|
||
if (huff !== 0) {
|
||
//table.op[next + huff] = 64; /* invalid code marker */
|
||
//table.bits[next + huff] = len - drop;
|
||
//table.val[next + huff] = 0;
|
||
table[next + huff] = ((len - drop) << 24) | (64 << 16) |0;
|
||
}
|
||
|
||
/* set return parameters */
|
||
//opts.table_index += used;
|
||
opts.bits = root;
|
||
return 0;
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pako/lib/zlib/messages.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/pako/lib/zlib/messages.js ***!
|
||
\************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||
//
|
||
// This software is provided 'as-is', without any express or implied
|
||
// warranty. In no event will the authors be held liable for any damages
|
||
// arising from the use of this software.
|
||
//
|
||
// Permission is granted to anyone to use this software for any purpose,
|
||
// including commercial applications, and to alter it and redistribute it
|
||
// freely, subject to the following restrictions:
|
||
//
|
||
// 1. The origin of this software must not be misrepresented; you must not
|
||
// claim that you wrote the original software. If you use this software
|
||
// in a product, an acknowledgment in the product documentation would be
|
||
// appreciated but is not required.
|
||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||
// misrepresented as being the original software.
|
||
// 3. This notice may not be removed or altered from any source distribution.
|
||
|
||
module.exports = {
|
||
2: 'need dictionary', /* Z_NEED_DICT 2 */
|
||
1: 'stream end', /* Z_STREAM_END 1 */
|
||
0: '', /* Z_OK 0 */
|
||
'-1': 'file error', /* Z_ERRNO (-1) */
|
||
'-2': 'stream error', /* Z_STREAM_ERROR (-2) */
|
||
'-3': 'data error', /* Z_DATA_ERROR (-3) */
|
||
'-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */
|
||
'-5': 'buffer error', /* Z_BUF_ERROR (-5) */
|
||
'-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pako/lib/zlib/trees.js":
|
||
/*!*********************************************!*\
|
||
!*** ./node_modules/pako/lib/zlib/trees.js ***!
|
||
\*********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||
//
|
||
// This software is provided 'as-is', without any express or implied
|
||
// warranty. In no event will the authors be held liable for any damages
|
||
// arising from the use of this software.
|
||
//
|
||
// Permission is granted to anyone to use this software for any purpose,
|
||
// including commercial applications, and to alter it and redistribute it
|
||
// freely, subject to the following restrictions:
|
||
//
|
||
// 1. The origin of this software must not be misrepresented; you must not
|
||
// claim that you wrote the original software. If you use this software
|
||
// in a product, an acknowledgment in the product documentation would be
|
||
// appreciated but is not required.
|
||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||
// misrepresented as being the original software.
|
||
// 3. This notice may not be removed or altered from any source distribution.
|
||
|
||
/* eslint-disable space-unary-ops */
|
||
|
||
var utils = __webpack_require__(/*! ../utils/common */ "./node_modules/pako/lib/utils/common.js");
|
||
|
||
/* Public constants ==========================================================*/
|
||
/* ===========================================================================*/
|
||
|
||
|
||
//var Z_FILTERED = 1;
|
||
//var Z_HUFFMAN_ONLY = 2;
|
||
//var Z_RLE = 3;
|
||
var Z_FIXED = 4;
|
||
//var Z_DEFAULT_STRATEGY = 0;
|
||
|
||
/* Possible values of the data_type field (though see inflate()) */
|
||
var Z_BINARY = 0;
|
||
var Z_TEXT = 1;
|
||
//var Z_ASCII = 1; // = Z_TEXT
|
||
var Z_UNKNOWN = 2;
|
||
|
||
/*============================================================================*/
|
||
|
||
|
||
function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } }
|
||
|
||
// From zutil.h
|
||
|
||
var STORED_BLOCK = 0;
|
||
var STATIC_TREES = 1;
|
||
var DYN_TREES = 2;
|
||
/* The three kinds of block type */
|
||
|
||
var MIN_MATCH = 3;
|
||
var MAX_MATCH = 258;
|
||
/* The minimum and maximum match lengths */
|
||
|
||
// From deflate.h
|
||
/* ===========================================================================
|
||
* Internal compression state.
|
||
*/
|
||
|
||
var LENGTH_CODES = 29;
|
||
/* number of length codes, not counting the special END_BLOCK code */
|
||
|
||
var LITERALS = 256;
|
||
/* number of literal bytes 0..255 */
|
||
|
||
var L_CODES = LITERALS + 1 + LENGTH_CODES;
|
||
/* number of Literal or Length codes, including the END_BLOCK code */
|
||
|
||
var D_CODES = 30;
|
||
/* number of distance codes */
|
||
|
||
var BL_CODES = 19;
|
||
/* number of codes used to transfer the bit lengths */
|
||
|
||
var HEAP_SIZE = 2 * L_CODES + 1;
|
||
/* maximum heap size */
|
||
|
||
var MAX_BITS = 15;
|
||
/* All codes must not exceed MAX_BITS bits */
|
||
|
||
var Buf_size = 16;
|
||
/* size of bit buffer in bi_buf */
|
||
|
||
|
||
/* ===========================================================================
|
||
* Constants
|
||
*/
|
||
|
||
var MAX_BL_BITS = 7;
|
||
/* Bit length codes must not exceed MAX_BL_BITS bits */
|
||
|
||
var END_BLOCK = 256;
|
||
/* end of block literal code */
|
||
|
||
var REP_3_6 = 16;
|
||
/* repeat previous bit length 3-6 times (2 bits of repeat count) */
|
||
|
||
var REPZ_3_10 = 17;
|
||
/* repeat a zero length 3-10 times (3 bits of repeat count) */
|
||
|
||
var REPZ_11_138 = 18;
|
||
/* repeat a zero length 11-138 times (7 bits of repeat count) */
|
||
|
||
/* eslint-disable comma-spacing,array-bracket-spacing */
|
||
var extra_lbits = /* extra bits for each length code */
|
||
[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0];
|
||
|
||
var extra_dbits = /* extra bits for each distance code */
|
||
[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13];
|
||
|
||
var extra_blbits = /* extra bits for each bit length code */
|
||
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7];
|
||
|
||
var bl_order =
|
||
[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];
|
||
/* eslint-enable comma-spacing,array-bracket-spacing */
|
||
|
||
/* The lengths of the bit length codes are sent in order of decreasing
|
||
* probability, to avoid transmitting the lengths for unused bit length codes.
|
||
*/
|
||
|
||
/* ===========================================================================
|
||
* Local data. These are initialized only once.
|
||
*/
|
||
|
||
// We pre-fill arrays with 0 to avoid uninitialized gaps
|
||
|
||
var DIST_CODE_LEN = 512; /* see definition of array dist_code below */
|
||
|
||
// !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1
|
||
var static_ltree = new Array((L_CODES + 2) * 2);
|
||
zero(static_ltree);
|
||
/* The static literal tree. Since the bit lengths are imposed, there is no
|
||
* need for the L_CODES extra codes used during heap construction. However
|
||
* The codes 286 and 287 are needed to build a canonical tree (see _tr_init
|
||
* below).
|
||
*/
|
||
|
||
var static_dtree = new Array(D_CODES * 2);
|
||
zero(static_dtree);
|
||
/* The static distance tree. (Actually a trivial tree since all codes use
|
||
* 5 bits.)
|
||
*/
|
||
|
||
var _dist_code = new Array(DIST_CODE_LEN);
|
||
zero(_dist_code);
|
||
/* Distance codes. The first 256 values correspond to the distances
|
||
* 3 .. 258, the last 256 values correspond to the top 8 bits of
|
||
* the 15 bit distances.
|
||
*/
|
||
|
||
var _length_code = new Array(MAX_MATCH - MIN_MATCH + 1);
|
||
zero(_length_code);
|
||
/* length code for each normalized match length (0 == MIN_MATCH) */
|
||
|
||
var base_length = new Array(LENGTH_CODES);
|
||
zero(base_length);
|
||
/* First normalized length for each code (0 = MIN_MATCH) */
|
||
|
||
var base_dist = new Array(D_CODES);
|
||
zero(base_dist);
|
||
/* First normalized distance for each code (0 = distance of 1) */
|
||
|
||
|
||
function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) {
|
||
|
||
this.static_tree = static_tree; /* static tree or NULL */
|
||
this.extra_bits = extra_bits; /* extra bits for each code or NULL */
|
||
this.extra_base = extra_base; /* base index for extra_bits */
|
||
this.elems = elems; /* max number of elements in the tree */
|
||
this.max_length = max_length; /* max bit length for the codes */
|
||
|
||
// show if `static_tree` has data or dummy - needed for monomorphic objects
|
||
this.has_stree = static_tree && static_tree.length;
|
||
}
|
||
|
||
|
||
var static_l_desc;
|
||
var static_d_desc;
|
||
var static_bl_desc;
|
||
|
||
|
||
function TreeDesc(dyn_tree, stat_desc) {
|
||
this.dyn_tree = dyn_tree; /* the dynamic tree */
|
||
this.max_code = 0; /* largest code with non zero frequency */
|
||
this.stat_desc = stat_desc; /* the corresponding static tree */
|
||
}
|
||
|
||
|
||
|
||
function d_code(dist) {
|
||
return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)];
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Output a short LSB first on the stream.
|
||
* IN assertion: there is enough room in pendingBuf.
|
||
*/
|
||
function put_short(s, w) {
|
||
// put_byte(s, (uch)((w) & 0xff));
|
||
// put_byte(s, (uch)((ush)(w) >> 8));
|
||
s.pending_buf[s.pending++] = (w) & 0xff;
|
||
s.pending_buf[s.pending++] = (w >>> 8) & 0xff;
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Send a value on a given number of bits.
|
||
* IN assertion: length <= 16 and value fits in length bits.
|
||
*/
|
||
function send_bits(s, value, length) {
|
||
if (s.bi_valid > (Buf_size - length)) {
|
||
s.bi_buf |= (value << s.bi_valid) & 0xffff;
|
||
put_short(s, s.bi_buf);
|
||
s.bi_buf = value >> (Buf_size - s.bi_valid);
|
||
s.bi_valid += length - Buf_size;
|
||
} else {
|
||
s.bi_buf |= (value << s.bi_valid) & 0xffff;
|
||
s.bi_valid += length;
|
||
}
|
||
}
|
||
|
||
|
||
function send_code(s, c, tree) {
|
||
send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/);
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Reverse the first len bits of a code, using straightforward code (a faster
|
||
* method would use a table)
|
||
* IN assertion: 1 <= len <= 15
|
||
*/
|
||
function bi_reverse(code, len) {
|
||
var res = 0;
|
||
do {
|
||
res |= code & 1;
|
||
code >>>= 1;
|
||
res <<= 1;
|
||
} while (--len > 0);
|
||
return res >>> 1;
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Flush the bit buffer, keeping at most 7 bits in it.
|
||
*/
|
||
function bi_flush(s) {
|
||
if (s.bi_valid === 16) {
|
||
put_short(s, s.bi_buf);
|
||
s.bi_buf = 0;
|
||
s.bi_valid = 0;
|
||
|
||
} else if (s.bi_valid >= 8) {
|
||
s.pending_buf[s.pending++] = s.bi_buf & 0xff;
|
||
s.bi_buf >>= 8;
|
||
s.bi_valid -= 8;
|
||
}
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Compute the optimal bit lengths for a tree and update the total bit length
|
||
* for the current block.
|
||
* IN assertion: the fields freq and dad are set, heap[heap_max] and
|
||
* above are the tree nodes sorted by increasing frequency.
|
||
* OUT assertions: the field len is set to the optimal bit length, the
|
||
* array bl_count contains the frequencies for each bit length.
|
||
* The length opt_len is updated; static_len is also updated if stree is
|
||
* not null.
|
||
*/
|
||
function gen_bitlen(s, desc)
|
||
// deflate_state *s;
|
||
// tree_desc *desc; /* the tree descriptor */
|
||
{
|
||
var tree = desc.dyn_tree;
|
||
var max_code = desc.max_code;
|
||
var stree = desc.stat_desc.static_tree;
|
||
var has_stree = desc.stat_desc.has_stree;
|
||
var extra = desc.stat_desc.extra_bits;
|
||
var base = desc.stat_desc.extra_base;
|
||
var max_length = desc.stat_desc.max_length;
|
||
var h; /* heap index */
|
||
var n, m; /* iterate over the tree elements */
|
||
var bits; /* bit length */
|
||
var xbits; /* extra bits */
|
||
var f; /* frequency */
|
||
var overflow = 0; /* number of elements with bit length too large */
|
||
|
||
for (bits = 0; bits <= MAX_BITS; bits++) {
|
||
s.bl_count[bits] = 0;
|
||
}
|
||
|
||
/* In a first pass, compute the optimal bit lengths (which may
|
||
* overflow in the case of the bit length tree).
|
||
*/
|
||
tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */
|
||
|
||
for (h = s.heap_max + 1; h < HEAP_SIZE; h++) {
|
||
n = s.heap[h];
|
||
bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1;
|
||
if (bits > max_length) {
|
||
bits = max_length;
|
||
overflow++;
|
||
}
|
||
tree[n * 2 + 1]/*.Len*/ = bits;
|
||
/* We overwrite tree[n].Dad which is no longer needed */
|
||
|
||
if (n > max_code) { continue; } /* not a leaf node */
|
||
|
||
s.bl_count[bits]++;
|
||
xbits = 0;
|
||
if (n >= base) {
|
||
xbits = extra[n - base];
|
||
}
|
||
f = tree[n * 2]/*.Freq*/;
|
||
s.opt_len += f * (bits + xbits);
|
||
if (has_stree) {
|
||
s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits);
|
||
}
|
||
}
|
||
if (overflow === 0) { return; }
|
||
|
||
// Trace((stderr,"\nbit length overflow\n"));
|
||
/* This happens for example on obj2 and pic of the Calgary corpus */
|
||
|
||
/* Find the first bit length which could increase: */
|
||
do {
|
||
bits = max_length - 1;
|
||
while (s.bl_count[bits] === 0) { bits--; }
|
||
s.bl_count[bits]--; /* move one leaf down the tree */
|
||
s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */
|
||
s.bl_count[max_length]--;
|
||
/* The brother of the overflow item also moves one step up,
|
||
* but this does not affect bl_count[max_length]
|
||
*/
|
||
overflow -= 2;
|
||
} while (overflow > 0);
|
||
|
||
/* Now recompute all bit lengths, scanning in increasing frequency.
|
||
* h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
|
||
* lengths instead of fixing only the wrong ones. This idea is taken
|
||
* from 'ar' written by Haruhiko Okumura.)
|
||
*/
|
||
for (bits = max_length; bits !== 0; bits--) {
|
||
n = s.bl_count[bits];
|
||
while (n !== 0) {
|
||
m = s.heap[--h];
|
||
if (m > max_code) { continue; }
|
||
if (tree[m * 2 + 1]/*.Len*/ !== bits) {
|
||
// Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
|
||
s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/;
|
||
tree[m * 2 + 1]/*.Len*/ = bits;
|
||
}
|
||
n--;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Generate the codes for a given tree and bit counts (which need not be
|
||
* optimal).
|
||
* IN assertion: the array bl_count contains the bit length statistics for
|
||
* the given tree and the field len is set for all tree elements.
|
||
* OUT assertion: the field code is set for all tree elements of non
|
||
* zero code length.
|
||
*/
|
||
function gen_codes(tree, max_code, bl_count)
|
||
// ct_data *tree; /* the tree to decorate */
|
||
// int max_code; /* largest code with non zero frequency */
|
||
// ushf *bl_count; /* number of codes at each bit length */
|
||
{
|
||
var next_code = new Array(MAX_BITS + 1); /* next code value for each bit length */
|
||
var code = 0; /* running code value */
|
||
var bits; /* bit index */
|
||
var n; /* code index */
|
||
|
||
/* The distribution counts are first used to generate the code values
|
||
* without bit reversal.
|
||
*/
|
||
for (bits = 1; bits <= MAX_BITS; bits++) {
|
||
next_code[bits] = code = (code + bl_count[bits - 1]) << 1;
|
||
}
|
||
/* Check that the bit counts in bl_count are consistent. The last code
|
||
* must be all ones.
|
||
*/
|
||
//Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
|
||
// "inconsistent bit counts");
|
||
//Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
|
||
|
||
for (n = 0; n <= max_code; n++) {
|
||
var len = tree[n * 2 + 1]/*.Len*/;
|
||
if (len === 0) { continue; }
|
||
/* Now reverse the bits */
|
||
tree[n * 2]/*.Code*/ = bi_reverse(next_code[len]++, len);
|
||
|
||
//Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
|
||
// n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
|
||
}
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Initialize the various 'constant' tables.
|
||
*/
|
||
function tr_static_init() {
|
||
var n; /* iterates over tree elements */
|
||
var bits; /* bit counter */
|
||
var length; /* length value */
|
||
var code; /* code value */
|
||
var dist; /* distance index */
|
||
var bl_count = new Array(MAX_BITS + 1);
|
||
/* number of codes at each bit length for an optimal tree */
|
||
|
||
// do check in _tr_init()
|
||
//if (static_init_done) return;
|
||
|
||
/* For some embedded targets, global variables are not initialized: */
|
||
/*#ifdef NO_INIT_GLOBAL_POINTERS
|
||
static_l_desc.static_tree = static_ltree;
|
||
static_l_desc.extra_bits = extra_lbits;
|
||
static_d_desc.static_tree = static_dtree;
|
||
static_d_desc.extra_bits = extra_dbits;
|
||
static_bl_desc.extra_bits = extra_blbits;
|
||
#endif*/
|
||
|
||
/* Initialize the mapping length (0..255) -> length code (0..28) */
|
||
length = 0;
|
||
for (code = 0; code < LENGTH_CODES - 1; code++) {
|
||
base_length[code] = length;
|
||
for (n = 0; n < (1 << extra_lbits[code]); n++) {
|
||
_length_code[length++] = code;
|
||
}
|
||
}
|
||
//Assert (length == 256, "tr_static_init: length != 256");
|
||
/* Note that the length 255 (match length 258) can be represented
|
||
* in two different ways: code 284 + 5 bits or code 285, so we
|
||
* overwrite length_code[255] to use the best encoding:
|
||
*/
|
||
_length_code[length - 1] = code;
|
||
|
||
/* Initialize the mapping dist (0..32K) -> dist code (0..29) */
|
||
dist = 0;
|
||
for (code = 0; code < 16; code++) {
|
||
base_dist[code] = dist;
|
||
for (n = 0; n < (1 << extra_dbits[code]); n++) {
|
||
_dist_code[dist++] = code;
|
||
}
|
||
}
|
||
//Assert (dist == 256, "tr_static_init: dist != 256");
|
||
dist >>= 7; /* from now on, all distances are divided by 128 */
|
||
for (; code < D_CODES; code++) {
|
||
base_dist[code] = dist << 7;
|
||
for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {
|
||
_dist_code[256 + dist++] = code;
|
||
}
|
||
}
|
||
//Assert (dist == 256, "tr_static_init: 256+dist != 512");
|
||
|
||
/* Construct the codes of the static literal tree */
|
||
for (bits = 0; bits <= MAX_BITS; bits++) {
|
||
bl_count[bits] = 0;
|
||
}
|
||
|
||
n = 0;
|
||
while (n <= 143) {
|
||
static_ltree[n * 2 + 1]/*.Len*/ = 8;
|
||
n++;
|
||
bl_count[8]++;
|
||
}
|
||
while (n <= 255) {
|
||
static_ltree[n * 2 + 1]/*.Len*/ = 9;
|
||
n++;
|
||
bl_count[9]++;
|
||
}
|
||
while (n <= 279) {
|
||
static_ltree[n * 2 + 1]/*.Len*/ = 7;
|
||
n++;
|
||
bl_count[7]++;
|
||
}
|
||
while (n <= 287) {
|
||
static_ltree[n * 2 + 1]/*.Len*/ = 8;
|
||
n++;
|
||
bl_count[8]++;
|
||
}
|
||
/* Codes 286 and 287 do not exist, but we must include them in the
|
||
* tree construction to get a canonical Huffman tree (longest code
|
||
* all ones)
|
||
*/
|
||
gen_codes(static_ltree, L_CODES + 1, bl_count);
|
||
|
||
/* The static distance tree is trivial: */
|
||
for (n = 0; n < D_CODES; n++) {
|
||
static_dtree[n * 2 + 1]/*.Len*/ = 5;
|
||
static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5);
|
||
}
|
||
|
||
// Now data ready and we can init static trees
|
||
static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);
|
||
static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES, MAX_BITS);
|
||
static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES, MAX_BL_BITS);
|
||
|
||
//static_init_done = true;
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Initialize a new block.
|
||
*/
|
||
function init_block(s) {
|
||
var n; /* iterates over tree elements */
|
||
|
||
/* Initialize the trees. */
|
||
for (n = 0; n < L_CODES; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; }
|
||
for (n = 0; n < D_CODES; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; }
|
||
for (n = 0; n < BL_CODES; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; }
|
||
|
||
s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1;
|
||
s.opt_len = s.static_len = 0;
|
||
s.last_lit = s.matches = 0;
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Flush the bit buffer and align the output on a byte boundary
|
||
*/
|
||
function bi_windup(s)
|
||
{
|
||
if (s.bi_valid > 8) {
|
||
put_short(s, s.bi_buf);
|
||
} else if (s.bi_valid > 0) {
|
||
//put_byte(s, (Byte)s->bi_buf);
|
||
s.pending_buf[s.pending++] = s.bi_buf;
|
||
}
|
||
s.bi_buf = 0;
|
||
s.bi_valid = 0;
|
||
}
|
||
|
||
/* ===========================================================================
|
||
* Copy a stored block, storing first the length and its
|
||
* one's complement if requested.
|
||
*/
|
||
function copy_block(s, buf, len, header)
|
||
//DeflateState *s;
|
||
//charf *buf; /* the input data */
|
||
//unsigned len; /* its length */
|
||
//int header; /* true if block header must be written */
|
||
{
|
||
bi_windup(s); /* align on byte boundary */
|
||
|
||
if (header) {
|
||
put_short(s, len);
|
||
put_short(s, ~len);
|
||
}
|
||
// while (len--) {
|
||
// put_byte(s, *buf++);
|
||
// }
|
||
utils.arraySet(s.pending_buf, s.window, buf, len, s.pending);
|
||
s.pending += len;
|
||
}
|
||
|
||
/* ===========================================================================
|
||
* Compares to subtrees, using the tree depth as tie breaker when
|
||
* the subtrees have equal frequency. This minimizes the worst case length.
|
||
*/
|
||
function smaller(tree, n, m, depth) {
|
||
var _n2 = n * 2;
|
||
var _m2 = m * 2;
|
||
return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ ||
|
||
(tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m]));
|
||
}
|
||
|
||
/* ===========================================================================
|
||
* Restore the heap property by moving down the tree starting at node k,
|
||
* exchanging a node with the smallest of its two sons if necessary, stopping
|
||
* when the heap property is re-established (each father smaller than its
|
||
* two sons).
|
||
*/
|
||
function pqdownheap(s, tree, k)
|
||
// deflate_state *s;
|
||
// ct_data *tree; /* the tree to restore */
|
||
// int k; /* node to move down */
|
||
{
|
||
var v = s.heap[k];
|
||
var j = k << 1; /* left son of k */
|
||
while (j <= s.heap_len) {
|
||
/* Set j to the smallest of the two sons: */
|
||
if (j < s.heap_len &&
|
||
smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) {
|
||
j++;
|
||
}
|
||
/* Exit if v is smaller than both sons */
|
||
if (smaller(tree, v, s.heap[j], s.depth)) { break; }
|
||
|
||
/* Exchange v with the smallest son */
|
||
s.heap[k] = s.heap[j];
|
||
k = j;
|
||
|
||
/* And continue down the tree, setting j to the left son of k */
|
||
j <<= 1;
|
||
}
|
||
s.heap[k] = v;
|
||
}
|
||
|
||
|
||
// inlined manually
|
||
// var SMALLEST = 1;
|
||
|
||
/* ===========================================================================
|
||
* Send the block data compressed using the given Huffman trees
|
||
*/
|
||
function compress_block(s, ltree, dtree)
|
||
// deflate_state *s;
|
||
// const ct_data *ltree; /* literal tree */
|
||
// const ct_data *dtree; /* distance tree */
|
||
{
|
||
var dist; /* distance of matched string */
|
||
var lc; /* match length or unmatched char (if dist == 0) */
|
||
var lx = 0; /* running index in l_buf */
|
||
var code; /* the code to send */
|
||
var extra; /* number of extra bits to send */
|
||
|
||
if (s.last_lit !== 0) {
|
||
do {
|
||
dist = (s.pending_buf[s.d_buf + lx * 2] << 8) | (s.pending_buf[s.d_buf + lx * 2 + 1]);
|
||
lc = s.pending_buf[s.l_buf + lx];
|
||
lx++;
|
||
|
||
if (dist === 0) {
|
||
send_code(s, lc, ltree); /* send a literal byte */
|
||
//Tracecv(isgraph(lc), (stderr," '%c' ", lc));
|
||
} else {
|
||
/* Here, lc is the match length - MIN_MATCH */
|
||
code = _length_code[lc];
|
||
send_code(s, code + LITERALS + 1, ltree); /* send the length code */
|
||
extra = extra_lbits[code];
|
||
if (extra !== 0) {
|
||
lc -= base_length[code];
|
||
send_bits(s, lc, extra); /* send the extra length bits */
|
||
}
|
||
dist--; /* dist is now the match distance - 1 */
|
||
code = d_code(dist);
|
||
//Assert (code < D_CODES, "bad d_code");
|
||
|
||
send_code(s, code, dtree); /* send the distance code */
|
||
extra = extra_dbits[code];
|
||
if (extra !== 0) {
|
||
dist -= base_dist[code];
|
||
send_bits(s, dist, extra); /* send the extra distance bits */
|
||
}
|
||
} /* literal or match pair ? */
|
||
|
||
/* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
|
||
//Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
|
||
// "pendingBuf overflow");
|
||
|
||
} while (lx < s.last_lit);
|
||
}
|
||
|
||
send_code(s, END_BLOCK, ltree);
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Construct one Huffman tree and assigns the code bit strings and lengths.
|
||
* Update the total bit length for the current block.
|
||
* IN assertion: the field freq is set for all tree elements.
|
||
* OUT assertions: the fields len and code are set to the optimal bit length
|
||
* and corresponding code. The length opt_len is updated; static_len is
|
||
* also updated if stree is not null. The field max_code is set.
|
||
*/
|
||
function build_tree(s, desc)
|
||
// deflate_state *s;
|
||
// tree_desc *desc; /* the tree descriptor */
|
||
{
|
||
var tree = desc.dyn_tree;
|
||
var stree = desc.stat_desc.static_tree;
|
||
var has_stree = desc.stat_desc.has_stree;
|
||
var elems = desc.stat_desc.elems;
|
||
var n, m; /* iterate over heap elements */
|
||
var max_code = -1; /* largest code with non zero frequency */
|
||
var node; /* new node being created */
|
||
|
||
/* Construct the initial heap, with least frequent element in
|
||
* heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
|
||
* heap[0] is not used.
|
||
*/
|
||
s.heap_len = 0;
|
||
s.heap_max = HEAP_SIZE;
|
||
|
||
for (n = 0; n < elems; n++) {
|
||
if (tree[n * 2]/*.Freq*/ !== 0) {
|
||
s.heap[++s.heap_len] = max_code = n;
|
||
s.depth[n] = 0;
|
||
|
||
} else {
|
||
tree[n * 2 + 1]/*.Len*/ = 0;
|
||
}
|
||
}
|
||
|
||
/* The pkzip format requires that at least one distance code exists,
|
||
* and that at least one bit should be sent even if there is only one
|
||
* possible code. So to avoid special checks later on we force at least
|
||
* two codes of non zero frequency.
|
||
*/
|
||
while (s.heap_len < 2) {
|
||
node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0);
|
||
tree[node * 2]/*.Freq*/ = 1;
|
||
s.depth[node] = 0;
|
||
s.opt_len--;
|
||
|
||
if (has_stree) {
|
||
s.static_len -= stree[node * 2 + 1]/*.Len*/;
|
||
}
|
||
/* node is 0 or 1 so it does not have extra bits */
|
||
}
|
||
desc.max_code = max_code;
|
||
|
||
/* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
|
||
* establish sub-heaps of increasing lengths:
|
||
*/
|
||
for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); }
|
||
|
||
/* Construct the Huffman tree by repeatedly combining the least two
|
||
* frequent nodes.
|
||
*/
|
||
node = elems; /* next internal node of the tree */
|
||
do {
|
||
//pqremove(s, tree, n); /* n = node of least frequency */
|
||
/*** pqremove ***/
|
||
n = s.heap[1/*SMALLEST*/];
|
||
s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--];
|
||
pqdownheap(s, tree, 1/*SMALLEST*/);
|
||
/***/
|
||
|
||
m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */
|
||
|
||
s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */
|
||
s.heap[--s.heap_max] = m;
|
||
|
||
/* Create a new node father of n and m */
|
||
tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/;
|
||
s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1;
|
||
tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node;
|
||
|
||
/* and insert the new node in the heap */
|
||
s.heap[1/*SMALLEST*/] = node++;
|
||
pqdownheap(s, tree, 1/*SMALLEST*/);
|
||
|
||
} while (s.heap_len >= 2);
|
||
|
||
s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/];
|
||
|
||
/* At this point, the fields freq and dad are set. We can now
|
||
* generate the bit lengths.
|
||
*/
|
||
gen_bitlen(s, desc);
|
||
|
||
/* The field len is now set, we can generate the bit codes */
|
||
gen_codes(tree, max_code, s.bl_count);
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Scan a literal or distance tree to determine the frequencies of the codes
|
||
* in the bit length tree.
|
||
*/
|
||
function scan_tree(s, tree, max_code)
|
||
// deflate_state *s;
|
||
// ct_data *tree; /* the tree to be scanned */
|
||
// int max_code; /* and its largest code of non zero frequency */
|
||
{
|
||
var n; /* iterates over all tree elements */
|
||
var prevlen = -1; /* last emitted length */
|
||
var curlen; /* length of current code */
|
||
|
||
var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */
|
||
|
||
var count = 0; /* repeat count of the current code */
|
||
var max_count = 7; /* max repeat count */
|
||
var min_count = 4; /* min repeat count */
|
||
|
||
if (nextlen === 0) {
|
||
max_count = 138;
|
||
min_count = 3;
|
||
}
|
||
tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */
|
||
|
||
for (n = 0; n <= max_code; n++) {
|
||
curlen = nextlen;
|
||
nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;
|
||
|
||
if (++count < max_count && curlen === nextlen) {
|
||
continue;
|
||
|
||
} else if (count < min_count) {
|
||
s.bl_tree[curlen * 2]/*.Freq*/ += count;
|
||
|
||
} else if (curlen !== 0) {
|
||
|
||
if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; }
|
||
s.bl_tree[REP_3_6 * 2]/*.Freq*/++;
|
||
|
||
} else if (count <= 10) {
|
||
s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++;
|
||
|
||
} else {
|
||
s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++;
|
||
}
|
||
|
||
count = 0;
|
||
prevlen = curlen;
|
||
|
||
if (nextlen === 0) {
|
||
max_count = 138;
|
||
min_count = 3;
|
||
|
||
} else if (curlen === nextlen) {
|
||
max_count = 6;
|
||
min_count = 3;
|
||
|
||
} else {
|
||
max_count = 7;
|
||
min_count = 4;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Send a literal or distance tree in compressed form, using the codes in
|
||
* bl_tree.
|
||
*/
|
||
function send_tree(s, tree, max_code)
|
||
// deflate_state *s;
|
||
// ct_data *tree; /* the tree to be scanned */
|
||
// int max_code; /* and its largest code of non zero frequency */
|
||
{
|
||
var n; /* iterates over all tree elements */
|
||
var prevlen = -1; /* last emitted length */
|
||
var curlen; /* length of current code */
|
||
|
||
var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */
|
||
|
||
var count = 0; /* repeat count of the current code */
|
||
var max_count = 7; /* max repeat count */
|
||
var min_count = 4; /* min repeat count */
|
||
|
||
/* tree[max_code+1].Len = -1; */ /* guard already set */
|
||
if (nextlen === 0) {
|
||
max_count = 138;
|
||
min_count = 3;
|
||
}
|
||
|
||
for (n = 0; n <= max_code; n++) {
|
||
curlen = nextlen;
|
||
nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;
|
||
|
||
if (++count < max_count && curlen === nextlen) {
|
||
continue;
|
||
|
||
} else if (count < min_count) {
|
||
do { send_code(s, curlen, s.bl_tree); } while (--count !== 0);
|
||
|
||
} else if (curlen !== 0) {
|
||
if (curlen !== prevlen) {
|
||
send_code(s, curlen, s.bl_tree);
|
||
count--;
|
||
}
|
||
//Assert(count >= 3 && count <= 6, " 3_6?");
|
||
send_code(s, REP_3_6, s.bl_tree);
|
||
send_bits(s, count - 3, 2);
|
||
|
||
} else if (count <= 10) {
|
||
send_code(s, REPZ_3_10, s.bl_tree);
|
||
send_bits(s, count - 3, 3);
|
||
|
||
} else {
|
||
send_code(s, REPZ_11_138, s.bl_tree);
|
||
send_bits(s, count - 11, 7);
|
||
}
|
||
|
||
count = 0;
|
||
prevlen = curlen;
|
||
if (nextlen === 0) {
|
||
max_count = 138;
|
||
min_count = 3;
|
||
|
||
} else if (curlen === nextlen) {
|
||
max_count = 6;
|
||
min_count = 3;
|
||
|
||
} else {
|
||
max_count = 7;
|
||
min_count = 4;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Construct the Huffman tree for the bit lengths and return the index in
|
||
* bl_order of the last bit length code to send.
|
||
*/
|
||
function build_bl_tree(s) {
|
||
var max_blindex; /* index of last bit length code of non zero freq */
|
||
|
||
/* Determine the bit length frequencies for literal and distance trees */
|
||
scan_tree(s, s.dyn_ltree, s.l_desc.max_code);
|
||
scan_tree(s, s.dyn_dtree, s.d_desc.max_code);
|
||
|
||
/* Build the bit length tree: */
|
||
build_tree(s, s.bl_desc);
|
||
/* opt_len now includes the length of the tree representations, except
|
||
* the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
|
||
*/
|
||
|
||
/* Determine the number of bit length codes to send. The pkzip format
|
||
* requires that at least 4 bit length codes be sent. (appnote.txt says
|
||
* 3 but the actual value used is 4.)
|
||
*/
|
||
for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
|
||
if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) {
|
||
break;
|
||
}
|
||
}
|
||
/* Update opt_len to include the bit length tree and counts */
|
||
s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
|
||
//Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
|
||
// s->opt_len, s->static_len));
|
||
|
||
return max_blindex;
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Send the header for a block using dynamic Huffman trees: the counts, the
|
||
* lengths of the bit length codes, the literal tree and the distance tree.
|
||
* IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
|
||
*/
|
||
function send_all_trees(s, lcodes, dcodes, blcodes)
|
||
// deflate_state *s;
|
||
// int lcodes, dcodes, blcodes; /* number of codes for each tree */
|
||
{
|
||
var rank; /* index in bl_order */
|
||
|
||
//Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
|
||
//Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
|
||
// "too many codes");
|
||
//Tracev((stderr, "\nbl counts: "));
|
||
send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */
|
||
send_bits(s, dcodes - 1, 5);
|
||
send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */
|
||
for (rank = 0; rank < blcodes; rank++) {
|
||
//Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
|
||
send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3);
|
||
}
|
||
//Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
|
||
|
||
send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */
|
||
//Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
|
||
|
||
send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */
|
||
//Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Check if the data type is TEXT or BINARY, using the following algorithm:
|
||
* - TEXT if the two conditions below are satisfied:
|
||
* a) There are no non-portable control characters belonging to the
|
||
* "black list" (0..6, 14..25, 28..31).
|
||
* b) There is at least one printable character belonging to the
|
||
* "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
|
||
* - BINARY otherwise.
|
||
* - The following partially-portable control characters form a
|
||
* "gray list" that is ignored in this detection algorithm:
|
||
* (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
|
||
* IN assertion: the fields Freq of dyn_ltree are set.
|
||
*/
|
||
function detect_data_type(s) {
|
||
/* black_mask is the bit mask of black-listed bytes
|
||
* set bits 0..6, 14..25, and 28..31
|
||
* 0xf3ffc07f = binary 11110011111111111100000001111111
|
||
*/
|
||
var black_mask = 0xf3ffc07f;
|
||
var n;
|
||
|
||
/* Check for non-textual ("black-listed") bytes. */
|
||
for (n = 0; n <= 31; n++, black_mask >>>= 1) {
|
||
if ((black_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) {
|
||
return Z_BINARY;
|
||
}
|
||
}
|
||
|
||
/* Check for textual ("white-listed") bytes. */
|
||
if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 ||
|
||
s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) {
|
||
return Z_TEXT;
|
||
}
|
||
for (n = 32; n < LITERALS; n++) {
|
||
if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) {
|
||
return Z_TEXT;
|
||
}
|
||
}
|
||
|
||
/* There are no "black-listed" or "white-listed" bytes:
|
||
* this stream either is empty or has tolerated ("gray-listed") bytes only.
|
||
*/
|
||
return Z_BINARY;
|
||
}
|
||
|
||
|
||
var static_init_done = false;
|
||
|
||
/* ===========================================================================
|
||
* Initialize the tree data structures for a new zlib stream.
|
||
*/
|
||
function _tr_init(s)
|
||
{
|
||
|
||
if (!static_init_done) {
|
||
tr_static_init();
|
||
static_init_done = true;
|
||
}
|
||
|
||
s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc);
|
||
s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc);
|
||
s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc);
|
||
|
||
s.bi_buf = 0;
|
||
s.bi_valid = 0;
|
||
|
||
/* Initialize the first block of the first file: */
|
||
init_block(s);
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Send a stored block
|
||
*/
|
||
function _tr_stored_block(s, buf, stored_len, last)
|
||
//DeflateState *s;
|
||
//charf *buf; /* input block */
|
||
//ulg stored_len; /* length of input block */
|
||
//int last; /* one if this is the last block for a file */
|
||
{
|
||
send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */
|
||
copy_block(s, buf, stored_len, true); /* with header */
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Send one empty static block to give enough lookahead for inflate.
|
||
* This takes 10 bits, of which 7 may remain in the bit buffer.
|
||
*/
|
||
function _tr_align(s) {
|
||
send_bits(s, STATIC_TREES << 1, 3);
|
||
send_code(s, END_BLOCK, static_ltree);
|
||
bi_flush(s);
|
||
}
|
||
|
||
|
||
/* ===========================================================================
|
||
* Determine the best encoding for the current block: dynamic trees, static
|
||
* trees or store, and output the encoded block to the zip file.
|
||
*/
|
||
function _tr_flush_block(s, buf, stored_len, last)
|
||
//DeflateState *s;
|
||
//charf *buf; /* input block, or NULL if too old */
|
||
//ulg stored_len; /* length of input block */
|
||
//int last; /* one if this is the last block for a file */
|
||
{
|
||
var opt_lenb, static_lenb; /* opt_len and static_len in bytes */
|
||
var max_blindex = 0; /* index of last bit length code of non zero freq */
|
||
|
||
/* Build the Huffman trees unless a stored block is forced */
|
||
if (s.level > 0) {
|
||
|
||
/* Check if the file is binary or text */
|
||
if (s.strm.data_type === Z_UNKNOWN) {
|
||
s.strm.data_type = detect_data_type(s);
|
||
}
|
||
|
||
/* Construct the literal and distance trees */
|
||
build_tree(s, s.l_desc);
|
||
// Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
|
||
// s->static_len));
|
||
|
||
build_tree(s, s.d_desc);
|
||
// Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
|
||
// s->static_len));
|
||
/* At this point, opt_len and static_len are the total bit lengths of
|
||
* the compressed block data, excluding the tree representations.
|
||
*/
|
||
|
||
/* Build the bit length tree for the above two trees, and get the index
|
||
* in bl_order of the last bit length code to send.
|
||
*/
|
||
max_blindex = build_bl_tree(s);
|
||
|
||
/* Determine the best encoding. Compute the block lengths in bytes. */
|
||
opt_lenb = (s.opt_len + 3 + 7) >>> 3;
|
||
static_lenb = (s.static_len + 3 + 7) >>> 3;
|
||
|
||
// Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
|
||
// opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
|
||
// s->last_lit));
|
||
|
||
if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; }
|
||
|
||
} else {
|
||
// Assert(buf != (char*)0, "lost buf");
|
||
opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
|
||
}
|
||
|
||
if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) {
|
||
/* 4: two words for the lengths */
|
||
|
||
/* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
|
||
* Otherwise we can't have processed more than WSIZE input bytes since
|
||
* the last block flush, because compression would have been
|
||
* successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
|
||
* transform a block into a stored block.
|
||
*/
|
||
_tr_stored_block(s, buf, stored_len, last);
|
||
|
||
} else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) {
|
||
|
||
send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3);
|
||
compress_block(s, static_ltree, static_dtree);
|
||
|
||
} else {
|
||
send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3);
|
||
send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1);
|
||
compress_block(s, s.dyn_ltree, s.dyn_dtree);
|
||
}
|
||
// Assert (s->compressed_len == s->bits_sent, "bad compressed size");
|
||
/* The above check is made mod 2^32, for files larger than 512 MB
|
||
* and uLong implemented on 32 bits.
|
||
*/
|
||
init_block(s);
|
||
|
||
if (last) {
|
||
bi_windup(s);
|
||
}
|
||
// Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
|
||
// s->compressed_len-7*last));
|
||
}
|
||
|
||
/* ===========================================================================
|
||
* Save the match info and tally the frequency counts. Return true if
|
||
* the current block must be flushed.
|
||
*/
|
||
function _tr_tally(s, dist, lc)
|
||
// deflate_state *s;
|
||
// unsigned dist; /* distance of matched string */
|
||
// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
|
||
{
|
||
//var out_length, in_length, dcode;
|
||
|
||
s.pending_buf[s.d_buf + s.last_lit * 2] = (dist >>> 8) & 0xff;
|
||
s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff;
|
||
|
||
s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff;
|
||
s.last_lit++;
|
||
|
||
if (dist === 0) {
|
||
/* lc is the unmatched char */
|
||
s.dyn_ltree[lc * 2]/*.Freq*/++;
|
||
} else {
|
||
s.matches++;
|
||
/* Here, lc is the match length - MIN_MATCH */
|
||
dist--; /* dist = match distance - 1 */
|
||
//Assert((ush)dist < (ush)MAX_DIST(s) &&
|
||
// (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
|
||
// (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
|
||
|
||
s.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]/*.Freq*/++;
|
||
s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++;
|
||
}
|
||
|
||
// (!) This block is disabled in zlib defaults,
|
||
// don't enable it for binary compatibility
|
||
|
||
//#ifdef TRUNCATE_BLOCK
|
||
// /* Try to guess if it is profitable to stop the current block here */
|
||
// if ((s.last_lit & 0x1fff) === 0 && s.level > 2) {
|
||
// /* Compute an upper bound for the compressed length */
|
||
// out_length = s.last_lit*8;
|
||
// in_length = s.strstart - s.block_start;
|
||
//
|
||
// for (dcode = 0; dcode < D_CODES; dcode++) {
|
||
// out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]);
|
||
// }
|
||
// out_length >>>= 3;
|
||
// //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
|
||
// // s->last_lit, in_length, out_length,
|
||
// // 100L - out_length*100L/in_length));
|
||
// if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) {
|
||
// return true;
|
||
// }
|
||
// }
|
||
//#endif
|
||
|
||
return (s.last_lit === s.lit_bufsize - 1);
|
||
/* We avoid equality with lit_bufsize because of wraparound at 64K
|
||
* on 16 bit machines and because stored blocks are restricted to
|
||
* 64K-1 bytes.
|
||
*/
|
||
}
|
||
|
||
exports._tr_init = _tr_init;
|
||
exports._tr_stored_block = _tr_stored_block;
|
||
exports._tr_flush_block = _tr_flush_block;
|
||
exports._tr_tally = _tr_tally;
|
||
exports._tr_align = _tr_align;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pako/lib/zlib/zstream.js":
|
||
/*!***********************************************!*\
|
||
!*** ./node_modules/pako/lib/zlib/zstream.js ***!
|
||
\***********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||
//
|
||
// This software is provided 'as-is', without any express or implied
|
||
// warranty. In no event will the authors be held liable for any damages
|
||
// arising from the use of this software.
|
||
//
|
||
// Permission is granted to anyone to use this software for any purpose,
|
||
// including commercial applications, and to alter it and redistribute it
|
||
// freely, subject to the following restrictions:
|
||
//
|
||
// 1. The origin of this software must not be misrepresented; you must not
|
||
// claim that you wrote the original software. If you use this software
|
||
// in a product, an acknowledgment in the product documentation would be
|
||
// appreciated but is not required.
|
||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||
// misrepresented as being the original software.
|
||
// 3. This notice may not be removed or altered from any source distribution.
|
||
|
||
function ZStream() {
|
||
/* next input byte */
|
||
this.input = null; // JS specific, because we have no pointers
|
||
this.next_in = 0;
|
||
/* number of bytes available at input */
|
||
this.avail_in = 0;
|
||
/* total number of input bytes read so far */
|
||
this.total_in = 0;
|
||
/* next output byte should be put there */
|
||
this.output = null; // JS specific, because we have no pointers
|
||
this.next_out = 0;
|
||
/* remaining free space at output */
|
||
this.avail_out = 0;
|
||
/* total number of bytes output so far */
|
||
this.total_out = 0;
|
||
/* last error message, NULL if no error */
|
||
this.msg = ''/*Z_NULL*/;
|
||
/* not visible by applications */
|
||
this.state = null;
|
||
/* best guess about the data type: binary or text */
|
||
this.data_type = 2/*Z_UNKNOWN*/;
|
||
/* adler32 value of the uncompressed data */
|
||
this.adler = 0;
|
||
}
|
||
|
||
module.exports = ZStream;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/parse-asn1/aesid.json":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/parse-asn1/aesid.json ***!
|
||
\********************************************/
|
||
/*! exports provided: 2.16.840.1.101.3.4.1.1, 2.16.840.1.101.3.4.1.2, 2.16.840.1.101.3.4.1.3, 2.16.840.1.101.3.4.1.4, 2.16.840.1.101.3.4.1.21, 2.16.840.1.101.3.4.1.22, 2.16.840.1.101.3.4.1.23, 2.16.840.1.101.3.4.1.24, 2.16.840.1.101.3.4.1.41, 2.16.840.1.101.3.4.1.42, 2.16.840.1.101.3.4.1.43, 2.16.840.1.101.3.4.1.44, default */
|
||
/***/ (function(module) {
|
||
|
||
module.exports = JSON.parse("{\"2.16.840.1.101.3.4.1.1\":\"aes-128-ecb\",\"2.16.840.1.101.3.4.1.2\":\"aes-128-cbc\",\"2.16.840.1.101.3.4.1.3\":\"aes-128-ofb\",\"2.16.840.1.101.3.4.1.4\":\"aes-128-cfb\",\"2.16.840.1.101.3.4.1.21\":\"aes-192-ecb\",\"2.16.840.1.101.3.4.1.22\":\"aes-192-cbc\",\"2.16.840.1.101.3.4.1.23\":\"aes-192-ofb\",\"2.16.840.1.101.3.4.1.24\":\"aes-192-cfb\",\"2.16.840.1.101.3.4.1.41\":\"aes-256-ecb\",\"2.16.840.1.101.3.4.1.42\":\"aes-256-cbc\",\"2.16.840.1.101.3.4.1.43\":\"aes-256-ofb\",\"2.16.840.1.101.3.4.1.44\":\"aes-256-cfb\"}");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/parse-asn1/asn1.js":
|
||
/*!*****************************************!*\
|
||
!*** ./node_modules/parse-asn1/asn1.js ***!
|
||
\*****************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
// from https://github.com/indutny/self-signed/blob/gh-pages/lib/asn1.js
|
||
// Fedor, you are amazing.
|
||
|
||
|
||
var asn1 = __webpack_require__(/*! asn1.js */ "./node_modules/asn1.js/lib/asn1.js")
|
||
|
||
exports.certificate = __webpack_require__(/*! ./certificate */ "./node_modules/parse-asn1/certificate.js")
|
||
|
||
var RSAPrivateKey = asn1.define('RSAPrivateKey', function () {
|
||
this.seq().obj(
|
||
this.key('version').int(),
|
||
this.key('modulus').int(),
|
||
this.key('publicExponent').int(),
|
||
this.key('privateExponent').int(),
|
||
this.key('prime1').int(),
|
||
this.key('prime2').int(),
|
||
this.key('exponent1').int(),
|
||
this.key('exponent2').int(),
|
||
this.key('coefficient').int()
|
||
)
|
||
})
|
||
exports.RSAPrivateKey = RSAPrivateKey
|
||
|
||
var RSAPublicKey = asn1.define('RSAPublicKey', function () {
|
||
this.seq().obj(
|
||
this.key('modulus').int(),
|
||
this.key('publicExponent').int()
|
||
)
|
||
})
|
||
exports.RSAPublicKey = RSAPublicKey
|
||
|
||
var PublicKey = asn1.define('SubjectPublicKeyInfo', function () {
|
||
this.seq().obj(
|
||
this.key('algorithm').use(AlgorithmIdentifier),
|
||
this.key('subjectPublicKey').bitstr()
|
||
)
|
||
})
|
||
exports.PublicKey = PublicKey
|
||
|
||
var AlgorithmIdentifier = asn1.define('AlgorithmIdentifier', function () {
|
||
this.seq().obj(
|
||
this.key('algorithm').objid(),
|
||
this.key('none').null_().optional(),
|
||
this.key('curve').objid().optional(),
|
||
this.key('params').seq().obj(
|
||
this.key('p').int(),
|
||
this.key('q').int(),
|
||
this.key('g').int()
|
||
).optional()
|
||
)
|
||
})
|
||
|
||
var PrivateKeyInfo = asn1.define('PrivateKeyInfo', function () {
|
||
this.seq().obj(
|
||
this.key('version').int(),
|
||
this.key('algorithm').use(AlgorithmIdentifier),
|
||
this.key('subjectPrivateKey').octstr()
|
||
)
|
||
})
|
||
exports.PrivateKey = PrivateKeyInfo
|
||
var EncryptedPrivateKeyInfo = asn1.define('EncryptedPrivateKeyInfo', function () {
|
||
this.seq().obj(
|
||
this.key('algorithm').seq().obj(
|
||
this.key('id').objid(),
|
||
this.key('decrypt').seq().obj(
|
||
this.key('kde').seq().obj(
|
||
this.key('id').objid(),
|
||
this.key('kdeparams').seq().obj(
|
||
this.key('salt').octstr(),
|
||
this.key('iters').int()
|
||
)
|
||
),
|
||
this.key('cipher').seq().obj(
|
||
this.key('algo').objid(),
|
||
this.key('iv').octstr()
|
||
)
|
||
)
|
||
),
|
||
this.key('subjectPrivateKey').octstr()
|
||
)
|
||
})
|
||
|
||
exports.EncryptedPrivateKey = EncryptedPrivateKeyInfo
|
||
|
||
var DSAPrivateKey = asn1.define('DSAPrivateKey', function () {
|
||
this.seq().obj(
|
||
this.key('version').int(),
|
||
this.key('p').int(),
|
||
this.key('q').int(),
|
||
this.key('g').int(),
|
||
this.key('pub_key').int(),
|
||
this.key('priv_key').int()
|
||
)
|
||
})
|
||
exports.DSAPrivateKey = DSAPrivateKey
|
||
|
||
exports.DSAparam = asn1.define('DSAparam', function () {
|
||
this.int()
|
||
})
|
||
|
||
var ECPrivateKey = asn1.define('ECPrivateKey', function () {
|
||
this.seq().obj(
|
||
this.key('version').int(),
|
||
this.key('privateKey').octstr(),
|
||
this.key('parameters').optional().explicit(0).use(ECParameters),
|
||
this.key('publicKey').optional().explicit(1).bitstr()
|
||
)
|
||
})
|
||
exports.ECPrivateKey = ECPrivateKey
|
||
|
||
var ECParameters = asn1.define('ECParameters', function () {
|
||
this.choice({
|
||
namedCurve: this.objid()
|
||
})
|
||
})
|
||
|
||
exports.signature = asn1.define('signature', function () {
|
||
this.seq().obj(
|
||
this.key('r').int(),
|
||
this.key('s').int()
|
||
)
|
||
})
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/parse-asn1/certificate.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/parse-asn1/certificate.js ***!
|
||
\************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
// from https://github.com/Rantanen/node-dtls/blob/25a7dc861bda38cfeac93a723500eea4f0ac2e86/Certificate.js
|
||
// thanks to @Rantanen
|
||
|
||
|
||
|
||
var asn = __webpack_require__(/*! asn1.js */ "./node_modules/asn1.js/lib/asn1.js")
|
||
|
||
var Time = asn.define('Time', function () {
|
||
this.choice({
|
||
utcTime: this.utctime(),
|
||
generalTime: this.gentime()
|
||
})
|
||
})
|
||
|
||
var AttributeTypeValue = asn.define('AttributeTypeValue', function () {
|
||
this.seq().obj(
|
||
this.key('type').objid(),
|
||
this.key('value').any()
|
||
)
|
||
})
|
||
|
||
var AlgorithmIdentifier = asn.define('AlgorithmIdentifier', function () {
|
||
this.seq().obj(
|
||
this.key('algorithm').objid(),
|
||
this.key('parameters').optional(),
|
||
this.key('curve').objid().optional()
|
||
)
|
||
})
|
||
|
||
var SubjectPublicKeyInfo = asn.define('SubjectPublicKeyInfo', function () {
|
||
this.seq().obj(
|
||
this.key('algorithm').use(AlgorithmIdentifier),
|
||
this.key('subjectPublicKey').bitstr()
|
||
)
|
||
})
|
||
|
||
var RelativeDistinguishedName = asn.define('RelativeDistinguishedName', function () {
|
||
this.setof(AttributeTypeValue)
|
||
})
|
||
|
||
var RDNSequence = asn.define('RDNSequence', function () {
|
||
this.seqof(RelativeDistinguishedName)
|
||
})
|
||
|
||
var Name = asn.define('Name', function () {
|
||
this.choice({
|
||
rdnSequence: this.use(RDNSequence)
|
||
})
|
||
})
|
||
|
||
var Validity = asn.define('Validity', function () {
|
||
this.seq().obj(
|
||
this.key('notBefore').use(Time),
|
||
this.key('notAfter').use(Time)
|
||
)
|
||
})
|
||
|
||
var Extension = asn.define('Extension', function () {
|
||
this.seq().obj(
|
||
this.key('extnID').objid(),
|
||
this.key('critical').bool().def(false),
|
||
this.key('extnValue').octstr()
|
||
)
|
||
})
|
||
|
||
var TBSCertificate = asn.define('TBSCertificate', function () {
|
||
this.seq().obj(
|
||
this.key('version').explicit(0).int().optional(),
|
||
this.key('serialNumber').int(),
|
||
this.key('signature').use(AlgorithmIdentifier),
|
||
this.key('issuer').use(Name),
|
||
this.key('validity').use(Validity),
|
||
this.key('subject').use(Name),
|
||
this.key('subjectPublicKeyInfo').use(SubjectPublicKeyInfo),
|
||
this.key('issuerUniqueID').implicit(1).bitstr().optional(),
|
||
this.key('subjectUniqueID').implicit(2).bitstr().optional(),
|
||
this.key('extensions').explicit(3).seqof(Extension).optional()
|
||
)
|
||
})
|
||
|
||
var X509Certificate = asn.define('X509Certificate', function () {
|
||
this.seq().obj(
|
||
this.key('tbsCertificate').use(TBSCertificate),
|
||
this.key('signatureAlgorithm').use(AlgorithmIdentifier),
|
||
this.key('signatureValue').bitstr()
|
||
)
|
||
})
|
||
|
||
module.exports = X509Certificate
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/parse-asn1/fixProc.js":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/parse-asn1/fixProc.js ***!
|
||
\********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
// adapted from https://github.com/apatil/pemstrip
|
||
var findProc = /Proc-Type: 4,ENCRYPTED[\n\r]+DEK-Info: AES-((?:128)|(?:192)|(?:256))-CBC,([0-9A-H]+)[\n\r]+([0-9A-z\n\r\+\/\=]+)[\n\r]+/m
|
||
var startRegex = /^-----BEGIN ((?:.*? KEY)|CERTIFICATE)-----/m
|
||
var fullRegex = /^-----BEGIN ((?:.*? KEY)|CERTIFICATE)-----([0-9A-z\n\r\+\/\=]+)-----END \1-----$/m
|
||
var evp = __webpack_require__(/*! evp_bytestokey */ "./node_modules/evp_bytestokey/index.js")
|
||
var ciphers = __webpack_require__(/*! browserify-aes */ "./node_modules/browserify-aes/browser.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
module.exports = function (okey, password) {
|
||
var key = okey.toString()
|
||
var match = key.match(findProc)
|
||
var decrypted
|
||
if (!match) {
|
||
var match2 = key.match(fullRegex)
|
||
decrypted = new Buffer(match2[2].replace(/[\r\n]/g, ''), 'base64')
|
||
} else {
|
||
var suite = 'aes' + match[1]
|
||
var iv = Buffer.from(match[2], 'hex')
|
||
var cipherText = Buffer.from(match[3].replace(/[\r\n]/g, ''), 'base64')
|
||
var cipherKey = evp(password, iv.slice(0, 8), parseInt(match[1], 10)).key
|
||
var out = []
|
||
var cipher = ciphers.createDecipheriv(suite, cipherKey, iv)
|
||
out.push(cipher.update(cipherText))
|
||
out.push(cipher.final())
|
||
decrypted = Buffer.concat(out)
|
||
}
|
||
var tag = key.match(startRegex)[1]
|
||
return {
|
||
tag: tag,
|
||
data: decrypted
|
||
}
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/parse-asn1/index.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/parse-asn1/index.js ***!
|
||
\******************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var asn1 = __webpack_require__(/*! ./asn1 */ "./node_modules/parse-asn1/asn1.js")
|
||
var aesid = __webpack_require__(/*! ./aesid.json */ "./node_modules/parse-asn1/aesid.json")
|
||
var fixProc = __webpack_require__(/*! ./fixProc */ "./node_modules/parse-asn1/fixProc.js")
|
||
var ciphers = __webpack_require__(/*! browserify-aes */ "./node_modules/browserify-aes/browser.js")
|
||
var compat = __webpack_require__(/*! pbkdf2 */ "./node_modules/pbkdf2/browser.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
module.exports = parseKeys
|
||
|
||
function parseKeys (buffer) {
|
||
var password
|
||
if (typeof buffer === 'object' && !Buffer.isBuffer(buffer)) {
|
||
password = buffer.passphrase
|
||
buffer = buffer.key
|
||
}
|
||
if (typeof buffer === 'string') {
|
||
buffer = Buffer.from(buffer)
|
||
}
|
||
|
||
var stripped = fixProc(buffer, password)
|
||
|
||
var type = stripped.tag
|
||
var data = stripped.data
|
||
var subtype, ndata
|
||
switch (type) {
|
||
case 'CERTIFICATE':
|
||
ndata = asn1.certificate.decode(data, 'der').tbsCertificate.subjectPublicKeyInfo
|
||
// falls through
|
||
case 'PUBLIC KEY':
|
||
if (!ndata) {
|
||
ndata = asn1.PublicKey.decode(data, 'der')
|
||
}
|
||
subtype = ndata.algorithm.algorithm.join('.')
|
||
switch (subtype) {
|
||
case '1.2.840.113549.1.1.1':
|
||
return asn1.RSAPublicKey.decode(ndata.subjectPublicKey.data, 'der')
|
||
case '1.2.840.10045.2.1':
|
||
ndata.subjectPrivateKey = ndata.subjectPublicKey
|
||
return {
|
||
type: 'ec',
|
||
data: ndata
|
||
}
|
||
case '1.2.840.10040.4.1':
|
||
ndata.algorithm.params.pub_key = asn1.DSAparam.decode(ndata.subjectPublicKey.data, 'der')
|
||
return {
|
||
type: 'dsa',
|
||
data: ndata.algorithm.params
|
||
}
|
||
default: throw new Error('unknown key id ' + subtype)
|
||
}
|
||
throw new Error('unknown key type ' + type)
|
||
case 'ENCRYPTED PRIVATE KEY':
|
||
data = asn1.EncryptedPrivateKey.decode(data, 'der')
|
||
data = decrypt(data, password)
|
||
// falls through
|
||
case 'PRIVATE KEY':
|
||
ndata = asn1.PrivateKey.decode(data, 'der')
|
||
subtype = ndata.algorithm.algorithm.join('.')
|
||
switch (subtype) {
|
||
case '1.2.840.113549.1.1.1':
|
||
return asn1.RSAPrivateKey.decode(ndata.subjectPrivateKey, 'der')
|
||
case '1.2.840.10045.2.1':
|
||
return {
|
||
curve: ndata.algorithm.curve,
|
||
privateKey: asn1.ECPrivateKey.decode(ndata.subjectPrivateKey, 'der').privateKey
|
||
}
|
||
case '1.2.840.10040.4.1':
|
||
ndata.algorithm.params.priv_key = asn1.DSAparam.decode(ndata.subjectPrivateKey, 'der')
|
||
return {
|
||
type: 'dsa',
|
||
params: ndata.algorithm.params
|
||
}
|
||
default: throw new Error('unknown key id ' + subtype)
|
||
}
|
||
throw new Error('unknown key type ' + type)
|
||
case 'RSA PUBLIC KEY':
|
||
return asn1.RSAPublicKey.decode(data, 'der')
|
||
case 'RSA PRIVATE KEY':
|
||
return asn1.RSAPrivateKey.decode(data, 'der')
|
||
case 'DSA PRIVATE KEY':
|
||
return {
|
||
type: 'dsa',
|
||
params: asn1.DSAPrivateKey.decode(data, 'der')
|
||
}
|
||
case 'EC PRIVATE KEY':
|
||
data = asn1.ECPrivateKey.decode(data, 'der')
|
||
return {
|
||
curve: data.parameters.value,
|
||
privateKey: data.privateKey
|
||
}
|
||
default: throw new Error('unknown key type ' + type)
|
||
}
|
||
}
|
||
parseKeys.signature = asn1.signature
|
||
function decrypt (data, password) {
|
||
var salt = data.algorithm.decrypt.kde.kdeparams.salt
|
||
var iters = parseInt(data.algorithm.decrypt.kde.kdeparams.iters.toString(), 10)
|
||
var algo = aesid[data.algorithm.decrypt.cipher.algo.join('.')]
|
||
var iv = data.algorithm.decrypt.cipher.iv
|
||
var cipherText = data.subjectPrivateKey
|
||
var keylen = parseInt(algo.split('-')[1], 10) / 8
|
||
var key = compat.pbkdf2Sync(password, salt, iters, keylen, 'sha1')
|
||
var cipher = ciphers.createDecipheriv(algo, key, iv)
|
||
var out = []
|
||
out.push(cipher.update(cipherText))
|
||
out.push(cipher.final())
|
||
return Buffer.concat(out)
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pbkdf2/browser.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/pbkdf2/browser.js ***!
|
||
\****************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
exports.pbkdf2 = __webpack_require__(/*! ./lib/async */ "./node_modules/pbkdf2/lib/async.js")
|
||
exports.pbkdf2Sync = __webpack_require__(/*! ./lib/sync */ "./node_modules/pbkdf2/lib/sync-browser.js")
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pbkdf2/lib/async.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/pbkdf2/lib/async.js ***!
|
||
\******************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(global, process) {var checkParameters = __webpack_require__(/*! ./precondition */ "./node_modules/pbkdf2/lib/precondition.js")
|
||
var defaultEncoding = __webpack_require__(/*! ./default-encoding */ "./node_modules/pbkdf2/lib/default-encoding.js")
|
||
var sync = __webpack_require__(/*! ./sync */ "./node_modules/pbkdf2/lib/sync-browser.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
var ZERO_BUF
|
||
var subtle = global.crypto && global.crypto.subtle
|
||
var toBrowser = {
|
||
'sha': 'SHA-1',
|
||
'sha-1': 'SHA-1',
|
||
'sha1': 'SHA-1',
|
||
'sha256': 'SHA-256',
|
||
'sha-256': 'SHA-256',
|
||
'sha384': 'SHA-384',
|
||
'sha-384': 'SHA-384',
|
||
'sha-512': 'SHA-512',
|
||
'sha512': 'SHA-512'
|
||
}
|
||
var checks = []
|
||
function checkNative (algo) {
|
||
if (global.process && !global.process.browser) {
|
||
return Promise.resolve(false)
|
||
}
|
||
if (!subtle || !subtle.importKey || !subtle.deriveBits) {
|
||
return Promise.resolve(false)
|
||
}
|
||
if (checks[algo] !== undefined) {
|
||
return checks[algo]
|
||
}
|
||
ZERO_BUF = ZERO_BUF || Buffer.alloc(8)
|
||
var prom = browserPbkdf2(ZERO_BUF, ZERO_BUF, 10, 128, algo)
|
||
.then(function () {
|
||
return true
|
||
}).catch(function () {
|
||
return false
|
||
})
|
||
checks[algo] = prom
|
||
return prom
|
||
}
|
||
|
||
function browserPbkdf2 (password, salt, iterations, length, algo) {
|
||
return subtle.importKey(
|
||
'raw', password, {name: 'PBKDF2'}, false, ['deriveBits']
|
||
).then(function (key) {
|
||
return subtle.deriveBits({
|
||
name: 'PBKDF2',
|
||
salt: salt,
|
||
iterations: iterations,
|
||
hash: {
|
||
name: algo
|
||
}
|
||
}, key, length << 3)
|
||
}).then(function (res) {
|
||
return Buffer.from(res)
|
||
})
|
||
}
|
||
|
||
function resolvePromise (promise, callback) {
|
||
promise.then(function (out) {
|
||
process.nextTick(function () {
|
||
callback(null, out)
|
||
})
|
||
}, function (e) {
|
||
process.nextTick(function () {
|
||
callback(e)
|
||
})
|
||
})
|
||
}
|
||
module.exports = function (password, salt, iterations, keylen, digest, callback) {
|
||
if (typeof digest === 'function') {
|
||
callback = digest
|
||
digest = undefined
|
||
}
|
||
|
||
digest = digest || 'sha1'
|
||
var algo = toBrowser[digest.toLowerCase()]
|
||
|
||
if (!algo || typeof global.Promise !== 'function') {
|
||
return process.nextTick(function () {
|
||
var out
|
||
try {
|
||
out = sync(password, salt, iterations, keylen, digest)
|
||
} catch (e) {
|
||
return callback(e)
|
||
}
|
||
callback(null, out)
|
||
})
|
||
}
|
||
|
||
checkParameters(password, salt, iterations, keylen)
|
||
if (typeof callback !== 'function') throw new Error('No callback provided to pbkdf2')
|
||
if (!Buffer.isBuffer(password)) password = Buffer.from(password, defaultEncoding)
|
||
if (!Buffer.isBuffer(salt)) salt = Buffer.from(salt, defaultEncoding)
|
||
|
||
resolvePromise(checkNative(algo).then(function (resp) {
|
||
if (resp) return browserPbkdf2(password, salt, iterations, keylen, algo)
|
||
|
||
return sync(password, salt, iterations, keylen, digest)
|
||
}), callback)
|
||
}
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js"), __webpack_require__(/*! ./../../process/browser.js */ "./node_modules/process/browser.js")))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pbkdf2/lib/default-encoding.js":
|
||
/*!*****************************************************!*\
|
||
!*** ./node_modules/pbkdf2/lib/default-encoding.js ***!
|
||
\*****************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(process) {var defaultEncoding
|
||
/* istanbul ignore next */
|
||
if (process.browser) {
|
||
defaultEncoding = 'utf-8'
|
||
} else {
|
||
var pVersionMajor = parseInt(process.version.split('.')[0].slice(1), 10)
|
||
|
||
defaultEncoding = pVersionMajor >= 6 ? 'utf-8' : 'binary'
|
||
}
|
||
module.exports = defaultEncoding
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../process/browser.js */ "./node_modules/process/browser.js")))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pbkdf2/lib/precondition.js":
|
||
/*!*************************************************!*\
|
||
!*** ./node_modules/pbkdf2/lib/precondition.js ***!
|
||
\*************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(Buffer) {var MAX_ALLOC = Math.pow(2, 30) - 1 // default in iojs
|
||
|
||
function checkBuffer (buf, name) {
|
||
if (typeof buf !== 'string' && !Buffer.isBuffer(buf)) {
|
||
throw new TypeError(name + ' must be a buffer or string')
|
||
}
|
||
}
|
||
|
||
module.exports = function (password, salt, iterations, keylen) {
|
||
checkBuffer(password, 'Password')
|
||
checkBuffer(salt, 'Salt')
|
||
|
||
if (typeof iterations !== 'number') {
|
||
throw new TypeError('Iterations not a number')
|
||
}
|
||
|
||
if (iterations < 0) {
|
||
throw new TypeError('Bad iterations')
|
||
}
|
||
|
||
if (typeof keylen !== 'number') {
|
||
throw new TypeError('Key length not a number')
|
||
}
|
||
|
||
if (keylen < 0 || keylen > MAX_ALLOC || keylen !== keylen) { /* eslint no-self-compare: 0 */
|
||
throw new TypeError('Bad key length')
|
||
}
|
||
}
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../buffer/index.js */ "./node_modules/buffer/index.js").Buffer))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/pbkdf2/lib/sync-browser.js":
|
||
/*!*************************************************!*\
|
||
!*** ./node_modules/pbkdf2/lib/sync-browser.js ***!
|
||
\*************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var md5 = __webpack_require__(/*! create-hash/md5 */ "./node_modules/create-hash/md5.js")
|
||
var RIPEMD160 = __webpack_require__(/*! ripemd160 */ "./node_modules/ripemd160/index.js")
|
||
var sha = __webpack_require__(/*! sha.js */ "./node_modules/sha.js/index.js")
|
||
|
||
var checkParameters = __webpack_require__(/*! ./precondition */ "./node_modules/pbkdf2/lib/precondition.js")
|
||
var defaultEncoding = __webpack_require__(/*! ./default-encoding */ "./node_modules/pbkdf2/lib/default-encoding.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
var ZEROS = Buffer.alloc(128)
|
||
var sizes = {
|
||
md5: 16,
|
||
sha1: 20,
|
||
sha224: 28,
|
||
sha256: 32,
|
||
sha384: 48,
|
||
sha512: 64,
|
||
rmd160: 20,
|
||
ripemd160: 20
|
||
}
|
||
|
||
function Hmac (alg, key, saltLen) {
|
||
var hash = getDigest(alg)
|
||
var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64
|
||
|
||
if (key.length > blocksize) {
|
||
key = hash(key)
|
||
} else if (key.length < blocksize) {
|
||
key = Buffer.concat([key, ZEROS], blocksize)
|
||
}
|
||
|
||
var ipad = Buffer.allocUnsafe(blocksize + sizes[alg])
|
||
var opad = Buffer.allocUnsafe(blocksize + sizes[alg])
|
||
for (var i = 0; i < blocksize; i++) {
|
||
ipad[i] = key[i] ^ 0x36
|
||
opad[i] = key[i] ^ 0x5C
|
||
}
|
||
|
||
var ipad1 = Buffer.allocUnsafe(blocksize + saltLen + 4)
|
||
ipad.copy(ipad1, 0, 0, blocksize)
|
||
this.ipad1 = ipad1
|
||
this.ipad2 = ipad
|
||
this.opad = opad
|
||
this.alg = alg
|
||
this.blocksize = blocksize
|
||
this.hash = hash
|
||
this.size = sizes[alg]
|
||
}
|
||
|
||
Hmac.prototype.run = function (data, ipad) {
|
||
data.copy(ipad, this.blocksize)
|
||
var h = this.hash(ipad)
|
||
h.copy(this.opad, this.blocksize)
|
||
return this.hash(this.opad)
|
||
}
|
||
|
||
function getDigest (alg) {
|
||
function shaFunc (data) {
|
||
return sha(alg).update(data).digest()
|
||
}
|
||
function rmd160Func (data) {
|
||
return new RIPEMD160().update(data).digest()
|
||
}
|
||
|
||
if (alg === 'rmd160' || alg === 'ripemd160') return rmd160Func
|
||
if (alg === 'md5') return md5
|
||
return shaFunc
|
||
}
|
||
|
||
function pbkdf2 (password, salt, iterations, keylen, digest) {
|
||
checkParameters(password, salt, iterations, keylen)
|
||
|
||
if (!Buffer.isBuffer(password)) password = Buffer.from(password, defaultEncoding)
|
||
if (!Buffer.isBuffer(salt)) salt = Buffer.from(salt, defaultEncoding)
|
||
|
||
digest = digest || 'sha1'
|
||
|
||
var hmac = new Hmac(digest, password, salt.length)
|
||
|
||
var DK = Buffer.allocUnsafe(keylen)
|
||
var block1 = Buffer.allocUnsafe(salt.length + 4)
|
||
salt.copy(block1, 0, 0, salt.length)
|
||
|
||
var destPos = 0
|
||
var hLen = sizes[digest]
|
||
var l = Math.ceil(keylen / hLen)
|
||
|
||
for (var i = 1; i <= l; i++) {
|
||
block1.writeUInt32BE(i, salt.length)
|
||
|
||
var T = hmac.run(block1, hmac.ipad1)
|
||
var U = T
|
||
|
||
for (var j = 1; j < iterations; j++) {
|
||
U = hmac.run(U, hmac.ipad2)
|
||
for (var k = 0; k < hLen; k++) T[k] ^= U[k]
|
||
}
|
||
|
||
T.copy(DK, destPos)
|
||
destPos += hLen
|
||
}
|
||
|
||
return DK
|
||
}
|
||
|
||
module.exports = pbkdf2
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/process-nextick-args/index.js":
|
||
/*!****************************************************!*\
|
||
!*** ./node_modules/process-nextick-args/index.js ***!
|
||
\****************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
/* WEBPACK VAR INJECTION */(function(process) {
|
||
|
||
if (!process.version ||
|
||
process.version.indexOf('v0.') === 0 ||
|
||
process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
|
||
module.exports = { nextTick: nextTick };
|
||
} else {
|
||
module.exports = process
|
||
}
|
||
|
||
function nextTick(fn, arg1, arg2, arg3) {
|
||
if (typeof fn !== 'function') {
|
||
throw new TypeError('"callback" argument must be a function');
|
||
}
|
||
var len = arguments.length;
|
||
var args, i;
|
||
switch (len) {
|
||
case 0:
|
||
case 1:
|
||
return process.nextTick(fn);
|
||
case 2:
|
||
return process.nextTick(function afterTickOne() {
|
||
fn.call(null, arg1);
|
||
});
|
||
case 3:
|
||
return process.nextTick(function afterTickTwo() {
|
||
fn.call(null, arg1, arg2);
|
||
});
|
||
case 4:
|
||
return process.nextTick(function afterTickThree() {
|
||
fn.call(null, arg1, arg2, arg3);
|
||
});
|
||
default:
|
||
args = new Array(len - 1);
|
||
i = 0;
|
||
while (i < args.length) {
|
||
args[i++] = arguments[i];
|
||
}
|
||
return process.nextTick(function afterTick() {
|
||
fn.apply(null, args);
|
||
});
|
||
}
|
||
}
|
||
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../process/browser.js */ "./node_modules/process/browser.js")))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/process/browser.js":
|
||
/*!*****************************************!*\
|
||
!*** ./node_modules/process/browser.js ***!
|
||
\*****************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
// shim for using process in browser
|
||
var process = module.exports = {};
|
||
|
||
// cached from whatever global is present so that test runners that stub it
|
||
// don't break things. But we need to wrap it in a try catch in case it is
|
||
// wrapped in strict mode code which doesn't define any globals. It's inside a
|
||
// function because try/catches deoptimize in certain engines.
|
||
|
||
var cachedSetTimeout;
|
||
var cachedClearTimeout;
|
||
|
||
function defaultSetTimout() {
|
||
throw new Error('setTimeout has not been defined');
|
||
}
|
||
function defaultClearTimeout () {
|
||
throw new Error('clearTimeout has not been defined');
|
||
}
|
||
(function () {
|
||
try {
|
||
if (typeof setTimeout === 'function') {
|
||
cachedSetTimeout = setTimeout;
|
||
} else {
|
||
cachedSetTimeout = defaultSetTimout;
|
||
}
|
||
} catch (e) {
|
||
cachedSetTimeout = defaultSetTimout;
|
||
}
|
||
try {
|
||
if (typeof clearTimeout === 'function') {
|
||
cachedClearTimeout = clearTimeout;
|
||
} else {
|
||
cachedClearTimeout = defaultClearTimeout;
|
||
}
|
||
} catch (e) {
|
||
cachedClearTimeout = defaultClearTimeout;
|
||
}
|
||
} ())
|
||
function runTimeout(fun) {
|
||
if (cachedSetTimeout === setTimeout) {
|
||
//normal enviroments in sane situations
|
||
return setTimeout(fun, 0);
|
||
}
|
||
// if setTimeout wasn't available but was latter defined
|
||
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
|
||
cachedSetTimeout = setTimeout;
|
||
return setTimeout(fun, 0);
|
||
}
|
||
try {
|
||
// when when somebody has screwed with setTimeout but no I.E. maddness
|
||
return cachedSetTimeout(fun, 0);
|
||
} catch(e){
|
||
try {
|
||
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
||
return cachedSetTimeout.call(null, fun, 0);
|
||
} catch(e){
|
||
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
|
||
return cachedSetTimeout.call(this, fun, 0);
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
function runClearTimeout(marker) {
|
||
if (cachedClearTimeout === clearTimeout) {
|
||
//normal enviroments in sane situations
|
||
return clearTimeout(marker);
|
||
}
|
||
// if clearTimeout wasn't available but was latter defined
|
||
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
|
||
cachedClearTimeout = clearTimeout;
|
||
return clearTimeout(marker);
|
||
}
|
||
try {
|
||
// when when somebody has screwed with setTimeout but no I.E. maddness
|
||
return cachedClearTimeout(marker);
|
||
} catch (e){
|
||
try {
|
||
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
||
return cachedClearTimeout.call(null, marker);
|
||
} catch (e){
|
||
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
|
||
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
|
||
return cachedClearTimeout.call(this, marker);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
}
|
||
var queue = [];
|
||
var draining = false;
|
||
var currentQueue;
|
||
var queueIndex = -1;
|
||
|
||
function cleanUpNextTick() {
|
||
if (!draining || !currentQueue) {
|
||
return;
|
||
}
|
||
draining = false;
|
||
if (currentQueue.length) {
|
||
queue = currentQueue.concat(queue);
|
||
} else {
|
||
queueIndex = -1;
|
||
}
|
||
if (queue.length) {
|
||
drainQueue();
|
||
}
|
||
}
|
||
|
||
function drainQueue() {
|
||
if (draining) {
|
||
return;
|
||
}
|
||
var timeout = runTimeout(cleanUpNextTick);
|
||
draining = true;
|
||
|
||
var len = queue.length;
|
||
while(len) {
|
||
currentQueue = queue;
|
||
queue = [];
|
||
while (++queueIndex < len) {
|
||
if (currentQueue) {
|
||
currentQueue[queueIndex].run();
|
||
}
|
||
}
|
||
queueIndex = -1;
|
||
len = queue.length;
|
||
}
|
||
currentQueue = null;
|
||
draining = false;
|
||
runClearTimeout(timeout);
|
||
}
|
||
|
||
process.nextTick = function (fun) {
|
||
var args = new Array(arguments.length - 1);
|
||
if (arguments.length > 1) {
|
||
for (var i = 1; i < arguments.length; i++) {
|
||
args[i - 1] = arguments[i];
|
||
}
|
||
}
|
||
queue.push(new Item(fun, args));
|
||
if (queue.length === 1 && !draining) {
|
||
runTimeout(drainQueue);
|
||
}
|
||
};
|
||
|
||
// v8 likes predictible objects
|
||
function Item(fun, array) {
|
||
this.fun = fun;
|
||
this.array = array;
|
||
}
|
||
Item.prototype.run = function () {
|
||
this.fun.apply(null, this.array);
|
||
};
|
||
process.title = 'browser';
|
||
process.browser = true;
|
||
process.env = {};
|
||
process.argv = [];
|
||
process.version = ''; // empty string to avoid regexp issues
|
||
process.versions = {};
|
||
|
||
function noop() {}
|
||
|
||
process.on = noop;
|
||
process.addListener = noop;
|
||
process.once = noop;
|
||
process.off = noop;
|
||
process.removeListener = noop;
|
||
process.removeAllListeners = noop;
|
||
process.emit = noop;
|
||
process.prependListener = noop;
|
||
process.prependOnceListener = noop;
|
||
|
||
process.listeners = function (name) { return [] }
|
||
|
||
process.binding = function (name) {
|
||
throw new Error('process.binding is not supported');
|
||
};
|
||
|
||
process.cwd = function () { return '/' };
|
||
process.chdir = function (dir) {
|
||
throw new Error('process.chdir is not supported');
|
||
};
|
||
process.umask = function() { return 0; };
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/public-encrypt/browser.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/public-encrypt/browser.js ***!
|
||
\************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
exports.publicEncrypt = __webpack_require__(/*! ./publicEncrypt */ "./node_modules/public-encrypt/publicEncrypt.js")
|
||
exports.privateDecrypt = __webpack_require__(/*! ./privateDecrypt */ "./node_modules/public-encrypt/privateDecrypt.js")
|
||
|
||
exports.privateEncrypt = function privateEncrypt (key, buf) {
|
||
return exports.publicEncrypt(key, buf, true)
|
||
}
|
||
|
||
exports.publicDecrypt = function publicDecrypt (key, buf) {
|
||
return exports.privateDecrypt(key, buf, true)
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/public-encrypt/mgf.js":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/public-encrypt/mgf.js ***!
|
||
\********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var createHash = __webpack_require__(/*! create-hash */ "./node_modules/create-hash/browser.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
module.exports = function (seed, len) {
|
||
var t = Buffer.alloc(0)
|
||
var i = 0
|
||
var c
|
||
while (t.length < len) {
|
||
c = i2ops(i++)
|
||
t = Buffer.concat([t, createHash('sha1').update(seed).update(c).digest()])
|
||
}
|
||
return t.slice(0, len)
|
||
}
|
||
|
||
function i2ops (c) {
|
||
var out = Buffer.allocUnsafe(4)
|
||
out.writeUInt32BE(c, 0)
|
||
return out
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/public-encrypt/privateDecrypt.js":
|
||
/*!*******************************************************!*\
|
||
!*** ./node_modules/public-encrypt/privateDecrypt.js ***!
|
||
\*******************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var parseKeys = __webpack_require__(/*! parse-asn1 */ "./node_modules/parse-asn1/index.js")
|
||
var mgf = __webpack_require__(/*! ./mgf */ "./node_modules/public-encrypt/mgf.js")
|
||
var xor = __webpack_require__(/*! ./xor */ "./node_modules/public-encrypt/xor.js")
|
||
var BN = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js")
|
||
var crt = __webpack_require__(/*! browserify-rsa */ "./node_modules/browserify-rsa/index.js")
|
||
var createHash = __webpack_require__(/*! create-hash */ "./node_modules/create-hash/browser.js")
|
||
var withPublic = __webpack_require__(/*! ./withPublic */ "./node_modules/public-encrypt/withPublic.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
module.exports = function privateDecrypt (privateKey, enc, reverse) {
|
||
var padding
|
||
if (privateKey.padding) {
|
||
padding = privateKey.padding
|
||
} else if (reverse) {
|
||
padding = 1
|
||
} else {
|
||
padding = 4
|
||
}
|
||
|
||
var key = parseKeys(privateKey)
|
||
var k = key.modulus.byteLength()
|
||
if (enc.length > k || new BN(enc).cmp(key.modulus) >= 0) {
|
||
throw new Error('decryption error')
|
||
}
|
||
var msg
|
||
if (reverse) {
|
||
msg = withPublic(new BN(enc), key)
|
||
} else {
|
||
msg = crt(enc, key)
|
||
}
|
||
var zBuffer = Buffer.alloc(k - msg.length)
|
||
msg = Buffer.concat([zBuffer, msg], k)
|
||
if (padding === 4) {
|
||
return oaep(key, msg)
|
||
} else if (padding === 1) {
|
||
return pkcs1(key, msg, reverse)
|
||
} else if (padding === 3) {
|
||
return msg
|
||
} else {
|
||
throw new Error('unknown padding')
|
||
}
|
||
}
|
||
|
||
function oaep (key, msg) {
|
||
var k = key.modulus.byteLength()
|
||
var iHash = createHash('sha1').update(Buffer.alloc(0)).digest()
|
||
var hLen = iHash.length
|
||
if (msg[0] !== 0) {
|
||
throw new Error('decryption error')
|
||
}
|
||
var maskedSeed = msg.slice(1, hLen + 1)
|
||
var maskedDb = msg.slice(hLen + 1)
|
||
var seed = xor(maskedSeed, mgf(maskedDb, hLen))
|
||
var db = xor(maskedDb, mgf(seed, k - hLen - 1))
|
||
if (compare(iHash, db.slice(0, hLen))) {
|
||
throw new Error('decryption error')
|
||
}
|
||
var i = hLen
|
||
while (db[i] === 0) {
|
||
i++
|
||
}
|
||
if (db[i++] !== 1) {
|
||
throw new Error('decryption error')
|
||
}
|
||
return db.slice(i)
|
||
}
|
||
|
||
function pkcs1 (key, msg, reverse) {
|
||
var p1 = msg.slice(0, 2)
|
||
var i = 2
|
||
var status = 0
|
||
while (msg[i++] !== 0) {
|
||
if (i >= msg.length) {
|
||
status++
|
||
break
|
||
}
|
||
}
|
||
var ps = msg.slice(2, i - 1)
|
||
|
||
if ((p1.toString('hex') !== '0002' && !reverse) || (p1.toString('hex') !== '0001' && reverse)) {
|
||
status++
|
||
}
|
||
if (ps.length < 8) {
|
||
status++
|
||
}
|
||
if (status) {
|
||
throw new Error('decryption error')
|
||
}
|
||
return msg.slice(i)
|
||
}
|
||
function compare (a, b) {
|
||
a = Buffer.from(a)
|
||
b = Buffer.from(b)
|
||
var dif = 0
|
||
var len = a.length
|
||
if (a.length !== b.length) {
|
||
dif++
|
||
len = Math.min(a.length, b.length)
|
||
}
|
||
var i = -1
|
||
while (++i < len) {
|
||
dif += (a[i] ^ b[i])
|
||
}
|
||
return dif
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/public-encrypt/publicEncrypt.js":
|
||
/*!******************************************************!*\
|
||
!*** ./node_modules/public-encrypt/publicEncrypt.js ***!
|
||
\******************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var parseKeys = __webpack_require__(/*! parse-asn1 */ "./node_modules/parse-asn1/index.js")
|
||
var randomBytes = __webpack_require__(/*! randombytes */ "./node_modules/randombytes/browser.js")
|
||
var createHash = __webpack_require__(/*! create-hash */ "./node_modules/create-hash/browser.js")
|
||
var mgf = __webpack_require__(/*! ./mgf */ "./node_modules/public-encrypt/mgf.js")
|
||
var xor = __webpack_require__(/*! ./xor */ "./node_modules/public-encrypt/xor.js")
|
||
var BN = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js")
|
||
var withPublic = __webpack_require__(/*! ./withPublic */ "./node_modules/public-encrypt/withPublic.js")
|
||
var crt = __webpack_require__(/*! browserify-rsa */ "./node_modules/browserify-rsa/index.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
module.exports = function publicEncrypt (publicKey, msg, reverse) {
|
||
var padding
|
||
if (publicKey.padding) {
|
||
padding = publicKey.padding
|
||
} else if (reverse) {
|
||
padding = 1
|
||
} else {
|
||
padding = 4
|
||
}
|
||
var key = parseKeys(publicKey)
|
||
var paddedMsg
|
||
if (padding === 4) {
|
||
paddedMsg = oaep(key, msg)
|
||
} else if (padding === 1) {
|
||
paddedMsg = pkcs1(key, msg, reverse)
|
||
} else if (padding === 3) {
|
||
paddedMsg = new BN(msg)
|
||
if (paddedMsg.cmp(key.modulus) >= 0) {
|
||
throw new Error('data too long for modulus')
|
||
}
|
||
} else {
|
||
throw new Error('unknown padding')
|
||
}
|
||
if (reverse) {
|
||
return crt(paddedMsg, key)
|
||
} else {
|
||
return withPublic(paddedMsg, key)
|
||
}
|
||
}
|
||
|
||
function oaep (key, msg) {
|
||
var k = key.modulus.byteLength()
|
||
var mLen = msg.length
|
||
var iHash = createHash('sha1').update(Buffer.alloc(0)).digest()
|
||
var hLen = iHash.length
|
||
var hLen2 = 2 * hLen
|
||
if (mLen > k - hLen2 - 2) {
|
||
throw new Error('message too long')
|
||
}
|
||
var ps = Buffer.alloc(k - mLen - hLen2 - 2)
|
||
var dblen = k - hLen - 1
|
||
var seed = randomBytes(hLen)
|
||
var maskedDb = xor(Buffer.concat([iHash, ps, Buffer.alloc(1, 1), msg], dblen), mgf(seed, dblen))
|
||
var maskedSeed = xor(seed, mgf(maskedDb, hLen))
|
||
return new BN(Buffer.concat([Buffer.alloc(1), maskedSeed, maskedDb], k))
|
||
}
|
||
function pkcs1 (key, msg, reverse) {
|
||
var mLen = msg.length
|
||
var k = key.modulus.byteLength()
|
||
if (mLen > k - 11) {
|
||
throw new Error('message too long')
|
||
}
|
||
var ps
|
||
if (reverse) {
|
||
ps = Buffer.alloc(k - mLen - 3, 0xff)
|
||
} else {
|
||
ps = nonZero(k - mLen - 3)
|
||
}
|
||
return new BN(Buffer.concat([Buffer.from([0, reverse ? 1 : 2]), ps, Buffer.alloc(1), msg], k))
|
||
}
|
||
function nonZero (len) {
|
||
var out = Buffer.allocUnsafe(len)
|
||
var i = 0
|
||
var cache = randomBytes(len * 2)
|
||
var cur = 0
|
||
var num
|
||
while (i < len) {
|
||
if (cur === cache.length) {
|
||
cache = randomBytes(len * 2)
|
||
cur = 0
|
||
}
|
||
num = cache[cur++]
|
||
if (num) {
|
||
out[i++] = num
|
||
}
|
||
}
|
||
return out
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/public-encrypt/withPublic.js":
|
||
/*!***************************************************!*\
|
||
!*** ./node_modules/public-encrypt/withPublic.js ***!
|
||
\***************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var BN = __webpack_require__(/*! bn.js */ "./node_modules/bn.js/lib/bn.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
function withPublic (paddedMsg, key) {
|
||
return Buffer.from(paddedMsg
|
||
.toRed(BN.mont(key.modulus))
|
||
.redPow(new BN(key.publicExponent))
|
||
.fromRed()
|
||
.toArray())
|
||
}
|
||
|
||
module.exports = withPublic
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/public-encrypt/xor.js":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/public-encrypt/xor.js ***!
|
||
\********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
module.exports = function xor (a, b) {
|
||
var len = a.length
|
||
var i = -1
|
||
while (++i < len) {
|
||
a[i] ^= b[i]
|
||
}
|
||
return a
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/randombytes/browser.js":
|
||
/*!*********************************************!*\
|
||
!*** ./node_modules/randombytes/browser.js ***!
|
||
\*********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
/* WEBPACK VAR INJECTION */(function(global, process) {
|
||
|
||
// limit of Crypto.getRandomValues()
|
||
// https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
|
||
var MAX_BYTES = 65536
|
||
|
||
// Node supports requesting up to this number of bytes
|
||
// https://github.com/nodejs/node/blob/master/lib/internal/crypto/random.js#L48
|
||
var MAX_UINT32 = 4294967295
|
||
|
||
function oldBrowser () {
|
||
throw new Error('Secure random number generation is not supported by this browser.\nUse Chrome, Firefox or Internet Explorer 11')
|
||
}
|
||
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
var crypto = global.crypto || global.msCrypto
|
||
|
||
if (crypto && crypto.getRandomValues) {
|
||
module.exports = randomBytes
|
||
} else {
|
||
module.exports = oldBrowser
|
||
}
|
||
|
||
function randomBytes (size, cb) {
|
||
// phantomjs needs to throw
|
||
if (size > MAX_UINT32) throw new RangeError('requested too many random bytes')
|
||
|
||
var bytes = Buffer.allocUnsafe(size)
|
||
|
||
if (size > 0) { // getRandomValues fails on IE if size == 0
|
||
if (size > MAX_BYTES) { // this is the max bytes crypto.getRandomValues
|
||
// can do at once see https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues
|
||
for (var generated = 0; generated < size; generated += MAX_BYTES) {
|
||
// buffer.slice automatically checks if the end is past the end of
|
||
// the buffer so we don't have to here
|
||
crypto.getRandomValues(bytes.slice(generated, generated + MAX_BYTES))
|
||
}
|
||
} else {
|
||
crypto.getRandomValues(bytes)
|
||
}
|
||
}
|
||
|
||
if (typeof cb === 'function') {
|
||
return process.nextTick(function () {
|
||
cb(null, bytes)
|
||
})
|
||
}
|
||
|
||
return bytes
|
||
}
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js"), __webpack_require__(/*! ./../process/browser.js */ "./node_modules/process/browser.js")))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/randomfill/browser.js":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/randomfill/browser.js ***!
|
||
\********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
/* WEBPACK VAR INJECTION */(function(global, process) {
|
||
|
||
function oldBrowser () {
|
||
throw new Error('secure random number generation not supported by this browser\nuse chrome, FireFox or Internet Explorer 11')
|
||
}
|
||
var safeBuffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js")
|
||
var randombytes = __webpack_require__(/*! randombytes */ "./node_modules/randombytes/browser.js")
|
||
var Buffer = safeBuffer.Buffer
|
||
var kBufferMaxLength = safeBuffer.kMaxLength
|
||
var crypto = global.crypto || global.msCrypto
|
||
var kMaxUint32 = Math.pow(2, 32) - 1
|
||
function assertOffset (offset, length) {
|
||
if (typeof offset !== 'number' || offset !== offset) { // eslint-disable-line no-self-compare
|
||
throw new TypeError('offset must be a number')
|
||
}
|
||
|
||
if (offset > kMaxUint32 || offset < 0) {
|
||
throw new TypeError('offset must be a uint32')
|
||
}
|
||
|
||
if (offset > kBufferMaxLength || offset > length) {
|
||
throw new RangeError('offset out of range')
|
||
}
|
||
}
|
||
|
||
function assertSize (size, offset, length) {
|
||
if (typeof size !== 'number' || size !== size) { // eslint-disable-line no-self-compare
|
||
throw new TypeError('size must be a number')
|
||
}
|
||
|
||
if (size > kMaxUint32 || size < 0) {
|
||
throw new TypeError('size must be a uint32')
|
||
}
|
||
|
||
if (size + offset > length || size > kBufferMaxLength) {
|
||
throw new RangeError('buffer too small')
|
||
}
|
||
}
|
||
if ((crypto && crypto.getRandomValues) || !process.browser) {
|
||
exports.randomFill = randomFill
|
||
exports.randomFillSync = randomFillSync
|
||
} else {
|
||
exports.randomFill = oldBrowser
|
||
exports.randomFillSync = oldBrowser
|
||
}
|
||
function randomFill (buf, offset, size, cb) {
|
||
if (!Buffer.isBuffer(buf) && !(buf instanceof global.Uint8Array)) {
|
||
throw new TypeError('"buf" argument must be a Buffer or Uint8Array')
|
||
}
|
||
|
||
if (typeof offset === 'function') {
|
||
cb = offset
|
||
offset = 0
|
||
size = buf.length
|
||
} else if (typeof size === 'function') {
|
||
cb = size
|
||
size = buf.length - offset
|
||
} else if (typeof cb !== 'function') {
|
||
throw new TypeError('"cb" argument must be a function')
|
||
}
|
||
assertOffset(offset, buf.length)
|
||
assertSize(size, offset, buf.length)
|
||
return actualFill(buf, offset, size, cb)
|
||
}
|
||
|
||
function actualFill (buf, offset, size, cb) {
|
||
if (process.browser) {
|
||
var ourBuf = buf.buffer
|
||
var uint = new Uint8Array(ourBuf, offset, size)
|
||
crypto.getRandomValues(uint)
|
||
if (cb) {
|
||
process.nextTick(function () {
|
||
cb(null, buf)
|
||
})
|
||
return
|
||
}
|
||
return buf
|
||
}
|
||
if (cb) {
|
||
randombytes(size, function (err, bytes) {
|
||
if (err) {
|
||
return cb(err)
|
||
}
|
||
bytes.copy(buf, offset)
|
||
cb(null, buf)
|
||
})
|
||
return
|
||
}
|
||
var bytes = randombytes(size)
|
||
bytes.copy(buf, offset)
|
||
return buf
|
||
}
|
||
function randomFillSync (buf, offset, size) {
|
||
if (typeof offset === 'undefined') {
|
||
offset = 0
|
||
}
|
||
if (!Buffer.isBuffer(buf) && !(buf instanceof global.Uint8Array)) {
|
||
throw new TypeError('"buf" argument must be a Buffer or Uint8Array')
|
||
}
|
||
|
||
assertOffset(offset, buf.length)
|
||
|
||
if (size === undefined) size = buf.length - offset
|
||
|
||
assertSize(size, offset, buf.length)
|
||
|
||
return actualFill(buf, offset, size)
|
||
}
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js"), __webpack_require__(/*! ./../process/browser.js */ "./node_modules/process/browser.js")))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/readable-stream/duplex-browser.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/readable-stream/duplex-browser.js ***!
|
||
\********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
module.exports = __webpack_require__(/*! ./lib/_stream_duplex.js */ "./node_modules/readable-stream/lib/_stream_duplex.js");
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/readable-stream/lib/_stream_duplex.js":
|
||
/*!************************************************************!*\
|
||
!*** ./node_modules/readable-stream/lib/_stream_duplex.js ***!
|
||
\************************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
// Copyright Joyent, Inc. and other Node contributors.
|
||
//
|
||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||
// copy of this software and associated documentation files (the
|
||
// "Software"), to deal in the Software without restriction, including
|
||
// without limitation the rights to use, copy, modify, merge, publish,
|
||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||
// persons to whom the Software is furnished to do so, subject to the
|
||
// following conditions:
|
||
//
|
||
// The above copyright notice and this permission notice shall be included
|
||
// in all copies or substantial portions of the Software.
|
||
//
|
||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
||
// a duplex stream is just a stream that is both readable and writable.
|
||
// Since JS doesn't have multiple prototypal inheritance, this class
|
||
// prototypally inherits from Readable, and then parasitically from
|
||
// Writable.
|
||
|
||
|
||
|
||
/*<replacement>*/
|
||
|
||
var pna = __webpack_require__(/*! process-nextick-args */ "./node_modules/process-nextick-args/index.js");
|
||
/*</replacement>*/
|
||
|
||
/*<replacement>*/
|
||
var objectKeys = Object.keys || function (obj) {
|
||
var keys = [];
|
||
for (var key in obj) {
|
||
keys.push(key);
|
||
}return keys;
|
||
};
|
||
/*</replacement>*/
|
||
|
||
module.exports = Duplex;
|
||
|
||
/*<replacement>*/
|
||
var util = __webpack_require__(/*! core-util-is */ "./node_modules/core-util-is/lib/util.js");
|
||
util.inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
/*</replacement>*/
|
||
|
||
var Readable = __webpack_require__(/*! ./_stream_readable */ "./node_modules/readable-stream/lib/_stream_readable.js");
|
||
var Writable = __webpack_require__(/*! ./_stream_writable */ "./node_modules/readable-stream/lib/_stream_writable.js");
|
||
|
||
util.inherits(Duplex, Readable);
|
||
|
||
{
|
||
// avoid scope creep, the keys array can then be collected
|
||
var keys = objectKeys(Writable.prototype);
|
||
for (var v = 0; v < keys.length; v++) {
|
||
var method = keys[v];
|
||
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
|
||
}
|
||
}
|
||
|
||
function Duplex(options) {
|
||
if (!(this instanceof Duplex)) return new Duplex(options);
|
||
|
||
Readable.call(this, options);
|
||
Writable.call(this, options);
|
||
|
||
if (options && options.readable === false) this.readable = false;
|
||
|
||
if (options && options.writable === false) this.writable = false;
|
||
|
||
this.allowHalfOpen = true;
|
||
if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;
|
||
|
||
this.once('end', onend);
|
||
}
|
||
|
||
Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', {
|
||
// making it explicit this property is not enumerable
|
||
// because otherwise some prototype manipulation in
|
||
// userland will fail
|
||
enumerable: false,
|
||
get: function () {
|
||
return this._writableState.highWaterMark;
|
||
}
|
||
});
|
||
|
||
// the no-half-open enforcer
|
||
function onend() {
|
||
// if we allow half-open state, or if the writable side ended,
|
||
// then we're ok.
|
||
if (this.allowHalfOpen || this._writableState.ended) return;
|
||
|
||
// no more data can be written.
|
||
// But allow more writes to happen in this tick.
|
||
pna.nextTick(onEndNT, this);
|
||
}
|
||
|
||
function onEndNT(self) {
|
||
self.end();
|
||
}
|
||
|
||
Object.defineProperty(Duplex.prototype, 'destroyed', {
|
||
get: function () {
|
||
if (this._readableState === undefined || this._writableState === undefined) {
|
||
return false;
|
||
}
|
||
return this._readableState.destroyed && this._writableState.destroyed;
|
||
},
|
||
set: function (value) {
|
||
// we ignore the value if the stream
|
||
// has not been initialized yet
|
||
if (this._readableState === undefined || this._writableState === undefined) {
|
||
return;
|
||
}
|
||
|
||
// backward compatibility, the user is explicitly
|
||
// managing destroyed
|
||
this._readableState.destroyed = value;
|
||
this._writableState.destroyed = value;
|
||
}
|
||
});
|
||
|
||
Duplex.prototype._destroy = function (err, cb) {
|
||
this.push(null);
|
||
this.end();
|
||
|
||
pna.nextTick(cb, err);
|
||
};
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/readable-stream/lib/_stream_passthrough.js":
|
||
/*!*****************************************************************!*\
|
||
!*** ./node_modules/readable-stream/lib/_stream_passthrough.js ***!
|
||
\*****************************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
// Copyright Joyent, Inc. and other Node contributors.
|
||
//
|
||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||
// copy of this software and associated documentation files (the
|
||
// "Software"), to deal in the Software without restriction, including
|
||
// without limitation the rights to use, copy, modify, merge, publish,
|
||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||
// persons to whom the Software is furnished to do so, subject to the
|
||
// following conditions:
|
||
//
|
||
// The above copyright notice and this permission notice shall be included
|
||
// in all copies or substantial portions of the Software.
|
||
//
|
||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
||
// a passthrough stream.
|
||
// basically just the most minimal sort of Transform stream.
|
||
// Every written chunk gets output as-is.
|
||
|
||
|
||
|
||
module.exports = PassThrough;
|
||
|
||
var Transform = __webpack_require__(/*! ./_stream_transform */ "./node_modules/readable-stream/lib/_stream_transform.js");
|
||
|
||
/*<replacement>*/
|
||
var util = __webpack_require__(/*! core-util-is */ "./node_modules/core-util-is/lib/util.js");
|
||
util.inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
/*</replacement>*/
|
||
|
||
util.inherits(PassThrough, Transform);
|
||
|
||
function PassThrough(options) {
|
||
if (!(this instanceof PassThrough)) return new PassThrough(options);
|
||
|
||
Transform.call(this, options);
|
||
}
|
||
|
||
PassThrough.prototype._transform = function (chunk, encoding, cb) {
|
||
cb(null, chunk);
|
||
};
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/readable-stream/lib/_stream_readable.js":
|
||
/*!**************************************************************!*\
|
||
!*** ./node_modules/readable-stream/lib/_stream_readable.js ***!
|
||
\**************************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
/* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors.
|
||
//
|
||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||
// copy of this software and associated documentation files (the
|
||
// "Software"), to deal in the Software without restriction, including
|
||
// without limitation the rights to use, copy, modify, merge, publish,
|
||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||
// persons to whom the Software is furnished to do so, subject to the
|
||
// following conditions:
|
||
//
|
||
// The above copyright notice and this permission notice shall be included
|
||
// in all copies or substantial portions of the Software.
|
||
//
|
||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
||
|
||
|
||
/*<replacement>*/
|
||
|
||
var pna = __webpack_require__(/*! process-nextick-args */ "./node_modules/process-nextick-args/index.js");
|
||
/*</replacement>*/
|
||
|
||
module.exports = Readable;
|
||
|
||
/*<replacement>*/
|
||
var isArray = __webpack_require__(/*! isarray */ "./node_modules/isarray/index.js");
|
||
/*</replacement>*/
|
||
|
||
/*<replacement>*/
|
||
var Duplex;
|
||
/*</replacement>*/
|
||
|
||
Readable.ReadableState = ReadableState;
|
||
|
||
/*<replacement>*/
|
||
var EE = __webpack_require__(/*! events */ "./node_modules/events/events.js").EventEmitter;
|
||
|
||
var EElistenerCount = function (emitter, type) {
|
||
return emitter.listeners(type).length;
|
||
};
|
||
/*</replacement>*/
|
||
|
||
/*<replacement>*/
|
||
var Stream = __webpack_require__(/*! ./internal/streams/stream */ "./node_modules/readable-stream/lib/internal/streams/stream-browser.js");
|
||
/*</replacement>*/
|
||
|
||
/*<replacement>*/
|
||
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer;
|
||
var OurUint8Array = global.Uint8Array || function () {};
|
||
function _uint8ArrayToBuffer(chunk) {
|
||
return Buffer.from(chunk);
|
||
}
|
||
function _isUint8Array(obj) {
|
||
return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
|
||
}
|
||
|
||
/*</replacement>*/
|
||
|
||
/*<replacement>*/
|
||
var util = __webpack_require__(/*! core-util-is */ "./node_modules/core-util-is/lib/util.js");
|
||
util.inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
/*</replacement>*/
|
||
|
||
/*<replacement>*/
|
||
var debugUtil = __webpack_require__(/*! util */ 0);
|
||
var debug = void 0;
|
||
if (debugUtil && debugUtil.debuglog) {
|
||
debug = debugUtil.debuglog('stream');
|
||
} else {
|
||
debug = function () {};
|
||
}
|
||
/*</replacement>*/
|
||
|
||
var BufferList = __webpack_require__(/*! ./internal/streams/BufferList */ "./node_modules/readable-stream/lib/internal/streams/BufferList.js");
|
||
var destroyImpl = __webpack_require__(/*! ./internal/streams/destroy */ "./node_modules/readable-stream/lib/internal/streams/destroy.js");
|
||
var StringDecoder;
|
||
|
||
util.inherits(Readable, Stream);
|
||
|
||
var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume'];
|
||
|
||
function prependListener(emitter, event, fn) {
|
||
// Sadly this is not cacheable as some libraries bundle their own
|
||
// event emitter implementation with them.
|
||
if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn);
|
||
|
||
// This is a hack to make sure that our error handler is attached before any
|
||
// userland ones. NEVER DO THIS. This is here only because this code needs
|
||
// to continue to work with older versions of Node.js that do not include
|
||
// the prependListener() method. The goal is to eventually remove this hack.
|
||
if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];
|
||
}
|
||
|
||
function ReadableState(options, stream) {
|
||
Duplex = Duplex || __webpack_require__(/*! ./_stream_duplex */ "./node_modules/readable-stream/lib/_stream_duplex.js");
|
||
|
||
options = options || {};
|
||
|
||
// Duplex streams are both readable and writable, but share
|
||
// the same options object.
|
||
// However, some cases require setting options to different
|
||
// values for the readable and the writable sides of the duplex stream.
|
||
// These options can be provided separately as readableXXX and writableXXX.
|
||
var isDuplex = stream instanceof Duplex;
|
||
|
||
// object stream flag. Used to make read(n) ignore n and to
|
||
// make all the buffer merging and length checks go away
|
||
this.objectMode = !!options.objectMode;
|
||
|
||
if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
|
||
|
||
// the point at which it stops calling _read() to fill the buffer
|
||
// Note: 0 is a valid value, means "don't call _read preemptively ever"
|
||
var hwm = options.highWaterMark;
|
||
var readableHwm = options.readableHighWaterMark;
|
||
var defaultHwm = this.objectMode ? 16 : 16 * 1024;
|
||
|
||
if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (readableHwm || readableHwm === 0)) this.highWaterMark = readableHwm;else this.highWaterMark = defaultHwm;
|
||
|
||
// cast to ints.
|
||
this.highWaterMark = Math.floor(this.highWaterMark);
|
||
|
||
// A linked list is used to store data chunks instead of an array because the
|
||
// linked list can remove elements from the beginning faster than
|
||
// array.shift()
|
||
this.buffer = new BufferList();
|
||
this.length = 0;
|
||
this.pipes = null;
|
||
this.pipesCount = 0;
|
||
this.flowing = null;
|
||
this.ended = false;
|
||
this.endEmitted = false;
|
||
this.reading = false;
|
||
|
||
// a flag to be able to tell if the event 'readable'/'data' is emitted
|
||
// immediately, or on a later tick. We set this to true at first, because
|
||
// any actions that shouldn't happen until "later" should generally also
|
||
// not happen before the first read call.
|
||
this.sync = true;
|
||
|
||
// whenever we return null, then we set a flag to say
|
||
// that we're awaiting a 'readable' event emission.
|
||
this.needReadable = false;
|
||
this.emittedReadable = false;
|
||
this.readableListening = false;
|
||
this.resumeScheduled = false;
|
||
|
||
// has it been destroyed
|
||
this.destroyed = false;
|
||
|
||
// Crypto is kind of old and crusty. Historically, its default string
|
||
// encoding is 'binary' so we have to make this configurable.
|
||
// Everything else in the universe uses 'utf8', though.
|
||
this.defaultEncoding = options.defaultEncoding || 'utf8';
|
||
|
||
// the number of writers that are awaiting a drain event in .pipe()s
|
||
this.awaitDrain = 0;
|
||
|
||
// if true, a maybeReadMore has been scheduled
|
||
this.readingMore = false;
|
||
|
||
this.decoder = null;
|
||
this.encoding = null;
|
||
if (options.encoding) {
|
||
if (!StringDecoder) StringDecoder = __webpack_require__(/*! string_decoder/ */ "./node_modules/string_decoder/lib/string_decoder.js").StringDecoder;
|
||
this.decoder = new StringDecoder(options.encoding);
|
||
this.encoding = options.encoding;
|
||
}
|
||
}
|
||
|
||
function Readable(options) {
|
||
Duplex = Duplex || __webpack_require__(/*! ./_stream_duplex */ "./node_modules/readable-stream/lib/_stream_duplex.js");
|
||
|
||
if (!(this instanceof Readable)) return new Readable(options);
|
||
|
||
this._readableState = new ReadableState(options, this);
|
||
|
||
// legacy
|
||
this.readable = true;
|
||
|
||
if (options) {
|
||
if (typeof options.read === 'function') this._read = options.read;
|
||
|
||
if (typeof options.destroy === 'function') this._destroy = options.destroy;
|
||
}
|
||
|
||
Stream.call(this);
|
||
}
|
||
|
||
Object.defineProperty(Readable.prototype, 'destroyed', {
|
||
get: function () {
|
||
if (this._readableState === undefined) {
|
||
return false;
|
||
}
|
||
return this._readableState.destroyed;
|
||
},
|
||
set: function (value) {
|
||
// we ignore the value if the stream
|
||
// has not been initialized yet
|
||
if (!this._readableState) {
|
||
return;
|
||
}
|
||
|
||
// backward compatibility, the user is explicitly
|
||
// managing destroyed
|
||
this._readableState.destroyed = value;
|
||
}
|
||
});
|
||
|
||
Readable.prototype.destroy = destroyImpl.destroy;
|
||
Readable.prototype._undestroy = destroyImpl.undestroy;
|
||
Readable.prototype._destroy = function (err, cb) {
|
||
this.push(null);
|
||
cb(err);
|
||
};
|
||
|
||
// Manually shove something into the read() buffer.
|
||
// This returns true if the highWaterMark has not been hit yet,
|
||
// similar to how Writable.write() returns true if you should
|
||
// write() some more.
|
||
Readable.prototype.push = function (chunk, encoding) {
|
||
var state = this._readableState;
|
||
var skipChunkCheck;
|
||
|
||
if (!state.objectMode) {
|
||
if (typeof chunk === 'string') {
|
||
encoding = encoding || state.defaultEncoding;
|
||
if (encoding !== state.encoding) {
|
||
chunk = Buffer.from(chunk, encoding);
|
||
encoding = '';
|
||
}
|
||
skipChunkCheck = true;
|
||
}
|
||
} else {
|
||
skipChunkCheck = true;
|
||
}
|
||
|
||
return readableAddChunk(this, chunk, encoding, false, skipChunkCheck);
|
||
};
|
||
|
||
// Unshift should *always* be something directly out of read()
|
||
Readable.prototype.unshift = function (chunk) {
|
||
return readableAddChunk(this, chunk, null, true, false);
|
||
};
|
||
|
||
function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) {
|
||
var state = stream._readableState;
|
||
if (chunk === null) {
|
||
state.reading = false;
|
||
onEofChunk(stream, state);
|
||
} else {
|
||
var er;
|
||
if (!skipChunkCheck) er = chunkInvalid(state, chunk);
|
||
if (er) {
|
||
stream.emit('error', er);
|
||
} else if (state.objectMode || chunk && chunk.length > 0) {
|
||
if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) {
|
||
chunk = _uint8ArrayToBuffer(chunk);
|
||
}
|
||
|
||
if (addToFront) {
|
||
if (state.endEmitted) stream.emit('error', new Error('stream.unshift() after end event'));else addChunk(stream, state, chunk, true);
|
||
} else if (state.ended) {
|
||
stream.emit('error', new Error('stream.push() after EOF'));
|
||
} else {
|
||
state.reading = false;
|
||
if (state.decoder && !encoding) {
|
||
chunk = state.decoder.write(chunk);
|
||
if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state);
|
||
} else {
|
||
addChunk(stream, state, chunk, false);
|
||
}
|
||
}
|
||
} else if (!addToFront) {
|
||
state.reading = false;
|
||
}
|
||
}
|
||
|
||
return needMoreData(state);
|
||
}
|
||
|
||
function addChunk(stream, state, chunk, addToFront) {
|
||
if (state.flowing && state.length === 0 && !state.sync) {
|
||
stream.emit('data', chunk);
|
||
stream.read(0);
|
||
} else {
|
||
// update the buffer info.
|
||
state.length += state.objectMode ? 1 : chunk.length;
|
||
if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
|
||
|
||
if (state.needReadable) emitReadable(stream);
|
||
}
|
||
maybeReadMore(stream, state);
|
||
}
|
||
|
||
function chunkInvalid(state, chunk) {
|
||
var er;
|
||
if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
|
||
er = new TypeError('Invalid non-string/buffer chunk');
|
||
}
|
||
return er;
|
||
}
|
||
|
||
// if it's past the high water mark, we can push in some more.
|
||
// Also, if we have no data yet, we can stand some
|
||
// more bytes. This is to work around cases where hwm=0,
|
||
// such as the repl. Also, if the push() triggered a
|
||
// readable event, and the user called read(largeNumber) such that
|
||
// needReadable was set, then we ought to push more, so that another
|
||
// 'readable' event will be triggered.
|
||
function needMoreData(state) {
|
||
return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);
|
||
}
|
||
|
||
Readable.prototype.isPaused = function () {
|
||
return this._readableState.flowing === false;
|
||
};
|
||
|
||
// backwards compatibility.
|
||
Readable.prototype.setEncoding = function (enc) {
|
||
if (!StringDecoder) StringDecoder = __webpack_require__(/*! string_decoder/ */ "./node_modules/string_decoder/lib/string_decoder.js").StringDecoder;
|
||
this._readableState.decoder = new StringDecoder(enc);
|
||
this._readableState.encoding = enc;
|
||
return this;
|
||
};
|
||
|
||
// Don't raise the hwm > 8MB
|
||
var MAX_HWM = 0x800000;
|
||
function computeNewHighWaterMark(n) {
|
||
if (n >= MAX_HWM) {
|
||
n = MAX_HWM;
|
||
} else {
|
||
// Get the next highest power of 2 to prevent increasing hwm excessively in
|
||
// tiny amounts
|
||
n--;
|
||
n |= n >>> 1;
|
||
n |= n >>> 2;
|
||
n |= n >>> 4;
|
||
n |= n >>> 8;
|
||
n |= n >>> 16;
|
||
n++;
|
||
}
|
||
return n;
|
||
}
|
||
|
||
// This function is designed to be inlinable, so please take care when making
|
||
// changes to the function body.
|
||
function howMuchToRead(n, state) {
|
||
if (n <= 0 || state.length === 0 && state.ended) return 0;
|
||
if (state.objectMode) return 1;
|
||
if (n !== n) {
|
||
// Only flow one buffer at a time
|
||
if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;
|
||
}
|
||
// If we're asking for more than the current hwm, then raise the hwm.
|
||
if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
|
||
if (n <= state.length) return n;
|
||
// Don't have enough
|
||
if (!state.ended) {
|
||
state.needReadable = true;
|
||
return 0;
|
||
}
|
||
return state.length;
|
||
}
|
||
|
||
// you can override either this method, or the async _read(n) below.
|
||
Readable.prototype.read = function (n) {
|
||
debug('read', n);
|
||
n = parseInt(n, 10);
|
||
var state = this._readableState;
|
||
var nOrig = n;
|
||
|
||
if (n !== 0) state.emittedReadable = false;
|
||
|
||
// if we're doing read(0) to trigger a readable event, but we
|
||
// already have a bunch of data in the buffer, then just trigger
|
||
// the 'readable' event and move on.
|
||
if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {
|
||
debug('read: emitReadable', state.length, state.ended);
|
||
if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
|
||
return null;
|
||
}
|
||
|
||
n = howMuchToRead(n, state);
|
||
|
||
// if we've ended, and we're now clear, then finish it up.
|
||
if (n === 0 && state.ended) {
|
||
if (state.length === 0) endReadable(this);
|
||
return null;
|
||
}
|
||
|
||
// All the actual chunk generation logic needs to be
|
||
// *below* the call to _read. The reason is that in certain
|
||
// synthetic stream cases, such as passthrough streams, _read
|
||
// may be a completely synchronous operation which may change
|
||
// the state of the read buffer, providing enough data when
|
||
// before there was *not* enough.
|
||
//
|
||
// So, the steps are:
|
||
// 1. Figure out what the state of things will be after we do
|
||
// a read from the buffer.
|
||
//
|
||
// 2. If that resulting state will trigger a _read, then call _read.
|
||
// Note that this may be asynchronous, or synchronous. Yes, it is
|
||
// deeply ugly to write APIs this way, but that still doesn't mean
|
||
// that the Readable class should behave improperly, as streams are
|
||
// designed to be sync/async agnostic.
|
||
// Take note if the _read call is sync or async (ie, if the read call
|
||
// has returned yet), so that we know whether or not it's safe to emit
|
||
// 'readable' etc.
|
||
//
|
||
// 3. Actually pull the requested chunks out of the buffer and return.
|
||
|
||
// if we need a readable event, then we need to do some reading.
|
||
var doRead = state.needReadable;
|
||
debug('need readable', doRead);
|
||
|
||
// if we currently have less than the highWaterMark, then also read some
|
||
if (state.length === 0 || state.length - n < state.highWaterMark) {
|
||
doRead = true;
|
||
debug('length less than watermark', doRead);
|
||
}
|
||
|
||
// however, if we've ended, then there's no point, and if we're already
|
||
// reading, then it's unnecessary.
|
||
if (state.ended || state.reading) {
|
||
doRead = false;
|
||
debug('reading or ended', doRead);
|
||
} else if (doRead) {
|
||
debug('do read');
|
||
state.reading = true;
|
||
state.sync = true;
|
||
// if the length is currently zero, then we *need* a readable event.
|
||
if (state.length === 0) state.needReadable = true;
|
||
// call internal read method
|
||
this._read(state.highWaterMark);
|
||
state.sync = false;
|
||
// If _read pushed data synchronously, then `reading` will be false,
|
||
// and we need to re-evaluate how much data we can return to the user.
|
||
if (!state.reading) n = howMuchToRead(nOrig, state);
|
||
}
|
||
|
||
var ret;
|
||
if (n > 0) ret = fromList(n, state);else ret = null;
|
||
|
||
if (ret === null) {
|
||
state.needReadable = true;
|
||
n = 0;
|
||
} else {
|
||
state.length -= n;
|
||
}
|
||
|
||
if (state.length === 0) {
|
||
// If we have nothing in the buffer, then we want to know
|
||
// as soon as we *do* get something into the buffer.
|
||
if (!state.ended) state.needReadable = true;
|
||
|
||
// If we tried to read() past the EOF, then emit end on the next tick.
|
||
if (nOrig !== n && state.ended) endReadable(this);
|
||
}
|
||
|
||
if (ret !== null) this.emit('data', ret);
|
||
|
||
return ret;
|
||
};
|
||
|
||
function onEofChunk(stream, state) {
|
||
if (state.ended) return;
|
||
if (state.decoder) {
|
||
var chunk = state.decoder.end();
|
||
if (chunk && chunk.length) {
|
||
state.buffer.push(chunk);
|
||
state.length += state.objectMode ? 1 : chunk.length;
|
||
}
|
||
}
|
||
state.ended = true;
|
||
|
||
// emit 'readable' now to make sure it gets picked up.
|
||
emitReadable(stream);
|
||
}
|
||
|
||
// Don't emit readable right away in sync mode, because this can trigger
|
||
// another read() call => stack overflow. This way, it might trigger
|
||
// a nextTick recursion warning, but that's not so bad.
|
||
function emitReadable(stream) {
|
||
var state = stream._readableState;
|
||
state.needReadable = false;
|
||
if (!state.emittedReadable) {
|
||
debug('emitReadable', state.flowing);
|
||
state.emittedReadable = true;
|
||
if (state.sync) pna.nextTick(emitReadable_, stream);else emitReadable_(stream);
|
||
}
|
||
}
|
||
|
||
function emitReadable_(stream) {
|
||
debug('emit readable');
|
||
stream.emit('readable');
|
||
flow(stream);
|
||
}
|
||
|
||
// at this point, the user has presumably seen the 'readable' event,
|
||
// and called read() to consume some data. that may have triggered
|
||
// in turn another _read(n) call, in which case reading = true if
|
||
// it's in progress.
|
||
// However, if we're not ended, or reading, and the length < hwm,
|
||
// then go ahead and try to read some more preemptively.
|
||
function maybeReadMore(stream, state) {
|
||
if (!state.readingMore) {
|
||
state.readingMore = true;
|
||
pna.nextTick(maybeReadMore_, stream, state);
|
||
}
|
||
}
|
||
|
||
function maybeReadMore_(stream, state) {
|
||
var len = state.length;
|
||
while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {
|
||
debug('maybeReadMore read 0');
|
||
stream.read(0);
|
||
if (len === state.length)
|
||
// didn't get any data, stop spinning.
|
||
break;else len = state.length;
|
||
}
|
||
state.readingMore = false;
|
||
}
|
||
|
||
// abstract method. to be overridden in specific implementation classes.
|
||
// call cb(er, data) where data is <= n in length.
|
||
// for virtual (non-string, non-buffer) streams, "length" is somewhat
|
||
// arbitrary, and perhaps not very meaningful.
|
||
Readable.prototype._read = function (n) {
|
||
this.emit('error', new Error('_read() is not implemented'));
|
||
};
|
||
|
||
Readable.prototype.pipe = function (dest, pipeOpts) {
|
||
var src = this;
|
||
var state = this._readableState;
|
||
|
||
switch (state.pipesCount) {
|
||
case 0:
|
||
state.pipes = dest;
|
||
break;
|
||
case 1:
|
||
state.pipes = [state.pipes, dest];
|
||
break;
|
||
default:
|
||
state.pipes.push(dest);
|
||
break;
|
||
}
|
||
state.pipesCount += 1;
|
||
debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
|
||
|
||
var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
|
||
|
||
var endFn = doEnd ? onend : unpipe;
|
||
if (state.endEmitted) pna.nextTick(endFn);else src.once('end', endFn);
|
||
|
||
dest.on('unpipe', onunpipe);
|
||
function onunpipe(readable, unpipeInfo) {
|
||
debug('onunpipe');
|
||
if (readable === src) {
|
||
if (unpipeInfo && unpipeInfo.hasUnpiped === false) {
|
||
unpipeInfo.hasUnpiped = true;
|
||
cleanup();
|
||
}
|
||
}
|
||
}
|
||
|
||
function onend() {
|
||
debug('onend');
|
||
dest.end();
|
||
}
|
||
|
||
// when the dest drains, it reduces the awaitDrain counter
|
||
// on the source. This would be more elegant with a .once()
|
||
// handler in flow(), but adding and removing repeatedly is
|
||
// too slow.
|
||
var ondrain = pipeOnDrain(src);
|
||
dest.on('drain', ondrain);
|
||
|
||
var cleanedUp = false;
|
||
function cleanup() {
|
||
debug('cleanup');
|
||
// cleanup event handlers once the pipe is broken
|
||
dest.removeListener('close', onclose);
|
||
dest.removeListener('finish', onfinish);
|
||
dest.removeListener('drain', ondrain);
|
||
dest.removeListener('error', onerror);
|
||
dest.removeListener('unpipe', onunpipe);
|
||
src.removeListener('end', onend);
|
||
src.removeListener('end', unpipe);
|
||
src.removeListener('data', ondata);
|
||
|
||
cleanedUp = true;
|
||
|
||
// if the reader is waiting for a drain event from this
|
||
// specific writer, then it would cause it to never start
|
||
// flowing again.
|
||
// So, if this is awaiting a drain, then we just call it now.
|
||
// If we don't know, then assume that we are waiting for one.
|
||
if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
|
||
}
|
||
|
||
// If the user pushes more data while we're writing to dest then we'll end up
|
||
// in ondata again. However, we only want to increase awaitDrain once because
|
||
// dest will only emit one 'drain' event for the multiple writes.
|
||
// => Introduce a guard on increasing awaitDrain.
|
||
var increasedAwaitDrain = false;
|
||
src.on('data', ondata);
|
||
function ondata(chunk) {
|
||
debug('ondata');
|
||
increasedAwaitDrain = false;
|
||
var ret = dest.write(chunk);
|
||
if (false === ret && !increasedAwaitDrain) {
|
||
// If the user unpiped during `dest.write()`, it is possible
|
||
// to get stuck in a permanently paused state if that write
|
||
// also returned false.
|
||
// => Check whether `dest` is still a piping destination.
|
||
if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {
|
||
debug('false write response, pause', src._readableState.awaitDrain);
|
||
src._readableState.awaitDrain++;
|
||
increasedAwaitDrain = true;
|
||
}
|
||
src.pause();
|
||
}
|
||
}
|
||
|
||
// if the dest has an error, then stop piping into it.
|
||
// however, don't suppress the throwing behavior for this.
|
||
function onerror(er) {
|
||
debug('onerror', er);
|
||
unpipe();
|
||
dest.removeListener('error', onerror);
|
||
if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);
|
||
}
|
||
|
||
// Make sure our error handler is attached before userland ones.
|
||
prependListener(dest, 'error', onerror);
|
||
|
||
// Both close and finish should trigger unpipe, but only once.
|
||
function onclose() {
|
||
dest.removeListener('finish', onfinish);
|
||
unpipe();
|
||
}
|
||
dest.once('close', onclose);
|
||
function onfinish() {
|
||
debug('onfinish');
|
||
dest.removeListener('close', onclose);
|
||
unpipe();
|
||
}
|
||
dest.once('finish', onfinish);
|
||
|
||
function unpipe() {
|
||
debug('unpipe');
|
||
src.unpipe(dest);
|
||
}
|
||
|
||
// tell the dest that it's being piped to
|
||
dest.emit('pipe', src);
|
||
|
||
// start the flow if it hasn't been started already.
|
||
if (!state.flowing) {
|
||
debug('pipe resume');
|
||
src.resume();
|
||
}
|
||
|
||
return dest;
|
||
};
|
||
|
||
function pipeOnDrain(src) {
|
||
return function () {
|
||
var state = src._readableState;
|
||
debug('pipeOnDrain', state.awaitDrain);
|
||
if (state.awaitDrain) state.awaitDrain--;
|
||
if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
|
||
state.flowing = true;
|
||
flow(src);
|
||
}
|
||
};
|
||
}
|
||
|
||
Readable.prototype.unpipe = function (dest) {
|
||
var state = this._readableState;
|
||
var unpipeInfo = { hasUnpiped: false };
|
||
|
||
// if we're not piping anywhere, then do nothing.
|
||
if (state.pipesCount === 0) return this;
|
||
|
||
// just one destination. most common case.
|
||
if (state.pipesCount === 1) {
|
||
// passed in one, but it's not the right one.
|
||
if (dest && dest !== state.pipes) return this;
|
||
|
||
if (!dest) dest = state.pipes;
|
||
|
||
// got a match.
|
||
state.pipes = null;
|
||
state.pipesCount = 0;
|
||
state.flowing = false;
|
||
if (dest) dest.emit('unpipe', this, unpipeInfo);
|
||
return this;
|
||
}
|
||
|
||
// slow case. multiple pipe destinations.
|
||
|
||
if (!dest) {
|
||
// remove all.
|
||
var dests = state.pipes;
|
||
var len = state.pipesCount;
|
||
state.pipes = null;
|
||
state.pipesCount = 0;
|
||
state.flowing = false;
|
||
|
||
for (var i = 0; i < len; i++) {
|
||
dests[i].emit('unpipe', this, unpipeInfo);
|
||
}return this;
|
||
}
|
||
|
||
// try to find the right one.
|
||
var index = indexOf(state.pipes, dest);
|
||
if (index === -1) return this;
|
||
|
||
state.pipes.splice(index, 1);
|
||
state.pipesCount -= 1;
|
||
if (state.pipesCount === 1) state.pipes = state.pipes[0];
|
||
|
||
dest.emit('unpipe', this, unpipeInfo);
|
||
|
||
return this;
|
||
};
|
||
|
||
// set up data events if they are asked for
|
||
// Ensure readable listeners eventually get something
|
||
Readable.prototype.on = function (ev, fn) {
|
||
var res = Stream.prototype.on.call(this, ev, fn);
|
||
|
||
if (ev === 'data') {
|
||
// Start flowing on next tick if stream isn't explicitly paused
|
||
if (this._readableState.flowing !== false) this.resume();
|
||
} else if (ev === 'readable') {
|
||
var state = this._readableState;
|
||
if (!state.endEmitted && !state.readableListening) {
|
||
state.readableListening = state.needReadable = true;
|
||
state.emittedReadable = false;
|
||
if (!state.reading) {
|
||
pna.nextTick(nReadingNextTick, this);
|
||
} else if (state.length) {
|
||
emitReadable(this);
|
||
}
|
||
}
|
||
}
|
||
|
||
return res;
|
||
};
|
||
Readable.prototype.addListener = Readable.prototype.on;
|
||
|
||
function nReadingNextTick(self) {
|
||
debug('readable nexttick read 0');
|
||
self.read(0);
|
||
}
|
||
|
||
// pause() and resume() are remnants of the legacy readable stream API
|
||
// If the user uses them, then switch into old mode.
|
||
Readable.prototype.resume = function () {
|
||
var state = this._readableState;
|
||
if (!state.flowing) {
|
||
debug('resume');
|
||
state.flowing = true;
|
||
resume(this, state);
|
||
}
|
||
return this;
|
||
};
|
||
|
||
function resume(stream, state) {
|
||
if (!state.resumeScheduled) {
|
||
state.resumeScheduled = true;
|
||
pna.nextTick(resume_, stream, state);
|
||
}
|
||
}
|
||
|
||
function resume_(stream, state) {
|
||
if (!state.reading) {
|
||
debug('resume read 0');
|
||
stream.read(0);
|
||
}
|
||
|
||
state.resumeScheduled = false;
|
||
state.awaitDrain = 0;
|
||
stream.emit('resume');
|
||
flow(stream);
|
||
if (state.flowing && !state.reading) stream.read(0);
|
||
}
|
||
|
||
Readable.prototype.pause = function () {
|
||
debug('call pause flowing=%j', this._readableState.flowing);
|
||
if (false !== this._readableState.flowing) {
|
||
debug('pause');
|
||
this._readableState.flowing = false;
|
||
this.emit('pause');
|
||
}
|
||
return this;
|
||
};
|
||
|
||
function flow(stream) {
|
||
var state = stream._readableState;
|
||
debug('flow', state.flowing);
|
||
while (state.flowing && stream.read() !== null) {}
|
||
}
|
||
|
||
// wrap an old-style stream as the async data source.
|
||
// This is *not* part of the readable stream interface.
|
||
// It is an ugly unfortunate mess of history.
|
||
Readable.prototype.wrap = function (stream) {
|
||
var _this = this;
|
||
|
||
var state = this._readableState;
|
||
var paused = false;
|
||
|
||
stream.on('end', function () {
|
||
debug('wrapped end');
|
||
if (state.decoder && !state.ended) {
|
||
var chunk = state.decoder.end();
|
||
if (chunk && chunk.length) _this.push(chunk);
|
||
}
|
||
|
||
_this.push(null);
|
||
});
|
||
|
||
stream.on('data', function (chunk) {
|
||
debug('wrapped data');
|
||
if (state.decoder) chunk = state.decoder.write(chunk);
|
||
|
||
// don't skip over falsy values in objectMode
|
||
if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
|
||
|
||
var ret = _this.push(chunk);
|
||
if (!ret) {
|
||
paused = true;
|
||
stream.pause();
|
||
}
|
||
});
|
||
|
||
// proxy all the other methods.
|
||
// important when wrapping filters and duplexes.
|
||
for (var i in stream) {
|
||
if (this[i] === undefined && typeof stream[i] === 'function') {
|
||
this[i] = function (method) {
|
||
return function () {
|
||
return stream[method].apply(stream, arguments);
|
||
};
|
||
}(i);
|
||
}
|
||
}
|
||
|
||
// proxy certain important events.
|
||
for (var n = 0; n < kProxyEvents.length; n++) {
|
||
stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n]));
|
||
}
|
||
|
||
// when we try to consume some more bytes, simply unpause the
|
||
// underlying stream.
|
||
this._read = function (n) {
|
||
debug('wrapped _read', n);
|
||
if (paused) {
|
||
paused = false;
|
||
stream.resume();
|
||
}
|
||
};
|
||
|
||
return this;
|
||
};
|
||
|
||
Object.defineProperty(Readable.prototype, 'readableHighWaterMark', {
|
||
// making it explicit this property is not enumerable
|
||
// because otherwise some prototype manipulation in
|
||
// userland will fail
|
||
enumerable: false,
|
||
get: function () {
|
||
return this._readableState.highWaterMark;
|
||
}
|
||
});
|
||
|
||
// exposed for testing purposes only.
|
||
Readable._fromList = fromList;
|
||
|
||
// Pluck off n bytes from an array of buffers.
|
||
// Length is the combined lengths of all the buffers in the list.
|
||
// This function is designed to be inlinable, so please take care when making
|
||
// changes to the function body.
|
||
function fromList(n, state) {
|
||
// nothing buffered
|
||
if (state.length === 0) return null;
|
||
|
||
var ret;
|
||
if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {
|
||
// read it all, truncate the list
|
||
if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length);
|
||
state.buffer.clear();
|
||
} else {
|
||
// read part of list
|
||
ret = fromListPartial(n, state.buffer, state.decoder);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
// Extracts only enough buffered data to satisfy the amount requested.
|
||
// This function is designed to be inlinable, so please take care when making
|
||
// changes to the function body.
|
||
function fromListPartial(n, list, hasStrings) {
|
||
var ret;
|
||
if (n < list.head.data.length) {
|
||
// slice is the same for buffers and strings
|
||
ret = list.head.data.slice(0, n);
|
||
list.head.data = list.head.data.slice(n);
|
||
} else if (n === list.head.data.length) {
|
||
// first chunk is a perfect match
|
||
ret = list.shift();
|
||
} else {
|
||
// result spans more than one buffer
|
||
ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
// Copies a specified amount of characters from the list of buffered data
|
||
// chunks.
|
||
// This function is designed to be inlinable, so please take care when making
|
||
// changes to the function body.
|
||
function copyFromBufferString(n, list) {
|
||
var p = list.head;
|
||
var c = 1;
|
||
var ret = p.data;
|
||
n -= ret.length;
|
||
while (p = p.next) {
|
||
var str = p.data;
|
||
var nb = n > str.length ? str.length : n;
|
||
if (nb === str.length) ret += str;else ret += str.slice(0, n);
|
||
n -= nb;
|
||
if (n === 0) {
|
||
if (nb === str.length) {
|
||
++c;
|
||
if (p.next) list.head = p.next;else list.head = list.tail = null;
|
||
} else {
|
||
list.head = p;
|
||
p.data = str.slice(nb);
|
||
}
|
||
break;
|
||
}
|
||
++c;
|
||
}
|
||
list.length -= c;
|
||
return ret;
|
||
}
|
||
|
||
// Copies a specified amount of bytes from the list of buffered data chunks.
|
||
// This function is designed to be inlinable, so please take care when making
|
||
// changes to the function body.
|
||
function copyFromBuffer(n, list) {
|
||
var ret = Buffer.allocUnsafe(n);
|
||
var p = list.head;
|
||
var c = 1;
|
||
p.data.copy(ret);
|
||
n -= p.data.length;
|
||
while (p = p.next) {
|
||
var buf = p.data;
|
||
var nb = n > buf.length ? buf.length : n;
|
||
buf.copy(ret, ret.length - n, 0, nb);
|
||
n -= nb;
|
||
if (n === 0) {
|
||
if (nb === buf.length) {
|
||
++c;
|
||
if (p.next) list.head = p.next;else list.head = list.tail = null;
|
||
} else {
|
||
list.head = p;
|
||
p.data = buf.slice(nb);
|
||
}
|
||
break;
|
||
}
|
||
++c;
|
||
}
|
||
list.length -= c;
|
||
return ret;
|
||
}
|
||
|
||
function endReadable(stream) {
|
||
var state = stream._readableState;
|
||
|
||
// If we get here before consuming all the bytes, then that is a
|
||
// bug in node. Should never happen.
|
||
if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream');
|
||
|
||
if (!state.endEmitted) {
|
||
state.ended = true;
|
||
pna.nextTick(endReadableNT, state, stream);
|
||
}
|
||
}
|
||
|
||
function endReadableNT(state, stream) {
|
||
// Check that we didn't get one last unshift.
|
||
if (!state.endEmitted && state.length === 0) {
|
||
state.endEmitted = true;
|
||
stream.readable = false;
|
||
stream.emit('end');
|
||
}
|
||
}
|
||
|
||
function indexOf(xs, x) {
|
||
for (var i = 0, l = xs.length; i < l; i++) {
|
||
if (xs[i] === x) return i;
|
||
}
|
||
return -1;
|
||
}
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js"), __webpack_require__(/*! ./../../process/browser.js */ "./node_modules/process/browser.js")))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/readable-stream/lib/_stream_transform.js":
|
||
/*!***************************************************************!*\
|
||
!*** ./node_modules/readable-stream/lib/_stream_transform.js ***!
|
||
\***************************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
// Copyright Joyent, Inc. and other Node contributors.
|
||
//
|
||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||
// copy of this software and associated documentation files (the
|
||
// "Software"), to deal in the Software without restriction, including
|
||
// without limitation the rights to use, copy, modify, merge, publish,
|
||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||
// persons to whom the Software is furnished to do so, subject to the
|
||
// following conditions:
|
||
//
|
||
// The above copyright notice and this permission notice shall be included
|
||
// in all copies or substantial portions of the Software.
|
||
//
|
||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
||
// a transform stream is a readable/writable stream where you do
|
||
// something with the data. Sometimes it's called a "filter",
|
||
// but that's not a great name for it, since that implies a thing where
|
||
// some bits pass through, and others are simply ignored. (That would
|
||
// be a valid example of a transform, of course.)
|
||
//
|
||
// While the output is causally related to the input, it's not a
|
||
// necessarily symmetric or synchronous transformation. For example,
|
||
// a zlib stream might take multiple plain-text writes(), and then
|
||
// emit a single compressed chunk some time in the future.
|
||
//
|
||
// Here's how this works:
|
||
//
|
||
// The Transform stream has all the aspects of the readable and writable
|
||
// stream classes. When you write(chunk), that calls _write(chunk,cb)
|
||
// internally, and returns false if there's a lot of pending writes
|
||
// buffered up. When you call read(), that calls _read(n) until
|
||
// there's enough pending readable data buffered up.
|
||
//
|
||
// In a transform stream, the written data is placed in a buffer. When
|
||
// _read(n) is called, it transforms the queued up data, calling the
|
||
// buffered _write cb's as it consumes chunks. If consuming a single
|
||
// written chunk would result in multiple output chunks, then the first
|
||
// outputted bit calls the readcb, and subsequent chunks just go into
|
||
// the read buffer, and will cause it to emit 'readable' if necessary.
|
||
//
|
||
// This way, back-pressure is actually determined by the reading side,
|
||
// since _read has to be called to start processing a new chunk. However,
|
||
// a pathological inflate type of transform can cause excessive buffering
|
||
// here. For example, imagine a stream where every byte of input is
|
||
// interpreted as an integer from 0-255, and then results in that many
|
||
// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in
|
||
// 1kb of data being output. In this case, you could write a very small
|
||
// amount of input, and end up with a very large amount of output. In
|
||
// such a pathological inflating mechanism, there'd be no way to tell
|
||
// the system to stop doing the transform. A single 4MB write could
|
||
// cause the system to run out of memory.
|
||
//
|
||
// However, even in such a pathological case, only a single written chunk
|
||
// would be consumed, and then the rest would wait (un-transformed) until
|
||
// the results of the previous transformed chunk were consumed.
|
||
|
||
|
||
|
||
module.exports = Transform;
|
||
|
||
var Duplex = __webpack_require__(/*! ./_stream_duplex */ "./node_modules/readable-stream/lib/_stream_duplex.js");
|
||
|
||
/*<replacement>*/
|
||
var util = __webpack_require__(/*! core-util-is */ "./node_modules/core-util-is/lib/util.js");
|
||
util.inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
/*</replacement>*/
|
||
|
||
util.inherits(Transform, Duplex);
|
||
|
||
function afterTransform(er, data) {
|
||
var ts = this._transformState;
|
||
ts.transforming = false;
|
||
|
||
var cb = ts.writecb;
|
||
|
||
if (!cb) {
|
||
return this.emit('error', new Error('write callback called multiple times'));
|
||
}
|
||
|
||
ts.writechunk = null;
|
||
ts.writecb = null;
|
||
|
||
if (data != null) // single equals check for both `null` and `undefined`
|
||
this.push(data);
|
||
|
||
cb(er);
|
||
|
||
var rs = this._readableState;
|
||
rs.reading = false;
|
||
if (rs.needReadable || rs.length < rs.highWaterMark) {
|
||
this._read(rs.highWaterMark);
|
||
}
|
||
}
|
||
|
||
function Transform(options) {
|
||
if (!(this instanceof Transform)) return new Transform(options);
|
||
|
||
Duplex.call(this, options);
|
||
|
||
this._transformState = {
|
||
afterTransform: afterTransform.bind(this),
|
||
needTransform: false,
|
||
transforming: false,
|
||
writecb: null,
|
||
writechunk: null,
|
||
writeencoding: null
|
||
};
|
||
|
||
// start out asking for a readable event once data is transformed.
|
||
this._readableState.needReadable = true;
|
||
|
||
// we have implemented the _read method, and done the other things
|
||
// that Readable wants before the first _read call, so unset the
|
||
// sync guard flag.
|
||
this._readableState.sync = false;
|
||
|
||
if (options) {
|
||
if (typeof options.transform === 'function') this._transform = options.transform;
|
||
|
||
if (typeof options.flush === 'function') this._flush = options.flush;
|
||
}
|
||
|
||
// When the writable side finishes, then flush out anything remaining.
|
||
this.on('prefinish', prefinish);
|
||
}
|
||
|
||
function prefinish() {
|
||
var _this = this;
|
||
|
||
if (typeof this._flush === 'function') {
|
||
this._flush(function (er, data) {
|
||
done(_this, er, data);
|
||
});
|
||
} else {
|
||
done(this, null, null);
|
||
}
|
||
}
|
||
|
||
Transform.prototype.push = function (chunk, encoding) {
|
||
this._transformState.needTransform = false;
|
||
return Duplex.prototype.push.call(this, chunk, encoding);
|
||
};
|
||
|
||
// This is the part where you do stuff!
|
||
// override this function in implementation classes.
|
||
// 'chunk' is an input chunk.
|
||
//
|
||
// Call `push(newChunk)` to pass along transformed output
|
||
// to the readable side. You may call 'push' zero or more times.
|
||
//
|
||
// Call `cb(err)` when you are done with this chunk. If you pass
|
||
// an error, then that'll put the hurt on the whole operation. If you
|
||
// never call cb(), then you'll never get another chunk.
|
||
Transform.prototype._transform = function (chunk, encoding, cb) {
|
||
throw new Error('_transform() is not implemented');
|
||
};
|
||
|
||
Transform.prototype._write = function (chunk, encoding, cb) {
|
||
var ts = this._transformState;
|
||
ts.writecb = cb;
|
||
ts.writechunk = chunk;
|
||
ts.writeencoding = encoding;
|
||
if (!ts.transforming) {
|
||
var rs = this._readableState;
|
||
if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
|
||
}
|
||
};
|
||
|
||
// Doesn't matter what the args are here.
|
||
// _transform does all the work.
|
||
// That we got here means that the readable side wants more data.
|
||
Transform.prototype._read = function (n) {
|
||
var ts = this._transformState;
|
||
|
||
if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
|
||
ts.transforming = true;
|
||
this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
|
||
} else {
|
||
// mark that we need a transform, so that any data that comes in
|
||
// will get processed, now that we've asked for it.
|
||
ts.needTransform = true;
|
||
}
|
||
};
|
||
|
||
Transform.prototype._destroy = function (err, cb) {
|
||
var _this2 = this;
|
||
|
||
Duplex.prototype._destroy.call(this, err, function (err2) {
|
||
cb(err2);
|
||
_this2.emit('close');
|
||
});
|
||
};
|
||
|
||
function done(stream, er, data) {
|
||
if (er) return stream.emit('error', er);
|
||
|
||
if (data != null) // single equals check for both `null` and `undefined`
|
||
stream.push(data);
|
||
|
||
// if there's nothing in the write buffer, then that means
|
||
// that nothing more will ever be provided
|
||
if (stream._writableState.length) throw new Error('Calling transform done when ws.length != 0');
|
||
|
||
if (stream._transformState.transforming) throw new Error('Calling transform done when still transforming');
|
||
|
||
return stream.push(null);
|
||
}
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/readable-stream/lib/_stream_writable.js":
|
||
/*!**************************************************************!*\
|
||
!*** ./node_modules/readable-stream/lib/_stream_writable.js ***!
|
||
\**************************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
/* WEBPACK VAR INJECTION */(function(process, setImmediate, global) {// Copyright Joyent, Inc. and other Node contributors.
|
||
//
|
||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||
// copy of this software and associated documentation files (the
|
||
// "Software"), to deal in the Software without restriction, including
|
||
// without limitation the rights to use, copy, modify, merge, publish,
|
||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||
// persons to whom the Software is furnished to do so, subject to the
|
||
// following conditions:
|
||
//
|
||
// The above copyright notice and this permission notice shall be included
|
||
// in all copies or substantial portions of the Software.
|
||
//
|
||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
||
// A bit simpler than readable streams.
|
||
// Implement an async ._write(chunk, encoding, cb), and it'll handle all
|
||
// the drain event emission and buffering.
|
||
|
||
|
||
|
||
/*<replacement>*/
|
||
|
||
var pna = __webpack_require__(/*! process-nextick-args */ "./node_modules/process-nextick-args/index.js");
|
||
/*</replacement>*/
|
||
|
||
module.exports = Writable;
|
||
|
||
/* <replacement> */
|
||
function WriteReq(chunk, encoding, cb) {
|
||
this.chunk = chunk;
|
||
this.encoding = encoding;
|
||
this.callback = cb;
|
||
this.next = null;
|
||
}
|
||
|
||
// It seems a linked list but it is not
|
||
// there will be only 2 of these for each stream
|
||
function CorkedRequest(state) {
|
||
var _this = this;
|
||
|
||
this.next = null;
|
||
this.entry = null;
|
||
this.finish = function () {
|
||
onCorkedFinish(_this, state);
|
||
};
|
||
}
|
||
/* </replacement> */
|
||
|
||
/*<replacement>*/
|
||
var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : pna.nextTick;
|
||
/*</replacement>*/
|
||
|
||
/*<replacement>*/
|
||
var Duplex;
|
||
/*</replacement>*/
|
||
|
||
Writable.WritableState = WritableState;
|
||
|
||
/*<replacement>*/
|
||
var util = __webpack_require__(/*! core-util-is */ "./node_modules/core-util-is/lib/util.js");
|
||
util.inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
/*</replacement>*/
|
||
|
||
/*<replacement>*/
|
||
var internalUtil = {
|
||
deprecate: __webpack_require__(/*! util-deprecate */ "./node_modules/util-deprecate/browser.js")
|
||
};
|
||
/*</replacement>*/
|
||
|
||
/*<replacement>*/
|
||
var Stream = __webpack_require__(/*! ./internal/streams/stream */ "./node_modules/readable-stream/lib/internal/streams/stream-browser.js");
|
||
/*</replacement>*/
|
||
|
||
/*<replacement>*/
|
||
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer;
|
||
var OurUint8Array = global.Uint8Array || function () {};
|
||
function _uint8ArrayToBuffer(chunk) {
|
||
return Buffer.from(chunk);
|
||
}
|
||
function _isUint8Array(obj) {
|
||
return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
|
||
}
|
||
|
||
/*</replacement>*/
|
||
|
||
var destroyImpl = __webpack_require__(/*! ./internal/streams/destroy */ "./node_modules/readable-stream/lib/internal/streams/destroy.js");
|
||
|
||
util.inherits(Writable, Stream);
|
||
|
||
function nop() {}
|
||
|
||
function WritableState(options, stream) {
|
||
Duplex = Duplex || __webpack_require__(/*! ./_stream_duplex */ "./node_modules/readable-stream/lib/_stream_duplex.js");
|
||
|
||
options = options || {};
|
||
|
||
// Duplex streams are both readable and writable, but share
|
||
// the same options object.
|
||
// However, some cases require setting options to different
|
||
// values for the readable and the writable sides of the duplex stream.
|
||
// These options can be provided separately as readableXXX and writableXXX.
|
||
var isDuplex = stream instanceof Duplex;
|
||
|
||
// object stream flag to indicate whether or not this stream
|
||
// contains buffers or objects.
|
||
this.objectMode = !!options.objectMode;
|
||
|
||
if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
|
||
|
||
// the point at which write() starts returning false
|
||
// Note: 0 is a valid value, means that we always return false if
|
||
// the entire buffer is not flushed immediately on write()
|
||
var hwm = options.highWaterMark;
|
||
var writableHwm = options.writableHighWaterMark;
|
||
var defaultHwm = this.objectMode ? 16 : 16 * 1024;
|
||
|
||
if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (writableHwm || writableHwm === 0)) this.highWaterMark = writableHwm;else this.highWaterMark = defaultHwm;
|
||
|
||
// cast to ints.
|
||
this.highWaterMark = Math.floor(this.highWaterMark);
|
||
|
||
// if _final has been called
|
||
this.finalCalled = false;
|
||
|
||
// drain event flag.
|
||
this.needDrain = false;
|
||
// at the start of calling end()
|
||
this.ending = false;
|
||
// when end() has been called, and returned
|
||
this.ended = false;
|
||
// when 'finish' is emitted
|
||
this.finished = false;
|
||
|
||
// has it been destroyed
|
||
this.destroyed = false;
|
||
|
||
// should we decode strings into buffers before passing to _write?
|
||
// this is here so that some node-core streams can optimize string
|
||
// handling at a lower level.
|
||
var noDecode = options.decodeStrings === false;
|
||
this.decodeStrings = !noDecode;
|
||
|
||
// Crypto is kind of old and crusty. Historically, its default string
|
||
// encoding is 'binary' so we have to make this configurable.
|
||
// Everything else in the universe uses 'utf8', though.
|
||
this.defaultEncoding = options.defaultEncoding || 'utf8';
|
||
|
||
// not an actual buffer we keep track of, but a measurement
|
||
// of how much we're waiting to get pushed to some underlying
|
||
// socket or file.
|
||
this.length = 0;
|
||
|
||
// a flag to see when we're in the middle of a write.
|
||
this.writing = false;
|
||
|
||
// when true all writes will be buffered until .uncork() call
|
||
this.corked = 0;
|
||
|
||
// a flag to be able to tell if the onwrite cb is called immediately,
|
||
// or on a later tick. We set this to true at first, because any
|
||
// actions that shouldn't happen until "later" should generally also
|
||
// not happen before the first write call.
|
||
this.sync = true;
|
||
|
||
// a flag to know if we're processing previously buffered items, which
|
||
// may call the _write() callback in the same tick, so that we don't
|
||
// end up in an overlapped onwrite situation.
|
||
this.bufferProcessing = false;
|
||
|
||
// the callback that's passed to _write(chunk,cb)
|
||
this.onwrite = function (er) {
|
||
onwrite(stream, er);
|
||
};
|
||
|
||
// the callback that the user supplies to write(chunk,encoding,cb)
|
||
this.writecb = null;
|
||
|
||
// the amount that is being written when _write is called.
|
||
this.writelen = 0;
|
||
|
||
this.bufferedRequest = null;
|
||
this.lastBufferedRequest = null;
|
||
|
||
// number of pending user-supplied write callbacks
|
||
// this must be 0 before 'finish' can be emitted
|
||
this.pendingcb = 0;
|
||
|
||
// emit prefinish if the only thing we're waiting for is _write cbs
|
||
// This is relevant for synchronous Transform streams
|
||
this.prefinished = false;
|
||
|
||
// True if the error was already emitted and should not be thrown again
|
||
this.errorEmitted = false;
|
||
|
||
// count buffered requests
|
||
this.bufferedRequestCount = 0;
|
||
|
||
// allocate the first CorkedRequest, there is always
|
||
// one allocated and free to use, and we maintain at most two
|
||
this.corkedRequestsFree = new CorkedRequest(this);
|
||
}
|
||
|
||
WritableState.prototype.getBuffer = function getBuffer() {
|
||
var current = this.bufferedRequest;
|
||
var out = [];
|
||
while (current) {
|
||
out.push(current);
|
||
current = current.next;
|
||
}
|
||
return out;
|
||
};
|
||
|
||
(function () {
|
||
try {
|
||
Object.defineProperty(WritableState.prototype, 'buffer', {
|
||
get: internalUtil.deprecate(function () {
|
||
return this.getBuffer();
|
||
}, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003')
|
||
});
|
||
} catch (_) {}
|
||
})();
|
||
|
||
// Test _writableState for inheritance to account for Duplex streams,
|
||
// whose prototype chain only points to Readable.
|
||
var realHasInstance;
|
||
if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {
|
||
realHasInstance = Function.prototype[Symbol.hasInstance];
|
||
Object.defineProperty(Writable, Symbol.hasInstance, {
|
||
value: function (object) {
|
||
if (realHasInstance.call(this, object)) return true;
|
||
if (this !== Writable) return false;
|
||
|
||
return object && object._writableState instanceof WritableState;
|
||
}
|
||
});
|
||
} else {
|
||
realHasInstance = function (object) {
|
||
return object instanceof this;
|
||
};
|
||
}
|
||
|
||
function Writable(options) {
|
||
Duplex = Duplex || __webpack_require__(/*! ./_stream_duplex */ "./node_modules/readable-stream/lib/_stream_duplex.js");
|
||
|
||
// Writable ctor is applied to Duplexes, too.
|
||
// `realHasInstance` is necessary because using plain `instanceof`
|
||
// would return false, as no `_writableState` property is attached.
|
||
|
||
// Trying to use the custom `instanceof` for Writable here will also break the
|
||
// Node.js LazyTransform implementation, which has a non-trivial getter for
|
||
// `_writableState` that would lead to infinite recursion.
|
||
if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) {
|
||
return new Writable(options);
|
||
}
|
||
|
||
this._writableState = new WritableState(options, this);
|
||
|
||
// legacy.
|
||
this.writable = true;
|
||
|
||
if (options) {
|
||
if (typeof options.write === 'function') this._write = options.write;
|
||
|
||
if (typeof options.writev === 'function') this._writev = options.writev;
|
||
|
||
if (typeof options.destroy === 'function') this._destroy = options.destroy;
|
||
|
||
if (typeof options.final === 'function') this._final = options.final;
|
||
}
|
||
|
||
Stream.call(this);
|
||
}
|
||
|
||
// Otherwise people can pipe Writable streams, which is just wrong.
|
||
Writable.prototype.pipe = function () {
|
||
this.emit('error', new Error('Cannot pipe, not readable'));
|
||
};
|
||
|
||
function writeAfterEnd(stream, cb) {
|
||
var er = new Error('write after end');
|
||
// TODO: defer error events consistently everywhere, not just the cb
|
||
stream.emit('error', er);
|
||
pna.nextTick(cb, er);
|
||
}
|
||
|
||
// Checks that a user-supplied chunk is valid, especially for the particular
|
||
// mode the stream is in. Currently this means that `null` is never accepted
|
||
// and undefined/non-string values are only allowed in object mode.
|
||
function validChunk(stream, state, chunk, cb) {
|
||
var valid = true;
|
||
var er = false;
|
||
|
||
if (chunk === null) {
|
||
er = new TypeError('May not write null values to stream');
|
||
} else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
|
||
er = new TypeError('Invalid non-string/buffer chunk');
|
||
}
|
||
if (er) {
|
||
stream.emit('error', er);
|
||
pna.nextTick(cb, er);
|
||
valid = false;
|
||
}
|
||
return valid;
|
||
}
|
||
|
||
Writable.prototype.write = function (chunk, encoding, cb) {
|
||
var state = this._writableState;
|
||
var ret = false;
|
||
var isBuf = !state.objectMode && _isUint8Array(chunk);
|
||
|
||
if (isBuf && !Buffer.isBuffer(chunk)) {
|
||
chunk = _uint8ArrayToBuffer(chunk);
|
||
}
|
||
|
||
if (typeof encoding === 'function') {
|
||
cb = encoding;
|
||
encoding = null;
|
||
}
|
||
|
||
if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
|
||
|
||
if (typeof cb !== 'function') cb = nop;
|
||
|
||
if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) {
|
||
state.pendingcb++;
|
||
ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
|
||
}
|
||
|
||
return ret;
|
||
};
|
||
|
||
Writable.prototype.cork = function () {
|
||
var state = this._writableState;
|
||
|
||
state.corked++;
|
||
};
|
||
|
||
Writable.prototype.uncork = function () {
|
||
var state = this._writableState;
|
||
|
||
if (state.corked) {
|
||
state.corked--;
|
||
|
||
if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
|
||
}
|
||
};
|
||
|
||
Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
|
||
// node::ParseEncoding() requires lower case.
|
||
if (typeof encoding === 'string') encoding = encoding.toLowerCase();
|
||
if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
|
||
this._writableState.defaultEncoding = encoding;
|
||
return this;
|
||
};
|
||
|
||
function decodeChunk(state, chunk, encoding) {
|
||
if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
|
||
chunk = Buffer.from(chunk, encoding);
|
||
}
|
||
return chunk;
|
||
}
|
||
|
||
Object.defineProperty(Writable.prototype, 'writableHighWaterMark', {
|
||
// making it explicit this property is not enumerable
|
||
// because otherwise some prototype manipulation in
|
||
// userland will fail
|
||
enumerable: false,
|
||
get: function () {
|
||
return this._writableState.highWaterMark;
|
||
}
|
||
});
|
||
|
||
// if we're already writing something, then just put this
|
||
// in the queue, and wait our turn. Otherwise, call _write
|
||
// If we return false, then we need a drain event, so set that flag.
|
||
function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {
|
||
if (!isBuf) {
|
||
var newChunk = decodeChunk(state, chunk, encoding);
|
||
if (chunk !== newChunk) {
|
||
isBuf = true;
|
||
encoding = 'buffer';
|
||
chunk = newChunk;
|
||
}
|
||
}
|
||
var len = state.objectMode ? 1 : chunk.length;
|
||
|
||
state.length += len;
|
||
|
||
var ret = state.length < state.highWaterMark;
|
||
// we must ensure that previous needDrain will not be reset to false.
|
||
if (!ret) state.needDrain = true;
|
||
|
||
if (state.writing || state.corked) {
|
||
var last = state.lastBufferedRequest;
|
||
state.lastBufferedRequest = {
|
||
chunk: chunk,
|
||
encoding: encoding,
|
||
isBuf: isBuf,
|
||
callback: cb,
|
||
next: null
|
||
};
|
||
if (last) {
|
||
last.next = state.lastBufferedRequest;
|
||
} else {
|
||
state.bufferedRequest = state.lastBufferedRequest;
|
||
}
|
||
state.bufferedRequestCount += 1;
|
||
} else {
|
||
doWrite(stream, state, false, len, chunk, encoding, cb);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
function doWrite(stream, state, writev, len, chunk, encoding, cb) {
|
||
state.writelen = len;
|
||
state.writecb = cb;
|
||
state.writing = true;
|
||
state.sync = true;
|
||
if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
|
||
state.sync = false;
|
||
}
|
||
|
||
function onwriteError(stream, state, sync, er, cb) {
|
||
--state.pendingcb;
|
||
|
||
if (sync) {
|
||
// defer the callback if we are being called synchronously
|
||
// to avoid piling up things on the stack
|
||
pna.nextTick(cb, er);
|
||
// this can emit finish, and it will always happen
|
||
// after error
|
||
pna.nextTick(finishMaybe, stream, state);
|
||
stream._writableState.errorEmitted = true;
|
||
stream.emit('error', er);
|
||
} else {
|
||
// the caller expect this to happen before if
|
||
// it is async
|
||
cb(er);
|
||
stream._writableState.errorEmitted = true;
|
||
stream.emit('error', er);
|
||
// this can emit finish, but finish must
|
||
// always follow error
|
||
finishMaybe(stream, state);
|
||
}
|
||
}
|
||
|
||
function onwriteStateUpdate(state) {
|
||
state.writing = false;
|
||
state.writecb = null;
|
||
state.length -= state.writelen;
|
||
state.writelen = 0;
|
||
}
|
||
|
||
function onwrite(stream, er) {
|
||
var state = stream._writableState;
|
||
var sync = state.sync;
|
||
var cb = state.writecb;
|
||
|
||
onwriteStateUpdate(state);
|
||
|
||
if (er) onwriteError(stream, state, sync, er, cb);else {
|
||
// Check if we're actually ready to finish, but don't emit yet
|
||
var finished = needFinish(state);
|
||
|
||
if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
|
||
clearBuffer(stream, state);
|
||
}
|
||
|
||
if (sync) {
|
||
/*<replacement>*/
|
||
asyncWrite(afterWrite, stream, state, finished, cb);
|
||
/*</replacement>*/
|
||
} else {
|
||
afterWrite(stream, state, finished, cb);
|
||
}
|
||
}
|
||
}
|
||
|
||
function afterWrite(stream, state, finished, cb) {
|
||
if (!finished) onwriteDrain(stream, state);
|
||
state.pendingcb--;
|
||
cb();
|
||
finishMaybe(stream, state);
|
||
}
|
||
|
||
// Must force callback to be called on nextTick, so that we don't
|
||
// emit 'drain' before the write() consumer gets the 'false' return
|
||
// value, and has a chance to attach a 'drain' listener.
|
||
function onwriteDrain(stream, state) {
|
||
if (state.length === 0 && state.needDrain) {
|
||
state.needDrain = false;
|
||
stream.emit('drain');
|
||
}
|
||
}
|
||
|
||
// if there's something in the buffer waiting, then process it
|
||
function clearBuffer(stream, state) {
|
||
state.bufferProcessing = true;
|
||
var entry = state.bufferedRequest;
|
||
|
||
if (stream._writev && entry && entry.next) {
|
||
// Fast case, write everything using _writev()
|
||
var l = state.bufferedRequestCount;
|
||
var buffer = new Array(l);
|
||
var holder = state.corkedRequestsFree;
|
||
holder.entry = entry;
|
||
|
||
var count = 0;
|
||
var allBuffers = true;
|
||
while (entry) {
|
||
buffer[count] = entry;
|
||
if (!entry.isBuf) allBuffers = false;
|
||
entry = entry.next;
|
||
count += 1;
|
||
}
|
||
buffer.allBuffers = allBuffers;
|
||
|
||
doWrite(stream, state, true, state.length, buffer, '', holder.finish);
|
||
|
||
// doWrite is almost always async, defer these to save a bit of time
|
||
// as the hot path ends with doWrite
|
||
state.pendingcb++;
|
||
state.lastBufferedRequest = null;
|
||
if (holder.next) {
|
||
state.corkedRequestsFree = holder.next;
|
||
holder.next = null;
|
||
} else {
|
||
state.corkedRequestsFree = new CorkedRequest(state);
|
||
}
|
||
state.bufferedRequestCount = 0;
|
||
} else {
|
||
// Slow case, write chunks one-by-one
|
||
while (entry) {
|
||
var chunk = entry.chunk;
|
||
var encoding = entry.encoding;
|
||
var cb = entry.callback;
|
||
var len = state.objectMode ? 1 : chunk.length;
|
||
|
||
doWrite(stream, state, false, len, chunk, encoding, cb);
|
||
entry = entry.next;
|
||
state.bufferedRequestCount--;
|
||
// if we didn't call the onwrite immediately, then
|
||
// it means that we need to wait until it does.
|
||
// also, that means that the chunk and cb are currently
|
||
// being processed, so move the buffer counter past them.
|
||
if (state.writing) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (entry === null) state.lastBufferedRequest = null;
|
||
}
|
||
|
||
state.bufferedRequest = entry;
|
||
state.bufferProcessing = false;
|
||
}
|
||
|
||
Writable.prototype._write = function (chunk, encoding, cb) {
|
||
cb(new Error('_write() is not implemented'));
|
||
};
|
||
|
||
Writable.prototype._writev = null;
|
||
|
||
Writable.prototype.end = function (chunk, encoding, cb) {
|
||
var state = this._writableState;
|
||
|
||
if (typeof chunk === 'function') {
|
||
cb = chunk;
|
||
chunk = null;
|
||
encoding = null;
|
||
} else if (typeof encoding === 'function') {
|
||
cb = encoding;
|
||
encoding = null;
|
||
}
|
||
|
||
if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
|
||
|
||
// .end() fully uncorks
|
||
if (state.corked) {
|
||
state.corked = 1;
|
||
this.uncork();
|
||
}
|
||
|
||
// ignore unnecessary end() calls.
|
||
if (!state.ending && !state.finished) endWritable(this, state, cb);
|
||
};
|
||
|
||
function needFinish(state) {
|
||
return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
|
||
}
|
||
function callFinal(stream, state) {
|
||
stream._final(function (err) {
|
||
state.pendingcb--;
|
||
if (err) {
|
||
stream.emit('error', err);
|
||
}
|
||
state.prefinished = true;
|
||
stream.emit('prefinish');
|
||
finishMaybe(stream, state);
|
||
});
|
||
}
|
||
function prefinish(stream, state) {
|
||
if (!state.prefinished && !state.finalCalled) {
|
||
if (typeof stream._final === 'function') {
|
||
state.pendingcb++;
|
||
state.finalCalled = true;
|
||
pna.nextTick(callFinal, stream, state);
|
||
} else {
|
||
state.prefinished = true;
|
||
stream.emit('prefinish');
|
||
}
|
||
}
|
||
}
|
||
|
||
function finishMaybe(stream, state) {
|
||
var need = needFinish(state);
|
||
if (need) {
|
||
prefinish(stream, state);
|
||
if (state.pendingcb === 0) {
|
||
state.finished = true;
|
||
stream.emit('finish');
|
||
}
|
||
}
|
||
return need;
|
||
}
|
||
|
||
function endWritable(stream, state, cb) {
|
||
state.ending = true;
|
||
finishMaybe(stream, state);
|
||
if (cb) {
|
||
if (state.finished) pna.nextTick(cb);else stream.once('finish', cb);
|
||
}
|
||
state.ended = true;
|
||
stream.writable = false;
|
||
}
|
||
|
||
function onCorkedFinish(corkReq, state, err) {
|
||
var entry = corkReq.entry;
|
||
corkReq.entry = null;
|
||
while (entry) {
|
||
var cb = entry.callback;
|
||
state.pendingcb--;
|
||
cb(err);
|
||
entry = entry.next;
|
||
}
|
||
if (state.corkedRequestsFree) {
|
||
state.corkedRequestsFree.next = corkReq;
|
||
} else {
|
||
state.corkedRequestsFree = corkReq;
|
||
}
|
||
}
|
||
|
||
Object.defineProperty(Writable.prototype, 'destroyed', {
|
||
get: function () {
|
||
if (this._writableState === undefined) {
|
||
return false;
|
||
}
|
||
return this._writableState.destroyed;
|
||
},
|
||
set: function (value) {
|
||
// we ignore the value if the stream
|
||
// has not been initialized yet
|
||
if (!this._writableState) {
|
||
return;
|
||
}
|
||
|
||
// backward compatibility, the user is explicitly
|
||
// managing destroyed
|
||
this._writableState.destroyed = value;
|
||
}
|
||
});
|
||
|
||
Writable.prototype.destroy = destroyImpl.destroy;
|
||
Writable.prototype._undestroy = destroyImpl.undestroy;
|
||
Writable.prototype._destroy = function (err, cb) {
|
||
this.end();
|
||
cb(err);
|
||
};
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../process/browser.js */ "./node_modules/process/browser.js"), __webpack_require__(/*! ./../../timers-browserify/main.js */ "./node_modules/timers-browserify/main.js").setImmediate, __webpack_require__(/*! ./../../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js")))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/readable-stream/lib/internal/streams/BufferList.js":
|
||
/*!*************************************************************************!*\
|
||
!*** ./node_modules/readable-stream/lib/internal/streams/BufferList.js ***!
|
||
\*************************************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer;
|
||
var util = __webpack_require__(/*! util */ 1);
|
||
|
||
function copyBuffer(src, target, offset) {
|
||
src.copy(target, offset);
|
||
}
|
||
|
||
module.exports = function () {
|
||
function BufferList() {
|
||
_classCallCheck(this, BufferList);
|
||
|
||
this.head = null;
|
||
this.tail = null;
|
||
this.length = 0;
|
||
}
|
||
|
||
BufferList.prototype.push = function push(v) {
|
||
var entry = { data: v, next: null };
|
||
if (this.length > 0) this.tail.next = entry;else this.head = entry;
|
||
this.tail = entry;
|
||
++this.length;
|
||
};
|
||
|
||
BufferList.prototype.unshift = function unshift(v) {
|
||
var entry = { data: v, next: this.head };
|
||
if (this.length === 0) this.tail = entry;
|
||
this.head = entry;
|
||
++this.length;
|
||
};
|
||
|
||
BufferList.prototype.shift = function shift() {
|
||
if (this.length === 0) return;
|
||
var ret = this.head.data;
|
||
if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;
|
||
--this.length;
|
||
return ret;
|
||
};
|
||
|
||
BufferList.prototype.clear = function clear() {
|
||
this.head = this.tail = null;
|
||
this.length = 0;
|
||
};
|
||
|
||
BufferList.prototype.join = function join(s) {
|
||
if (this.length === 0) return '';
|
||
var p = this.head;
|
||
var ret = '' + p.data;
|
||
while (p = p.next) {
|
||
ret += s + p.data;
|
||
}return ret;
|
||
};
|
||
|
||
BufferList.prototype.concat = function concat(n) {
|
||
if (this.length === 0) return Buffer.alloc(0);
|
||
if (this.length === 1) return this.head.data;
|
||
var ret = Buffer.allocUnsafe(n >>> 0);
|
||
var p = this.head;
|
||
var i = 0;
|
||
while (p) {
|
||
copyBuffer(p.data, ret, i);
|
||
i += p.data.length;
|
||
p = p.next;
|
||
}
|
||
return ret;
|
||
};
|
||
|
||
return BufferList;
|
||
}();
|
||
|
||
if (util && util.inspect && util.inspect.custom) {
|
||
module.exports.prototype[util.inspect.custom] = function () {
|
||
var obj = util.inspect({ length: this.length });
|
||
return this.constructor.name + ' ' + obj;
|
||
};
|
||
}
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/readable-stream/lib/internal/streams/destroy.js":
|
||
/*!**********************************************************************!*\
|
||
!*** ./node_modules/readable-stream/lib/internal/streams/destroy.js ***!
|
||
\**********************************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
/*<replacement>*/
|
||
|
||
var pna = __webpack_require__(/*! process-nextick-args */ "./node_modules/process-nextick-args/index.js");
|
||
/*</replacement>*/
|
||
|
||
// undocumented cb() API, needed for core, not for public API
|
||
function destroy(err, cb) {
|
||
var _this = this;
|
||
|
||
var readableDestroyed = this._readableState && this._readableState.destroyed;
|
||
var writableDestroyed = this._writableState && this._writableState.destroyed;
|
||
|
||
if (readableDestroyed || writableDestroyed) {
|
||
if (cb) {
|
||
cb(err);
|
||
} else if (err && (!this._writableState || !this._writableState.errorEmitted)) {
|
||
pna.nextTick(emitErrorNT, this, err);
|
||
}
|
||
return this;
|
||
}
|
||
|
||
// we set destroyed to true before firing error callbacks in order
|
||
// to make it re-entrance safe in case destroy() is called within callbacks
|
||
|
||
if (this._readableState) {
|
||
this._readableState.destroyed = true;
|
||
}
|
||
|
||
// if this is a duplex stream mark the writable part as destroyed as well
|
||
if (this._writableState) {
|
||
this._writableState.destroyed = true;
|
||
}
|
||
|
||
this._destroy(err || null, function (err) {
|
||
if (!cb && err) {
|
||
pna.nextTick(emitErrorNT, _this, err);
|
||
if (_this._writableState) {
|
||
_this._writableState.errorEmitted = true;
|
||
}
|
||
} else if (cb) {
|
||
cb(err);
|
||
}
|
||
});
|
||
|
||
return this;
|
||
}
|
||
|
||
function undestroy() {
|
||
if (this._readableState) {
|
||
this._readableState.destroyed = false;
|
||
this._readableState.reading = false;
|
||
this._readableState.ended = false;
|
||
this._readableState.endEmitted = false;
|
||
}
|
||
|
||
if (this._writableState) {
|
||
this._writableState.destroyed = false;
|
||
this._writableState.ended = false;
|
||
this._writableState.ending = false;
|
||
this._writableState.finished = false;
|
||
this._writableState.errorEmitted = false;
|
||
}
|
||
}
|
||
|
||
function emitErrorNT(self, err) {
|
||
self.emit('error', err);
|
||
}
|
||
|
||
module.exports = {
|
||
destroy: destroy,
|
||
undestroy: undestroy
|
||
};
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/readable-stream/lib/internal/streams/stream-browser.js":
|
||
/*!*****************************************************************************!*\
|
||
!*** ./node_modules/readable-stream/lib/internal/streams/stream-browser.js ***!
|
||
\*****************************************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
module.exports = __webpack_require__(/*! events */ "./node_modules/events/events.js").EventEmitter;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/readable-stream/passthrough.js":
|
||
/*!*****************************************************!*\
|
||
!*** ./node_modules/readable-stream/passthrough.js ***!
|
||
\*****************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
module.exports = __webpack_require__(/*! ./readable */ "./node_modules/readable-stream/readable-browser.js").PassThrough
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/readable-stream/readable-browser.js":
|
||
/*!**********************************************************!*\
|
||
!*** ./node_modules/readable-stream/readable-browser.js ***!
|
||
\**********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
exports = module.exports = __webpack_require__(/*! ./lib/_stream_readable.js */ "./node_modules/readable-stream/lib/_stream_readable.js");
|
||
exports.Stream = exports;
|
||
exports.Readable = exports;
|
||
exports.Writable = __webpack_require__(/*! ./lib/_stream_writable.js */ "./node_modules/readable-stream/lib/_stream_writable.js");
|
||
exports.Duplex = __webpack_require__(/*! ./lib/_stream_duplex.js */ "./node_modules/readable-stream/lib/_stream_duplex.js");
|
||
exports.Transform = __webpack_require__(/*! ./lib/_stream_transform.js */ "./node_modules/readable-stream/lib/_stream_transform.js");
|
||
exports.PassThrough = __webpack_require__(/*! ./lib/_stream_passthrough.js */ "./node_modules/readable-stream/lib/_stream_passthrough.js");
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/readable-stream/transform.js":
|
||
/*!***************************************************!*\
|
||
!*** ./node_modules/readable-stream/transform.js ***!
|
||
\***************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
module.exports = __webpack_require__(/*! ./readable */ "./node_modules/readable-stream/readable-browser.js").Transform
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/readable-stream/writable-browser.js":
|
||
/*!**********************************************************!*\
|
||
!*** ./node_modules/readable-stream/writable-browser.js ***!
|
||
\**********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
module.exports = __webpack_require__(/*! ./lib/_stream_writable.js */ "./node_modules/readable-stream/lib/_stream_writable.js");
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/ripemd160/index.js":
|
||
/*!*****************************************!*\
|
||
!*** ./node_modules/ripemd160/index.js ***!
|
||
\*****************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var Buffer = __webpack_require__(/*! buffer */ "./node_modules/buffer/index.js").Buffer
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
var HashBase = __webpack_require__(/*! hash-base */ "./node_modules/hash-base/index.js")
|
||
|
||
var ARRAY16 = new Array(16)
|
||
|
||
var zl = [
|
||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||
7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
|
||
3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
|
||
1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
|
||
4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
|
||
]
|
||
|
||
var zr = [
|
||
5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
|
||
6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
|
||
15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
|
||
8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
|
||
12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
|
||
]
|
||
|
||
var sl = [
|
||
11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
|
||
7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
|
||
11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
|
||
11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
|
||
9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
|
||
]
|
||
|
||
var sr = [
|
||
8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
|
||
9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
|
||
9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
|
||
15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
|
||
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
|
||
]
|
||
|
||
var hl = [0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e]
|
||
var hr = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000]
|
||
|
||
function RIPEMD160 () {
|
||
HashBase.call(this, 64)
|
||
|
||
// state
|
||
this._a = 0x67452301
|
||
this._b = 0xefcdab89
|
||
this._c = 0x98badcfe
|
||
this._d = 0x10325476
|
||
this._e = 0xc3d2e1f0
|
||
}
|
||
|
||
inherits(RIPEMD160, HashBase)
|
||
|
||
RIPEMD160.prototype._update = function () {
|
||
var words = ARRAY16
|
||
for (var j = 0; j < 16; ++j) words[j] = this._block.readInt32LE(j * 4)
|
||
|
||
var al = this._a | 0
|
||
var bl = this._b | 0
|
||
var cl = this._c | 0
|
||
var dl = this._d | 0
|
||
var el = this._e | 0
|
||
|
||
var ar = this._a | 0
|
||
var br = this._b | 0
|
||
var cr = this._c | 0
|
||
var dr = this._d | 0
|
||
var er = this._e | 0
|
||
|
||
// computation
|
||
for (var i = 0; i < 80; i += 1) {
|
||
var tl
|
||
var tr
|
||
if (i < 16) {
|
||
tl = fn1(al, bl, cl, dl, el, words[zl[i]], hl[0], sl[i])
|
||
tr = fn5(ar, br, cr, dr, er, words[zr[i]], hr[0], sr[i])
|
||
} else if (i < 32) {
|
||
tl = fn2(al, bl, cl, dl, el, words[zl[i]], hl[1], sl[i])
|
||
tr = fn4(ar, br, cr, dr, er, words[zr[i]], hr[1], sr[i])
|
||
} else if (i < 48) {
|
||
tl = fn3(al, bl, cl, dl, el, words[zl[i]], hl[2], sl[i])
|
||
tr = fn3(ar, br, cr, dr, er, words[zr[i]], hr[2], sr[i])
|
||
} else if (i < 64) {
|
||
tl = fn4(al, bl, cl, dl, el, words[zl[i]], hl[3], sl[i])
|
||
tr = fn2(ar, br, cr, dr, er, words[zr[i]], hr[3], sr[i])
|
||
} else { // if (i<80) {
|
||
tl = fn5(al, bl, cl, dl, el, words[zl[i]], hl[4], sl[i])
|
||
tr = fn1(ar, br, cr, dr, er, words[zr[i]], hr[4], sr[i])
|
||
}
|
||
|
||
al = el
|
||
el = dl
|
||
dl = rotl(cl, 10)
|
||
cl = bl
|
||
bl = tl
|
||
|
||
ar = er
|
||
er = dr
|
||
dr = rotl(cr, 10)
|
||
cr = br
|
||
br = tr
|
||
}
|
||
|
||
// update state
|
||
var t = (this._b + cl + dr) | 0
|
||
this._b = (this._c + dl + er) | 0
|
||
this._c = (this._d + el + ar) | 0
|
||
this._d = (this._e + al + br) | 0
|
||
this._e = (this._a + bl + cr) | 0
|
||
this._a = t
|
||
}
|
||
|
||
RIPEMD160.prototype._digest = function () {
|
||
// create padding and handle blocks
|
||
this._block[this._blockOffset++] = 0x80
|
||
if (this._blockOffset > 56) {
|
||
this._block.fill(0, this._blockOffset, 64)
|
||
this._update()
|
||
this._blockOffset = 0
|
||
}
|
||
|
||
this._block.fill(0, this._blockOffset, 56)
|
||
this._block.writeUInt32LE(this._length[0], 56)
|
||
this._block.writeUInt32LE(this._length[1], 60)
|
||
this._update()
|
||
|
||
// produce result
|
||
var buffer = Buffer.alloc ? Buffer.alloc(20) : new Buffer(20)
|
||
buffer.writeInt32LE(this._a, 0)
|
||
buffer.writeInt32LE(this._b, 4)
|
||
buffer.writeInt32LE(this._c, 8)
|
||
buffer.writeInt32LE(this._d, 12)
|
||
buffer.writeInt32LE(this._e, 16)
|
||
return buffer
|
||
}
|
||
|
||
function rotl (x, n) {
|
||
return (x << n) | (x >>> (32 - n))
|
||
}
|
||
|
||
function fn1 (a, b, c, d, e, m, k, s) {
|
||
return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + e) | 0
|
||
}
|
||
|
||
function fn2 (a, b, c, d, e, m, k, s) {
|
||
return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + e) | 0
|
||
}
|
||
|
||
function fn3 (a, b, c, d, e, m, k, s) {
|
||
return (rotl((a + ((b | (~c)) ^ d) + m + k) | 0, s) + e) | 0
|
||
}
|
||
|
||
function fn4 (a, b, c, d, e, m, k, s) {
|
||
return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + e) | 0
|
||
}
|
||
|
||
function fn5 (a, b, c, d, e, m, k, s) {
|
||
return (rotl((a + (b ^ (c | (~d))) + m + k) | 0, s) + e) | 0
|
||
}
|
||
|
||
module.exports = RIPEMD160
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/safe-buffer/index.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/safe-buffer/index.js ***!
|
||
\*******************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* eslint-disable node/no-deprecated-api */
|
||
var buffer = __webpack_require__(/*! buffer */ "./node_modules/buffer/index.js")
|
||
var Buffer = buffer.Buffer
|
||
|
||
// alternative to using Object.keys for old browsers
|
||
function copyProps (src, dst) {
|
||
for (var key in src) {
|
||
dst[key] = src[key]
|
||
}
|
||
}
|
||
if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
|
||
module.exports = buffer
|
||
} else {
|
||
// Copy properties from require('buffer')
|
||
copyProps(buffer, exports)
|
||
exports.Buffer = SafeBuffer
|
||
}
|
||
|
||
function SafeBuffer (arg, encodingOrOffset, length) {
|
||
return Buffer(arg, encodingOrOffset, length)
|
||
}
|
||
|
||
// Copy static methods from Buffer
|
||
copyProps(Buffer, SafeBuffer)
|
||
|
||
SafeBuffer.from = function (arg, encodingOrOffset, length) {
|
||
if (typeof arg === 'number') {
|
||
throw new TypeError('Argument must not be a number')
|
||
}
|
||
return Buffer(arg, encodingOrOffset, length)
|
||
}
|
||
|
||
SafeBuffer.alloc = function (size, fill, encoding) {
|
||
if (typeof size !== 'number') {
|
||
throw new TypeError('Argument must be a number')
|
||
}
|
||
var buf = Buffer(size)
|
||
if (fill !== undefined) {
|
||
if (typeof encoding === 'string') {
|
||
buf.fill(fill, encoding)
|
||
} else {
|
||
buf.fill(fill)
|
||
}
|
||
} else {
|
||
buf.fill(0)
|
||
}
|
||
return buf
|
||
}
|
||
|
||
SafeBuffer.allocUnsafe = function (size) {
|
||
if (typeof size !== 'number') {
|
||
throw new TypeError('Argument must be a number')
|
||
}
|
||
return Buffer(size)
|
||
}
|
||
|
||
SafeBuffer.allocUnsafeSlow = function (size) {
|
||
if (typeof size !== 'number') {
|
||
throw new TypeError('Argument must be a number')
|
||
}
|
||
return buffer.SlowBuffer(size)
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/setimmediate/setImmediate.js":
|
||
/*!***************************************************!*\
|
||
!*** ./node_modules/setimmediate/setImmediate.js ***!
|
||
\***************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) {
|
||
"use strict";
|
||
|
||
if (global.setImmediate) {
|
||
return;
|
||
}
|
||
|
||
var nextHandle = 1; // Spec says greater than zero
|
||
var tasksByHandle = {};
|
||
var currentlyRunningATask = false;
|
||
var doc = global.document;
|
||
var registerImmediate;
|
||
|
||
function setImmediate(callback) {
|
||
// Callback can either be a function or a string
|
||
if (typeof callback !== "function") {
|
||
callback = new Function("" + callback);
|
||
}
|
||
// Copy function arguments
|
||
var args = new Array(arguments.length - 1);
|
||
for (var i = 0; i < args.length; i++) {
|
||
args[i] = arguments[i + 1];
|
||
}
|
||
// Store and register the task
|
||
var task = { callback: callback, args: args };
|
||
tasksByHandle[nextHandle] = task;
|
||
registerImmediate(nextHandle);
|
||
return nextHandle++;
|
||
}
|
||
|
||
function clearImmediate(handle) {
|
||
delete tasksByHandle[handle];
|
||
}
|
||
|
||
function run(task) {
|
||
var callback = task.callback;
|
||
var args = task.args;
|
||
switch (args.length) {
|
||
case 0:
|
||
callback();
|
||
break;
|
||
case 1:
|
||
callback(args[0]);
|
||
break;
|
||
case 2:
|
||
callback(args[0], args[1]);
|
||
break;
|
||
case 3:
|
||
callback(args[0], args[1], args[2]);
|
||
break;
|
||
default:
|
||
callback.apply(undefined, args);
|
||
break;
|
||
}
|
||
}
|
||
|
||
function runIfPresent(handle) {
|
||
// From the spec: "Wait until any invocations of this algorithm started before this one have completed."
|
||
// So if we're currently running a task, we'll need to delay this invocation.
|
||
if (currentlyRunningATask) {
|
||
// Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
|
||
// "too much recursion" error.
|
||
setTimeout(runIfPresent, 0, handle);
|
||
} else {
|
||
var task = tasksByHandle[handle];
|
||
if (task) {
|
||
currentlyRunningATask = true;
|
||
try {
|
||
run(task);
|
||
} finally {
|
||
clearImmediate(handle);
|
||
currentlyRunningATask = false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function installNextTickImplementation() {
|
||
registerImmediate = function(handle) {
|
||
process.nextTick(function () { runIfPresent(handle); });
|
||
};
|
||
}
|
||
|
||
function canUsePostMessage() {
|
||
// The test against `importScripts` prevents this implementation from being installed inside a web worker,
|
||
// where `global.postMessage` means something completely different and can't be used for this purpose.
|
||
if (global.postMessage && !global.importScripts) {
|
||
var postMessageIsAsynchronous = true;
|
||
var oldOnMessage = global.onmessage;
|
||
global.onmessage = function() {
|
||
postMessageIsAsynchronous = false;
|
||
};
|
||
global.postMessage("", "*");
|
||
global.onmessage = oldOnMessage;
|
||
return postMessageIsAsynchronous;
|
||
}
|
||
}
|
||
|
||
function installPostMessageImplementation() {
|
||
// Installs an event handler on `global` for the `message` event: see
|
||
// * https://developer.mozilla.org/en/DOM/window.postMessage
|
||
// * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
|
||
|
||
var messagePrefix = "setImmediate$" + Math.random() + "$";
|
||
var onGlobalMessage = function(event) {
|
||
if (event.source === global &&
|
||
typeof event.data === "string" &&
|
||
event.data.indexOf(messagePrefix) === 0) {
|
||
runIfPresent(+event.data.slice(messagePrefix.length));
|
||
}
|
||
};
|
||
|
||
if (global.addEventListener) {
|
||
global.addEventListener("message", onGlobalMessage, false);
|
||
} else {
|
||
global.attachEvent("onmessage", onGlobalMessage);
|
||
}
|
||
|
||
registerImmediate = function(handle) {
|
||
global.postMessage(messagePrefix + handle, "*");
|
||
};
|
||
}
|
||
|
||
function installMessageChannelImplementation() {
|
||
var channel = new MessageChannel();
|
||
channel.port1.onmessage = function(event) {
|
||
var handle = event.data;
|
||
runIfPresent(handle);
|
||
};
|
||
|
||
registerImmediate = function(handle) {
|
||
channel.port2.postMessage(handle);
|
||
};
|
||
}
|
||
|
||
function installReadyStateChangeImplementation() {
|
||
var html = doc.documentElement;
|
||
registerImmediate = function(handle) {
|
||
// Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
|
||
// into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
|
||
var script = doc.createElement("script");
|
||
script.onreadystatechange = function () {
|
||
runIfPresent(handle);
|
||
script.onreadystatechange = null;
|
||
html.removeChild(script);
|
||
script = null;
|
||
};
|
||
html.appendChild(script);
|
||
};
|
||
}
|
||
|
||
function installSetTimeoutImplementation() {
|
||
registerImmediate = function(handle) {
|
||
setTimeout(runIfPresent, 0, handle);
|
||
};
|
||
}
|
||
|
||
// If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
|
||
var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);
|
||
attachTo = attachTo && attachTo.setTimeout ? attachTo : global;
|
||
|
||
// Don't get fooled by e.g. browserify environments.
|
||
if ({}.toString.call(global.process) === "[object process]") {
|
||
// For Node.js before 0.9
|
||
installNextTickImplementation();
|
||
|
||
} else if (canUsePostMessage()) {
|
||
// For non-IE10 modern browsers
|
||
installPostMessageImplementation();
|
||
|
||
} else if (global.MessageChannel) {
|
||
// For web workers, where supported
|
||
installMessageChannelImplementation();
|
||
|
||
} else if (doc && "onreadystatechange" in doc.createElement("script")) {
|
||
// For IE 6–8
|
||
installReadyStateChangeImplementation();
|
||
|
||
} else {
|
||
// For older browsers
|
||
installSetTimeoutImplementation();
|
||
}
|
||
|
||
attachTo.setImmediate = setImmediate;
|
||
attachTo.clearImmediate = clearImmediate;
|
||
}(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self));
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js"), __webpack_require__(/*! ./../process/browser.js */ "./node_modules/process/browser.js")))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/sha.js/hash.js":
|
||
/*!*************************************!*\
|
||
!*** ./node_modules/sha.js/hash.js ***!
|
||
\*************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
// prototype class for hash functions
|
||
function Hash (blockSize, finalSize) {
|
||
this._block = Buffer.alloc(blockSize)
|
||
this._finalSize = finalSize
|
||
this._blockSize = blockSize
|
||
this._len = 0
|
||
}
|
||
|
||
Hash.prototype.update = function (data, enc) {
|
||
if (typeof data === 'string') {
|
||
enc = enc || 'utf8'
|
||
data = Buffer.from(data, enc)
|
||
}
|
||
|
||
var block = this._block
|
||
var blockSize = this._blockSize
|
||
var length = data.length
|
||
var accum = this._len
|
||
|
||
for (var offset = 0; offset < length;) {
|
||
var assigned = accum % blockSize
|
||
var remainder = Math.min(length - offset, blockSize - assigned)
|
||
|
||
for (var i = 0; i < remainder; i++) {
|
||
block[assigned + i] = data[offset + i]
|
||
}
|
||
|
||
accum += remainder
|
||
offset += remainder
|
||
|
||
if ((accum % blockSize) === 0) {
|
||
this._update(block)
|
||
}
|
||
}
|
||
|
||
this._len += length
|
||
return this
|
||
}
|
||
|
||
Hash.prototype.digest = function (enc) {
|
||
var rem = this._len % this._blockSize
|
||
|
||
this._block[rem] = 0x80
|
||
|
||
// zero (rem + 1) trailing bits, where (rem + 1) is the smallest
|
||
// non-negative solution to the equation (length + 1 + (rem + 1)) === finalSize mod blockSize
|
||
this._block.fill(0, rem + 1)
|
||
|
||
if (rem >= this._finalSize) {
|
||
this._update(this._block)
|
||
this._block.fill(0)
|
||
}
|
||
|
||
var bits = this._len * 8
|
||
|
||
// uint32
|
||
if (bits <= 0xffffffff) {
|
||
this._block.writeUInt32BE(bits, this._blockSize - 4)
|
||
|
||
// uint64
|
||
} else {
|
||
var lowBits = (bits & 0xffffffff) >>> 0
|
||
var highBits = (bits - lowBits) / 0x100000000
|
||
|
||
this._block.writeUInt32BE(highBits, this._blockSize - 8)
|
||
this._block.writeUInt32BE(lowBits, this._blockSize - 4)
|
||
}
|
||
|
||
this._update(this._block)
|
||
var hash = this._hash()
|
||
|
||
return enc ? hash.toString(enc) : hash
|
||
}
|
||
|
||
Hash.prototype._update = function () {
|
||
throw new Error('_update must be implemented by subclass')
|
||
}
|
||
|
||
module.exports = Hash
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/sha.js/index.js":
|
||
/*!**************************************!*\
|
||
!*** ./node_modules/sha.js/index.js ***!
|
||
\**************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var exports = module.exports = function SHA (algorithm) {
|
||
algorithm = algorithm.toLowerCase()
|
||
|
||
var Algorithm = exports[algorithm]
|
||
if (!Algorithm) throw new Error(algorithm + ' is not supported (we accept pull requests)')
|
||
|
||
return new Algorithm()
|
||
}
|
||
|
||
exports.sha = __webpack_require__(/*! ./sha */ "./node_modules/sha.js/sha.js")
|
||
exports.sha1 = __webpack_require__(/*! ./sha1 */ "./node_modules/sha.js/sha1.js")
|
||
exports.sha224 = __webpack_require__(/*! ./sha224 */ "./node_modules/sha.js/sha224.js")
|
||
exports.sha256 = __webpack_require__(/*! ./sha256 */ "./node_modules/sha.js/sha256.js")
|
||
exports.sha384 = __webpack_require__(/*! ./sha384 */ "./node_modules/sha.js/sha384.js")
|
||
exports.sha512 = __webpack_require__(/*! ./sha512 */ "./node_modules/sha.js/sha512.js")
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/sha.js/sha.js":
|
||
/*!************************************!*\
|
||
!*** ./node_modules/sha.js/sha.js ***!
|
||
\************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/*
|
||
* A JavaScript implementation of the Secure Hash Algorithm, SHA-0, as defined
|
||
* in FIPS PUB 180-1
|
||
* This source code is derived from sha1.js of the same repository.
|
||
* The difference between SHA-0 and SHA-1 is just a bitwise rotate left
|
||
* operation was added.
|
||
*/
|
||
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
var Hash = __webpack_require__(/*! ./hash */ "./node_modules/sha.js/hash.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
var K = [
|
||
0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0
|
||
]
|
||
|
||
var W = new Array(80)
|
||
|
||
function Sha () {
|
||
this.init()
|
||
this._w = W
|
||
|
||
Hash.call(this, 64, 56)
|
||
}
|
||
|
||
inherits(Sha, Hash)
|
||
|
||
Sha.prototype.init = function () {
|
||
this._a = 0x67452301
|
||
this._b = 0xefcdab89
|
||
this._c = 0x98badcfe
|
||
this._d = 0x10325476
|
||
this._e = 0xc3d2e1f0
|
||
|
||
return this
|
||
}
|
||
|
||
function rotl5 (num) {
|
||
return (num << 5) | (num >>> 27)
|
||
}
|
||
|
||
function rotl30 (num) {
|
||
return (num << 30) | (num >>> 2)
|
||
}
|
||
|
||
function ft (s, b, c, d) {
|
||
if (s === 0) return (b & c) | ((~b) & d)
|
||
if (s === 2) return (b & c) | (b & d) | (c & d)
|
||
return b ^ c ^ d
|
||
}
|
||
|
||
Sha.prototype._update = function (M) {
|
||
var W = this._w
|
||
|
||
var a = this._a | 0
|
||
var b = this._b | 0
|
||
var c = this._c | 0
|
||
var d = this._d | 0
|
||
var e = this._e | 0
|
||
|
||
for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
|
||
for (; i < 80; ++i) W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]
|
||
|
||
for (var j = 0; j < 80; ++j) {
|
||
var s = ~~(j / 20)
|
||
var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0
|
||
|
||
e = d
|
||
d = c
|
||
c = rotl30(b)
|
||
b = a
|
||
a = t
|
||
}
|
||
|
||
this._a = (a + this._a) | 0
|
||
this._b = (b + this._b) | 0
|
||
this._c = (c + this._c) | 0
|
||
this._d = (d + this._d) | 0
|
||
this._e = (e + this._e) | 0
|
||
}
|
||
|
||
Sha.prototype._hash = function () {
|
||
var H = Buffer.allocUnsafe(20)
|
||
|
||
H.writeInt32BE(this._a | 0, 0)
|
||
H.writeInt32BE(this._b | 0, 4)
|
||
H.writeInt32BE(this._c | 0, 8)
|
||
H.writeInt32BE(this._d | 0, 12)
|
||
H.writeInt32BE(this._e | 0, 16)
|
||
|
||
return H
|
||
}
|
||
|
||
module.exports = Sha
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/sha.js/sha1.js":
|
||
/*!*************************************!*\
|
||
!*** ./node_modules/sha.js/sha1.js ***!
|
||
\*************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/*
|
||
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
|
||
* in FIPS PUB 180-1
|
||
* Version 2.1a Copyright Paul Johnston 2000 - 2002.
|
||
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
||
* Distributed under the BSD License
|
||
* See http://pajhome.org.uk/crypt/md5 for details.
|
||
*/
|
||
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
var Hash = __webpack_require__(/*! ./hash */ "./node_modules/sha.js/hash.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
var K = [
|
||
0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0
|
||
]
|
||
|
||
var W = new Array(80)
|
||
|
||
function Sha1 () {
|
||
this.init()
|
||
this._w = W
|
||
|
||
Hash.call(this, 64, 56)
|
||
}
|
||
|
||
inherits(Sha1, Hash)
|
||
|
||
Sha1.prototype.init = function () {
|
||
this._a = 0x67452301
|
||
this._b = 0xefcdab89
|
||
this._c = 0x98badcfe
|
||
this._d = 0x10325476
|
||
this._e = 0xc3d2e1f0
|
||
|
||
return this
|
||
}
|
||
|
||
function rotl1 (num) {
|
||
return (num << 1) | (num >>> 31)
|
||
}
|
||
|
||
function rotl5 (num) {
|
||
return (num << 5) | (num >>> 27)
|
||
}
|
||
|
||
function rotl30 (num) {
|
||
return (num << 30) | (num >>> 2)
|
||
}
|
||
|
||
function ft (s, b, c, d) {
|
||
if (s === 0) return (b & c) | ((~b) & d)
|
||
if (s === 2) return (b & c) | (b & d) | (c & d)
|
||
return b ^ c ^ d
|
||
}
|
||
|
||
Sha1.prototype._update = function (M) {
|
||
var W = this._w
|
||
|
||
var a = this._a | 0
|
||
var b = this._b | 0
|
||
var c = this._c | 0
|
||
var d = this._d | 0
|
||
var e = this._e | 0
|
||
|
||
for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
|
||
for (; i < 80; ++i) W[i] = rotl1(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16])
|
||
|
||
for (var j = 0; j < 80; ++j) {
|
||
var s = ~~(j / 20)
|
||
var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0
|
||
|
||
e = d
|
||
d = c
|
||
c = rotl30(b)
|
||
b = a
|
||
a = t
|
||
}
|
||
|
||
this._a = (a + this._a) | 0
|
||
this._b = (b + this._b) | 0
|
||
this._c = (c + this._c) | 0
|
||
this._d = (d + this._d) | 0
|
||
this._e = (e + this._e) | 0
|
||
}
|
||
|
||
Sha1.prototype._hash = function () {
|
||
var H = Buffer.allocUnsafe(20)
|
||
|
||
H.writeInt32BE(this._a | 0, 0)
|
||
H.writeInt32BE(this._b | 0, 4)
|
||
H.writeInt32BE(this._c | 0, 8)
|
||
H.writeInt32BE(this._d | 0, 12)
|
||
H.writeInt32BE(this._e | 0, 16)
|
||
|
||
return H
|
||
}
|
||
|
||
module.exports = Sha1
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/sha.js/sha224.js":
|
||
/*!***************************************!*\
|
||
!*** ./node_modules/sha.js/sha224.js ***!
|
||
\***************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/**
|
||
* A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
|
||
* in FIPS 180-2
|
||
* Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009.
|
||
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
||
*
|
||
*/
|
||
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
var Sha256 = __webpack_require__(/*! ./sha256 */ "./node_modules/sha.js/sha256.js")
|
||
var Hash = __webpack_require__(/*! ./hash */ "./node_modules/sha.js/hash.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
var W = new Array(64)
|
||
|
||
function Sha224 () {
|
||
this.init()
|
||
|
||
this._w = W // new Array(64)
|
||
|
||
Hash.call(this, 64, 56)
|
||
}
|
||
|
||
inherits(Sha224, Sha256)
|
||
|
||
Sha224.prototype.init = function () {
|
||
this._a = 0xc1059ed8
|
||
this._b = 0x367cd507
|
||
this._c = 0x3070dd17
|
||
this._d = 0xf70e5939
|
||
this._e = 0xffc00b31
|
||
this._f = 0x68581511
|
||
this._g = 0x64f98fa7
|
||
this._h = 0xbefa4fa4
|
||
|
||
return this
|
||
}
|
||
|
||
Sha224.prototype._hash = function () {
|
||
var H = Buffer.allocUnsafe(28)
|
||
|
||
H.writeInt32BE(this._a, 0)
|
||
H.writeInt32BE(this._b, 4)
|
||
H.writeInt32BE(this._c, 8)
|
||
H.writeInt32BE(this._d, 12)
|
||
H.writeInt32BE(this._e, 16)
|
||
H.writeInt32BE(this._f, 20)
|
||
H.writeInt32BE(this._g, 24)
|
||
|
||
return H
|
||
}
|
||
|
||
module.exports = Sha224
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/sha.js/sha256.js":
|
||
/*!***************************************!*\
|
||
!*** ./node_modules/sha.js/sha256.js ***!
|
||
\***************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/**
|
||
* A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
|
||
* in FIPS 180-2
|
||
* Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009.
|
||
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
||
*
|
||
*/
|
||
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
var Hash = __webpack_require__(/*! ./hash */ "./node_modules/sha.js/hash.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
var K = [
|
||
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
|
||
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
|
||
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
|
||
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
|
||
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
|
||
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
|
||
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
|
||
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
|
||
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
|
||
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
|
||
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
|
||
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
|
||
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
|
||
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
|
||
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
|
||
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
|
||
]
|
||
|
||
var W = new Array(64)
|
||
|
||
function Sha256 () {
|
||
this.init()
|
||
|
||
this._w = W // new Array(64)
|
||
|
||
Hash.call(this, 64, 56)
|
||
}
|
||
|
||
inherits(Sha256, Hash)
|
||
|
||
Sha256.prototype.init = function () {
|
||
this._a = 0x6a09e667
|
||
this._b = 0xbb67ae85
|
||
this._c = 0x3c6ef372
|
||
this._d = 0xa54ff53a
|
||
this._e = 0x510e527f
|
||
this._f = 0x9b05688c
|
||
this._g = 0x1f83d9ab
|
||
this._h = 0x5be0cd19
|
||
|
||
return this
|
||
}
|
||
|
||
function ch (x, y, z) {
|
||
return z ^ (x & (y ^ z))
|
||
}
|
||
|
||
function maj (x, y, z) {
|
||
return (x & y) | (z & (x | y))
|
||
}
|
||
|
||
function sigma0 (x) {
|
||
return (x >>> 2 | x << 30) ^ (x >>> 13 | x << 19) ^ (x >>> 22 | x << 10)
|
||
}
|
||
|
||
function sigma1 (x) {
|
||
return (x >>> 6 | x << 26) ^ (x >>> 11 | x << 21) ^ (x >>> 25 | x << 7)
|
||
}
|
||
|
||
function gamma0 (x) {
|
||
return (x >>> 7 | x << 25) ^ (x >>> 18 | x << 14) ^ (x >>> 3)
|
||
}
|
||
|
||
function gamma1 (x) {
|
||
return (x >>> 17 | x << 15) ^ (x >>> 19 | x << 13) ^ (x >>> 10)
|
||
}
|
||
|
||
Sha256.prototype._update = function (M) {
|
||
var W = this._w
|
||
|
||
var a = this._a | 0
|
||
var b = this._b | 0
|
||
var c = this._c | 0
|
||
var d = this._d | 0
|
||
var e = this._e | 0
|
||
var f = this._f | 0
|
||
var g = this._g | 0
|
||
var h = this._h | 0
|
||
|
||
for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
|
||
for (; i < 64; ++i) W[i] = (gamma1(W[i - 2]) + W[i - 7] + gamma0(W[i - 15]) + W[i - 16]) | 0
|
||
|
||
for (var j = 0; j < 64; ++j) {
|
||
var T1 = (h + sigma1(e) + ch(e, f, g) + K[j] + W[j]) | 0
|
||
var T2 = (sigma0(a) + maj(a, b, c)) | 0
|
||
|
||
h = g
|
||
g = f
|
||
f = e
|
||
e = (d + T1) | 0
|
||
d = c
|
||
c = b
|
||
b = a
|
||
a = (T1 + T2) | 0
|
||
}
|
||
|
||
this._a = (a + this._a) | 0
|
||
this._b = (b + this._b) | 0
|
||
this._c = (c + this._c) | 0
|
||
this._d = (d + this._d) | 0
|
||
this._e = (e + this._e) | 0
|
||
this._f = (f + this._f) | 0
|
||
this._g = (g + this._g) | 0
|
||
this._h = (h + this._h) | 0
|
||
}
|
||
|
||
Sha256.prototype._hash = function () {
|
||
var H = Buffer.allocUnsafe(32)
|
||
|
||
H.writeInt32BE(this._a, 0)
|
||
H.writeInt32BE(this._b, 4)
|
||
H.writeInt32BE(this._c, 8)
|
||
H.writeInt32BE(this._d, 12)
|
||
H.writeInt32BE(this._e, 16)
|
||
H.writeInt32BE(this._f, 20)
|
||
H.writeInt32BE(this._g, 24)
|
||
H.writeInt32BE(this._h, 28)
|
||
|
||
return H
|
||
}
|
||
|
||
module.exports = Sha256
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/sha.js/sha384.js":
|
||
/*!***************************************!*\
|
||
!*** ./node_modules/sha.js/sha384.js ***!
|
||
\***************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
var SHA512 = __webpack_require__(/*! ./sha512 */ "./node_modules/sha.js/sha512.js")
|
||
var Hash = __webpack_require__(/*! ./hash */ "./node_modules/sha.js/hash.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
var W = new Array(160)
|
||
|
||
function Sha384 () {
|
||
this.init()
|
||
this._w = W
|
||
|
||
Hash.call(this, 128, 112)
|
||
}
|
||
|
||
inherits(Sha384, SHA512)
|
||
|
||
Sha384.prototype.init = function () {
|
||
this._ah = 0xcbbb9d5d
|
||
this._bh = 0x629a292a
|
||
this._ch = 0x9159015a
|
||
this._dh = 0x152fecd8
|
||
this._eh = 0x67332667
|
||
this._fh = 0x8eb44a87
|
||
this._gh = 0xdb0c2e0d
|
||
this._hh = 0x47b5481d
|
||
|
||
this._al = 0xc1059ed8
|
||
this._bl = 0x367cd507
|
||
this._cl = 0x3070dd17
|
||
this._dl = 0xf70e5939
|
||
this._el = 0xffc00b31
|
||
this._fl = 0x68581511
|
||
this._gl = 0x64f98fa7
|
||
this._hl = 0xbefa4fa4
|
||
|
||
return this
|
||
}
|
||
|
||
Sha384.prototype._hash = function () {
|
||
var H = Buffer.allocUnsafe(48)
|
||
|
||
function writeInt64BE (h, l, offset) {
|
||
H.writeInt32BE(h, offset)
|
||
H.writeInt32BE(l, offset + 4)
|
||
}
|
||
|
||
writeInt64BE(this._ah, this._al, 0)
|
||
writeInt64BE(this._bh, this._bl, 8)
|
||
writeInt64BE(this._ch, this._cl, 16)
|
||
writeInt64BE(this._dh, this._dl, 24)
|
||
writeInt64BE(this._eh, this._el, 32)
|
||
writeInt64BE(this._fh, this._fl, 40)
|
||
|
||
return H
|
||
}
|
||
|
||
module.exports = Sha384
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/sha.js/sha512.js":
|
||
/*!***************************************!*\
|
||
!*** ./node_modules/sha.js/sha512.js ***!
|
||
\***************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")
|
||
var Hash = __webpack_require__(/*! ./hash */ "./node_modules/sha.js/hash.js")
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer
|
||
|
||
var K = [
|
||
0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
|
||
0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
|
||
0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
|
||
0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
|
||
0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
|
||
0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
|
||
0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
|
||
0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
|
||
0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
|
||
0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
|
||
0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
|
||
0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
|
||
0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
|
||
0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
|
||
0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
|
||
0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
|
||
0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
|
||
0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
|
||
0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
|
||
0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
|
||
0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
|
||
0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
|
||
0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
|
||
0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
|
||
0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
|
||
0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
|
||
0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
|
||
0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
|
||
0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
|
||
0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
|
||
0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
|
||
0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
|
||
0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
|
||
0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
|
||
0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
|
||
0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
|
||
0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
|
||
0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
|
||
0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
|
||
0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
|
||
]
|
||
|
||
var W = new Array(160)
|
||
|
||
function Sha512 () {
|
||
this.init()
|
||
this._w = W
|
||
|
||
Hash.call(this, 128, 112)
|
||
}
|
||
|
||
inherits(Sha512, Hash)
|
||
|
||
Sha512.prototype.init = function () {
|
||
this._ah = 0x6a09e667
|
||
this._bh = 0xbb67ae85
|
||
this._ch = 0x3c6ef372
|
||
this._dh = 0xa54ff53a
|
||
this._eh = 0x510e527f
|
||
this._fh = 0x9b05688c
|
||
this._gh = 0x1f83d9ab
|
||
this._hh = 0x5be0cd19
|
||
|
||
this._al = 0xf3bcc908
|
||
this._bl = 0x84caa73b
|
||
this._cl = 0xfe94f82b
|
||
this._dl = 0x5f1d36f1
|
||
this._el = 0xade682d1
|
||
this._fl = 0x2b3e6c1f
|
||
this._gl = 0xfb41bd6b
|
||
this._hl = 0x137e2179
|
||
|
||
return this
|
||
}
|
||
|
||
function Ch (x, y, z) {
|
||
return z ^ (x & (y ^ z))
|
||
}
|
||
|
||
function maj (x, y, z) {
|
||
return (x & y) | (z & (x | y))
|
||
}
|
||
|
||
function sigma0 (x, xl) {
|
||
return (x >>> 28 | xl << 4) ^ (xl >>> 2 | x << 30) ^ (xl >>> 7 | x << 25)
|
||
}
|
||
|
||
function sigma1 (x, xl) {
|
||
return (x >>> 14 | xl << 18) ^ (x >>> 18 | xl << 14) ^ (xl >>> 9 | x << 23)
|
||
}
|
||
|
||
function Gamma0 (x, xl) {
|
||
return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7)
|
||
}
|
||
|
||
function Gamma0l (x, xl) {
|
||
return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7 | xl << 25)
|
||
}
|
||
|
||
function Gamma1 (x, xl) {
|
||
return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6)
|
||
}
|
||
|
||
function Gamma1l (x, xl) {
|
||
return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6 | xl << 26)
|
||
}
|
||
|
||
function getCarry (a, b) {
|
||
return (a >>> 0) < (b >>> 0) ? 1 : 0
|
||
}
|
||
|
||
Sha512.prototype._update = function (M) {
|
||
var W = this._w
|
||
|
||
var ah = this._ah | 0
|
||
var bh = this._bh | 0
|
||
var ch = this._ch | 0
|
||
var dh = this._dh | 0
|
||
var eh = this._eh | 0
|
||
var fh = this._fh | 0
|
||
var gh = this._gh | 0
|
||
var hh = this._hh | 0
|
||
|
||
var al = this._al | 0
|
||
var bl = this._bl | 0
|
||
var cl = this._cl | 0
|
||
var dl = this._dl | 0
|
||
var el = this._el | 0
|
||
var fl = this._fl | 0
|
||
var gl = this._gl | 0
|
||
var hl = this._hl | 0
|
||
|
||
for (var i = 0; i < 32; i += 2) {
|
||
W[i] = M.readInt32BE(i * 4)
|
||
W[i + 1] = M.readInt32BE(i * 4 + 4)
|
||
}
|
||
for (; i < 160; i += 2) {
|
||
var xh = W[i - 15 * 2]
|
||
var xl = W[i - 15 * 2 + 1]
|
||
var gamma0 = Gamma0(xh, xl)
|
||
var gamma0l = Gamma0l(xl, xh)
|
||
|
||
xh = W[i - 2 * 2]
|
||
xl = W[i - 2 * 2 + 1]
|
||
var gamma1 = Gamma1(xh, xl)
|
||
var gamma1l = Gamma1l(xl, xh)
|
||
|
||
// W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]
|
||
var Wi7h = W[i - 7 * 2]
|
||
var Wi7l = W[i - 7 * 2 + 1]
|
||
|
||
var Wi16h = W[i - 16 * 2]
|
||
var Wi16l = W[i - 16 * 2 + 1]
|
||
|
||
var Wil = (gamma0l + Wi7l) | 0
|
||
var Wih = (gamma0 + Wi7h + getCarry(Wil, gamma0l)) | 0
|
||
Wil = (Wil + gamma1l) | 0
|
||
Wih = (Wih + gamma1 + getCarry(Wil, gamma1l)) | 0
|
||
Wil = (Wil + Wi16l) | 0
|
||
Wih = (Wih + Wi16h + getCarry(Wil, Wi16l)) | 0
|
||
|
||
W[i] = Wih
|
||
W[i + 1] = Wil
|
||
}
|
||
|
||
for (var j = 0; j < 160; j += 2) {
|
||
Wih = W[j]
|
||
Wil = W[j + 1]
|
||
|
||
var majh = maj(ah, bh, ch)
|
||
var majl = maj(al, bl, cl)
|
||
|
||
var sigma0h = sigma0(ah, al)
|
||
var sigma0l = sigma0(al, ah)
|
||
var sigma1h = sigma1(eh, el)
|
||
var sigma1l = sigma1(el, eh)
|
||
|
||
// t1 = h + sigma1 + ch + K[j] + W[j]
|
||
var Kih = K[j]
|
||
var Kil = K[j + 1]
|
||
|
||
var chh = Ch(eh, fh, gh)
|
||
var chl = Ch(el, fl, gl)
|
||
|
||
var t1l = (hl + sigma1l) | 0
|
||
var t1h = (hh + sigma1h + getCarry(t1l, hl)) | 0
|
||
t1l = (t1l + chl) | 0
|
||
t1h = (t1h + chh + getCarry(t1l, chl)) | 0
|
||
t1l = (t1l + Kil) | 0
|
||
t1h = (t1h + Kih + getCarry(t1l, Kil)) | 0
|
||
t1l = (t1l + Wil) | 0
|
||
t1h = (t1h + Wih + getCarry(t1l, Wil)) | 0
|
||
|
||
// t2 = sigma0 + maj
|
||
var t2l = (sigma0l + majl) | 0
|
||
var t2h = (sigma0h + majh + getCarry(t2l, sigma0l)) | 0
|
||
|
||
hh = gh
|
||
hl = gl
|
||
gh = fh
|
||
gl = fl
|
||
fh = eh
|
||
fl = el
|
||
el = (dl + t1l) | 0
|
||
eh = (dh + t1h + getCarry(el, dl)) | 0
|
||
dh = ch
|
||
dl = cl
|
||
ch = bh
|
||
cl = bl
|
||
bh = ah
|
||
bl = al
|
||
al = (t1l + t2l) | 0
|
||
ah = (t1h + t2h + getCarry(al, t1l)) | 0
|
||
}
|
||
|
||
this._al = (this._al + al) | 0
|
||
this._bl = (this._bl + bl) | 0
|
||
this._cl = (this._cl + cl) | 0
|
||
this._dl = (this._dl + dl) | 0
|
||
this._el = (this._el + el) | 0
|
||
this._fl = (this._fl + fl) | 0
|
||
this._gl = (this._gl + gl) | 0
|
||
this._hl = (this._hl + hl) | 0
|
||
|
||
this._ah = (this._ah + ah + getCarry(this._al, al)) | 0
|
||
this._bh = (this._bh + bh + getCarry(this._bl, bl)) | 0
|
||
this._ch = (this._ch + ch + getCarry(this._cl, cl)) | 0
|
||
this._dh = (this._dh + dh + getCarry(this._dl, dl)) | 0
|
||
this._eh = (this._eh + eh + getCarry(this._el, el)) | 0
|
||
this._fh = (this._fh + fh + getCarry(this._fl, fl)) | 0
|
||
this._gh = (this._gh + gh + getCarry(this._gl, gl)) | 0
|
||
this._hh = (this._hh + hh + getCarry(this._hl, hl)) | 0
|
||
}
|
||
|
||
Sha512.prototype._hash = function () {
|
||
var H = Buffer.allocUnsafe(64)
|
||
|
||
function writeInt64BE (h, l, offset) {
|
||
H.writeInt32BE(h, offset)
|
||
H.writeInt32BE(l, offset + 4)
|
||
}
|
||
|
||
writeInt64BE(this._ah, this._al, 0)
|
||
writeInt64BE(this._bh, this._bl, 8)
|
||
writeInt64BE(this._ch, this._cl, 16)
|
||
writeInt64BE(this._dh, this._dl, 24)
|
||
writeInt64BE(this._eh, this._el, 32)
|
||
writeInt64BE(this._fh, this._fl, 40)
|
||
writeInt64BE(this._gh, this._gl, 48)
|
||
writeInt64BE(this._hh, this._hl, 56)
|
||
|
||
return H
|
||
}
|
||
|
||
module.exports = Sha512
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/stream-browserify/index.js":
|
||
/*!*************************************************!*\
|
||
!*** ./node_modules/stream-browserify/index.js ***!
|
||
\*************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
// Copyright Joyent, Inc. and other Node contributors.
|
||
//
|
||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||
// copy of this software and associated documentation files (the
|
||
// "Software"), to deal in the Software without restriction, including
|
||
// without limitation the rights to use, copy, modify, merge, publish,
|
||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||
// persons to whom the Software is furnished to do so, subject to the
|
||
// following conditions:
|
||
//
|
||
// The above copyright notice and this permission notice shall be included
|
||
// in all copies or substantial portions of the Software.
|
||
//
|
||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
||
module.exports = Stream;
|
||
|
||
var EE = __webpack_require__(/*! events */ "./node_modules/events/events.js").EventEmitter;
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
|
||
|
||
inherits(Stream, EE);
|
||
Stream.Readable = __webpack_require__(/*! readable-stream/readable.js */ "./node_modules/readable-stream/readable-browser.js");
|
||
Stream.Writable = __webpack_require__(/*! readable-stream/writable.js */ "./node_modules/readable-stream/writable-browser.js");
|
||
Stream.Duplex = __webpack_require__(/*! readable-stream/duplex.js */ "./node_modules/readable-stream/duplex-browser.js");
|
||
Stream.Transform = __webpack_require__(/*! readable-stream/transform.js */ "./node_modules/readable-stream/transform.js");
|
||
Stream.PassThrough = __webpack_require__(/*! readable-stream/passthrough.js */ "./node_modules/readable-stream/passthrough.js");
|
||
|
||
// Backwards-compat with node 0.4.x
|
||
Stream.Stream = Stream;
|
||
|
||
|
||
|
||
// old-style streams. Note that the pipe method (the only relevant
|
||
// part of this class) is overridden in the Readable class.
|
||
|
||
function Stream() {
|
||
EE.call(this);
|
||
}
|
||
|
||
Stream.prototype.pipe = function(dest, options) {
|
||
var source = this;
|
||
|
||
function ondata(chunk) {
|
||
if (dest.writable) {
|
||
if (false === dest.write(chunk) && source.pause) {
|
||
source.pause();
|
||
}
|
||
}
|
||
}
|
||
|
||
source.on('data', ondata);
|
||
|
||
function ondrain() {
|
||
if (source.readable && source.resume) {
|
||
source.resume();
|
||
}
|
||
}
|
||
|
||
dest.on('drain', ondrain);
|
||
|
||
// If the 'end' option is not supplied, dest.end() will be called when
|
||
// source gets the 'end' or 'close' events. Only dest.end() once.
|
||
if (!dest._isStdio && (!options || options.end !== false)) {
|
||
source.on('end', onend);
|
||
source.on('close', onclose);
|
||
}
|
||
|
||
var didOnEnd = false;
|
||
function onend() {
|
||
if (didOnEnd) return;
|
||
didOnEnd = true;
|
||
|
||
dest.end();
|
||
}
|
||
|
||
|
||
function onclose() {
|
||
if (didOnEnd) return;
|
||
didOnEnd = true;
|
||
|
||
if (typeof dest.destroy === 'function') dest.destroy();
|
||
}
|
||
|
||
// don't leave dangling pipes when there are errors.
|
||
function onerror(er) {
|
||
cleanup();
|
||
if (EE.listenerCount(this, 'error') === 0) {
|
||
throw er; // Unhandled stream error in pipe.
|
||
}
|
||
}
|
||
|
||
source.on('error', onerror);
|
||
dest.on('error', onerror);
|
||
|
||
// remove all the event listeners that were added.
|
||
function cleanup() {
|
||
source.removeListener('data', ondata);
|
||
dest.removeListener('drain', ondrain);
|
||
|
||
source.removeListener('end', onend);
|
||
source.removeListener('close', onclose);
|
||
|
||
source.removeListener('error', onerror);
|
||
dest.removeListener('error', onerror);
|
||
|
||
source.removeListener('end', cleanup);
|
||
source.removeListener('close', cleanup);
|
||
|
||
dest.removeListener('close', cleanup);
|
||
}
|
||
|
||
source.on('end', cleanup);
|
||
source.on('close', cleanup);
|
||
|
||
dest.on('close', cleanup);
|
||
|
||
dest.emit('pipe', source);
|
||
|
||
// Allow for unix-like usage: A.pipe(B).pipe(C)
|
||
return dest;
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/string_decoder/lib/string_decoder.js":
|
||
/*!***********************************************************!*\
|
||
!*** ./node_modules/string_decoder/lib/string_decoder.js ***!
|
||
\***********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
// Copyright Joyent, Inc. and other Node contributors.
|
||
//
|
||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||
// copy of this software and associated documentation files (the
|
||
// "Software"), to deal in the Software without restriction, including
|
||
// without limitation the rights to use, copy, modify, merge, publish,
|
||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||
// persons to whom the Software is furnished to do so, subject to the
|
||
// following conditions:
|
||
//
|
||
// The above copyright notice and this permission notice shall be included
|
||
// in all copies or substantial portions of the Software.
|
||
//
|
||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
||
|
||
|
||
/*<replacement>*/
|
||
|
||
var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/safe-buffer/index.js").Buffer;
|
||
/*</replacement>*/
|
||
|
||
var isEncoding = Buffer.isEncoding || function (encoding) {
|
||
encoding = '' + encoding;
|
||
switch (encoding && encoding.toLowerCase()) {
|
||
case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw':
|
||
return true;
|
||
default:
|
||
return false;
|
||
}
|
||
};
|
||
|
||
function _normalizeEncoding(enc) {
|
||
if (!enc) return 'utf8';
|
||
var retried;
|
||
while (true) {
|
||
switch (enc) {
|
||
case 'utf8':
|
||
case 'utf-8':
|
||
return 'utf8';
|
||
case 'ucs2':
|
||
case 'ucs-2':
|
||
case 'utf16le':
|
||
case 'utf-16le':
|
||
return 'utf16le';
|
||
case 'latin1':
|
||
case 'binary':
|
||
return 'latin1';
|
||
case 'base64':
|
||
case 'ascii':
|
||
case 'hex':
|
||
return enc;
|
||
default:
|
||
if (retried) return; // undefined
|
||
enc = ('' + enc).toLowerCase();
|
||
retried = true;
|
||
}
|
||
}
|
||
};
|
||
|
||
// Do not cache `Buffer.isEncoding` when checking encoding names as some
|
||
// modules monkey-patch it to support additional encodings
|
||
function normalizeEncoding(enc) {
|
||
var nenc = _normalizeEncoding(enc);
|
||
if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc);
|
||
return nenc || enc;
|
||
}
|
||
|
||
// StringDecoder provides an interface for efficiently splitting a series of
|
||
// buffers into a series of JS strings without breaking apart multi-byte
|
||
// characters.
|
||
exports.StringDecoder = StringDecoder;
|
||
function StringDecoder(encoding) {
|
||
this.encoding = normalizeEncoding(encoding);
|
||
var nb;
|
||
switch (this.encoding) {
|
||
case 'utf16le':
|
||
this.text = utf16Text;
|
||
this.end = utf16End;
|
||
nb = 4;
|
||
break;
|
||
case 'utf8':
|
||
this.fillLast = utf8FillLast;
|
||
nb = 4;
|
||
break;
|
||
case 'base64':
|
||
this.text = base64Text;
|
||
this.end = base64End;
|
||
nb = 3;
|
||
break;
|
||
default:
|
||
this.write = simpleWrite;
|
||
this.end = simpleEnd;
|
||
return;
|
||
}
|
||
this.lastNeed = 0;
|
||
this.lastTotal = 0;
|
||
this.lastChar = Buffer.allocUnsafe(nb);
|
||
}
|
||
|
||
StringDecoder.prototype.write = function (buf) {
|
||
if (buf.length === 0) return '';
|
||
var r;
|
||
var i;
|
||
if (this.lastNeed) {
|
||
r = this.fillLast(buf);
|
||
if (r === undefined) return '';
|
||
i = this.lastNeed;
|
||
this.lastNeed = 0;
|
||
} else {
|
||
i = 0;
|
||
}
|
||
if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i);
|
||
return r || '';
|
||
};
|
||
|
||
StringDecoder.prototype.end = utf8End;
|
||
|
||
// Returns only complete characters in a Buffer
|
||
StringDecoder.prototype.text = utf8Text;
|
||
|
||
// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer
|
||
StringDecoder.prototype.fillLast = function (buf) {
|
||
if (this.lastNeed <= buf.length) {
|
||
buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed);
|
||
return this.lastChar.toString(this.encoding, 0, this.lastTotal);
|
||
}
|
||
buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length);
|
||
this.lastNeed -= buf.length;
|
||
};
|
||
|
||
// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a
|
||
// continuation byte. If an invalid byte is detected, -2 is returned.
|
||
function utf8CheckByte(byte) {
|
||
if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4;
|
||
return byte >> 6 === 0x02 ? -1 : -2;
|
||
}
|
||
|
||
// Checks at most 3 bytes at the end of a Buffer in order to detect an
|
||
// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4)
|
||
// needed to complete the UTF-8 character (if applicable) are returned.
|
||
function utf8CheckIncomplete(self, buf, i) {
|
||
var j = buf.length - 1;
|
||
if (j < i) return 0;
|
||
var nb = utf8CheckByte(buf[j]);
|
||
if (nb >= 0) {
|
||
if (nb > 0) self.lastNeed = nb - 1;
|
||
return nb;
|
||
}
|
||
if (--j < i || nb === -2) return 0;
|
||
nb = utf8CheckByte(buf[j]);
|
||
if (nb >= 0) {
|
||
if (nb > 0) self.lastNeed = nb - 2;
|
||
return nb;
|
||
}
|
||
if (--j < i || nb === -2) return 0;
|
||
nb = utf8CheckByte(buf[j]);
|
||
if (nb >= 0) {
|
||
if (nb > 0) {
|
||
if (nb === 2) nb = 0;else self.lastNeed = nb - 3;
|
||
}
|
||
return nb;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
// Validates as many continuation bytes for a multi-byte UTF-8 character as
|
||
// needed or are available. If we see a non-continuation byte where we expect
|
||
// one, we "replace" the validated continuation bytes we've seen so far with
|
||
// a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding
|
||
// behavior. The continuation byte check is included three times in the case
|
||
// where all of the continuation bytes for a character exist in the same buffer.
|
||
// It is also done this way as a slight performance increase instead of using a
|
||
// loop.
|
||
function utf8CheckExtraBytes(self, buf, p) {
|
||
if ((buf[0] & 0xC0) !== 0x80) {
|
||
self.lastNeed = 0;
|
||
return '\ufffd';
|
||
}
|
||
if (self.lastNeed > 1 && buf.length > 1) {
|
||
if ((buf[1] & 0xC0) !== 0x80) {
|
||
self.lastNeed = 1;
|
||
return '\ufffd';
|
||
}
|
||
if (self.lastNeed > 2 && buf.length > 2) {
|
||
if ((buf[2] & 0xC0) !== 0x80) {
|
||
self.lastNeed = 2;
|
||
return '\ufffd';
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer.
|
||
function utf8FillLast(buf) {
|
||
var p = this.lastTotal - this.lastNeed;
|
||
var r = utf8CheckExtraBytes(this, buf, p);
|
||
if (r !== undefined) return r;
|
||
if (this.lastNeed <= buf.length) {
|
||
buf.copy(this.lastChar, p, 0, this.lastNeed);
|
||
return this.lastChar.toString(this.encoding, 0, this.lastTotal);
|
||
}
|
||
buf.copy(this.lastChar, p, 0, buf.length);
|
||
this.lastNeed -= buf.length;
|
||
}
|
||
|
||
// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a
|
||
// partial character, the character's bytes are buffered until the required
|
||
// number of bytes are available.
|
||
function utf8Text(buf, i) {
|
||
var total = utf8CheckIncomplete(this, buf, i);
|
||
if (!this.lastNeed) return buf.toString('utf8', i);
|
||
this.lastTotal = total;
|
||
var end = buf.length - (total - this.lastNeed);
|
||
buf.copy(this.lastChar, 0, end);
|
||
return buf.toString('utf8', i, end);
|
||
}
|
||
|
||
// For UTF-8, a replacement character is added when ending on a partial
|
||
// character.
|
||
function utf8End(buf) {
|
||
var r = buf && buf.length ? this.write(buf) : '';
|
||
if (this.lastNeed) return r + '\ufffd';
|
||
return r;
|
||
}
|
||
|
||
// UTF-16LE typically needs two bytes per character, but even if we have an even
|
||
// number of bytes available, we need to check if we end on a leading/high
|
||
// surrogate. In that case, we need to wait for the next two bytes in order to
|
||
// decode the last character properly.
|
||
function utf16Text(buf, i) {
|
||
if ((buf.length - i) % 2 === 0) {
|
||
var r = buf.toString('utf16le', i);
|
||
if (r) {
|
||
var c = r.charCodeAt(r.length - 1);
|
||
if (c >= 0xD800 && c <= 0xDBFF) {
|
||
this.lastNeed = 2;
|
||
this.lastTotal = 4;
|
||
this.lastChar[0] = buf[buf.length - 2];
|
||
this.lastChar[1] = buf[buf.length - 1];
|
||
return r.slice(0, -1);
|
||
}
|
||
}
|
||
return r;
|
||
}
|
||
this.lastNeed = 1;
|
||
this.lastTotal = 2;
|
||
this.lastChar[0] = buf[buf.length - 1];
|
||
return buf.toString('utf16le', i, buf.length - 1);
|
||
}
|
||
|
||
// For UTF-16LE we do not explicitly append special replacement characters if we
|
||
// end on a partial character, we simply let v8 handle that.
|
||
function utf16End(buf) {
|
||
var r = buf && buf.length ? this.write(buf) : '';
|
||
if (this.lastNeed) {
|
||
var end = this.lastTotal - this.lastNeed;
|
||
return r + this.lastChar.toString('utf16le', 0, end);
|
||
}
|
||
return r;
|
||
}
|
||
|
||
function base64Text(buf, i) {
|
||
var n = (buf.length - i) % 3;
|
||
if (n === 0) return buf.toString('base64', i);
|
||
this.lastNeed = 3 - n;
|
||
this.lastTotal = 3;
|
||
if (n === 1) {
|
||
this.lastChar[0] = buf[buf.length - 1];
|
||
} else {
|
||
this.lastChar[0] = buf[buf.length - 2];
|
||
this.lastChar[1] = buf[buf.length - 1];
|
||
}
|
||
return buf.toString('base64', i, buf.length - n);
|
||
}
|
||
|
||
function base64End(buf) {
|
||
var r = buf && buf.length ? this.write(buf) : '';
|
||
if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed);
|
||
return r;
|
||
}
|
||
|
||
// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex)
|
||
function simpleWrite(buf) {
|
||
return buf.toString(this.encoding);
|
||
}
|
||
|
||
function simpleEnd(buf) {
|
||
return buf && buf.length ? this.write(buf) : '';
|
||
}
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/timers-browserify/main.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/timers-browserify/main.js ***!
|
||
\************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(global) {var scope = (typeof global !== "undefined" && global) ||
|
||
(typeof self !== "undefined" && self) ||
|
||
window;
|
||
var apply = Function.prototype.apply;
|
||
|
||
// DOM APIs, for completeness
|
||
|
||
exports.setTimeout = function() {
|
||
return new Timeout(apply.call(setTimeout, scope, arguments), clearTimeout);
|
||
};
|
||
exports.setInterval = function() {
|
||
return new Timeout(apply.call(setInterval, scope, arguments), clearInterval);
|
||
};
|
||
exports.clearTimeout =
|
||
exports.clearInterval = function(timeout) {
|
||
if (timeout) {
|
||
timeout.close();
|
||
}
|
||
};
|
||
|
||
function Timeout(id, clearFn) {
|
||
this._id = id;
|
||
this._clearFn = clearFn;
|
||
}
|
||
Timeout.prototype.unref = Timeout.prototype.ref = function() {};
|
||
Timeout.prototype.close = function() {
|
||
this._clearFn.call(scope, this._id);
|
||
};
|
||
|
||
// Does not start the time, just sets up the members needed.
|
||
exports.enroll = function(item, msecs) {
|
||
clearTimeout(item._idleTimeoutId);
|
||
item._idleTimeout = msecs;
|
||
};
|
||
|
||
exports.unenroll = function(item) {
|
||
clearTimeout(item._idleTimeoutId);
|
||
item._idleTimeout = -1;
|
||
};
|
||
|
||
exports._unrefActive = exports.active = function(item) {
|
||
clearTimeout(item._idleTimeoutId);
|
||
|
||
var msecs = item._idleTimeout;
|
||
if (msecs >= 0) {
|
||
item._idleTimeoutId = setTimeout(function onTimeout() {
|
||
if (item._onTimeout)
|
||
item._onTimeout();
|
||
}, msecs);
|
||
}
|
||
};
|
||
|
||
// setimmediate attaches itself to the global object
|
||
__webpack_require__(/*! setimmediate */ "./node_modules/setimmediate/setImmediate.js");
|
||
// On some exotic environments, it's not clear which object `setimmediate` was
|
||
// able to install onto. Search each possibility in the same order as the
|
||
// `setimmediate` library.
|
||
exports.setImmediate = (typeof self !== "undefined" && self.setImmediate) ||
|
||
(typeof global !== "undefined" && global.setImmediate) ||
|
||
(this && this.setImmediate);
|
||
exports.clearImmediate = (typeof self !== "undefined" && self.clearImmediate) ||
|
||
(typeof global !== "undefined" && global.clearImmediate) ||
|
||
(this && this.clearImmediate);
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js")))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/util-deprecate/browser.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/util-deprecate/browser.js ***!
|
||
\************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(global) {
|
||
/**
|
||
* Module exports.
|
||
*/
|
||
|
||
module.exports = deprecate;
|
||
|
||
/**
|
||
* Mark that a method should not be used.
|
||
* Returns a modified function which warns once by default.
|
||
*
|
||
* If `localStorage.noDeprecation = true` is set, then it is a no-op.
|
||
*
|
||
* If `localStorage.throwDeprecation = true` is set, then deprecated functions
|
||
* will throw an Error when invoked.
|
||
*
|
||
* If `localStorage.traceDeprecation = true` is set, then deprecated functions
|
||
* will invoke `console.trace()` instead of `console.error()`.
|
||
*
|
||
* @param {Function} fn - the function to deprecate
|
||
* @param {String} msg - the string to print to the console when `fn` is invoked
|
||
* @returns {Function} a new "deprecated" version of `fn`
|
||
* @api public
|
||
*/
|
||
|
||
function deprecate (fn, msg) {
|
||
if (config('noDeprecation')) {
|
||
return fn;
|
||
}
|
||
|
||
var warned = false;
|
||
function deprecated() {
|
||
if (!warned) {
|
||
if (config('throwDeprecation')) {
|
||
throw new Error(msg);
|
||
} else if (config('traceDeprecation')) {
|
||
console.trace(msg);
|
||
} else {
|
||
console.warn(msg);
|
||
}
|
||
warned = true;
|
||
}
|
||
return fn.apply(this, arguments);
|
||
}
|
||
|
||
return deprecated;
|
||
}
|
||
|
||
/**
|
||
* Checks `localStorage` for boolean values for the given `name`.
|
||
*
|
||
* @param {String} name
|
||
* @returns {Boolean}
|
||
* @api private
|
||
*/
|
||
|
||
function config (name) {
|
||
// accessing global.localStorage can trigger a DOMException in sandboxed iframes
|
||
try {
|
||
if (!global.localStorage) return false;
|
||
} catch (_) {
|
||
return false;
|
||
}
|
||
var val = global.localStorage[name];
|
||
if (null == val) return false;
|
||
return String(val).toLowerCase() === 'true';
|
||
}
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js")))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/vm-browserify/index.js":
|
||
/*!*********************************************!*\
|
||
!*** ./node_modules/vm-browserify/index.js ***!
|
||
\*********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
var indexOf = function (xs, item) {
|
||
if (xs.indexOf) return xs.indexOf(item);
|
||
else for (var i = 0; i < xs.length; i++) {
|
||
if (xs[i] === item) return i;
|
||
}
|
||
return -1;
|
||
};
|
||
var Object_keys = function (obj) {
|
||
if (Object.keys) return Object.keys(obj)
|
||
else {
|
||
var res = [];
|
||
for (var key in obj) res.push(key)
|
||
return res;
|
||
}
|
||
};
|
||
|
||
var forEach = function (xs, fn) {
|
||
if (xs.forEach) return xs.forEach(fn)
|
||
else for (var i = 0; i < xs.length; i++) {
|
||
fn(xs[i], i, xs);
|
||
}
|
||
};
|
||
|
||
var defineProp = (function() {
|
||
try {
|
||
Object.defineProperty({}, '_', {});
|
||
return function(obj, name, value) {
|
||
Object.defineProperty(obj, name, {
|
||
writable: true,
|
||
enumerable: false,
|
||
configurable: true,
|
||
value: value
|
||
})
|
||
};
|
||
} catch(e) {
|
||
return function(obj, name, value) {
|
||
obj[name] = value;
|
||
};
|
||
}
|
||
}());
|
||
|
||
var globals = ['Array', 'Boolean', 'Date', 'Error', 'EvalError', 'Function',
|
||
'Infinity', 'JSON', 'Math', 'NaN', 'Number', 'Object', 'RangeError',
|
||
'ReferenceError', 'RegExp', 'String', 'SyntaxError', 'TypeError', 'URIError',
|
||
'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape',
|
||
'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'undefined', 'unescape'];
|
||
|
||
function Context() {}
|
||
Context.prototype = {};
|
||
|
||
var Script = exports.Script = function NodeScript (code) {
|
||
if (!(this instanceof Script)) return new Script(code);
|
||
this.code = code;
|
||
};
|
||
|
||
Script.prototype.runInContext = function (context) {
|
||
if (!(context instanceof Context)) {
|
||
throw new TypeError("needs a 'context' argument.");
|
||
}
|
||
|
||
var iframe = document.createElement('iframe');
|
||
if (!iframe.style) iframe.style = {};
|
||
iframe.style.display = 'none';
|
||
|
||
document.body.appendChild(iframe);
|
||
|
||
var win = iframe.contentWindow;
|
||
var wEval = win.eval, wExecScript = win.execScript;
|
||
|
||
if (!wEval && wExecScript) {
|
||
// win.eval() magically appears when this is called in IE:
|
||
wExecScript.call(win, 'null');
|
||
wEval = win.eval;
|
||
}
|
||
|
||
forEach(Object_keys(context), function (key) {
|
||
win[key] = context[key];
|
||
});
|
||
forEach(globals, function (key) {
|
||
if (context[key]) {
|
||
win[key] = context[key];
|
||
}
|
||
});
|
||
|
||
var winKeys = Object_keys(win);
|
||
|
||
var res = wEval.call(win, this.code);
|
||
|
||
forEach(Object_keys(win), function (key) {
|
||
// Avoid copying circular objects like `top` and `window` by only
|
||
// updating existing context properties or new properties in the `win`
|
||
// that was only introduced after the eval.
|
||
if (key in context || indexOf(winKeys, key) === -1) {
|
||
context[key] = win[key];
|
||
}
|
||
});
|
||
|
||
forEach(globals, function (key) {
|
||
if (!(key in context)) {
|
||
defineProp(context, key, win[key]);
|
||
}
|
||
});
|
||
|
||
document.body.removeChild(iframe);
|
||
|
||
return res;
|
||
};
|
||
|
||
Script.prototype.runInThisContext = function () {
|
||
return eval(this.code); // maybe...
|
||
};
|
||
|
||
Script.prototype.runInNewContext = function (context) {
|
||
var ctx = Script.createContext(context);
|
||
var res = this.runInContext(ctx);
|
||
|
||
if (context) {
|
||
forEach(Object_keys(ctx), function (key) {
|
||
context[key] = ctx[key];
|
||
});
|
||
}
|
||
|
||
return res;
|
||
};
|
||
|
||
forEach(Object_keys(Script.prototype), function (name) {
|
||
exports[name] = Script[name] = function (code) {
|
||
var s = Script(code);
|
||
return s[name].apply(s, [].slice.call(arguments, 1));
|
||
};
|
||
});
|
||
|
||
exports.isContext = function (context) {
|
||
return context instanceof Context;
|
||
};
|
||
|
||
exports.createScript = function (code) {
|
||
return exports.Script(code);
|
||
};
|
||
|
||
exports.createContext = Script.createContext = function (context) {
|
||
var copy = new Context();
|
||
if(typeof context === 'object') {
|
||
forEach(Object_keys(context), function (key) {
|
||
copy[key] = context[key];
|
||
});
|
||
}
|
||
return copy;
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/webpack/buildin/global.js":
|
||
/*!***********************************!*\
|
||
!*** (webpack)/buildin/global.js ***!
|
||
\***********************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
var g;
|
||
|
||
// This works in non-strict mode
|
||
g = (function() {
|
||
return this;
|
||
})();
|
||
|
||
try {
|
||
// This works if eval is allowed (see CSP)
|
||
g = g || new Function("return this")();
|
||
} catch (e) {
|
||
// This works if the window reference is available
|
||
if (typeof window === "object") g = window;
|
||
}
|
||
|
||
// g can still be undefined, but nothing to do about it...
|
||
// We return undefined, instead of nothing here, so it's
|
||
// easier to handle this case. if(!global) { ...}
|
||
|
||
module.exports = g;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/webpack/buildin/module.js":
|
||
/*!***********************************!*\
|
||
!*** (webpack)/buildin/module.js ***!
|
||
\***********************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
module.exports = function(module) {
|
||
if (!module.webpackPolyfill) {
|
||
module.deprecate = function() {};
|
||
module.paths = [];
|
||
// module.parent = undefined by default
|
||
if (!module.children) module.children = [];
|
||
Object.defineProperty(module, "loaded", {
|
||
enumerable: true,
|
||
get: function() {
|
||
return module.l;
|
||
}
|
||
});
|
||
Object.defineProperty(module, "id", {
|
||
enumerable: true,
|
||
get: function() {
|
||
return module.i;
|
||
}
|
||
});
|
||
module.webpackPolyfill = 1;
|
||
}
|
||
return module;
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/annotation.ts":
|
||
/*!***************************!*\
|
||
!*** ./src/annotation.ts ***!
|
||
\***************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
/* WEBPACK VAR INJECTION */(function(process, Buffer) {
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const parser_1 = __webpack_require__(/*! ./parser */ "./src/parser.ts");
|
||
const text_annotation_1 = __webpack_require__(/*! ./annotations/text_annotation */ "./src/annotations/text_annotation.ts");
|
||
const text_markup_annotation_1 = __webpack_require__(/*! ./annotations/text_markup_annotation */ "./src/annotations/text_markup_annotation.ts");
|
||
const freetext_annotation_1 = __webpack_require__(/*! ./annotations/freetext_annotation */ "./src/annotations/freetext_annotation.ts");
|
||
const circle_square_annotation_1 = __webpack_require__(/*! ./annotations/circle_square_annotation */ "./src/annotations/circle_square_annotation.ts");
|
||
const polygon_polyline_annotation_1 = __webpack_require__(/*! ./annotations/polygon_polyline_annotation */ "./src/annotations/polygon_polyline_annotation.ts");
|
||
const ink_annotation_1 = __webpack_require__(/*! ./annotations/ink_annotation */ "./src/annotations/ink_annotation.ts");
|
||
const util_1 = __webpack_require__(/*! ./util */ "./src/util.ts");
|
||
const writer_1 = __webpack_require__(/*! ./writer */ "./src/writer.ts");
|
||
class ParameterParser {
|
||
/**
|
||
* Parses and checks the parameter. This is for backward compatibility and to support arbitrary annotation parameters
|
||
* */
|
||
static parseParameters(values) {
|
||
if (values.length === 0) {
|
||
throw Error("No parameters provided");
|
||
}
|
||
let i = 0;
|
||
if (typeof values[i] === 'number') {
|
||
let ret_val = {};
|
||
ret_val.page = values[i++];
|
||
ret_val.rect = values[i++];
|
||
ret_val.contents = values[i++];
|
||
if (typeof ret_val.contents !== 'string') {
|
||
throw Error("Invalid contents parameter");
|
||
}
|
||
ret_val.author = values[i++];
|
||
if (typeof ret_val.author !== 'string') {
|
||
throw Error("Invalid author parameter");
|
||
}
|
||
if (i >= values.length)
|
||
return ret_val;
|
||
if ("r" in values[i] && "g" in values[i] && "b" in values[i]) {
|
||
ret_val.color = values[i++];
|
||
}
|
||
else if (Array.isArray(values[i]) && values[i].length > 0 && typeof values[i][0] === 'number') {
|
||
ret_val.vertices = values[i++];
|
||
}
|
||
else if (Array.isArray(values[i]) && values[i].length > 0 && Array.isArray(values[i][0])) {
|
||
ret_val.inkList = values[i++];
|
||
}
|
||
else {
|
||
throw Error("Invalid parameter provided - is neither color, nor quadpoints array or an inklist");
|
||
}
|
||
if (i >= values.length)
|
||
return ret_val;
|
||
if ("r" in values[i] && "g" in values[i] && "b" in values[i]) {
|
||
if (ret_val.color) {
|
||
ret_val.fill = values[i++];
|
||
}
|
||
else {
|
||
ret_val.color = values[i++];
|
||
}
|
||
}
|
||
else if (Array.isArray(values[i]) && values[i].length > 0 && typeof values[i][0] === 'number') {
|
||
ret_val.quadPoints = values[i++];
|
||
}
|
||
else if (typeof values[i] === 'object') {
|
||
ret_val.config = true;
|
||
ret_val = Object.assign(ret_val, values[i++]);
|
||
}
|
||
else {
|
||
throw Error("Invalid parameter provided");
|
||
}
|
||
if (i >= values.length)
|
||
return ret_val;
|
||
if (!ret_val.config && typeof values[i] === 'object') {
|
||
ret_val = Object.assign(ret_val, values[i++]);
|
||
}
|
||
else {
|
||
throw Error("Invalid configuration provided");
|
||
}
|
||
return ret_val;
|
||
}
|
||
else if (typeof values[i] === 'object') {
|
||
return values[0];
|
||
}
|
||
else {
|
||
throw Error("Invalid configuration object");
|
||
}
|
||
}
|
||
}
|
||
exports.ParameterParser = ParameterParser;
|
||
/**
|
||
* The annotation factory provides methods to create annotations. Those are stored temporarily
|
||
* and than encoded into PDF code when the PDF document is written.
|
||
* */
|
||
class AnnotationFactory {
|
||
constructor(data, userPassword = "", ownerPassword = "") {
|
||
this.data = data;
|
||
this.userPassword = userPassword;
|
||
this.ownerPassword = ownerPassword;
|
||
this.annotations = [];
|
||
this.toDelete = [];
|
||
this.data = data;
|
||
this.parser = new parser_1.PDFDocumentParser(this.data, this.userPassword, this.ownerPassword);
|
||
}
|
||
/**
|
||
* Returns the number of annotations that will be added to the PDF document
|
||
* */
|
||
getAnnotationCount() {
|
||
return this.annotations.length;
|
||
}
|
||
/**
|
||
* Load a PDF file referenced by the given 'path'
|
||
* */
|
||
static loadFile(path, userPassword = "", ownerPassword = "") {
|
||
return new Promise((resolve) => {
|
||
if (typeof window !== 'undefined') { // browser environment
|
||
fetch(path).then((r) => r.blob()).then((data) => {
|
||
let reader = new FileReader();
|
||
reader.onload = () => {
|
||
resolve(new AnnotationFactory(reader.result, userPassword, ownerPassword));
|
||
};
|
||
reader.readAsArrayBuffer(data);
|
||
});
|
||
}
|
||
else if (typeof process === 'object') { // node environment
|
||
let fs = __webpack_require__(/*! fs */ "./node_modules/node-libs-browser/mock/empty.js");
|
||
let data = fs.readFileSync(path);
|
||
resolve(new AnnotationFactory(data, userPassword, ownerPassword));
|
||
}
|
||
else {
|
||
throw Error("Unsupported environment");
|
||
}
|
||
});
|
||
}
|
||
/**
|
||
* Generates a unique identifier necessary for creating the annotation
|
||
* */
|
||
generateUniqueIdentifier() {
|
||
return "pdfAnnotate-" + util_1.Util.convertDateToPDFDate(new Date()).slice(3, 17) + "-" + this.annotations.length;
|
||
}
|
||
/**
|
||
* Generates a default border
|
||
* */
|
||
createDefaultBorder() {
|
||
return {
|
||
vertical_corner_radius: 0,
|
||
horizontal_corner_radius: 0,
|
||
border_width: 1
|
||
};
|
||
}
|
||
/**
|
||
* Writes the created annotations into a bytestream
|
||
* */
|
||
write() {
|
||
if (this.annotations.length === 0 && this.toDelete.length === 0)
|
||
return this.data;
|
||
let writer = new writer_1.Writer(this.data, this.annotations, this.toDelete, this.parser);
|
||
return writer.write();
|
||
}
|
||
/**
|
||
* Checks the 'rect' parameter, whether all the entries are of type number and if the the number of entries is correct
|
||
* */
|
||
checkRect(nr, rect) {
|
||
if (!Array.isArray(rect)) {
|
||
throw Error("invalid rect parameter");
|
||
}
|
||
if (rect.length !== nr)
|
||
throw Error("Rect has invalid number of entries: " + rect + " has " + rect.length + " entries, but should have " + nr + " entries");
|
||
rect.forEach((a) => {
|
||
if ('number' !== typeof a)
|
||
throw Error("Rect " + rect + " has invalid entry: " + a);
|
||
});
|
||
}
|
||
/**
|
||
* Creates a base annotation that means the raw object of annotation or those parts that exist
|
||
* in equal form in all types of annotations
|
||
* */
|
||
createBaseAnnotation(page) {
|
||
if (page < 0) {
|
||
throw Error(`Invalid page number: ${page}`);
|
||
}
|
||
let annot = {
|
||
object_id: this.parser.getFreeObjectId(),
|
||
id: this.generateUniqueIdentifier(),
|
||
pageReference: this.parser.getPage(page),
|
||
updateDate: util_1.Util.convertDateToPDFDate(new Date()),
|
||
border: this.createDefaultBorder(),
|
||
page: page, rect: []
|
||
};
|
||
return annot;
|
||
}
|
||
/**
|
||
* Creates a text annotation
|
||
* page : the number of the PDF document page, where the annotation must be attached
|
||
* rect : the position of the annotation on the page
|
||
* contents : the content of the annotation
|
||
* author : the author of the annotation
|
||
* color : the color of the annotation in rgb. Can be of domain 0 - 255 or 0 - 1
|
||
* options : dictionary containing additional configuration values, see documentation
|
||
* */
|
||
createTextAnnotation(...values) {
|
||
let params = ParameterParser.parseParameters(values);
|
||
let annot = new text_annotation_1.TextAnnotationObj();
|
||
annot = Object.assign(annot, this.createBaseAnnotation(params.page));
|
||
annot = Object.assign(annot, params);
|
||
annot.validate();
|
||
this.annotations.push(annot);
|
||
}
|
||
/**
|
||
* Creates a highlight annotation
|
||
* page : the number of the PDF document page, where the annotation must be attached
|
||
* rect : the position of the annotation on the page
|
||
* contents : the content of the annotation
|
||
* author : the author of the annotation
|
||
* color : the color of the annotation in rgb. Can be of domain 0 - 255 or 0 - 1
|
||
* quadPoints : regions to mark with the highlight
|
||
* */
|
||
createHighlightAnnotation(...values) {
|
||
let params = ParameterParser.parseParameters(values);
|
||
let annot = new text_markup_annotation_1.HighlightAnnotationObj();
|
||
annot = Object.assign(annot, this.createBaseAnnotation(params.page));
|
||
annot = Object.assign(annot, params);
|
||
annot.validate();
|
||
this.annotations.push(annot);
|
||
}
|
||
/**
|
||
* Creates an underline annotation
|
||
* page : the number of the PDF document page, where the annotation must be attached
|
||
* rect : the position of the annotation on the page
|
||
* contents : the content of the annotation
|
||
* author : the author of the annotation
|
||
* color : the color of the annotation in rgb. Can be of domain 0 - 255 or 0 - 1
|
||
* quadPoints : regions to mark with the highlight
|
||
* */
|
||
createUnderlineAnnotation(...values) {
|
||
let params = ParameterParser.parseParameters(values);
|
||
let annot = new text_markup_annotation_1.UnderlineAnnotationObj();
|
||
annot = Object.assign(annot, this.createBaseAnnotation(params.page));
|
||
annot = Object.assign(annot, params);
|
||
annot.validate();
|
||
this.annotations.push(annot);
|
||
}
|
||
/**
|
||
* Creates a squiggle annotation
|
||
* page : the number of the PDF document page, where the annotation must be attached
|
||
* rect : the position of the annotation on the page
|
||
* contents : the content of the annotation
|
||
* author : the author of the annotation
|
||
* color : the color of the annotation in rgb. Can be of domain 0 - 255 or 0 - 1
|
||
* quadPoints : regions to mark with the highlight
|
||
* */
|
||
createSquigglyAnnotation(...values) {
|
||
let params = ParameterParser.parseParameters(values);
|
||
let annot = new text_markup_annotation_1.SquigglyAnnotationObj();
|
||
annot = Object.assign(annot, this.createBaseAnnotation(params.page));
|
||
annot = Object.assign(annot, params);
|
||
annot.validate();
|
||
this.annotations.push(annot);
|
||
}
|
||
/**
|
||
* Creates a strike out annotation
|
||
* page : the number of the PDF document page, where the annotation must be attached
|
||
* rect : the position of the annotation on the page
|
||
* contents : the content of the annotation
|
||
* author : the author of the annotation
|
||
* color : the color of the annotation in rgb. Can be of domain 0 - 255 or 0 - 1
|
||
* quadPoints : regions to mark with the highlight
|
||
* */
|
||
createStrikeOutAnnotation(...values) {
|
||
let params = ParameterParser.parseParameters(values);
|
||
let annot = new text_markup_annotation_1.StrikeOutAnnotationObj();
|
||
annot = Object.assign(annot, this.createBaseAnnotation(params.page));
|
||
annot = Object.assign(annot, params);
|
||
annot.validate();
|
||
this.annotations.push(annot);
|
||
}
|
||
/**
|
||
* Creates a free text annotation
|
||
* page : the number of the PDF document page, where the annotation must be attached
|
||
* rect : the position of the annotation on the page
|
||
* contents : the content of the annotation
|
||
* author : the author of the annotation
|
||
* color : the color of the annotation in rgb. Can be of domain 0 - 255 or 0 - 1
|
||
* */
|
||
createFreeTextAnnotation(...values) {
|
||
let params = ParameterParser.parseParameters(values);
|
||
let annot = new freetext_annotation_1.FreeTextAnnotationObj();
|
||
annot = Object.assign(annot, this.createBaseAnnotation(params.page));
|
||
annot = Object.assign(annot, params);
|
||
annot.validate();
|
||
this.annotations.push(annot);
|
||
}
|
||
createLineAnnotation() {
|
||
throw Error("No yet implemented");
|
||
}
|
||
/**
|
||
* Creates a square annotation
|
||
* page : the number of the PDF document page, where the annotation must be attached
|
||
* rect : the position of the annotation on the page
|
||
* contents : the content of the annotation
|
||
* author : the author of the annotation
|
||
* color : the color of the annotation in rgb. Can be of domain 0 - 255 or 0 - 1
|
||
* fill : the filling color of the annotation in rgb. Can be of domain 0 - 255 or 0 - 1
|
||
* */
|
||
createSquareAnnotation(...values) {
|
||
let params = ParameterParser.parseParameters(values);
|
||
let annot = new circle_square_annotation_1.SquareAnnotationObj();
|
||
annot = Object.assign(annot, this.createBaseAnnotation(params.page));
|
||
annot = Object.assign(annot, params);
|
||
annot.validate();
|
||
this.annotations.push(annot);
|
||
}
|
||
/**
|
||
* Creates a circle annotation
|
||
* page : the number of the PDF document page, where the annotation must be attached
|
||
* rect : the position of the annotation on the page
|
||
* contents : the content of the annotation
|
||
* author : the author of the annotation
|
||
* color : the color of the annotation in rgb. Can be of domain 0 - 255 or 0 - 1
|
||
* fill : the filling color of the annotation in rgb. Can be of domain 0 - 255 or 0 - 1
|
||
* */
|
||
createCircleAnnotation(...values) {
|
||
let params = ParameterParser.parseParameters(values);
|
||
let annot = new circle_square_annotation_1.CircleAnnotationObj();
|
||
annot = Object.assign(annot, this.createBaseAnnotation(params.page));
|
||
annot = Object.assign(annot, params);
|
||
annot.validate();
|
||
this.annotations.push(annot);
|
||
}
|
||
/**
|
||
* Creates a polygon annotation
|
||
* page : the number of the PDF document page, where the annotation must be attached
|
||
* rect : the position of the annotation on the page
|
||
* contents : the content of the annotation
|
||
* author : the author of the annotation
|
||
* vertices : the vertices defining the arrangement of the object
|
||
* color : the color of the annotation in rgb. Can be of domain 0 - 255 or 0 - 1
|
||
* */
|
||
createPolygonAnnotation(...values) {
|
||
let params = ParameterParser.parseParameters(values);
|
||
let annot = new polygon_polyline_annotation_1.PolygonAnnotationObj();
|
||
annot = Object.assign(annot, this.createBaseAnnotation(params.page));
|
||
annot = Object.assign(annot, params);
|
||
annot.validate();
|
||
this.annotations.push(annot);
|
||
}
|
||
/**
|
||
* Creates a polyline annotation
|
||
* page : the number of the PDF document page, where the annotation must be attached
|
||
* rect : the position of the annotation on the page
|
||
* contents : the content of the annotation
|
||
* author : the author of the annotation
|
||
* vertices : the vertices defining the arrangement of the object
|
||
* color : the color of the annotation in rgb. Can be of domain 0 - 255 or 0 - 1
|
||
* */
|
||
createPolyLineAnnotation(...values) {
|
||
let params = ParameterParser.parseParameters(values);
|
||
let annot = new polygon_polyline_annotation_1.PolyLineAnnotationObj();
|
||
annot = Object.assign(annot, this.createBaseAnnotation(params.page));
|
||
annot = Object.assign(annot, params);
|
||
annot.validate();
|
||
this.annotations.push(annot);
|
||
}
|
||
/**
|
||
* Creates an ink annotation
|
||
* page : the number of the PDF document page, where the annotation must be attached
|
||
* rect : the position of the annotation on the page
|
||
* contents : the content of the annotation
|
||
* author : the author of the annotation
|
||
* inkList : a list of list containing the points for drawing the lines
|
||
* color : the color of the annotation in rgb. Can be of domain 0 - 255 or 0 - 1
|
||
* */
|
||
createInkAnnotation(...values) {
|
||
let params = ParameterParser.parseParameters(values);
|
||
let annot = new ink_annotation_1.InkAnnotationObj();
|
||
annot = Object.assign(annot, this.createBaseAnnotation(params.page));
|
||
annot = Object.assign(annot, params);
|
||
annot.validate();
|
||
this.annotations.push(annot);
|
||
}
|
||
/**
|
||
* Creates a stamp annotation. There exists a number of predifined stamps that can be attached to PDF documents.
|
||
* page : the number of the PDF document page, where the annotation must be attached
|
||
* contents : the content of the annotation
|
||
* author : the author of the annotation
|
||
* stampType : the name of the used stamp type. Can be: [Approved, Experimental, NotApproved, AsIs, Expired, NotForPublicRelease, Confidential, Final, Sold, Departmental, ForComment, TopSecret, Draft, ForPublicRelease]
|
||
* color : the color of the annotation in rgb. Can be of domain 0 - 255 or 0 - 1
|
||
* */
|
||
createStampAnnotation(...values) {
|
||
let params = ParameterParser.parseParameters(values);
|
||
let annot = Object.assign(this.createBaseAnnotation(params.page), {
|
||
opacity: 1,
|
||
initiallyOpen: false,
|
||
annotation_flag: 4,
|
||
color: params.color,
|
||
stampType: params.stampType
|
||
});
|
||
annot.type = "/Stamp";
|
||
this.annotations.push(annot);
|
||
}
|
||
/**
|
||
* Creates a visual symbol that indcates the existance of text edits.
|
||
* page : the number of the PDF document page, where the annotation must be attached
|
||
* contents : the content of the annotation
|
||
* author : the author of the annotation
|
||
* caretSymbol : None or P, with P for using the paragraph symbol as caret
|
||
* color : the color of the annotation in rgb. Can be of domain 0 - 255 or 0 - 1
|
||
* */
|
||
createCaretAnnotation(...values) {
|
||
let params = ParameterParser.parseParameters(values);
|
||
let annot = Object.assign(this.createBaseAnnotation(params.page), {
|
||
opacity: 1,
|
||
initiallyOpen: false,
|
||
annotation_flag: 4,
|
||
color: params.color,
|
||
caretSymbol: params.caretSymbol
|
||
});
|
||
annot.type = "/Caret";
|
||
this.annotations.push(annot);
|
||
}
|
||
createPopupAnnotation() {
|
||
throw Error("No yet implemented");
|
||
}
|
||
/**
|
||
* Deletes the annotation with the given id or the given reference object
|
||
* */
|
||
deleteAnnotation(id) {
|
||
return new Promise((resolve) => {
|
||
// delete if it was just created but is not in the pdf document
|
||
for (let i = 0; i < this.annotations.length; ++i) {
|
||
if ('string' === typeof id && this.annotations[i].id === id) {
|
||
this.annotations = this.annotations.slice(i, 1);
|
||
resolve(this.toDelete);
|
||
return;
|
||
}
|
||
else if (id.obj && this.annotations[i].object_id && id.obj === this.annotations[i].object_id.obj && id.generation && id.generation === this.annotations[i].object_id.generation) {
|
||
this.annotations = this.annotations.slice(i, 1);
|
||
resolve(this.toDelete);
|
||
return;
|
||
}
|
||
}
|
||
this.getAnnotations().then((annots) => {
|
||
for (let _annots of annots) {
|
||
for (let annot of _annots) {
|
||
if ('string' === typeof id && annot.id === id) {
|
||
this.toDelete.push(annot);
|
||
resolve(this.toDelete);
|
||
return;
|
||
}
|
||
else if (id.obj && annot.object_id && id.obj === annot.object_id.obj && id.generation && id.generation === annot.object_id.generation) {
|
||
this.toDelete.push(annot);
|
||
resolve(this.toDelete);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
});
|
||
}
|
||
/**
|
||
* Returns a promise with all the annotations that are part of the document. This
|
||
* comprises annotations, that are already part of the parsed document and those that were created using this library and
|
||
* not yet appended to the document.
|
||
* */
|
||
getAnnotations() {
|
||
return new Promise((resolve) => {
|
||
let existingAnnots = this.parser.extractAnnotations();
|
||
for (let newAnnot of this.annotations) {
|
||
existingAnnots[newAnnot.page].push(newAnnot);
|
||
}
|
||
resolve(existingAnnots);
|
||
});
|
||
}
|
||
/**
|
||
* Downloads the adapted PDF document
|
||
* */
|
||
download(fileName = "output.pdf") {
|
||
let a = document.createElement("a");
|
||
document.body.appendChild(a);
|
||
a.style = "display: none";
|
||
let extended_pdf = this.write();
|
||
let blob = new Blob([extended_pdf], { type: "application/pdf" });
|
||
let url = window.URL.createObjectURL(blob);
|
||
a.href = url;
|
||
a.download = fileName;
|
||
a.click();
|
||
a.remove();
|
||
window.URL.revokeObjectURL(url);
|
||
}
|
||
/**
|
||
* Saves the adapted PDF document in a nodejs environment and downloads it in a browser environment.
|
||
* */
|
||
save(fileName = "output.pdf") {
|
||
if (typeof window !== 'undefined') { // browser environment
|
||
this.download(fileName);
|
||
}
|
||
else if (typeof process === 'object') { // node environment
|
||
const fs = __webpack_require__(/*! fs */ "./node_modules/node-libs-browser/mock/empty.js");
|
||
let data = this.write();
|
||
fs.writeFile(fileName, Buffer.from(new Uint8Array(data)), (err) => {
|
||
if (err) {
|
||
throw Error(err);
|
||
}
|
||
});
|
||
}
|
||
else {
|
||
throw Error("Unsupported environment");
|
||
}
|
||
}
|
||
}
|
||
exports.AnnotationFactory = AnnotationFactory;
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../node_modules/process/browser.js */ "./node_modules/process/browser.js"), __webpack_require__(/*! ./../node_modules/buffer/index.js */ "./node_modules/buffer/index.js").Buffer))
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/annotations/annotation_errors.ts":
|
||
/*!**********************************************!*\
|
||
!*** ./src/annotations/annotation_errors.ts ***!
|
||
\**********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
class InvalidAnnotationTypeError extends Error {
|
||
constructor(message) {
|
||
super(message);
|
||
this.message = message;
|
||
this.name = "InvalidAnnotationTypeError";
|
||
}
|
||
}
|
||
exports.InvalidAnnotationTypeError = InvalidAnnotationTypeError;
|
||
class InvalidOpacityError extends Error {
|
||
constructor(message) {
|
||
super(message);
|
||
this.message = message;
|
||
this.name = "InvalidOpacityError";
|
||
}
|
||
}
|
||
exports.InvalidOpacityError = InvalidOpacityError;
|
||
class InvalidColorError extends Error {
|
||
constructor(message) {
|
||
super(message);
|
||
this.message = message;
|
||
this.name = "InvalidColorError";
|
||
}
|
||
}
|
||
exports.InvalidColorError = InvalidColorError;
|
||
class ColorOutOfRangeError extends Error {
|
||
constructor(message) {
|
||
super(message);
|
||
this.message = message;
|
||
this.name = "ColorOutOfRangeError";
|
||
}
|
||
}
|
||
exports.ColorOutOfRangeError = ColorOutOfRangeError;
|
||
class InvalidReferencePointerError extends Error {
|
||
constructor(message) {
|
||
super(message);
|
||
this.message = message;
|
||
this.name = "InvalidReferencePointerError";
|
||
}
|
||
}
|
||
exports.InvalidReferencePointerError = InvalidReferencePointerError;
|
||
class InvalidDateError extends Error {
|
||
constructor(message) {
|
||
super(message);
|
||
this.message = message;
|
||
this.name = "InvalidDateError";
|
||
}
|
||
}
|
||
exports.InvalidDateError = InvalidDateError;
|
||
class InvalidRectError extends Error {
|
||
constructor(message) {
|
||
super(message);
|
||
this.message = message;
|
||
this.name = "InvalidRectError";
|
||
}
|
||
}
|
||
exports.InvalidRectError = InvalidRectError;
|
||
class InvalidIDError extends Error {
|
||
constructor(message) {
|
||
super(message);
|
||
this.message = message;
|
||
this.name = "InvalidIDError";
|
||
}
|
||
}
|
||
exports.InvalidIDError = InvalidIDError;
|
||
class InvalidStateError extends Error {
|
||
constructor(message) {
|
||
super(message);
|
||
this.message = message;
|
||
this.name = "InvalidStateError";
|
||
}
|
||
}
|
||
exports.InvalidStateError = InvalidStateError;
|
||
class InvalidQuadPointError extends Error {
|
||
constructor(message) {
|
||
super(message);
|
||
this.message = message;
|
||
this.name = "InvalidQuadPointError";
|
||
}
|
||
}
|
||
exports.InvalidQuadPointError = InvalidQuadPointError;
|
||
class InvalidVerticesError extends Error {
|
||
constructor(message) {
|
||
super(message);
|
||
this.message = message;
|
||
this.name = "InvalidVerticesError";
|
||
}
|
||
}
|
||
exports.InvalidVerticesError = InvalidVerticesError;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/annotations/annotation_types.ts":
|
||
/*!*********************************************!*\
|
||
!*** ./src/annotations/annotation_types.ts ***!
|
||
\*********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const util_1 = __webpack_require__(/*! ../util */ "./src/util.ts");
|
||
const annotation_errors_1 = __webpack_require__(/*! ./annotation_errors */ "./src/annotations/annotation_errors.ts");
|
||
const writer_util_1 = __webpack_require__(/*! ../writer-util */ "./src/writer-util.ts");
|
||
var LineEndingStyle;
|
||
(function (LineEndingStyle) {
|
||
LineEndingStyle[LineEndingStyle["Square"] = 0] = "Square";
|
||
LineEndingStyle[LineEndingStyle["Circle"] = 1] = "Circle";
|
||
LineEndingStyle[LineEndingStyle["Diamond"] = 2] = "Diamond";
|
||
LineEndingStyle[LineEndingStyle["OpenArrow"] = 3] = "OpenArrow";
|
||
LineEndingStyle[LineEndingStyle["ClosedArrow"] = 4] = "ClosedArrow";
|
||
LineEndingStyle[LineEndingStyle["Butt"] = 5] = "Butt";
|
||
LineEndingStyle[LineEndingStyle["ROpenArrow"] = 6] = "ROpenArrow";
|
||
LineEndingStyle[LineEndingStyle["RClosedArrow"] = 7] = "RClosedArrow";
|
||
LineEndingStyle[LineEndingStyle["Slash"] = 8] = "Slash";
|
||
LineEndingStyle[LineEndingStyle["None"] = 9] = "None";
|
||
})(LineEndingStyle = exports.LineEndingStyle || (exports.LineEndingStyle = {}));
|
||
var BorderStyles;
|
||
(function (BorderStyles) {
|
||
BorderStyles[BorderStyles["Solid"] = 0] = "Solid";
|
||
BorderStyles[BorderStyles["Dashed"] = 1] = "Dashed";
|
||
BorderStyles[BorderStyles["Beveled"] = 2] = "Beveled";
|
||
BorderStyles[BorderStyles["Inset"] = 3] = "Inset";
|
||
BorderStyles[BorderStyles["Underline"] = 4] = "Underline";
|
||
})(BorderStyles = exports.BorderStyles || (exports.BorderStyles = {}));
|
||
class BaseAnnotationObj {
|
||
constructor() {
|
||
this.object_id = undefined; // an unused object id
|
||
this.is_deleted = false; // internal flag to determine whether the annotation was deleted
|
||
this.page = -1;
|
||
this.pageReference = undefined; // The reference to the page object to which the annotation is added
|
||
this.type = "";
|
||
this.type_encoded = [];
|
||
this.rect = [];
|
||
this.contents = "";
|
||
this.id = ""; // /NM
|
||
this.updateDate = ""; // /M
|
||
}
|
||
writeAnnotationPreamble() {
|
||
let ret = writer_util_1.WriterUtil.writeReferencePointer(this.object_id);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.OBJ);
|
||
ret.push(writer_util_1.WriterUtil.CR);
|
||
ret.push(writer_util_1.WriterUtil.LF);
|
||
ret = ret.concat(writer_util_1.WriterUtil.DICT_START);
|
||
ret = ret.concat(writer_util_1.WriterUtil.TYPE_ANNOT);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
return ret;
|
||
}
|
||
writeAnnotationObject(cryptoInterface) {
|
||
let ret = [];
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.PAGE_REFERENCE);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.writeReferencePointer(this.pageReference.object_id, true));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.SUBTYPE);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(this.type_encoded);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.RECT);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.writeNumberArray(this.rect));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.CONTENTS);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_START);
|
||
ret = ret.concat(Array.from(util_1.Util.escapeString(cryptoInterface.encrypt(new Uint8Array(util_1.Util.convertStringToAscii(this.contents)), this.object_id))));
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_END);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.ID);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_START);
|
||
ret = ret.concat(Array.from(util_1.Util.escapeString(cryptoInterface.encrypt(new Uint8Array(util_1.Util.convertStringToAscii(this.id)), this.object_id))));
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_END);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.UPDATE_DATE);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_START);
|
||
ret = ret.concat(Array.from(util_1.Util.escapeString(cryptoInterface.encrypt(new Uint8Array(util_1.Util.convertStringToAscii(this.updateDate)), this.object_id))));
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_END);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
if (this.annotationFlags) {
|
||
let flags_value = this.encodeAnnotationFlags();
|
||
ret = ret.concat(writer_util_1.WriterUtil.FLAG);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(util_1.Util.convertNumberToCharArray(flags_value));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
if (this.border) {
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.BORDER);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.writeNumberArray([this.border.horizontal_corner_radius || 0, this.border.vertical_corner_radius || 0, this.border.border_width || 1]));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
if (this.color) {
|
||
if (this.color.r > 1)
|
||
this.color.r /= 255;
|
||
if (this.color.g > 1)
|
||
this.color.g /= 255;
|
||
if (this.color.b > 1)
|
||
this.color.b /= 255;
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.COLOR);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.writeNumberArray([this.color.r, this.color.g, this.color.b]));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
if (this.raw_parameters && this.raw_parameters.length > 0) {
|
||
for (let i of this.raw_parameters) {
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(i);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
}
|
||
return ret;
|
||
}
|
||
convertLineEndingStyle(lne) {
|
||
switch (lne) {
|
||
case LineEndingStyle.Square:
|
||
return util_1.Util.convertStringToAscii("/Square");
|
||
case LineEndingStyle.Circle:
|
||
return util_1.Util.convertStringToAscii("/Circle");
|
||
case LineEndingStyle.Diamond:
|
||
return util_1.Util.convertStringToAscii("/Diamond");
|
||
case LineEndingStyle.OpenArrow:
|
||
return util_1.Util.convertStringToAscii("/OpenArrow");
|
||
case LineEndingStyle.ClosedArrow:
|
||
return util_1.Util.convertStringToAscii("/ClosedArrow");
|
||
case LineEndingStyle.Butt:
|
||
return util_1.Util.convertStringToAscii("/Butt");
|
||
case LineEndingStyle.ROpenArrow:
|
||
return util_1.Util.convertStringToAscii("/ROpenArrow");
|
||
case LineEndingStyle.RClosedArrow:
|
||
return util_1.Util.convertStringToAscii("/RClosedArrow");
|
||
case LineEndingStyle.Slash:
|
||
return util_1.Util.convertStringToAscii("/Slash");
|
||
default:
|
||
return util_1.Util.convertStringToAscii("/None");
|
||
}
|
||
}
|
||
writeAnnotationPostamble() {
|
||
let ret = writer_util_1.WriterUtil.DICT_END;
|
||
ret.push(writer_util_1.WriterUtil.CR);
|
||
ret.push(writer_util_1.WriterUtil.LF);
|
||
ret = ret.concat(writer_util_1.WriterUtil.ENDOBJ);
|
||
ret.push(writer_util_1.WriterUtil.CR);
|
||
ret.push(writer_util_1.WriterUtil.LF);
|
||
return ret;
|
||
}
|
||
encodeAnnotationFlags() {
|
||
if (!this.annotationFlags) {
|
||
return 0;
|
||
}
|
||
let val = 0;
|
||
if (this.annotationFlags.invisible) {
|
||
val |= 1;
|
||
}
|
||
if (this.annotationFlags.hidden) {
|
||
val |= 2;
|
||
}
|
||
if (this.annotationFlags.print) {
|
||
val |= 4;
|
||
}
|
||
if (this.annotationFlags.noZoom) {
|
||
val |= 8;
|
||
}
|
||
if (this.annotationFlags.noRotate) {
|
||
val |= 16;
|
||
}
|
||
if (this.annotationFlags.noView) {
|
||
val |= 32;
|
||
}
|
||
if (this.annotationFlags.readOnly) {
|
||
val |= 64;
|
||
}
|
||
if (this.annotationFlags.locked) {
|
||
val |= 128;
|
||
}
|
||
if (this.annotationFlags.toggleNoView) {
|
||
val |= 256;
|
||
}
|
||
if (this.annotationFlags.lockedContents) {
|
||
val |= 512;
|
||
}
|
||
return val;
|
||
}
|
||
/**
|
||
* If enact is true, the error will be thrown directly, otherwise the errors are collected
|
||
* and returned as error list.
|
||
* */
|
||
validate(enact = true) {
|
||
let errorList = this.checkRect(4, this.rect);
|
||
errorList = errorList.concat(this.checkReferencePointer(this.object_id));
|
||
if (!this.pageReference || typeof this.pageReference !== 'object') {
|
||
errorList.push(new annotation_errors_1.InvalidReferencePointerError("Inalid page reference"));
|
||
}
|
||
let res = this.checkDate(this.updateDate);
|
||
if (res[1]) {
|
||
this.updateDate = res[1];
|
||
}
|
||
errorList = errorList.concat(res[0]);
|
||
errorList = errorList.concat(this.checkColor(this.color));
|
||
if (!this.id || this.id === "") {
|
||
errorList.push(new annotation_errors_1.InvalidIDError("Invalid ID provided"));
|
||
}
|
||
if (enact) {
|
||
for (let error of errorList) {
|
||
throw error;
|
||
}
|
||
}
|
||
return errorList;
|
||
}
|
||
checkColor(color) {
|
||
let errorList = [];
|
||
if (!color) {
|
||
return errorList;
|
||
}
|
||
if (!(color && "r" in color && "g" in color && "b" in color)) {
|
||
errorList.push(new annotation_errors_1.InvalidColorError("Not {r: <r>, g: <g>, b: <b>}"));
|
||
}
|
||
if (color.r > 255 || color.r < 0) {
|
||
errorList.push(new annotation_errors_1.ColorOutOfRangeError("Red value out of range"));
|
||
}
|
||
if (color.g > 255 || color.g < 0) {
|
||
errorList.push(new annotation_errors_1.ColorOutOfRangeError("Green value out of range"));
|
||
}
|
||
if (color.b > 255 && color.b < 0) {
|
||
errorList.push(new annotation_errors_1.ColorOutOfRangeError("Blue value out of range"));
|
||
}
|
||
return errorList;
|
||
}
|
||
checkReferencePointer(ptr) {
|
||
let errorList = [];
|
||
if (!(ptr && "obj" in ptr && ptr.obj >= 0 && "generation" in ptr && ptr.generation >= 0)) {
|
||
errorList.push(new annotation_errors_1.InvalidReferencePointerError("Invalid reference pointer"));
|
||
}
|
||
return errorList;
|
||
}
|
||
checkDate(date) {
|
||
if (typeof date === 'string') {
|
||
return [[], date];
|
||
}
|
||
let errorList = [];
|
||
let ret_val = undefined;
|
||
try {
|
||
ret_val = util_1.Util.convertDateToPDFDate(date);
|
||
}
|
||
catch (e) {
|
||
errorList.push(new annotation_errors_1.InvalidDateError("Invalid update date provided"));
|
||
}
|
||
return [errorList, ret_val];
|
||
}
|
||
checkRect(nr, rect) {
|
||
let errorList = [];
|
||
if (!Array.isArray(rect)) {
|
||
errorList.push(new annotation_errors_1.InvalidRectError("invalid rect parameter"));
|
||
}
|
||
if (rect.length !== nr) {
|
||
errorList.push(new annotation_errors_1.InvalidRectError("Rect has invalid number of entries: " + rect + " has " + rect.length + " entries, but should have " + nr + " entries"));
|
||
}
|
||
rect.forEach((a) => {
|
||
if ('number' !== typeof a) {
|
||
errorList.push(new annotation_errors_1.InvalidRectError("Rect " + rect + " has invalid entry: " + a));
|
||
}
|
||
});
|
||
return errorList;
|
||
}
|
||
}
|
||
exports.BaseAnnotationObj = BaseAnnotationObj;
|
||
var ReplyTypes;
|
||
(function (ReplyTypes) {
|
||
ReplyTypes[ReplyTypes["Reply"] = 0] = "Reply";
|
||
ReplyTypes[ReplyTypes["Group"] = 1] = "Group";
|
||
})(ReplyTypes = exports.ReplyTypes || (exports.ReplyTypes = {}));
|
||
class MarkupAnnotationObj extends BaseAnnotationObj {
|
||
constructor() {
|
||
super();
|
||
this.author = "";
|
||
this.opacity = 1; // /CA
|
||
this.subject = "";
|
||
}
|
||
writeAnnotationObject(cryptoInterface) {
|
||
let ret = super.writeAnnotationObject(cryptoInterface);
|
||
ret = ret.concat(writer_util_1.WriterUtil.AUTHOR);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_START);
|
||
ret = ret.concat(Array.from(util_1.Util.escapeString(cryptoInterface.encrypt(new Uint8Array(util_1.Util.convertStringToAscii(this.author)), this.object_id))));
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_END);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
if (this.opacity) {
|
||
ret = ret.concat(writer_util_1.WriterUtil.OPACITY);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(util_1.Util.convertNumberToCharArray(this.opacity));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
if (this.creationDate) {
|
||
ret = ret.concat(writer_util_1.WriterUtil.CREATION_DATE);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_START);
|
||
ret = ret.concat(Array.from(util_1.Util.escapeString(cryptoInterface.encrypt(new Uint8Array(util_1.Util.convertStringToAscii(this.creationDate)), this.object_id))));
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_END);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
if (this.subject !== "") {
|
||
ret = ret.concat(writer_util_1.WriterUtil.SUBJ);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_START);
|
||
ret = ret.concat(Array.from(util_1.Util.escapeString(cryptoInterface.encrypt(new Uint8Array(util_1.Util.convertStringToAscii(this.subject)), this.object_id))));
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_END);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
if (this.richtextString) {
|
||
ret = ret.concat(writer_util_1.WriterUtil.RC);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_START);
|
||
ret = ret.concat(Array.from(util_1.Util.escapeString(cryptoInterface.encrypt(new Uint8Array(util_1.Util.convertStringToAscii(this.richtextString)), this.object_id))));
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_END);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
return ret;
|
||
}
|
||
validate(enact = true) {
|
||
let errorList = super.validate(false);
|
||
if (this.opacity) {
|
||
try {
|
||
this.opacity = +this.opacity;
|
||
}
|
||
catch (e) {
|
||
errorList.push(new annotation_errors_1.InvalidOpacityError("Opacity no numerical value"));
|
||
}
|
||
if (this.opacity < 0 || this.opacity > 255) {
|
||
errorList.push(new annotation_errors_1.InvalidOpacityError("Opacity out of range"));
|
||
}
|
||
}
|
||
if (this.creationDate) {
|
||
let res = this.checkDate(this.creationDate);
|
||
this.creationDate = res[1];
|
||
errorList = errorList.concat(res[0]);
|
||
}
|
||
if (enact) {
|
||
for (let error of errorList) {
|
||
throw error;
|
||
}
|
||
}
|
||
return errorList;
|
||
}
|
||
}
|
||
exports.MarkupAnnotationObj = MarkupAnnotationObj;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/annotations/circle_square_annotation.ts":
|
||
/*!*****************************************************!*\
|
||
!*** ./src/annotations/circle_square_annotation.ts ***!
|
||
\*****************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const annotation_types_1 = __webpack_require__(/*! ./annotation_types */ "./src/annotations/annotation_types.ts");
|
||
const annotation_errors_1 = __webpack_require__(/*! ./annotation_errors */ "./src/annotations/annotation_errors.ts");
|
||
const writer_util_1 = __webpack_require__(/*! ../writer-util */ "./src/writer-util.ts");
|
||
class CircleSquareAnnotationObj extends annotation_types_1.MarkupAnnotationObj {
|
||
constructor() {
|
||
super();
|
||
this.differenceRectangle = [];
|
||
}
|
||
writeAnnotationObject(cryptoInterface) {
|
||
let ret = super.writeAnnotationObject(cryptoInterface);
|
||
if (this.fill) {
|
||
let fill = this.fill;
|
||
if (fill.r > 1)
|
||
fill.r /= 255;
|
||
if (fill.g > 1)
|
||
fill.g /= 255;
|
||
if (fill.b > 1)
|
||
fill.b /= 255;
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.FILL);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.writeNumberArray([fill.r, fill.g, fill.b]));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
if (this.differenceRectangle && this.differenceRectangle.length > 0) {
|
||
ret = ret.concat(writer_util_1.WriterUtil.DIFFERENCE_RECTANGLE);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.writeNumberArray(this.differenceRectangle));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
return ret;
|
||
}
|
||
validate(enact = true) {
|
||
let errorList = super.validate(false);
|
||
if (this.fill) {
|
||
errorList = errorList.concat(this.checkColor(this.fill));
|
||
}
|
||
if (enact) {
|
||
for (let error of errorList) {
|
||
throw error;
|
||
}
|
||
}
|
||
return errorList;
|
||
}
|
||
}
|
||
exports.CircleSquareAnnotationObj = CircleSquareAnnotationObj;
|
||
class CircleAnnotationObj extends CircleSquareAnnotationObj {
|
||
constructor() {
|
||
super();
|
||
this.type = "/Circle";
|
||
this.type_encoded = [47, 67, 105, 114, 99, 108, 101]; // = '/Circle'
|
||
}
|
||
validate(enact = true) {
|
||
let errorList = super.validate(false);
|
||
if (this.type !== "/Circle") {
|
||
errorList.push(new annotation_errors_1.InvalidAnnotationTypeError(`Invalid annotation type ${this.type}`));
|
||
}
|
||
if (enact) {
|
||
for (let error of errorList) {
|
||
throw error;
|
||
}
|
||
}
|
||
return errorList;
|
||
}
|
||
}
|
||
exports.CircleAnnotationObj = CircleAnnotationObj;
|
||
class SquareAnnotationObj extends CircleSquareAnnotationObj {
|
||
constructor() {
|
||
super();
|
||
this.type = "/Square";
|
||
this.type_encoded = [47, 83, 113, 117, 97, 114, 101]; // = '/Square'
|
||
}
|
||
validate(enact = true) {
|
||
let errorList = super.validate(false);
|
||
if (this.type !== "/Square") {
|
||
errorList.push(new annotation_errors_1.InvalidAnnotationTypeError(`Invalid annotation type ${this.type}`));
|
||
}
|
||
if (enact) {
|
||
for (let error of errorList) {
|
||
throw error;
|
||
}
|
||
}
|
||
return errorList;
|
||
}
|
||
}
|
||
exports.SquareAnnotationObj = SquareAnnotationObj;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/annotations/freetext_annotation.ts":
|
||
/*!************************************************!*\
|
||
!*** ./src/annotations/freetext_annotation.ts ***!
|
||
\************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const annotation_types_1 = __webpack_require__(/*! ./annotation_types */ "./src/annotations/annotation_types.ts");
|
||
const annotation_errors_1 = __webpack_require__(/*! ./annotation_errors */ "./src/annotations/annotation_errors.ts");
|
||
const writer_util_1 = __webpack_require__(/*! ../writer-util */ "./src/writer-util.ts");
|
||
const util_1 = __webpack_require__(/*! ../util */ "./src/util.ts");
|
||
var TextJustification;
|
||
(function (TextJustification) {
|
||
TextJustification[TextJustification["Left"] = 0] = "Left";
|
||
TextJustification[TextJustification["Centered"] = 1] = "Centered";
|
||
TextJustification[TextJustification["Right"] = 2] = "Right";
|
||
})(TextJustification = exports.TextJustification || (exports.TextJustification = {}));
|
||
var FreeTextType;
|
||
(function (FreeTextType) {
|
||
FreeTextType[FreeTextType["FreeText"] = 0] = "FreeText";
|
||
FreeTextType[FreeTextType["FreeTextCallout"] = 1] = "FreeTextCallout";
|
||
FreeTextType[FreeTextType["FreeTextTypeWriter"] = 2] = "FreeTextTypeWriter";
|
||
})(FreeTextType = exports.FreeTextType || (exports.FreeTextType = {}));
|
||
class FreeTextAnnotationObj extends annotation_types_1.MarkupAnnotationObj {
|
||
constructor() {
|
||
super();
|
||
this.defaultAppearance = "/Invalid_font 9 Tf"; // /DA
|
||
this.differenceRectangle = [];
|
||
this.textJustification = TextJustification.Left; // /Q
|
||
this.calloutLine = [];
|
||
this.freeTextType = FreeTextType.FreeText;
|
||
this.lineEndingStyle = annotation_types_1.LineEndingStyle.None;
|
||
this.type = "/FreeText";
|
||
this.type_encoded = [47, 70, 114, 101, 101, 84, 101, 120, 116]; // = '/FreeText'
|
||
}
|
||
convertJustification(just) {
|
||
switch (just) {
|
||
case TextJustification.Left:
|
||
return 0;
|
||
case TextJustification.Centered:
|
||
return 1;
|
||
case TextJustification.Right:
|
||
return 2;
|
||
default:
|
||
return 0;
|
||
}
|
||
}
|
||
convertFreeTextType(ft) {
|
||
switch (ft) {
|
||
case FreeTextType.FreeText:
|
||
return util_1.Util.convertStringToAscii("/FreeText");
|
||
case FreeTextType.FreeTextCallout:
|
||
return util_1.Util.convertStringToAscii("/FreeTextCallout");
|
||
case FreeTextType.FreeTextTypeWriter:
|
||
return util_1.Util.convertStringToAscii("/FreeTextTypeWriter");
|
||
default:
|
||
return util_1.Util.convertStringToAscii("/FreeText");
|
||
}
|
||
}
|
||
writeAnnotationObject(cryptoInterface) {
|
||
let ret = super.writeAnnotationObject(cryptoInterface);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.DEFAULT_APPEARANCE);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_START);
|
||
ret = ret.concat(util_1.Util.convertStringToAscii(this.defaultAppearance));
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_END);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.TEXT_JUSTIFICATION);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(util_1.Util.convertNumberToCharArray(this.convertJustification(this.textJustification)));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.IT);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(this.convertFreeTextType(this.freeTextType));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
if (this.calloutLine.length > 0) {
|
||
ret = ret.concat(writer_util_1.WriterUtil.CALLOUT_LINE);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.writeNumberArray(this.calloutLine));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
if (this.lineEndingStyle !== annotation_types_1.LineEndingStyle.None) {
|
||
ret = ret.concat(writer_util_1.WriterUtil.LINE_ENDING);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(this.convertLineEndingStyle(this.lineEndingStyle));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
if (this.defaultStyleString && this.defaultStyleString !== "") {
|
||
ret = ret.concat(writer_util_1.WriterUtil.DEFAULT_STYLE_STRING);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_START);
|
||
ret = ret.concat(util_1.Util.convertStringToAscii(this.defaultStyleString));
|
||
ret.push(writer_util_1.WriterUtil.BRACKET_END);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
if (this.differenceRectangle && this.differenceRectangle.length > 0) {
|
||
ret = ret.concat(writer_util_1.WriterUtil.DIFFERENCE_RECTANGLE);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.writeNumberArray(this.differenceRectangle));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
return ret;
|
||
}
|
||
validate(enact = true) {
|
||
let errorList = super.validate(false);
|
||
if (this.type !== "/FreeText") {
|
||
errorList.push(new annotation_errors_1.InvalidAnnotationTypeError(`Invalid annotation type ${this.type}`));
|
||
}
|
||
if (this.calloutLine && this.calloutLine.length > 0 && this.freeTextType !== FreeTextType.FreeTextCallout) {
|
||
console.log("Warning: Callout line only relevant for free text type: 'Callout'");
|
||
}
|
||
if (enact) {
|
||
for (let error of errorList) {
|
||
throw error;
|
||
}
|
||
}
|
||
return errorList;
|
||
}
|
||
}
|
||
exports.FreeTextAnnotationObj = FreeTextAnnotationObj;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/annotations/ink_annotation.ts":
|
||
/*!*******************************************!*\
|
||
!*** ./src/annotations/ink_annotation.ts ***!
|
||
\*******************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const annotation_types_1 = __webpack_require__(/*! ./annotation_types */ "./src/annotations/annotation_types.ts");
|
||
const annotation_errors_1 = __webpack_require__(/*! ./annotation_errors */ "./src/annotations/annotation_errors.ts");
|
||
const writer_util_1 = __webpack_require__(/*! ../writer-util */ "./src/writer-util.ts");
|
||
class InkAnnotationObj extends annotation_types_1.MarkupAnnotationObj {
|
||
constructor() {
|
||
super();
|
||
this.inkList = [];
|
||
this.type = "/Ink";
|
||
this.type_encoded = [47, 73, 110, 107]; // = '/Ink'
|
||
}
|
||
writeAnnotationObject(cryptoInterface) {
|
||
let ret = super.writeAnnotationObject(cryptoInterface);
|
||
if (this.inkList && this.inkList.length > 0) {
|
||
ret = ret.concat(writer_util_1.WriterUtil.INKLIST);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.writeNestedNumberArray(this.inkList));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
return ret;
|
||
}
|
||
validate(enact = true) {
|
||
let errorList = super.validate(false);
|
||
if (this.type !== "/Ink") {
|
||
errorList.push(new annotation_errors_1.InvalidAnnotationTypeError(`Invalid annotation type ${this.type}`));
|
||
}
|
||
if ('number' === typeof this.inkList[0]) {
|
||
this.inkList = [this.inkList];
|
||
}
|
||
if (enact) {
|
||
for (let error of errorList) {
|
||
throw error;
|
||
}
|
||
}
|
||
return errorList;
|
||
}
|
||
}
|
||
exports.InkAnnotationObj = InkAnnotationObj;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/annotations/polygon_polyline_annotation.ts":
|
||
/*!********************************************************!*\
|
||
!*** ./src/annotations/polygon_polyline_annotation.ts ***!
|
||
\********************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const annotation_types_1 = __webpack_require__(/*! ./annotation_types */ "./src/annotations/annotation_types.ts");
|
||
const annotation_errors_1 = __webpack_require__(/*! ./annotation_errors */ "./src/annotations/annotation_errors.ts");
|
||
const writer_util_1 = __webpack_require__(/*! ../writer-util */ "./src/writer-util.ts");
|
||
var PolygonPolyLineIntent;
|
||
(function (PolygonPolyLineIntent) {
|
||
PolygonPolyLineIntent[PolygonPolyLineIntent["PolygonCloud"] = 0] = "PolygonCloud";
|
||
PolygonPolyLineIntent[PolygonPolyLineIntent["PolyLineDimension"] = 1] = "PolyLineDimension";
|
||
PolygonPolyLineIntent[PolygonPolyLineIntent["PolygonDimension"] = 2] = "PolygonDimension";
|
||
})(PolygonPolyLineIntent = exports.PolygonPolyLineIntent || (exports.PolygonPolyLineIntent = {}));
|
||
class PolygonPolyLineAnnotationObj extends annotation_types_1.MarkupAnnotationObj {
|
||
constructor() {
|
||
super();
|
||
this.vertices = [];
|
||
}
|
||
writeAnnotationObject(cryptoInterface) {
|
||
let ret = super.writeAnnotationObject(cryptoInterface);
|
||
if (this.fill) {
|
||
let fill = this.fill;
|
||
if (fill.r > 1)
|
||
fill.r /= 255;
|
||
if (fill.g > 1)
|
||
fill.g /= 255;
|
||
if (fill.b > 1)
|
||
fill.b /= 255;
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.FILL);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.writeNumberArray([fill.r, fill.g, fill.b]));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
ret = ret.concat(writer_util_1.WriterUtil.VERTICES);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.writeNumberArray(this.vertices));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
return ret;
|
||
}
|
||
validate(enact = true) {
|
||
let errorList = super.validate(false);
|
||
if (this.fill) {
|
||
errorList = errorList.concat(this.checkColor(this.fill));
|
||
}
|
||
if (!this.vertices || this.vertices.length == 0) {
|
||
errorList.push(new annotation_errors_1.InvalidVerticesError("No vertices provided"));
|
||
}
|
||
if (this.vertices.length % 2 !== 0) {
|
||
errorList.push(new annotation_errors_1.InvalidVerticesError("number of vertices must be an even number"));
|
||
}
|
||
if (enact) {
|
||
for (let error of errorList) {
|
||
throw error;
|
||
}
|
||
}
|
||
return errorList;
|
||
}
|
||
}
|
||
exports.PolygonPolyLineAnnotationObj = PolygonPolyLineAnnotationObj;
|
||
class PolyLineAnnotationObj extends PolygonPolyLineAnnotationObj {
|
||
constructor() {
|
||
super();
|
||
this.lineEndingStyles = [];
|
||
this.type = "/PolyLine";
|
||
this.type_encoded = [47, 80, 111, 108, 121, 76, 105, 110, 101]; // '/PolyLine
|
||
}
|
||
writeAnnotationObject(cryptoInterface) {
|
||
let ret = super.writeAnnotationObject(cryptoInterface);
|
||
if (this.lineEndingStyles && this.lineEndingStyles.length >= 2) {
|
||
ret = ret.concat(writer_util_1.WriterUtil.LINE_ENDING);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret.push(writer_util_1.WriterUtil.ARRAY_START);
|
||
ret = ret.concat(this.convertLineEndingStyle(this.lineEndingStyles[0]));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(this.convertLineEndingStyle(this.lineEndingStyles[1]));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret.push(writer_util_1.WriterUtil.ARRAY_END);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
return ret;
|
||
}
|
||
validate(enact = true) {
|
||
let errorList = super.validate(false);
|
||
if (this.type !== "/PolyLine") {
|
||
errorList.push(new annotation_errors_1.InvalidAnnotationTypeError(`Invalid annotation type ${this.type}`));
|
||
}
|
||
if (enact) {
|
||
for (let error of errorList) {
|
||
throw error;
|
||
}
|
||
}
|
||
return errorList;
|
||
}
|
||
}
|
||
exports.PolyLineAnnotationObj = PolyLineAnnotationObj;
|
||
class PolygonAnnotationObj extends PolygonPolyLineAnnotationObj {
|
||
constructor() {
|
||
super();
|
||
this.type = "/Polygon";
|
||
this.type_encoded = [47, 80, 111, 108, 121, 103, 111, 110]; // = '/Polygon
|
||
}
|
||
validate(enact = true) {
|
||
let errorList = super.validate(false);
|
||
if (this.type !== "/Polygon") {
|
||
errorList.push(new annotation_errors_1.InvalidAnnotationTypeError(`Invalid annotation type ${this.type}`));
|
||
}
|
||
if (enact) {
|
||
for (let error of errorList) {
|
||
throw error;
|
||
}
|
||
}
|
||
return errorList;
|
||
}
|
||
}
|
||
exports.PolygonAnnotationObj = PolygonAnnotationObj;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/annotations/text_annotation.ts":
|
||
/*!********************************************!*\
|
||
!*** ./src/annotations/text_annotation.ts ***!
|
||
\********************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const annotation_types_1 = __webpack_require__(/*! ./annotation_types */ "./src/annotations/annotation_types.ts");
|
||
const annotation_errors_1 = __webpack_require__(/*! ./annotation_errors */ "./src/annotations/annotation_errors.ts");
|
||
const writer_util_1 = __webpack_require__(/*! ../writer-util */ "./src/writer-util.ts");
|
||
const util_1 = __webpack_require__(/*! ../util */ "./src/util.ts");
|
||
var AnnotationIcon;
|
||
(function (AnnotationIcon) {
|
||
AnnotationIcon[AnnotationIcon["Comment"] = 0] = "Comment";
|
||
AnnotationIcon[AnnotationIcon["Key"] = 1] = "Key";
|
||
AnnotationIcon[AnnotationIcon["Note"] = 2] = "Note";
|
||
AnnotationIcon[AnnotationIcon["Help"] = 3] = "Help";
|
||
AnnotationIcon[AnnotationIcon["NewParagraph"] = 4] = "NewParagraph";
|
||
AnnotationIcon[AnnotationIcon["Paragraph"] = 5] = "Paragraph";
|
||
AnnotationIcon[AnnotationIcon["Insert"] = 6] = "Insert";
|
||
})(AnnotationIcon = exports.AnnotationIcon || (exports.AnnotationIcon = {}));
|
||
var AnnotationStateModel;
|
||
(function (AnnotationStateModel) {
|
||
AnnotationStateModel[AnnotationStateModel["Marked"] = 0] = "Marked";
|
||
AnnotationStateModel[AnnotationStateModel["Review"] = 1] = "Review";
|
||
})(AnnotationStateModel = exports.AnnotationStateModel || (exports.AnnotationStateModel = {}));
|
||
var AnnotationState;
|
||
(function (AnnotationState) {
|
||
AnnotationState[AnnotationState["Marked"] = 0] = "Marked";
|
||
AnnotationState[AnnotationState["Unmarked"] = 1] = "Unmarked";
|
||
AnnotationState[AnnotationState["Accepted"] = 2] = "Accepted";
|
||
AnnotationState[AnnotationState["Rejected"] = 3] = "Rejected";
|
||
AnnotationState[AnnotationState["Cancelled"] = 4] = "Cancelled";
|
||
AnnotationState[AnnotationState["Completed"] = 5] = "Completed";
|
||
AnnotationState[AnnotationState["None"] = 6] = "None";
|
||
})(AnnotationState = exports.AnnotationState || (exports.AnnotationState = {}));
|
||
class TextAnnotationObj extends annotation_types_1.MarkupAnnotationObj {
|
||
constructor() {
|
||
super();
|
||
this.open = false;
|
||
this.icon = AnnotationIcon.Note;
|
||
this.state = undefined;
|
||
this.type = "/Text";
|
||
this.type_encoded = [47, 84, 101, 120, 116]; // = '/Text'
|
||
// demanded by PDF specification (p. 394 - 12.5.6.4 Text Annotations)
|
||
this.annotationFlags = { noZoom: true, noRotate: true };
|
||
}
|
||
convertAnnotationIcon(icon) {
|
||
switch (icon) {
|
||
case AnnotationIcon.Comment:
|
||
return [47, 67, 111, 109, 109, 101, 110, 116]; // = '/Comment'
|
||
case AnnotationIcon.Key:
|
||
return [47, 75, 101, 121]; // = '/Key'
|
||
case AnnotationIcon.Note:
|
||
return [47, 78, 111, 116, 101]; // = '/Note'
|
||
case AnnotationIcon.Help:
|
||
return [47, 72, 101, 108, 112]; // = '/Help'
|
||
case AnnotationIcon.NewParagraph:
|
||
return [47, 78, 101, 119, 80, 97, 114, 97, 103, 114, 97, 112, 104]; // = '/NewParagraph'
|
||
case AnnotationIcon.Paragraph:
|
||
return [47, 80, 97, 114, 97, 103, 114, 97, 112, 104]; // = '/Paragraph'
|
||
case AnnotationIcon.Insert:
|
||
return [47, 73, 110, 115, 101, 114, 116]; // = '/Insert'
|
||
}
|
||
return [];
|
||
}
|
||
convertState(state) {
|
||
switch (state) {
|
||
case AnnotationState.Marked:
|
||
return util_1.Util.convertStringToAscii("/Marked");
|
||
case AnnotationState.Unmarked:
|
||
return util_1.Util.convertStringToAscii("/Unmarked");
|
||
case AnnotationState.Accepted:
|
||
return util_1.Util.convertStringToAscii("/Accepted");
|
||
case AnnotationState.Rejected:
|
||
return util_1.Util.convertStringToAscii("/Rejected");
|
||
case AnnotationState.Cancelled:
|
||
return util_1.Util.convertStringToAscii("/Cancelled");
|
||
case AnnotationState.Completed:
|
||
return util_1.Util.convertStringToAscii("/Completed");
|
||
case AnnotationState.None:
|
||
return util_1.Util.convertStringToAscii("/None");
|
||
}
|
||
return [];
|
||
}
|
||
convertStateModel(stateModel) {
|
||
switch (stateModel) {
|
||
case AnnotationStateModel.Marked:
|
||
return util_1.Util.convertStringToAscii("/Marked");
|
||
case AnnotationStateModel.Review:
|
||
return util_1.Util.convertStringToAscii("/Review");
|
||
}
|
||
return [];
|
||
}
|
||
writeAnnotationObject(cryptoInterface) {
|
||
let ret = super.writeAnnotationObject(cryptoInterface);
|
||
if (this.open) {
|
||
ret = ret.concat(writer_util_1.WriterUtil.OPEN);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.TRUE);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
if (this.icon) {
|
||
ret = ret.concat(writer_util_1.WriterUtil.NAME);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(this.convertAnnotationIcon(this.icon));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
if (this.state) {
|
||
ret = ret.concat(writer_util_1.WriterUtil.STATE);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(this.convertState(this.state));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
if (this.stateModel) {
|
||
ret = ret.concat(writer_util_1.WriterUtil.STATEMODEL);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(this.convertStateModel(this.stateModel));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
return ret;
|
||
}
|
||
validate(enact = true) {
|
||
let errorList = super.validate(false);
|
||
if (this.type !== "/Text") {
|
||
errorList.push(new annotation_errors_1.InvalidAnnotationTypeError(`Invalid annotation type ${this.type}`));
|
||
}
|
||
if (this.state && !this.stateModel) {
|
||
errorList.push(new annotation_errors_1.InvalidStateError("You need to specify a state model, when specifying a state"));
|
||
}
|
||
if (this.stateModel && !this.state) {
|
||
if (this.stateModel.valueOf() === AnnotationStateModel.Marked) {
|
||
this.state = AnnotationState.Unmarked;
|
||
}
|
||
else if (this.stateModel.valueOf() === AnnotationStateModel.Review) {
|
||
this.state = AnnotationState.None;
|
||
}
|
||
else {
|
||
errorList.push(new annotation_errors_1.InvalidStateError("Invalid state model selected"));
|
||
}
|
||
}
|
||
if (this.state && this.stateModel) {
|
||
if (this.stateModel.valueOf() === AnnotationStateModel.Marked) {
|
||
if (this.state.valueOf() !== AnnotationState.Marked && this.state.valueOf() !== AnnotationState.Unmarked) {
|
||
errorList.push(new annotation_errors_1.InvalidStateError("Invalid annotation state for state model 'Marked' only 'Marked' and 'Unmarked' are legal values"));
|
||
}
|
||
}
|
||
else if (this.stateModel.valueOf() === AnnotationStateModel.Review) {
|
||
if (this.state.valueOf() !== AnnotationState.Accepted && this.state.valueOf() !== AnnotationState.Rejected &&
|
||
this.state.valueOf() !== AnnotationState.Cancelled && this.state.valueOf() !== AnnotationState.Completed &&
|
||
this.state.valueOf() !== AnnotationState.None) {
|
||
errorList.push(new annotation_errors_1.InvalidStateError("Invalid annotation state for state model 'Review' only 'Accepted', 'Rejected', 'Cancelled', 'Completed' and 'None' are legal values"));
|
||
}
|
||
}
|
||
else {
|
||
errorList.push(new annotation_errors_1.InvalidStateError("Invalid state model selected"));
|
||
}
|
||
}
|
||
if (enact) {
|
||
for (let error of errorList) {
|
||
throw error;
|
||
}
|
||
}
|
||
return errorList;
|
||
}
|
||
}
|
||
exports.TextAnnotationObj = TextAnnotationObj;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/annotations/text_markup_annotation.ts":
|
||
/*!***************************************************!*\
|
||
!*** ./src/annotations/text_markup_annotation.ts ***!
|
||
\***************************************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const annotation_types_1 = __webpack_require__(/*! ./annotation_types */ "./src/annotations/annotation_types.ts");
|
||
const annotation_errors_1 = __webpack_require__(/*! ./annotation_errors */ "./src/annotations/annotation_errors.ts");
|
||
const writer_util_1 = __webpack_require__(/*! ../writer-util */ "./src/writer-util.ts");
|
||
class TextMarkupAnnotationObj extends annotation_types_1.MarkupAnnotationObj {
|
||
constructor() {
|
||
super(...arguments);
|
||
this.quadPoints = [];
|
||
}
|
||
writeAnnotationObject(cryptoInterface) {
|
||
let ret = super.writeAnnotationObject(cryptoInterface);
|
||
ret = ret.concat(writer_util_1.WriterUtil.QUADPOINTS);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.writeNumberArray(this.quadPoints));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
return ret;
|
||
}
|
||
validate(enact = true) {
|
||
let errorList = super.validate(false);
|
||
if (errorList.length === 1 && errorList[0] instanceof annotation_errors_1.InvalidRectError) {
|
||
if (this.quadPoints && this.quadPoints.length > 0) {
|
||
this.rect = this.extractRectFromQuadPoints(this.quadPoints);
|
||
errorList = this.checkRect(4, this.rect);
|
||
}
|
||
}
|
||
if (!this.quadPoints || this.quadPoints.length === 0) {
|
||
let rect = this.rect;
|
||
this.quadPoints = [rect[0], rect[3], rect[2], rect[3], rect[0], rect[1], rect[2], rect[1]];
|
||
}
|
||
errorList = errorList.concat(this.checkQuadPoints(this.quadPoints));
|
||
if (enact) {
|
||
for (let error of errorList) {
|
||
throw error;
|
||
}
|
||
}
|
||
return errorList;
|
||
}
|
||
/**
|
||
* Extracts the rectangular hull from a quadPoint definition
|
||
* */
|
||
extractRectFromQuadPoints(quadPoints) {
|
||
let x_values = quadPoints.filter((element, index) => index % 2 === 0);
|
||
let y_values = quadPoints.filter((element, index) => index % 2 !== 0);
|
||
return [Math.min(...x_values), Math.min(...y_values), Math.max(...x_values), Math.max(...y_values)];
|
||
}
|
||
/**
|
||
* Checks the 'quadPoints' parameter
|
||
* */
|
||
checkQuadPoints(quadPoints) {
|
||
let errorList = [];
|
||
if (quadPoints.length % 8 !== 0)
|
||
errorList.push(new annotation_errors_1.InvalidQuadPointError(`Quadpoints array has length ${quadPoints.length} but must be a multiple of 8`));
|
||
quadPoints.forEach((a) => {
|
||
if ('number' !== typeof a)
|
||
errorList.push(new annotation_errors_1.InvalidQuadPointError("Quadpoint " + quadPoints + " has invalid entry: " + a));
|
||
});
|
||
return errorList;
|
||
}
|
||
}
|
||
exports.TextMarkupAnnotationObj = TextMarkupAnnotationObj;
|
||
class HighlightAnnotationObj extends TextMarkupAnnotationObj {
|
||
constructor() {
|
||
super();
|
||
this.type = "/Highlight";
|
||
this.type_encoded = [47, 72, 105, 103, 104, 108, 105, 103, 104, 116]; // = '/Highlight'
|
||
}
|
||
validate(enact = true) {
|
||
let errorList = super.validate(false);
|
||
if (this.type !== "/Highlight") {
|
||
errorList.push(new annotation_errors_1.InvalidAnnotationTypeError(`Invalid annotation type ${this.type}`));
|
||
}
|
||
if (enact) {
|
||
for (let error of errorList) {
|
||
throw error;
|
||
}
|
||
}
|
||
return errorList;
|
||
}
|
||
}
|
||
exports.HighlightAnnotationObj = HighlightAnnotationObj;
|
||
class UnderlineAnnotationObj extends TextMarkupAnnotationObj {
|
||
constructor() {
|
||
super();
|
||
this.type = "/Underline";
|
||
this.type_encoded = [47, 85, 110, 100, 101, 114, 108, 105, 110, 101]; // = '/Underline'
|
||
}
|
||
validate(enact = true) {
|
||
let errorList = super.validate(false);
|
||
if (this.type !== "/Underline") {
|
||
errorList.push(new annotation_errors_1.InvalidAnnotationTypeError(`Invalid annotation type ${this.type}`));
|
||
}
|
||
if (enact) {
|
||
for (let error of errorList) {
|
||
throw error;
|
||
}
|
||
}
|
||
return errorList;
|
||
}
|
||
}
|
||
exports.UnderlineAnnotationObj = UnderlineAnnotationObj;
|
||
class SquigglyAnnotationObj extends TextMarkupAnnotationObj {
|
||
constructor() {
|
||
super();
|
||
this.type = "/Squiggly";
|
||
this.type_encoded = [47, 83, 113, 117, 105, 103, 103, 108, 121]; // = '/Squiggly'
|
||
}
|
||
validate(enact = true) {
|
||
let errorList = super.validate(false);
|
||
if (this.type !== "/Squiggly") {
|
||
errorList.push(new annotation_errors_1.InvalidAnnotationTypeError(`Invalid annotation type ${this.type}`));
|
||
}
|
||
if (enact) {
|
||
for (let error of errorList) {
|
||
throw error;
|
||
}
|
||
}
|
||
return errorList;
|
||
}
|
||
}
|
||
exports.SquigglyAnnotationObj = SquigglyAnnotationObj;
|
||
class StrikeOutAnnotationObj extends TextMarkupAnnotationObj {
|
||
constructor() {
|
||
super();
|
||
this.type = "/StrikeOut";
|
||
this.type_encoded = [47, 83, 116, 114, 105, 107, 101, 79, 117, 116]; // = '/StrikeOut'
|
||
}
|
||
validate(enact = true) {
|
||
let errorList = super.validate(false);
|
||
if (this.type !== "/StrikeOut") {
|
||
errorList.push(new annotation_errors_1.InvalidAnnotationTypeError(`Invalid annotation type ${this.type}`));
|
||
}
|
||
if (enact) {
|
||
for (let error of errorList) {
|
||
throw error;
|
||
}
|
||
}
|
||
return errorList;
|
||
}
|
||
}
|
||
exports.StrikeOutAnnotationObj = StrikeOutAnnotationObj;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/array-util.ts":
|
||
/*!***************************!*\
|
||
!*** ./src/array-util.ts ***!
|
||
\***************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const util_1 = __webpack_require__(/*! ./util */ "./src/util.ts");
|
||
const object_util_1 = __webpack_require__(/*! ./object-util */ "./src/object-util.ts");
|
||
/**
|
||
* Holds the logic for extracting arrays
|
||
* */
|
||
class ArrayUtil {
|
||
/**
|
||
* Extracts array of numbers and arrays of references
|
||
*
|
||
* The function supports arbitrarily nesting of arrays and multiple types.
|
||
* */
|
||
static extractArray(data, ptr) {
|
||
ptr = util_1.Util.skipSpaces(data, ptr);
|
||
let start_index = ptr;
|
||
if (data[ptr] !== util_1.Util.ARRAY_START[0])
|
||
throw Error("Invalid array sequence -- does not start with '['");
|
||
ptr += 1;
|
||
let next = util_1.Util.readNextWord(data, ptr);
|
||
let next_string = next.result;
|
||
ptr = next.start_index;
|
||
let ret_list = [];
|
||
while (next_string) {
|
||
if (next_string[0] === util_1.Util.ARRAY_START[0]) {
|
||
let sub_array = ArrayUtil.extractArray(data, ptr);
|
||
ptr = sub_array.end_index;
|
||
ret_list.push(sub_array.result);
|
||
}
|
||
else if (util_1.Util.areArraysEqual(next_string, util_1.Util.NULL)) {
|
||
ret_list.push("null");
|
||
ptr += next_string.length - 1;
|
||
}
|
||
else if (next_string[0] === util_1.Util.LITERAL_STRING_END[0]) {
|
||
return { result: ret_list, start_index: start_index, end_index: next.end_index };
|
||
}
|
||
else if (next_string[0] === util_1.Util.LITERAL_STRING_START[0]) {
|
||
let extracted_string = util_1.Util.extractString(data, ptr);
|
||
ret_list.push(extracted_string.result);
|
||
ptr = extracted_string.end_index;
|
||
}
|
||
else if (next_string[0] === util_1.Util.DICT_START[0]) { // <
|
||
let lookup_word = util_1.Util.readNextWord(data, next.end_index + 1);
|
||
if (lookup_word.result && lookup_word.result[0] === util_1.Util.DICT_START[0]) {
|
||
let dict = {};
|
||
ptr = object_util_1.ObjectUtil.extractDictValueRec(data, ptr, dict);
|
||
ret_list.push(dict);
|
||
}
|
||
else {
|
||
let hex_string = util_1.Util.extractHexString(data, ptr);
|
||
ret_list.push(hex_string.result);
|
||
ptr = hex_string.end_index;
|
||
}
|
||
}
|
||
else if (next_string[0] === 47) { // /
|
||
let opt_value = util_1.Util.extractOptionValue(data, ptr);
|
||
ret_list.push("/" + opt_value.result);
|
||
ptr = opt_value.end_index;
|
||
}
|
||
else if (next_string[0] === util_1.Util.R[0]) { // Reference pointer
|
||
let obj = ret_list[ret_list.length - 2];
|
||
let generation = ret_list[ret_list.length - 1];
|
||
ret_list = ret_list.slice(0, ret_list.length - 2);
|
||
ret_list.push({ obj: obj, generation: generation });
|
||
ptr = next.end_index;
|
||
}
|
||
else if (next_string[0] === util_1.Util.ARRAY_END[0]) {
|
||
break;
|
||
}
|
||
else {
|
||
let nbr = util_1.Util.extractNumber(data, ptr);
|
||
ret_list.push(nbr.result);
|
||
ptr = nbr.end_index;
|
||
}
|
||
++ptr;
|
||
ptr = util_1.Util.skipSpaces(data, ptr);
|
||
next = util_1.Util.readNextWord(data, ptr);
|
||
next_string = next.result;
|
||
ptr = next.start_index;
|
||
}
|
||
return { result: ret_list, start_index: start_index, end_index: next.end_index };
|
||
}
|
||
}
|
||
exports.ArrayUtil = ArrayUtil;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/crypto-util.ts":
|
||
/*!****************************!*\
|
||
!*** ./src/crypto-util.ts ***!
|
||
\****************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const util_1 = __webpack_require__(/*! ./util */ "./src/util.ts");
|
||
const crypto = __webpack_require__(/*! crypto-js */ "./node_modules/crypto-js/index.js");
|
||
class CryptoUtil {
|
||
/**
|
||
* Transforms a uint8array into a crypto-js word array
|
||
* */
|
||
static convertToWordArray(arr) {
|
||
let new_val_int32 = util_1.Util.convertUint8ArrayToInt32Array(arr);
|
||
return crypto.lib.WordArray.create(Array.from(new_val_int32), arr.length);
|
||
}
|
||
/**
|
||
* Converts a given word array into a uint8 array
|
||
* */
|
||
static convertWordArrayToByteArray(arr) {
|
||
return util_1.Util.convertInt32ArrayToUint8Array(arr.words);
|
||
}
|
||
/**
|
||
* Converts a number into a little endian byte array
|
||
* */
|
||
static convertNumberToLittleEndianByteArray(nbr) {
|
||
return util_1.Util.convertInt32ArrayToUint8Array(new Int32Array([nbr])).reverse();
|
||
}
|
||
/**
|
||
* Returns the MD5 hash
|
||
* */
|
||
static MD5(data) {
|
||
if (data instanceof Uint8Array) {
|
||
data = CryptoUtil.convertToWordArray(data);
|
||
}
|
||
return crypto.MD5(data);
|
||
}
|
||
/**
|
||
* Returns the MD5 hash as byte array
|
||
* */
|
||
static MD5AsByteArray(data) {
|
||
if (data instanceof Uint8Array) {
|
||
data = CryptoUtil.convertToWordArray(data);
|
||
}
|
||
return CryptoUtil.convertWordArrayToByteArray(crypto.MD5(data));
|
||
}
|
||
/**
|
||
* Returns the MD5 hash as hex string
|
||
* */
|
||
static MD5Hex(data) {
|
||
return CryptoUtil.MD5(data).toString(crypto.enc.Hex);
|
||
}
|
||
/**
|
||
* Returns the RC4 encrypted data
|
||
* */
|
||
static RC4(data, key) {
|
||
if (data instanceof Uint8Array) {
|
||
data = CryptoUtil.convertToWordArray(data);
|
||
}
|
||
if (key instanceof Uint8Array) {
|
||
key = CryptoUtil.convertToWordArray(key);
|
||
}
|
||
return crypto.RC4.encrypt(data, key).ciphertext;
|
||
}
|
||
/**
|
||
* Returns the RC4 encrypted data as hex string
|
||
* */
|
||
static RC4Hex(data, key) {
|
||
return CryptoUtil.RC4(data, key).toString(crypto.enc.Hex);
|
||
}
|
||
/**
|
||
* Pads the provided password string
|
||
* */
|
||
static padPasswortString(password) {
|
||
if (typeof password === 'string') {
|
||
password = new Uint8Array(util_1.Util.convertStringToAscii(password));
|
||
}
|
||
let ret_val = new Uint8Array(32);
|
||
ret_val.set(password.slice(0, 32));
|
||
if (password.length < 32) {
|
||
ret_val.set(CryptoUtil.PADDING_STRING.slice(0, 32 - password.length), password.length);
|
||
}
|
||
return ret_val;
|
||
}
|
||
/**
|
||
* Xors every byte of the provided _byte_array with the value _k
|
||
* */
|
||
static xorBytes(_byte_array, _k) {
|
||
let _ret_val = [];
|
||
for (let i = 0; i < _byte_array.length; ++i) {
|
||
_ret_val.push(_byte_array[i] ^ _k);
|
||
}
|
||
return CryptoUtil.convertToWordArray(new Uint8Array(_ret_val));
|
||
}
|
||
}
|
||
exports.CryptoUtil = CryptoUtil;
|
||
CryptoUtil.PADDING_STRING = [
|
||
0x28,
|
||
0xBF,
|
||
0x4E,
|
||
0x5E,
|
||
0x4E,
|
||
0x75,
|
||
0x8A,
|
||
0x41,
|
||
0x64,
|
||
0x00,
|
||
0x4E,
|
||
0x56,
|
||
0xFF,
|
||
0xFA,
|
||
0x01,
|
||
0x08,
|
||
0x2E,
|
||
0x2E,
|
||
0x00,
|
||
0xB6,
|
||
0xD0,
|
||
0x68,
|
||
0x3E,
|
||
0x80,
|
||
0x2F,
|
||
0x0C,
|
||
0xA9,
|
||
0xFE,
|
||
0x64,
|
||
0x53,
|
||
0x69,
|
||
0x7A
|
||
];
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/crypto.ts":
|
||
/*!***********************!*\
|
||
!*** ./src/crypto.ts ***!
|
||
\***********************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const util_1 = __webpack_require__(/*! ./util */ "./src/util.ts");
|
||
const crypto_util_1 = __webpack_require__(/*! ./crypto-util */ "./src/crypto-util.ts");
|
||
exports.RC4_40_BIT = true;
|
||
class IdentityEngine {
|
||
encrypt(data, reference) {
|
||
return data;
|
||
}
|
||
decrypt(data, reference) {
|
||
return data;
|
||
}
|
||
isUserPasswordCorrect() {
|
||
return true;
|
||
}
|
||
isOwnerPasswordCorrect() {
|
||
return true;
|
||
}
|
||
}
|
||
exports.IdentityEngine = IdentityEngine;
|
||
class RC4CryptoEngine {
|
||
constructor(cryptoConfiguration, file_id, rc4_40_bit = false) {
|
||
this.cryptoConfiguration = cryptoConfiguration;
|
||
this.file_id = file_id;
|
||
this.rc4_40_bit = rc4_40_bit;
|
||
this.encryptionKey = undefined;
|
||
this.computed_user_password = undefined;
|
||
this.computed_owner_password = undefined;
|
||
}
|
||
encrypt(data, reference) {
|
||
if (!reference)
|
||
throw Error("Undefined reference pointer of encrypted object");
|
||
let encryptionKey = this.computeEncryptionKey();
|
||
let adapted_key = new Uint8Array(encryptionKey.length + 5);
|
||
adapted_key.set(encryptionKey, 0);
|
||
let obj = crypto_util_1.CryptoUtil.convertNumberToLittleEndianByteArray(reference.obj);
|
||
adapted_key.set(obj.slice(0, 3), encryptionKey.length);
|
||
let gen = crypto_util_1.CryptoUtil.convertNumberToLittleEndianByteArray(reference.generation);
|
||
adapted_key.set(gen.slice(0, 2), encryptionKey.length + 3);
|
||
let key_hash = crypto_util_1.CryptoUtil.MD5AsByteArray(adapted_key);
|
||
let encrypted = crypto_util_1.CryptoUtil.RC4(data, key_hash.slice(0, Math.min(encryptionKey.length + 5, 16)));
|
||
return crypto_util_1.CryptoUtil.convertWordArrayToByteArray(encrypted);
|
||
}
|
||
decrypt(data, reference) {
|
||
return this.encrypt(data, reference);
|
||
}
|
||
/**
|
||
* Computes the RC4 encryption key
|
||
* */
|
||
computeEncryptionKey() {
|
||
if (this.encryptionKey)
|
||
return this.encryptionKey;
|
||
let userpwd = crypto_util_1.CryptoUtil.padPasswortString(this.cryptoConfiguration.user_pwd);
|
||
if (!this.cryptoConfiguration.owner_pwd_c)
|
||
throw Error("Invalid /O value (owner password)");
|
||
let oValue = this.cryptoConfiguration.owner_pwd_c;
|
||
if (oValue.length !== 32)
|
||
throw Error(`Invalid length of owner value. Is ${oValue.length} but must be 32.`);
|
||
if (!this.cryptoConfiguration.permissions)
|
||
throw Error("Permissions not set");
|
||
let permissions = crypto_util_1.CryptoUtil.convertNumberToLittleEndianByteArray(this.cryptoConfiguration.permissions);
|
||
if (!this.file_id || this.file_id.length === 0)
|
||
throw Error("File ID not set");
|
||
let keylength = 40;
|
||
if (this.cryptoConfiguration.length)
|
||
keylength = this.cryptoConfiguration.length;
|
||
let file_id = this.file_id[0];
|
||
let stuff = new Uint8Array(userpwd.length + oValue.length + permissions.length + file_id.length);
|
||
stuff.set(userpwd, 0);
|
||
stuff.set(oValue, userpwd.length);
|
||
stuff.set(permissions, userpwd.length + oValue.length);
|
||
stuff.set(file_id, userpwd.length + oValue.length + permissions.length);
|
||
let h = crypto_util_1.CryptoUtil.MD5AsByteArray(stuff);
|
||
keylength = keylength >> 3;
|
||
if (this.cryptoConfiguration.revision && this.cryptoConfiguration.revision >= 3) {
|
||
for (let i = 0; i < 50; ++i) {
|
||
h = crypto_util_1.CryptoUtil.MD5AsByteArray(h.slice(0, keylength));
|
||
}
|
||
}
|
||
if (this.rc4_40_bit) {
|
||
this.encryptionKey = h.slice(0, 5);
|
||
}
|
||
else {
|
||
this.encryptionKey = h;
|
||
}
|
||
return this.encryptionKey;
|
||
}
|
||
/**
|
||
* Derives the user password (/U) value
|
||
* */
|
||
computeUserPassword() {
|
||
if (this.computed_user_password)
|
||
return this.computed_user_password;
|
||
if (this.cryptoConfiguration.revision && this.cryptoConfiguration.revision >= 3) {
|
||
return this.computeUserPasswordRevision3OrGreater();
|
||
}
|
||
else if (this.cryptoConfiguration.revision === 2) {
|
||
return this.computeUserPasswordRevision2();
|
||
}
|
||
return new Uint8Array([]);
|
||
}
|
||
/**
|
||
* Computes the user password for security handlers of revision 2
|
||
* */
|
||
computeUserPasswordRevision2() {
|
||
let padding_str = new Uint8Array(crypto_util_1.CryptoUtil.PADDING_STRING);
|
||
let enc_key = this.computeEncryptionKey();
|
||
let x = crypto_util_1.CryptoUtil.RC4(padding_str, enc_key);
|
||
this.computed_user_password = crypto_util_1.CryptoUtil.convertWordArrayToByteArray(x);
|
||
return this.computed_user_password;
|
||
}
|
||
/**
|
||
* Computes the user password for security handlers of revision 3 or higher
|
||
* */
|
||
computeUserPasswordRevision3OrGreater() {
|
||
if (!this.file_id)
|
||
throw Error("No file id");
|
||
let id_str_array = this.file_id[0];
|
||
let new_val = new Uint8Array(crypto_util_1.CryptoUtil.PADDING_STRING.length + id_str_array.length);
|
||
new_val.set(crypto_util_1.CryptoUtil.PADDING_STRING, 0);
|
||
new_val.set(id_str_array, crypto_util_1.CryptoUtil.PADDING_STRING.length);
|
||
let x = crypto_util_1.CryptoUtil.MD5(new_val);
|
||
let enc_key = this.computeEncryptionKey();
|
||
for (let i = 0; i < 20; ++i) {
|
||
x = crypto_util_1.CryptoUtil.RC4(x, crypto_util_1.CryptoUtil.xorBytes(enc_key, i));
|
||
}
|
||
this.computed_user_password = crypto_util_1.CryptoUtil.convertWordArrayToByteArray(x);
|
||
return this.computed_user_password;
|
||
}
|
||
/**
|
||
* Derives the owner password (/O) value
|
||
**/
|
||
computeOwnerPassword() {
|
||
if (this.computed_owner_password)
|
||
return this.computed_owner_password;
|
||
let pwd_string = this.cryptoConfiguration.owner_pwd;
|
||
// if no owner password is set, but a user password use this
|
||
if (!this.cryptoConfiguration.owner_pwd || this.cryptoConfiguration.owner_pwd === "")
|
||
pwd_string = this.cryptoConfiguration.user_pwd;
|
||
let ownerpwd = crypto_util_1.CryptoUtil.padPasswortString(pwd_string);
|
||
let h = crypto_util_1.CryptoUtil.MD5(ownerpwd);
|
||
let count = 1;
|
||
if (this.cryptoConfiguration.revision && this.cryptoConfiguration.revision >= 3) {
|
||
count = 20;
|
||
for (let i = 0; i < 50; ++i) {
|
||
h = crypto_util_1.CryptoUtil.MD5(h);
|
||
}
|
||
}
|
||
let length = 128;
|
||
if (this.cryptoConfiguration.length)
|
||
length = this.cryptoConfiguration.length;
|
||
let enc_key = crypto_util_1.CryptoUtil.convertWordArrayToByteArray(h).slice(0, length / 8);
|
||
let userpwd = crypto_util_1.CryptoUtil.padPasswortString(this.cryptoConfiguration.user_pwd);
|
||
let x = crypto_util_1.CryptoUtil.convertToWordArray(userpwd);
|
||
for (let i = 0; i < count; ++i) {
|
||
x = crypto_util_1.CryptoUtil.RC4(x, crypto_util_1.CryptoUtil.xorBytes(enc_key, i));
|
||
}
|
||
this.computed_owner_password = crypto_util_1.CryptoUtil.convertWordArrayToByteArray(x);
|
||
return this.computed_owner_password;
|
||
}
|
||
/**
|
||
* Returns true if the provided password corresponds to the defined /U value
|
||
* */
|
||
isUserPasswordCorrect() {
|
||
let user_pwd = this.computeUserPassword();
|
||
if (!this.cryptoConfiguration.user_pwd_c)
|
||
throw Error("Invalid /U value (user password)");
|
||
if (this.cryptoConfiguration.revision && this.cryptoConfiguration.revision >= 3) {
|
||
return util_1.Util.areArraysEqual(user_pwd, this.cryptoConfiguration.user_pwd_c.slice(0, 16));
|
||
}
|
||
else {
|
||
return util_1.Util.areArraysEqual(user_pwd, this.cryptoConfiguration.user_pwd_c);
|
||
}
|
||
}
|
||
/**
|
||
* Returns true if the provided password corresponds to the defined /O value
|
||
* */
|
||
isOwnerPasswordCorrect() {
|
||
let owner_pwd = this.computeOwnerPassword();
|
||
if (!this.cryptoConfiguration.owner_pwd_c)
|
||
throw Error("Invalid /O value (owner password)");
|
||
return util_1.Util.areArraysEqual(owner_pwd, this.cryptoConfiguration.owner_pwd_c);
|
||
}
|
||
}
|
||
exports.RC4CryptoEngine = RC4CryptoEngine;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/document-history.ts":
|
||
/*!*********************************!*\
|
||
!*** ./src/document-history.ts ***!
|
||
\*********************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const util_1 = __webpack_require__(/*! ./util */ "./src/util.ts");
|
||
const object_util_1 = __webpack_require__(/*! ./object-util */ "./src/object-util.ts");
|
||
var generateDefaultTrailer = () => {
|
||
return { size: -1, root: { obj: -1, generation: -1 }, is_encrypted: false };
|
||
};
|
||
/**
|
||
* Holds the complete information of one update section in the Cross-Reference-Stream Object format.
|
||
*
|
||
* */
|
||
class CrossReferenceStreamObject {
|
||
constructor(data) {
|
||
this.data = data;
|
||
this.refs = [];
|
||
this.trailer = generateDefaultTrailer();
|
||
this.streamLength = -1;
|
||
this.w = [];
|
||
this.index = [];
|
||
this.start_pointer = 0;
|
||
}
|
||
/**
|
||
* Extracts a cross reference section that is a continuous definition of cross reference entries
|
||
* */
|
||
extractCrossReferenceSection(first_object_id, object_count, stream) {
|
||
let current_object_id = first_object_id;
|
||
for (let i = 0; i < object_count; ++i) {
|
||
let _type = stream.getNBytesAsNumber(this.w[0]);
|
||
let xref = undefined;
|
||
switch (_type) {
|
||
case 0:
|
||
xref = { id: current_object_id++, pointer: stream.getNBytesAsNumber(this.w[1]), generation: this.w[2] === 0 ? 0 : stream.getNBytesAsNumber(this.w[2]), free: true, update: false };
|
||
break;
|
||
case 1:
|
||
xref = { id: current_object_id++, pointer: stream.getNBytesAsNumber(this.w[1]), generation: this.w[2] === 0 ? 0 : stream.getNBytesAsNumber(this.w[2]), free: false, update: true };
|
||
break;
|
||
case 2:
|
||
// in this case the pointer becomes the stream object id that contains the compressed object and the generation represents the index of the object in the stream
|
||
xref = { id: current_object_id++, pointer: stream.getNBytesAsNumber(this.w[1]), generation: this.w[2] === 0 ? 0 : stream.getNBytesAsNumber(this.w[2]), free: true, update: false, compressed: true };
|
||
break;
|
||
}
|
||
if (xref)
|
||
this.refs.push(xref);
|
||
else
|
||
throw Error(`Invalid cross-reference-stream type ${_type}`);
|
||
}
|
||
}
|
||
/**
|
||
* Extracts the cross-reference-table from the stream
|
||
* */
|
||
extractStream(stream) {
|
||
let cross_reference_length = this.w.reduce((a, b) => a + b, 0);
|
||
// check if the data stream has a valid size
|
||
if (stream.getLength() !== cross_reference_length * this.index.filter((v, i) => i % 2 === 1).reduce((a, b) => a + b, 0))
|
||
throw Error(`Invalid stream length - is ${stream.getLength()} but should be ${cross_reference_length * this.index.filter((v, i) => i % 2 === 1).reduce((a, b) => a + b, 0)}`);
|
||
if (this.index.length % 2 === 1)
|
||
throw Error(`Invalid index flag ${this.index}`);
|
||
for (let i = 0; i < this.index.length; i += 2) {
|
||
this.extractCrossReferenceSection(this.index[i], this.index[i + 1], stream);
|
||
}
|
||
}
|
||
/**
|
||
* Parses the Cross-Reference-Stream-Object at the given index
|
||
* */
|
||
extract(xref) {
|
||
let index = xref.pointer;
|
||
this.start_pointer = index;
|
||
let crs_object = object_util_1.ObjectUtil.extractObject(this.data, xref);
|
||
let ptr_object_end = util_1.Util.locateSequence(util_1.Util.ENDOBJ, this.data, index);
|
||
this.data = this.data.slice(index, ptr_object_end);
|
||
// check type
|
||
if (crs_object.value["/Type"] !== "/XRef")
|
||
throw Error(`Invalid Cross-Reference-Stream-object type: ${crs_object.value["/Type"]}`);
|
||
// extract size
|
||
if (!crs_object.value["/Size"])
|
||
throw Error(`Invalid size value ${crs_object.value["/Size"]}`);
|
||
this.trailer.size = crs_object.value["/Size"];
|
||
// extract ROOT if it exists
|
||
if (crs_object.value["/Root"])
|
||
this.trailer.root = crs_object.value["/Root"];
|
||
// extract PREV if it exists
|
||
if (crs_object.value["/Prev"])
|
||
this.trailer.prev = crs_object.value["/Prev"];
|
||
// extract W parameter
|
||
this.w = crs_object.value["/W"];
|
||
if (!this.w || 0 === this.w.length)
|
||
throw Error("Invalid /W parameter in Cross-Reference-Stream-Object");
|
||
// extract Index parameter
|
||
this.index = crs_object.value["/Index"];
|
||
if (!this.index || 0 === this.index.length)
|
||
this.index = [0, crs_object.value["/Size"]];
|
||
if (!crs_object.stream)
|
||
throw Error("Missing stream at cross reference stream object");
|
||
let stream = crs_object.stream;
|
||
if (!stream)
|
||
throw Error("Invalid stream object");
|
||
this.streamLength = crs_object.value["/Length"];
|
||
this.extractStream(stream);
|
||
// the cross-reference-stream object is also a known reference
|
||
this.refs.push({ id: crs_object.id.obj, pointer: this.start_pointer, generation: crs_object.id.generation, free: false, update: true });
|
||
}
|
||
/**
|
||
* Returs the update section representing this CrossReferenceStreamObject
|
||
* */
|
||
getUpdateSection() {
|
||
return {
|
||
start_pointer: this.start_pointer,
|
||
size: this.trailer.size,
|
||
prev: this.trailer.prev,
|
||
root: this.trailer.root,
|
||
refs: this.refs,
|
||
is_encrypted: this.trailer.is_encrypted,
|
||
encrypt: this.trailer.encrypt,
|
||
id: this.trailer.id
|
||
};
|
||
}
|
||
}
|
||
exports.CrossReferenceStreamObject = CrossReferenceStreamObject;
|
||
/**
|
||
* Holds the complete information of one update section in the Cross-Reference-Table format. That comprises:
|
||
* - the body update
|
||
* - the crossiste reference table
|
||
* - the trailer
|
||
* */
|
||
class CrossReferenceTable {
|
||
constructor(data) {
|
||
this.data = data;
|
||
this.refs = [];
|
||
this.start_pointer = -1;
|
||
this.trailer = generateDefaultTrailer();
|
||
}
|
||
/**
|
||
* Returns the reference with the given id
|
||
* */
|
||
getReference(id) {
|
||
for (let ref of this.refs) {
|
||
if (ref.id === id)
|
||
return ref;
|
||
}
|
||
return undefined;
|
||
}
|
||
/**
|
||
* Returs the update section representing this CrossReferenceTable
|
||
* */
|
||
getUpdateSection() {
|
||
return {
|
||
start_pointer: this.start_pointer,
|
||
size: this.trailer.size,
|
||
refs: this.refs,
|
||
prev: this.trailer.prev,
|
||
root: this.trailer.root,
|
||
is_encrypted: this.trailer.is_encrypted,
|
||
encrypt: this.trailer.encrypt,
|
||
id: this.trailer.id
|
||
};
|
||
}
|
||
/**
|
||
* Extracts the header of a sub section. For instance
|
||
*
|
||
* 0 1 // <--
|
||
* ...
|
||
*
|
||
* So the obejct id 0 and the number of sub section entries 1
|
||
* */
|
||
extractSubSectionHeader(index) {
|
||
let ptr = util_1.Util.locateDelimiter(this.data, index);
|
||
let obj_id = util_1.Util.extractNumber(this.data, index, ptr).result;
|
||
ptr = util_1.Util.skipDelimiter(this.data, ptr + 1);
|
||
let ptr_ref_count = ptr;
|
||
ptr = util_1.Util.locateDelimiter(this.data, ptr);
|
||
let reference_count = util_1.Util.extractNumber(this.data, ptr_ref_count, ptr).result;
|
||
return { id: obj_id, count: reference_count, end_ptr: ptr };
|
||
}
|
||
/**
|
||
* Extracts the references of a sub section. The index points to the start of
|
||
* the first reference and count represents the number of references that are
|
||
* contained in the subsection.
|
||
*
|
||
* The first_object_id is the id provided in the sub section header
|
||
*
|
||
* By definition of the PDF standard one entry is 20 bytes long, but since the standard is rarely respected we better make it failsafe
|
||
* */
|
||
extractReferences(index, count, first_object_id) {
|
||
let _refs = [];
|
||
let res = { result: null, start_index: -1, end_index: index };
|
||
for (let i = 0; count === -1 || i < count; ++i) {
|
||
res = util_1.Util.readNextWord(this.data, res.end_index + 1);
|
||
let pointer = util_1.Util.extractNumber(res.result, 0).result;
|
||
res = util_1.Util.readNextWord(this.data, res.end_index + 1);
|
||
let generation = util_1.Util.extractNumber(res.result, 0).result;
|
||
res = util_1.Util.readNextWord(this.data, res.end_index + 1);
|
||
let ptr_flag = res.result;
|
||
let isFree = ptr_flag[0] === 102; // 102 = f
|
||
_refs.push({
|
||
id: first_object_id + i,
|
||
pointer: pointer,
|
||
generation: generation,
|
||
free: isFree,
|
||
update: !isFree
|
||
});
|
||
// if the word trailer occurs stop since we reached the end
|
||
if (this.data[util_1.Util.skipSpaces(this.data, res.end_index + 1)] === 116) {
|
||
break;
|
||
}
|
||
}
|
||
return { refs: _refs, end_index: res.end_index };
|
||
}
|
||
/**
|
||
* Extracts the trailer of the subsection that means the part stating with the 'trailer' keyword and
|
||
* in particular the trailer dictionary
|
||
* */
|
||
extractTrailer(index) {
|
||
// run forward to the dictionary start
|
||
index = util_1.Util.locateSequence(util_1.Util.DICT_START, this.data, index) + 2;
|
||
let obj = {};
|
||
object_util_1.ObjectUtil.extractDictKeyRec(this.data, index, obj);
|
||
return {
|
||
size: obj["/Size"],
|
||
root: obj["/Root"],
|
||
prev: obj["/Prev"] ? obj["/Prev"] : undefined,
|
||
is_encrypted: obj["/Encrypt"] ? true : false,
|
||
encrypt: obj["/Encrypt"] ? obj["/Encrypt"] : undefined,
|
||
id: obj["/ID"] ? obj["/ID"] : undefined
|
||
};
|
||
}
|
||
/**
|
||
* Parses the Cross Reference Table at the given index
|
||
* */
|
||
extract(index, skipXREFString = false) {
|
||
this.start_pointer = index;
|
||
let start_ptr = index;
|
||
if (!skipXREFString)
|
||
start_ptr += 5; // + length(xref) + blank
|
||
start_ptr = util_1.Util.skipDelimiter(this.data, start_ptr);
|
||
// check if there actually is a subsection header
|
||
// if the line finishes with an 'f' we know that it starts with the first cross reference entry
|
||
let tmp_ptr = start_ptr;
|
||
while (tmp_ptr < this.data.length && this.data[tmp_ptr] !== 102 && this.data[tmp_ptr] !== 13 && this.data[tmp_ptr] !== 10)
|
||
tmp_ptr++;
|
||
let first_header = { id: 0, count: -1, end_ptr: start_ptr - 1 };
|
||
if (this.data[tmp_ptr] === 10 || this.data[tmp_ptr] === 13)
|
||
first_header = this.extractSubSectionHeader(start_ptr);
|
||
let ref_start = util_1.Util.skipDelimiter(this.data, first_header.end_ptr + 1);
|
||
// extract first reference
|
||
let reference_result = this.extractReferences(ref_start, first_header.count, first_header.id);
|
||
this.refs = this.refs.concat(reference_result.refs);
|
||
// extract remaining references
|
||
start_ptr = util_1.Util.skipSpaces(this.data, reference_result.end_index + 1);
|
||
while (first_header.count > 0 && this.data[start_ptr] !== 116) { // 116 = 't' start of the word trailer that concludes the crosssite reference section
|
||
let header = this.extractSubSectionHeader(start_ptr);
|
||
ref_start = util_1.Util.skipDelimiter(this.data, header.end_ptr + 1);
|
||
let references = this.extractReferences(ref_start, header.count, header.id);
|
||
this.refs = this.refs.concat(references.refs);
|
||
start_ptr = util_1.Util.skipSpaces(this.data, references.end_index + 1);
|
||
}
|
||
this.trailer = this.extractTrailer(start_ptr);
|
||
}
|
||
}
|
||
exports.CrossReferenceTable = CrossReferenceTable;
|
||
/**
|
||
* Represents the complete PDF document history and therefore holds the
|
||
* updated body parts, the crosssite references and the document trailers
|
||
* */
|
||
class DocumentHistory {
|
||
constructor(data) {
|
||
this.data = data;
|
||
this.updates = [];
|
||
this.trailerSize = -1;
|
||
/**
|
||
* Holds object ids that were formerly freed and are now 'already' reused.
|
||
* This is used to prevent a freed object a second time */
|
||
this.already_reused_ids = [];
|
||
this.data = new Uint8Array(data);
|
||
}
|
||
/**
|
||
* Extracts the cross reference table starting at the given index
|
||
* */
|
||
extractCrossReferenceTable(index, skipXREFString = false) {
|
||
let crt = new CrossReferenceTable(this.data);
|
||
crt.extract(index, skipXREFString);
|
||
return crt;
|
||
}
|
||
/**
|
||
* Extracts the cross reference stream object starting at the given index
|
||
* */
|
||
extractCrossReferenceStreamObject(xref) {
|
||
let crs = new CrossReferenceStreamObject(this.data);
|
||
crs.extract(xref);
|
||
return crs;
|
||
}
|
||
/**
|
||
* Extracts the last update section of a document (that means
|
||
* the most recent update locating at the end of the file)
|
||
*
|
||
* Handles missing or wrong pointers
|
||
* and also decides, whether the cross reference table is provided as stream object or regular
|
||
* */
|
||
extractDocumentEntry() {
|
||
let ptr = this.data.length - 1;
|
||
let ptr_startxref = util_1.Util.locateSequenceReversed(util_1.Util.STARTXREF, this.data, ptr, true) + 9;
|
||
// identify cross reference section type
|
||
let section_type = "UNKNOWN";
|
||
let preceding_word_index = util_1.Util.skipSpacesReverse(this.data, ptr_startxref - 10);
|
||
if (util_1.Util.areArraysEqual(this.data.slice(preceding_word_index - 5, preceding_word_index + 1), util_1.Util.ENDOBJ)) {
|
||
section_type = "stream";
|
||
}
|
||
else {
|
||
section_type = "trailer";
|
||
}
|
||
// try to locate cross reference table manually
|
||
let locateXREFStartManually = () => {
|
||
let new_ptr = util_1.Util.locateSequenceReversed(util_1.Util.XREF, this.data, this.data.length);
|
||
section_type = "trailer";
|
||
while (new_ptr > 0 && this.data[new_ptr - 1] === 116) { // 116 = 't' -> we are looking for 'xref' not 'startxref'
|
||
new_ptr = util_1.Util.locateSequenceReversed(util_1.Util.XREF, this.data, new_ptr - 1);
|
||
}
|
||
if (new_ptr === -1) { // than we try to identify the word 'trailer' and run backwards as long as we find a symbol that is not a number or 'f' or 'n' - what could possibly go wrong
|
||
section_type = "trailer_without_xref_start";
|
||
new_ptr = util_1.Util.locateSequenceReversed(util_1.Util.TRAILER, this.data, this.data.length);
|
||
if (new_ptr > 0) {
|
||
new_ptr--;
|
||
while (new_ptr > 0 && (util_1.Util.isSpace(this.data[new_ptr]) || util_1.Util.isNumber(this.data[new_ptr]) || this.data[new_ptr] === 110 || //110 = 'n' 102 = 'f'
|
||
this.data[new_ptr] === 102))
|
||
--new_ptr;
|
||
new_ptr = util_1.Util.skipSpaces(this.data, new_ptr + 1);
|
||
}
|
||
}
|
||
return { pointer: new_ptr, sectionType: section_type };
|
||
};
|
||
try {
|
||
ptr = util_1.Util.extractNumber(this.data, ptr_startxref).result;
|
||
}
|
||
catch (err) {
|
||
return locateXREFStartManually();
|
||
}
|
||
if (ptr > this.data.length) {
|
||
return locateXREFStartManually();
|
||
}
|
||
// start section with XREF?
|
||
if (section_type !== "stream" && !(this.data[ptr] === util_1.Util.XREF[0] && this.data[ptr + 1] === util_1.Util.XREF[1] && this.data[ptr + 2] === util_1.Util.XREF[2] && this.data[ptr + 3] === util_1.Util.XREF[3])) {
|
||
return locateXREFStartManually();
|
||
}
|
||
return { pointer: ptr, sectionType: section_type };
|
||
}
|
||
/**
|
||
* Extracts the entire update sections
|
||
*
|
||
* Needs to adapt depending whether the document uses a cross-reference table or a cross-reference stream object
|
||
* */
|
||
extractDocumentHistory() {
|
||
let document_entry = this.extractDocumentEntry();
|
||
let ptr = document_entry.pointer;
|
||
if (ptr === -1) {
|
||
throw Error("Could not locate document entry");
|
||
}
|
||
let xref = {
|
||
id: -1,
|
||
pointer: ptr,
|
||
generation: 0,
|
||
free: false,
|
||
update: true
|
||
};
|
||
this.extractCrossReferenceTables(document_entry, xref);
|
||
// adapt pointer in case there is junk before the header
|
||
let pdf_header_start = util_1.Util.locateSequence(util_1.Util.VERSION, this.data, 0);
|
||
if (pdf_header_start !== 0 && pdf_header_start !== -1) {
|
||
for (let updateSection of this.updates) {
|
||
for (let ref of updateSection.refs) {
|
||
ref.pointer += pdf_header_start;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* Extracts the cross reference tables of the entire document
|
||
* */
|
||
extractCrossReferenceTables(document_entry, xref) {
|
||
let ptr = document_entry.pointer;
|
||
// Handle cross reference table
|
||
if (document_entry.sectionType === "trailer") {
|
||
let crt = this.extractCrossReferenceTable(ptr);
|
||
this.updates.push(crt.getUpdateSection());
|
||
let us = this.updates[0];
|
||
while (us.prev) {
|
||
crt = this.extractCrossReferenceTable(us.prev);
|
||
this.updates.push(crt.getUpdateSection());
|
||
us = this.updates[this.updates.length - 1];
|
||
}
|
||
}
|
||
else if (document_entry.sectionType === "stream") { // handle cross reference stream object
|
||
let crs = this.extractCrossReferenceStreamObject(xref);
|
||
this.updates.push(crs.getUpdateSection());
|
||
let us = this.updates[0];
|
||
while (us.prev) {
|
||
let _xref = {
|
||
id: -1,
|
||
pointer: us.prev,
|
||
generation: 0,
|
||
free: false,
|
||
update: true
|
||
};
|
||
crs = this.extractCrossReferenceStreamObject(_xref);
|
||
this.updates.push(crs.getUpdateSection());
|
||
us = this.updates[this.updates.length - 1];
|
||
}
|
||
}
|
||
else if (document_entry.sectionType === "trailer_without_xref_start") {
|
||
let crt = this.extractCrossReferenceTable(ptr, true);
|
||
this.updates.push(crt.getUpdateSection());
|
||
let us = this.updates[0];
|
||
while (us.prev) {
|
||
crt = this.extractCrossReferenceTable(us.prev);
|
||
this.updates.push(crt.getUpdateSection());
|
||
us = this.updates[this.updates.length - 1];
|
||
}
|
||
}
|
||
else {
|
||
throw Error("Could not part cross reference table");
|
||
}
|
||
this.trailerSize = this.extractReferenceNumberCount();
|
||
}
|
||
/**
|
||
* Counts the number of specified objects
|
||
* */
|
||
extractReferenceNumberCount() {
|
||
let visited = [];
|
||
let count = 0;
|
||
for (let update of this.updates) {
|
||
for (let ref of update.refs) {
|
||
if (!visited.includes(ref.id)) {
|
||
count++;
|
||
visited.push(ref.id);
|
||
}
|
||
}
|
||
}
|
||
return count;
|
||
}
|
||
/**
|
||
* Primarily for clarification. The first element is the most recent. We parsed backwards.
|
||
* */
|
||
getRecentUpdate() {
|
||
return this.updates[0];
|
||
}
|
||
/**
|
||
* Indicates whether the PDF document is encrypted
|
||
* */
|
||
isEncrypted() {
|
||
return this.getRecentUpdate().is_encrypted;
|
||
}
|
||
/**
|
||
* By running through the PDf history we can for every object id determine the pointer address to the most recent version, and
|
||
* whether the object id is still in used.
|
||
*
|
||
* So the object lookup table has an entry for every existing object id, a pointer to the the most recent object definition, as long
|
||
* as the object exists, or an according indication otherwise.
|
||
* */
|
||
createObjectLookupTable() {
|
||
let objTable = {};
|
||
let update = this.getRecentUpdate();
|
||
let i = 1;
|
||
while (Object.keys(objTable).length < this.extractReferenceNumberCount()) {
|
||
let refs = update.refs;
|
||
for (let ref of refs) {
|
||
if (!objTable.hasOwnProperty(ref.id)) {
|
||
objTable[ref.id] = ref;
|
||
}
|
||
}
|
||
update = this.updates[i];
|
||
++i;
|
||
}
|
||
return objTable;
|
||
}
|
||
/**
|
||
* Returns the new object id. It primarily tries to reuse an existing id, but if no such exists it will return a
|
||
* new one
|
||
* */
|
||
getFreeObjectId() {
|
||
let objectLookupTable = this.createObjectLookupTable();
|
||
let free_header = objectLookupTable[0];
|
||
if (!free_header)
|
||
throw Error("Crosssite reference has no header for the linked list of free objects");
|
||
// if the pointer of object 0 points to 0 there is no freed object that can be reused
|
||
if (0 === free_header.pointer) {
|
||
if (-1 === this.trailerSize)
|
||
throw Error("Trailer size not set");
|
||
return { obj: this.trailerSize++, generation: 0, reused: false };
|
||
}
|
||
// get list head
|
||
let ptr = free_header.pointer;
|
||
let freedHeaderList = [];
|
||
while (ptr !== 0) {
|
||
freedHeaderList.push(free_header);
|
||
free_header = objectLookupTable[ptr];
|
||
if (!free_header.free) {
|
||
// handle the case of an incosistent xref
|
||
return { obj: this.trailerSize++, generation: 0, reused: false };
|
||
}
|
||
ptr = free_header.pointer;
|
||
}
|
||
let getFreeHeader = (freeHeaderList) => {
|
||
for (let p of freeHeaderList.reverse()) {
|
||
if (p.generation < 65535 && // max generation number
|
||
-1 === this.already_reused_ids.indexOf(p)) { // not already reused
|
||
return p;
|
||
}
|
||
}
|
||
return undefined;
|
||
};
|
||
let reused_free_header = getFreeHeader(freedHeaderList);
|
||
if (reused_free_header) {
|
||
free_header = reused_free_header;
|
||
// store used id to make sure it will not be selected again
|
||
this.already_reused_ids.push(free_header);
|
||
}
|
||
else {
|
||
// handle the case that all freed object ids are already reused
|
||
return { obj: this.trailerSize++, generation: 0, reused: false };
|
||
}
|
||
return { obj: free_header.pointer, generation: objectLookupTable[free_header.id].generation, reused: true };
|
||
}
|
||
}
|
||
exports.DocumentHistory = DocumentHistory;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/index.ts":
|
||
/*!**********************!*\
|
||
!*** ./src/index.ts ***!
|
||
\**********************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
var parser_1 = __webpack_require__(/*! ./parser */ "./src/parser.ts");
|
||
exports.PDFDocumentParser = parser_1.PDFDocumentParser;
|
||
var annotation_types_1 = __webpack_require__(/*! ./annotations/annotation_types */ "./src/annotations/annotation_types.ts");
|
||
exports.LineEndingStyle = annotation_types_1.LineEndingStyle;
|
||
var text_annotation_1 = __webpack_require__(/*! ./annotations/text_annotation */ "./src/annotations/text_annotation.ts");
|
||
exports.AnnotationIcon = text_annotation_1.AnnotationIcon;
|
||
exports.AnnotationState = text_annotation_1.AnnotationState;
|
||
exports.AnnotationStateModel = text_annotation_1.AnnotationStateModel;
|
||
var freetext_annotation_1 = __webpack_require__(/*! ./annotations/freetext_annotation */ "./src/annotations/freetext_annotation.ts");
|
||
exports.TextJustification = freetext_annotation_1.TextJustification;
|
||
exports.FreeTextType = freetext_annotation_1.FreeTextType;
|
||
var util_1 = __webpack_require__(/*! ./util */ "./src/util.ts");
|
||
exports.Util = util_1.Util;
|
||
var annotation_1 = __webpack_require__(/*! ./annotation */ "./src/annotation.ts");
|
||
exports.AnnotationFactory = annotation_1.AnnotationFactory;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/object-util.ts":
|
||
/*!****************************!*\
|
||
!*** ./src/object-util.ts ***!
|
||
\****************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const util_1 = __webpack_require__(/*! ./util */ "./src/util.ts");
|
||
const array_util_1 = __webpack_require__(/*! ./array-util */ "./src/array-util.ts");
|
||
const stream_1 = __webpack_require__(/*! ./stream */ "./src/stream.ts");
|
||
/**
|
||
* While the general Util class holds low level methods to navigate through the pdf data, the ObjectUtil
|
||
* is purposefully build to extract complete objects. It returns those as json dictionaries.
|
||
* */
|
||
class ObjectUtil {
|
||
static extractDictKeyRec(data, ptr, dict) {
|
||
let next = util_1.Util.readNextWord(data, ptr);
|
||
let next_string = next.result;
|
||
if (!next_string)
|
||
return ptr;
|
||
let _ptr = util_1.Util.skipDelimiter(next_string, 0);
|
||
if (next_string[0] && util_1.Util.DICT_END[0] === next_string[0]) {
|
||
let wordLookup = util_1.Util.readNextWord(data, next.end_index + 1);
|
||
if (wordLookup.result && util_1.Util.DICT_END[0] === wordLookup.result[0]) {
|
||
return wordLookup.end_index;
|
||
}
|
||
}
|
||
return ObjectUtil.extractDictValueRec(data, next.end_index + 1, dict, util_1.Util.convertAsciiToString(next_string));
|
||
}
|
||
static extractDictValueRec(data, ptr, dict, current_key = undefined) {
|
||
let next = util_1.Util.readNextWord(data, ptr);
|
||
let next_string = next.result || new Uint8Array([]);
|
||
ptr = next.end_index - next_string.length + 1;
|
||
if (next_string[0] === util_1.Util.ARRAY_START[0]) {
|
||
if (!current_key)
|
||
throw Error("Invalid anonymous array definition");
|
||
// handle array
|
||
let extracted_array = array_util_1.ArrayUtil.extractArray(data, ptr);
|
||
dict[current_key] = extracted_array.result;
|
||
return ObjectUtil.extractDictKeyRec(data, extracted_array.end_index + 1, dict);
|
||
}
|
||
else if (next_string[0] === util_1.Util.DICT_START[0] && data[next.end_index + 1] === util_1.Util.DICT_START[0]) {
|
||
if (current_key) {
|
||
let sup_dict = {};
|
||
let end_sub_dict = ObjectUtil.extractDictKeyRec(data, next.end_index + 2, sup_dict);
|
||
dict[current_key] = sup_dict;
|
||
return ObjectUtil.extractDictKeyRec(data, end_sub_dict + 1, dict);
|
||
}
|
||
else {
|
||
return ObjectUtil.extractDictKeyRec(data, next.end_index + 2, dict);
|
||
}
|
||
}
|
||
else if (next_string[0] === util_1.Util.HEX_STRING_START[0]) {
|
||
if (!current_key)
|
||
throw Error("Invalid anonymous string definition");
|
||
let extracted_string = util_1.Util.extractHexString(data, ptr);
|
||
dict[current_key] = extracted_string.result;
|
||
return ObjectUtil.extractDictKeyRec(data, extracted_string.end_index + 1, dict);
|
||
}
|
||
else if (next_string[0] === util_1.Util.LITERAL_STRING_START[0]) {
|
||
if (!current_key)
|
||
throw Error("Invalid anonymous string definition");
|
||
let extracted_string = util_1.Util.extractString(data, ptr);
|
||
dict[current_key] = extracted_string.result;
|
||
return ObjectUtil.extractDictKeyRec(data, extracted_string.end_index + 1, dict);
|
||
}
|
||
else if (next_string[0] === 47) { // /
|
||
if (!current_key)
|
||
throw Error("Invalid anonymous property definition");
|
||
let opt_value = util_1.Util.extractOptionValue(data, ptr);
|
||
dict[current_key] = "/" + opt_value.result;
|
||
return ObjectUtil.extractDictKeyRec(data, opt_value.end_index + 1, dict);
|
||
}
|
||
else { // It is a number, but this number might be part of a Reference
|
||
let lookupNext = util_1.Util.readNextWord(data, next.end_index + 1);
|
||
let lookupNextWord = lookupNext.result || new Uint8Array([]);
|
||
if (!current_key)
|
||
throw Error("Invalid anonymous reference/number definition");
|
||
let value_end_ptr = next.end_index + 1;
|
||
if (lookupNextWord[0] === 47 || lookupNextWord[0] === util_1.Util.DICT_END[0]) { // is a number
|
||
dict[current_key] = util_1.Util.extractNumber(data, ptr).result;
|
||
}
|
||
else { // is a rereference
|
||
let extracted_reference = util_1.Util.extractReferenceTyped(data, ptr);
|
||
dict[current_key] = extracted_reference.result;
|
||
value_end_ptr = extracted_reference.end_index + 1;
|
||
}
|
||
// handle Reference
|
||
return ObjectUtil.extractDictKeyRec(data, value_end_ptr, dict);
|
||
}
|
||
throw Error(`Could not interpret: ${util_1.Util.convertAsciiToString(next_string)}`);
|
||
}
|
||
/**
|
||
* Locates the object start in case the ptr does not point correctly
|
||
* */
|
||
static locateObjectStart(data, ptr) {
|
||
let obj_ptr = util_1.Util.locateSequence(util_1.Util.OBJ, data, ptr);
|
||
let endobj_ptr = util_1.Util.locateSequence(util_1.Util.ENDOBJ, data, ptr);
|
||
let consumeGenerationAndNumberRevere = (ptr) => {
|
||
// <id> <generation> obj ... endobj
|
||
// ^
|
||
// being somewhere here
|
||
let new_ptr = util_1.Util.skipSpacesReverse(data, ptr - 1);
|
||
// <id> <generation> obj ... endobj
|
||
// ^
|
||
// being somewhere here
|
||
while (new_ptr > 0 && !util_1.Util.isDelimiter(data[new_ptr]))
|
||
--new_ptr;
|
||
// <id> <generation> obj ... endobj
|
||
// ^
|
||
// being somewhere here
|
||
new_ptr = util_1.Util.skipSpacesReverse(data, new_ptr - 1);
|
||
// <id> <generation> obj ... endobj
|
||
// ^
|
||
// being somewhere here
|
||
while (new_ptr > 0 && !util_1.Util.isDelimiter(data[new_ptr]))
|
||
--new_ptr;
|
||
return new_ptr;
|
||
};
|
||
if (obj_ptr !== -1 && obj_ptr < endobj_ptr) {
|
||
return consumeGenerationAndNumberRevere(obj_ptr);
|
||
}
|
||
else if (obj_ptr > endobj_ptr || (obj_ptr === -1 && endobj_ptr > -1)) {
|
||
// <id> <generation> obj ... endobj
|
||
// ^
|
||
// being somewhere here
|
||
let new_ptr = util_1.Util.locateSequenceReversed(util_1.Util.OBJ, data, ptr);
|
||
return consumeGenerationAndNumberRevere(new_ptr);
|
||
}
|
||
else {
|
||
throw Error("Could not correct object start");
|
||
}
|
||
}
|
||
/**
|
||
* Parses a PDF object and returns a dictionary containing its fields
|
||
* */
|
||
static extractObject(data, xref, objectLookupTable = undefined) {
|
||
if (typeof xref !== 'number' && xref.compressed) {
|
||
if (!objectLookupTable)
|
||
throw Error("Provide ObjectLookupTable to extract stream object");
|
||
return ObjectUtil.extractStreamObject(data, xref.id, xref.generation, objectLookupTable[xref.pointer]);
|
||
}
|
||
let ret_obj = {};
|
||
let ptr = typeof xref === 'number' ? xref : xref.pointer;
|
||
let object_id = util_1.Util.extractObjectId(data, ptr);
|
||
if (isNaN(object_id.obj) || isNaN(object_id.generation)) {
|
||
return ObjectUtil.extractObject(data, ObjectUtil.locateObjectStart(data, ptr), objectLookupTable);
|
||
}
|
||
ret_obj.id = object_id;
|
||
ptr = util_1.Util.locateSequence(util_1.Util.OBJ, data, ptr);
|
||
if (ptr === -1)
|
||
throw { message: "Object missing 'obj' sequence", name: "MissingObjSequenceError" };
|
||
ptr += util_1.Util.OBJ.length;
|
||
let ptr_obj_end = util_1.Util.locateSequence(util_1.Util.ENDOBJ, data, ptr);
|
||
data = data.slice(ptr, ptr_obj_end);
|
||
// determine the type of the object:
|
||
let next = util_1.Util.readNextWord(data, 0);
|
||
if (next.result && next.result[0] === util_1.Util.DICT_START[0]) { // object contains a dict
|
||
let result_dict = {};
|
||
ObjectUtil.extractDictValueRec(data, 0, result_dict);
|
||
ret_obj.value = result_dict;
|
||
}
|
||
else if (next.result && next.result[0] === util_1.Util.ARRAY_START[0]) { // object contains an array
|
||
let lst = array_util_1.ArrayUtil.extractArray(data, 0);
|
||
ret_obj.value = lst.result;
|
||
}
|
||
else {
|
||
throw Error(`Invalid object type - starting with: ${next.result}`);
|
||
}
|
||
// check if the object has a stream part
|
||
ptr = util_1.Util.locateSequence(util_1.Util.STREAM, data, 0);
|
||
if (-1 !== ptr) {
|
||
// extract stream part
|
||
let ptr_stream_data_start = ptr + util_1.Util.STREAM.length;
|
||
ptr_stream_data_start = util_1.Util.skipDelimiter(data, ptr_stream_data_start);
|
||
let ptr_stream_data_end = ptr_stream_data_start + ret_obj.value["/Length"];
|
||
ret_obj.stream = ObjectUtil.extractStreamData(data.slice(ptr_stream_data_start, ptr_stream_data_end), ret_obj.value["/Filter"], ObjectUtil.translateDecodeParams(ret_obj));
|
||
}
|
||
return ret_obj;
|
||
}
|
||
static extractStreamObject(data, object_id_to_extract, offset, streamObj_xref) {
|
||
let ptr = streamObj_xref.pointer;
|
||
let ret_obj = {};
|
||
// extract object id
|
||
let object_id = util_1.Util.extractObjectId(data, ptr);
|
||
ret_obj.id = object_id;
|
||
ptr = util_1.Util.locateSequence(util_1.Util.OBJ, data, ptr) + util_1.Util.OBJ.length;
|
||
let ptr_obj_end = util_1.Util.locateSequence(util_1.Util.ENDOBJ, data, ptr);
|
||
data = data.slice(ptr, ptr_obj_end);
|
||
// extract dict part
|
||
let next = util_1.Util.readNextWord(data, 0);
|
||
if (!next.result || next.result[0] !== util_1.Util.DICT_START[0]) {
|
||
throw Error("Invalid stream object -- no dict");
|
||
}
|
||
let result_dict = {};
|
||
ObjectUtil.extractDictValueRec(data, 0, result_dict);
|
||
ret_obj.value = result_dict;
|
||
if (result_dict["/Filter"] && Array.isArray(result_dict["/Filter"]) && result_dict["/Filter"].length > 0)
|
||
result_dict["/Filter"] = result_dict["/Filter"][0];
|
||
// check if filter is supported
|
||
if (!result_dict["/Filter"] || result_dict["/Filter"] !== "/FlateDecode")
|
||
throw Error(`Unsupported stream filter: ${result_dict["/Filter"]} - Only supported filter is FlateDecode`);
|
||
if (!result_dict["/Type"] || result_dict["/Type"] !== "/ObjStm")
|
||
throw Error(`Invalid stream object type: ${result_dict["/Type"]}`);
|
||
// extract the stream length
|
||
let streamLength = result_dict["/Length"];
|
||
// extract stream part
|
||
let ptr_stream_data_start = util_1.Util.locateSequence(util_1.Util.STREAM, data) + util_1.Util.STREAM.length;
|
||
ptr_stream_data_start = util_1.Util.skipDelimiter(data, ptr_stream_data_start);
|
||
let ptr_stream_data_end = ptr_stream_data_start + streamLength;
|
||
let stream = ObjectUtil.extractStreamData(data.slice(ptr_stream_data_start, ptr_stream_data_end), result_dict["/Filter"], ObjectUtil.translateDecodeParams(result_dict));
|
||
if (!result_dict["/N"])
|
||
throw Error("Invalid stream object -- no number of objects specified");
|
||
if (!result_dict["/First"])
|
||
throw Error("Invalid stream object -- no offset to the first objct specified");
|
||
let streamReferences = ObjectUtil.extractStreamObjectTable(stream, result_dict["/N"], result_dict["/First"]);
|
||
if (!streamReferences[object_id_to_extract])
|
||
throw Error(`Object ${object_id_to_extract} not in stream object`);
|
||
let result_obj = { id: { obj: object_id_to_extract, generation: 0 } };
|
||
let stream_data = stream.getData();
|
||
next = util_1.Util.readNextWord(stream_data, streamReferences[object_id_to_extract]);
|
||
if (next.result && next.result[0] === util_1.Util.DICT_START[0]) { // object contains a dict
|
||
let value = {};
|
||
result_obj.pointer_stream_end = ObjectUtil.extractDictValueRec(stream_data, streamReferences[object_id_to_extract], value);
|
||
result_obj.value = value;
|
||
result_obj.stream = stream;
|
||
result_obj.pointer_stream_start = streamReferences[object_id_to_extract];
|
||
}
|
||
else if (next.result && next.result[0] === util_1.Util.ARRAY_START[0]) { // object contains an array
|
||
let lst = array_util_1.ArrayUtil.extractArray(stream_data, streamReferences[object_id_to_extract]);
|
||
result_obj.value = lst.result;
|
||
result_obj.stream = stream;
|
||
result_obj.pointer_stream_start = streamReferences[object_id_to_extract];
|
||
}
|
||
else {
|
||
throw Error(`Invalid stream object type - starting with: ${next.result}`);
|
||
}
|
||
return result_obj;
|
||
}
|
||
static translateDecodeParams(dict) {
|
||
if (!dict.value)
|
||
return undefined;
|
||
if (!dict.value["/DecodeParms"])
|
||
return undefined;
|
||
if (!dict.value["/DecodeParms"]["/Columns"])
|
||
return undefined;
|
||
if (!dict.value["/DecodeParms"]["/Predictor"])
|
||
return undefined;
|
||
return { columns: dict.value["/DecodeParms"]["/Columns"], predictor: dict.value["/DecodeParms"]["/Predictor"] };
|
||
}
|
||
static extractStreamObjectTable(stream, number_of_obj, offset_first_obj) {
|
||
let references = {};
|
||
for (let i = 0; i < number_of_obj; ++i) {
|
||
let obj_id = stream.getNumber();
|
||
let pointer = stream.getNumber() + offset_first_obj;
|
||
references[obj_id] = pointer;
|
||
}
|
||
return references;
|
||
}
|
||
static extractStreamData(streamData, compression, decodeParameters = undefined) {
|
||
let stream = undefined;
|
||
if (compression === '/FlateDecode') {
|
||
stream = new stream_1.FlateStream(streamData, decodeParameters);
|
||
}
|
||
else {
|
||
throw Error(`Unsupported stream filter: ${compression} - Only supported filter is FlateDecode (right now)`);
|
||
}
|
||
if (!stream)
|
||
throw Error("Could not derive stream");
|
||
return stream;
|
||
}
|
||
}
|
||
exports.ObjectUtil = ObjectUtil;
|
||
ObjectUtil.i = 0;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/parser.ts":
|
||
/*!***********************!*\
|
||
!*** ./src/parser.ts ***!
|
||
\***********************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const util_1 = __webpack_require__(/*! ./util */ "./src/util.ts");
|
||
const object_util_1 = __webpack_require__(/*! ./object-util */ "./src/object-util.ts");
|
||
const document_history_1 = __webpack_require__(/*! ./document-history */ "./src/document-history.ts");
|
||
const crypto_1 = __webpack_require__(/*! ./crypto */ "./src/crypto.ts");
|
||
class _Annotation {
|
||
constructor(data = new Uint8Array([]), cryptoInterface = new CryptoInterface()) {
|
||
this.data = data;
|
||
this.cryptoInterface = cryptoInterface;
|
||
this.page = -1; // the target page of the annotation
|
||
this.type = ""; // the sub type of the array (Text, Highlight, ...)
|
||
this.object_id = undefined; // an unused object id
|
||
this.id = ""; // unique annation identifier
|
||
this.rect = []; // the location of the annotation
|
||
this.author = ""; // the author of the annotation
|
||
this.pageReference = undefined; // The reference to the page object to which the annotation is added
|
||
this.updateDate = ""; // The date when the annotation was created or updated
|
||
this.border = undefined; // define the border
|
||
this.color = undefined; // the color set
|
||
this.fill = undefined; // the fill color set
|
||
this.data = data;
|
||
}
|
||
writeAnnotationPreamble() {
|
||
throw Error("Error");
|
||
}
|
||
writeAnnotationPostamble() {
|
||
throw Error("Error");
|
||
}
|
||
writeAnnotationObject(cryptoInterface) {
|
||
throw Error("Error");
|
||
}
|
||
encodeAnnotationFlags() {
|
||
if (!this.annotationFlags) {
|
||
return 0;
|
||
}
|
||
let val = 0;
|
||
if (this.annotationFlags.invisible) {
|
||
val |= 1;
|
||
}
|
||
if (this.annotationFlags.hidden) {
|
||
val |= 2;
|
||
}
|
||
if (this.annotationFlags.print) {
|
||
val |= 4;
|
||
}
|
||
if (this.annotationFlags.noZoom) {
|
||
val |= 8;
|
||
}
|
||
if (this.annotationFlags.noRotate) {
|
||
val |= 16;
|
||
}
|
||
if (this.annotationFlags.noView) {
|
||
val |= 32;
|
||
}
|
||
if (this.annotationFlags.readOnly) {
|
||
val |= 64;
|
||
}
|
||
if (this.annotationFlags.locked) {
|
||
val |= 128;
|
||
}
|
||
if (this.annotationFlags.toggleNoView) {
|
||
val |= 256;
|
||
}
|
||
if (this.annotationFlags.lockedContents) {
|
||
val |= 512;
|
||
}
|
||
return val;
|
||
}
|
||
/**
|
||
* Extract the annotation object (partially)
|
||
* */
|
||
extract(xref, page, objectLookupTable) {
|
||
let annot_obj = object_util_1.ObjectUtil.extractObject(this.data, xref, objectLookupTable);
|
||
this.object_id = annot_obj.id;
|
||
annot_obj = annot_obj.value;
|
||
this.type = annot_obj["/Subtype"];
|
||
this.rect = annot_obj["/Rect"];
|
||
this.pageReference = page;
|
||
if (annot_obj["/M"])
|
||
this.updateDate = util_1.Util.convertUnicodeToString(this.cryptoInterface.decrypt(annot_obj["/M"], this.object_id));
|
||
if (annot_obj["/Border"])
|
||
this.border = annot_obj["/Border"];
|
||
if (annot_obj["/C"])
|
||
this.color = annot_obj["/C"];
|
||
if (annot_obj["/T"])
|
||
this.author = util_1.Util.convertUnicodeToString(this.cryptoInterface.decrypt(annot_obj["/T"], this.object_id));
|
||
if (annot_obj["/NM"])
|
||
this.id = util_1.Util.convertUnicodeToString(this.cryptoInterface.decrypt(annot_obj["/NM"], this.object_id));
|
||
if (annot_obj["/Contents"])
|
||
this.contents = util_1.Util.convertUnicodeToString(this.cryptoInterface.decrypt(annot_obj["/Contents"], this.object_id));
|
||
if (annot_obj["/QuadPoints"])
|
||
this.quadPoints = annot_obj["/QuadPoints"];
|
||
if (annot_obj["/Inklist"])
|
||
this.inkList = annot_obj["/Inklist"];
|
||
}
|
||
}
|
||
exports._Annotation = _Annotation;
|
||
/**
|
||
* Represents the Catalog object of the PDF document
|
||
* */
|
||
class CatalogObject {
|
||
/**
|
||
* Extracts the data representing the object.
|
||
* */
|
||
constructor(data, xref, objectLookupTable) {
|
||
this.data = data;
|
||
this.xref = xref;
|
||
this.objectLookupTable = objectLookupTable;
|
||
this.pagesObjectId = { obj: -1, generation: -1 };
|
||
this.data = data;
|
||
let page_obj = object_util_1.ObjectUtil.extractObject(this.data, xref, objectLookupTable).value;
|
||
if (page_obj["/Type"] !== "/Catalog")
|
||
throw Error(`Invalid catalog object at position ${xref.pointer}`);
|
||
this.pagesObjectId = page_obj["/Pages"];
|
||
}
|
||
getPagesObjectId() {
|
||
return this.pagesObjectId;
|
||
}
|
||
}
|
||
exports.CatalogObject = CatalogObject;
|
||
/**
|
||
* Represents the PageTree object of the PDF document
|
||
* This is the object with /Type /Pages
|
||
* */
|
||
class PageTree {
|
||
constructor(data, objectLookupTable) {
|
||
this.data = data;
|
||
this.objectLookupTable = objectLookupTable;
|
||
this.pageCount = -1;
|
||
this.pageReferences = [];
|
||
this.visitedPages = [];
|
||
this.data = data;
|
||
}
|
||
/**
|
||
* Extracts the kids references recursively.
|
||
* For every kid it checks if the referenced object type is:
|
||
* - a /Pages object then it recursively lookups its children
|
||
* - a /Page object then it adds the references
|
||
* */
|
||
extractPageReferences(references) {
|
||
for (let reference of references) {
|
||
if (this.visitedPages.some(el => el.obj === reference.obj &&
|
||
el.generation === reference.generation)) {
|
||
continue;
|
||
}
|
||
let xref = this.objectLookupTable[reference.obj];
|
||
let kid_page_obj = object_util_1.ObjectUtil.extractObject(this.data, xref, this.objectLookupTable).value;
|
||
if (kid_page_obj["/Type"] === "/Page") {
|
||
this.pageReferences.push(reference);
|
||
}
|
||
else if (kid_page_obj["/Type"] === "/Pages") {
|
||
this.visitedPages.push(reference);
|
||
this.extractPageReferences(kid_page_obj["/Kids"]);
|
||
}
|
||
else {
|
||
throw Error(`Invalid object type ${kid_page_obj["/Type"]}`);
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* Extract the object data at the given pointer
|
||
* */
|
||
extract(xref, objectLookupTable) {
|
||
let page_tree_obj = object_util_1.ObjectUtil.extractObject(this.data, xref, objectLookupTable).value;
|
||
if (!page_tree_obj["/Kids"])
|
||
throw Error(`Could not find index of /Kids in /Pages object`);
|
||
let refs = page_tree_obj["/Kids"];
|
||
this.pageReferences = [];
|
||
this.extractPageReferences(refs);
|
||
this.pageCount = this.pageReferences.length;
|
||
}
|
||
/**
|
||
* Returns the number of pages the page tree comprises
|
||
* */
|
||
getPageCount() {
|
||
return this.pageCount;
|
||
}
|
||
/**
|
||
* Returns the reference to the page objects
|
||
* */
|
||
getPageReferences() {
|
||
return this.pageReferences;
|
||
}
|
||
}
|
||
exports.PageTree = PageTree;
|
||
/**
|
||
* Represents a page object in the PDF document
|
||
* */
|
||
class Page {
|
||
constructor(data, documentHistory) {
|
||
this.data = data;
|
||
this.documentHistory = documentHistory;
|
||
this.annots = [];
|
||
this.hasAnnotsField = false;
|
||
this.data = data;
|
||
}
|
||
/**
|
||
* Extracts the references in the linked annotations array
|
||
* */
|
||
extractAnnotationArray() {
|
||
let obj_table = this.documentHistory.createObjectLookupTable();
|
||
if (!this.annotsPointer)
|
||
throw Error("Annotations pointer not set");
|
||
let ref_annot_table = obj_table[this.annotsPointer.obj];
|
||
let annotations_obj = object_util_1.ObjectUtil.extractObject(this.data, ref_annot_table, obj_table);
|
||
this.annots = annotations_obj.value;
|
||
}
|
||
/**
|
||
* Extracts the page object starting at position ptr
|
||
* */
|
||
extract(xref, objectLookupTable) {
|
||
let page_obj = object_util_1.ObjectUtil.extractObject(this.data, xref, objectLookupTable);
|
||
this.object_id = page_obj.id;
|
||
let annots = page_obj.value["/Annots"];
|
||
if (annots) {
|
||
this.hasAnnotsField = true;
|
||
if (Array.isArray(annots)) {
|
||
this.annots = annots.filter((x) => x !== 'null');
|
||
}
|
||
else {
|
||
this.annotsPointer = annots;
|
||
this.extractAnnotationArray();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
exports.Page = Page;
|
||
/**
|
||
* Provides a configured interface to handle the encryption and decryption of PDFs
|
||
* */
|
||
class CryptoInterface {
|
||
constructor(data, documentHistory, ref_ptr, user_pwd, owner_pwd) {
|
||
this.data = data;
|
||
this.documentHistory = documentHistory;
|
||
this.ref_ptr = ref_ptr;
|
||
this.cryptoConfiguration = { version: undefined, revision: undefined, filter: undefined, user_pwd: "", owner_pwd: "", length: undefined, permissions: undefined, owner_pwd_c: undefined, user_pwd_c: undefined };
|
||
this.cryptoEngine = new crypto_1.IdentityEngine();
|
||
this.data = data;
|
||
this.documentHistory = documentHistory;
|
||
this.cryptoConfiguration.user_pwd = user_pwd ? user_pwd : "";
|
||
this.cryptoConfiguration.owner_pwd = owner_pwd ? owner_pwd : "";
|
||
if (this.ref_ptr && this.documentHistory) {
|
||
this.extractEncryptionDictionary(this.ref_ptr);
|
||
// setup crypto-engine
|
||
if (this.cryptoConfiguration.version === 1) {
|
||
this.cryptoEngine = new crypto_1.RC4CryptoEngine(this.cryptoConfiguration, this.documentHistory.getRecentUpdate().id, crypto_1.RC4_40_BIT);
|
||
}
|
||
else if (this.cryptoConfiguration.version === 2) {
|
||
this.cryptoEngine = new crypto_1.RC4CryptoEngine(this.cryptoConfiguration, this.documentHistory.getRecentUpdate().id);
|
||
}
|
||
else if (this.cryptoConfiguration.version === 4) {
|
||
console.log("Some fancy AES encryption");
|
||
}
|
||
else {
|
||
throw Error(`Unsupported Encryption ${this.cryptoConfiguration.version}`);
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* Returns the reference pointer
|
||
* */
|
||
getEncryptionDictReference() {
|
||
if (!this.ref_ptr)
|
||
return undefined;
|
||
return { obj: this.ref_ptr.id, generation: this.ref_ptr.generation };
|
||
}
|
||
encrypt(data, reference) {
|
||
return this.cryptoEngine.encrypt(data, reference);
|
||
}
|
||
decrypt(data, reference) {
|
||
return this.cryptoEngine.decrypt(data, reference);
|
||
}
|
||
isUserPasswordCorrect() {
|
||
if (!this.cryptoEngine) {
|
||
throw Error("Crypto engine not configured");
|
||
}
|
||
return this.cryptoEngine.isUserPasswordCorrect();
|
||
}
|
||
isOwnerPasswordCorrect() {
|
||
if (!this.cryptoEngine) {
|
||
throw Error("Crypto engine not configured");
|
||
}
|
||
return this.cryptoEngine.isOwnerPasswordCorrect();
|
||
}
|
||
/**
|
||
* Extracts the enrcyption dictionary
|
||
* */
|
||
extractEncryptionDictionary(ptr) {
|
||
if (!this.documentHistory) {
|
||
throw Error("Documenthistory not configured");
|
||
}
|
||
if (!this.data) {
|
||
throw Error("Data not configured");
|
||
}
|
||
let obj_table = this.documentHistory.createObjectLookupTable();
|
||
let page_obj = object_util_1.ObjectUtil.extractObject(this.data, ptr, obj_table);
|
||
this.cryptoConfiguration.version = page_obj.value["/V"];
|
||
this.cryptoConfiguration.revision = page_obj.value["/R"];
|
||
this.cryptoConfiguration.filter = page_obj.value["/Filter"];
|
||
this.cryptoConfiguration.user_pwd_c = page_obj.value["/U"];
|
||
this.cryptoConfiguration.owner_pwd_c = page_obj.value["/O"];
|
||
this.cryptoConfiguration.length = page_obj.value["/Length"];
|
||
this.cryptoConfiguration.permissions = page_obj.value["/P"];
|
||
}
|
||
}
|
||
exports.CryptoInterface = CryptoInterface;
|
||
/**
|
||
* Parses the relevant parts of the PDF document and provides functionality to extract the necessary information for
|
||
* adding annotations
|
||
* */
|
||
class PDFDocumentParser {
|
||
constructor(data, userpwd = "", ownerpwd = "") {
|
||
this.data = data;
|
||
this.version = undefined;
|
||
this.documentHistory = new document_history_1.DocumentHistory(new Uint8Array([]));
|
||
this.catalogObject = undefined;
|
||
this.pageTree = undefined;
|
||
this.cryptoInterface = new CryptoInterface();
|
||
this.data = new Uint8Array(data);
|
||
this.documentHistory = new document_history_1.DocumentHistory(this.data);
|
||
this.documentHistory.extractDocumentHistory();
|
||
if (this.documentHistory.isEncrypted()) {
|
||
// extract encryption dictionary
|
||
let obj_table = this.documentHistory.createObjectLookupTable();
|
||
let enc_obj = this.documentHistory.getRecentUpdate().encrypt;
|
||
if (!enc_obj)
|
||
throw Error("Invalid encryption indication");
|
||
let enc_obj_ptr = obj_table[enc_obj.obj];
|
||
this.cryptoInterface = new CryptoInterface(this.data, this.documentHistory, enc_obj_ptr, userpwd, ownerpwd);
|
||
// verify keys
|
||
if (!this.cryptoInterface.isUserPasswordCorrect()) {
|
||
if (!this.cryptoInterface.isOwnerPasswordCorrect()) {
|
||
throw Error("No valid user credentials");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* Returns the crypto interface
|
||
* */
|
||
getCryptoInterface() {
|
||
return this.cryptoInterface;
|
||
}
|
||
/**
|
||
* Returns the major and minor version of the pdf document
|
||
* */
|
||
getPDFVersion() {
|
||
if (this.version)
|
||
return this.version;
|
||
this.version = util_1.Util.extractVersion(this.data, 0);
|
||
return this.version;
|
||
}
|
||
/**
|
||
* Returns a free object id. It first checks wether there can be an freed object id reused. If that is not the case
|
||
* it creates a new one
|
||
* */
|
||
getFreeObjectId() {
|
||
return this.documentHistory.getFreeObjectId();
|
||
}
|
||
/**
|
||
* Returns the catalog object of the PDF file
|
||
* */
|
||
getCatalog() {
|
||
let recent_update = this.documentHistory.getRecentUpdate();
|
||
if (recent_update.root) {
|
||
let root_obj = recent_update.root;
|
||
let obj_table = this.documentHistory.createObjectLookupTable();
|
||
return new CatalogObject(this.data, obj_table[root_obj.obj], obj_table);
|
||
}
|
||
else { // If we do not know the catalogue object we need to look it up
|
||
// In cross reference stream objects no /ROOT field is required, however often it is provided anyway
|
||
// otherwise run this routine, but buffer the catalog object
|
||
if (this.catalogObject)
|
||
return this.catalogObject;
|
||
throw Error("Does not work for compressed data");
|
||
//let obj_table = this.documentHistory.createObjectLookupTable()
|
||
//for (let i = 1; i < recent_update.size; ++i) {
|
||
// let _type = Util.extractField(this.data, Util._TYPE, obj_table[i].pointer)
|
||
// if (Util.areArraysEqual(_type, Util.CATALOG)) {
|
||
// this.catalogObject = new CatalogObject(this.data, obj_table[i])
|
||
// if (this.catalogObject)
|
||
// return this.catalogObject
|
||
// }
|
||
//}
|
||
}
|
||
throw Error("Could not identify catalog object");
|
||
}
|
||
/**
|
||
* Returns the latest version of the page tree object of the document
|
||
* */
|
||
getPageTree() {
|
||
if (this.pageTree)
|
||
return this.pageTree;
|
||
let obj_table = this.documentHistory.createObjectLookupTable();
|
||
let catalog_object = this.getCatalog();
|
||
let pages_id = catalog_object.getPagesObjectId();
|
||
let pages_ref = obj_table[pages_id.obj];
|
||
let pageTree = new PageTree(this.data, obj_table);
|
||
pageTree.extract(pages_ref, obj_table);
|
||
this.pageTree = pageTree;
|
||
return pageTree;
|
||
}
|
||
/**
|
||
* Returns the latest version of the page with the given pageNumber
|
||
* */
|
||
getPage(pageNumber) {
|
||
let pageTree = this.getPageTree();
|
||
let pageId = pageTree.getPageReferences()[pageNumber];
|
||
let obj_table = this.documentHistory.createObjectLookupTable();
|
||
let obj_ptr = obj_table[pageId.obj];
|
||
let page = new Page(this.data, this.documentHistory);
|
||
page.extract(obj_ptr, obj_table);
|
||
return page;
|
||
}
|
||
/**
|
||
* Returns the annotations that exist in the document
|
||
* */
|
||
extractAnnotations() {
|
||
let annots = [];
|
||
let pt = this.getPageTree();
|
||
let obj_table = this.documentHistory.createObjectLookupTable();
|
||
let pageCount = pt.getPageCount();
|
||
for (let i = 0; i < pageCount; ++i) {
|
||
let page = this.getPage(i);
|
||
let annotationReferences = page.annots;
|
||
let pageAnnots = [];
|
||
for (let refPtr of annotationReferences) {
|
||
let a = new _Annotation(this.data, this.cryptoInterface);
|
||
a.extract(obj_table[refPtr.obj], page, obj_table);
|
||
a.page = i;
|
||
pageAnnots.push(a);
|
||
}
|
||
annots.push(pageAnnots);
|
||
}
|
||
return annots;
|
||
}
|
||
}
|
||
exports.PDFDocumentParser = PDFDocumentParser;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/stream.ts":
|
||
/*!***********************!*\
|
||
!*** ./src/stream.ts ***!
|
||
\***********************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const util_1 = __webpack_require__(/*! ./util */ "./src/util.ts");
|
||
const Pako = __webpack_require__(/*! pako */ "./node_modules/pako/index.js");
|
||
class Stream {
|
||
constructor(data) {
|
||
this.data = data;
|
||
this._ptr = 0;
|
||
}
|
||
getData() {
|
||
return this.data;
|
||
}
|
||
getLength() {
|
||
return this.data.length;
|
||
}
|
||
peekNBytes(n = 1, ptr = 0) {
|
||
return this.data.slice(ptr, ptr + n);
|
||
}
|
||
peekNBytesAsNumber(n = 1, ptr = 0) {
|
||
let res = 0;
|
||
for (let i = 0; i < n; ++i) {
|
||
res += (this.data[i + ptr] << 8 * (n - i - 1));
|
||
}
|
||
return res;
|
||
}
|
||
/**
|
||
* reads the next 'n' bytes of position 'ptr' and returns its content as a number
|
||
* */
|
||
getNBytesAsNumber(n = 1) {
|
||
let res = this.peekNBytesAsNumber(n, this._ptr);
|
||
this._ptr += n;
|
||
return res;
|
||
}
|
||
/**
|
||
* Reads the next byte from the stream
|
||
* */
|
||
getByte() {
|
||
return this.data[this._ptr++];
|
||
}
|
||
/**
|
||
* Skips spaces and than adds as many bytes to the number until another space is reached
|
||
* */
|
||
getNumber() {
|
||
let nbr = util_1.Util.extractNumber(this.data, this._ptr);
|
||
this._ptr = nbr.end_index + 1;
|
||
return nbr.result;
|
||
}
|
||
}
|
||
exports.Stream = Stream;
|
||
class FlateStream extends Stream {
|
||
constructor(data, decodeParameters = undefined) {
|
||
super(data);
|
||
this.data = data;
|
||
this.decodeParameters = decodeParameters;
|
||
if (this.data.length > 0) {
|
||
this.data = Pako.inflate(data);
|
||
}
|
||
if (decodeParameters) {
|
||
this.data = this.applyFilter(this.data, decodeParameters);
|
||
}
|
||
}
|
||
applyFilter(data, decodeParameters) {
|
||
if (decodeParameters.predictor >= 10) {
|
||
return this.applyPNGFilter(data, decodeParameters);
|
||
}
|
||
else if (decodeParameters.predictor === 2) {
|
||
throw Error("Unsupported filter -- file feature request");
|
||
}
|
||
return data;
|
||
}
|
||
applyPNGFilter(data, decodeParameters) {
|
||
if (data.length % (decodeParameters.columns + 1) !== 0)
|
||
throw Error("Invalid decode parameters");
|
||
let total_columns = decodeParameters.columns + 1;
|
||
let unfiltered_data = [];
|
||
let encoding = 0;
|
||
for (let i = 0; i < data.length; ++i) {
|
||
let left_value = 0;
|
||
let upper_value = 0;
|
||
let index_upper_value = 0;
|
||
let left_upper_value = 0;
|
||
if (i % total_columns === 0) {
|
||
encoding = data[i];
|
||
}
|
||
else {
|
||
switch (encoding) {
|
||
case 0: // no encoding
|
||
unfiltered_data.push(data[i]);
|
||
break;
|
||
case 1: // Sub fitler -- the difference of the current pixel and the pxiel before
|
||
// add the left already decoded pixel and 0 at the start of a row
|
||
left_value = ((i % total_columns) - 2 < 0) ? 0 : unfiltered_data[((i - 2) % decodeParameters.columns) + Math.floor(i / total_columns) * (decodeParameters.columns - 1)];
|
||
unfiltered_data.push((data[i] + left_value) % 256);
|
||
break;
|
||
case 2: // Up filter -- the difference of the current prixel and the pixel above
|
||
index_upper_value = i - (total_columns + Math.floor(i / total_columns));
|
||
upper_value = (index_upper_value < 0) ? 0 : unfiltered_data[index_upper_value];
|
||
unfiltered_data.push((data[i] + upper_value) % 256);
|
||
break;
|
||
case 3: // Average filter -- considers the average of the upper and the left pixel
|
||
index_upper_value = i - (total_columns + Math.floor(i / total_columns));
|
||
index_upper_value = i - (total_columns + Math.floor(i / total_columns));
|
||
upper_value = (index_upper_value < 0) ? 0 : unfiltered_data[index_upper_value];
|
||
left_value = ((i % total_columns) - 2 < 0) ? 0 : unfiltered_data[((i - 2) % decodeParameters.columns) + Math.floor(i / total_columns) * (decodeParameters.columns - 1)];
|
||
unfiltered_data.push((data[i] + Math.floor((upper_value + left_value) / 2)) % 256);
|
||
break;
|
||
case 4: // Paeth -- uses three neighbouring bytes (left, upper and upper left) to compute a linear function
|
||
index_upper_value = i - (total_columns + Math.floor(i / total_columns));
|
||
upper_value = (index_upper_value < 0) ? 0 : unfiltered_data[index_upper_value];
|
||
left_value = ((i % total_columns) - 2 < 0) ? 0 : unfiltered_data[((i - 2) % decodeParameters.columns) + Math.floor(i / total_columns) * (decodeParameters.columns - 1)];
|
||
left_upper_value = (index_upper_value - 1 < 0) ? 0 : unfiltered_data[index_upper_value - 1];
|
||
unfiltered_data.push((data[i] + this.paethPredictor(left_value, upper_value, left_upper_value)) % 256);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return new Uint8Array(unfiltered_data);
|
||
}
|
||
/**
|
||
* Computes the path predictor of the given byets
|
||
* */
|
||
paethPredictor(left_byte, upper_byte, upper_left_byte) {
|
||
let p = left_byte + upper_byte - upper_left_byte;
|
||
let pa = Math.abs(p - left_byte);
|
||
let pb = Math.abs(p - upper_byte);
|
||
let pc = Math.abs(p - upper_left_byte);
|
||
if (pa <= pb && pa <= pc) {
|
||
return left_byte;
|
||
}
|
||
else if (pb <= pc) {
|
||
return upper_byte;
|
||
}
|
||
else {
|
||
return upper_left_byte;
|
||
}
|
||
}
|
||
}
|
||
exports.FlateStream = FlateStream;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/util.ts":
|
||
/*!*********************!*\
|
||
!*** ./src/util.ts ***!
|
||
\*********************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
/**
|
||
* This class provides methods to navigate through the byte array representing the PDF document
|
||
* */
|
||
class Util {
|
||
/**
|
||
* Extracts the version information of a PDF file
|
||
* */
|
||
static extractVersion(data, index = 0) {
|
||
let ptr_version_start = Util.locateSequence(Util.VERSION, data, index) + Util.VERSION.length;
|
||
let ptr_delimiter = Util.locateSequence([Util.DOT], data, ptr_version_start);
|
||
let major_version = Util.extractNumber(data, ptr_version_start, ptr_delimiter).result;
|
||
let ptr_end = Util.locateDelimiter(data, ptr_delimiter);
|
||
let minor_version = Util.extractNumber(data, ptr_delimiter + 1, ptr_end).result;
|
||
return { major: major_version, minor: minor_version };
|
||
}
|
||
/**
|
||
* Consumes comments that is
|
||
* '%.................. EOL'
|
||
*
|
||
* Also handles mulitple line comments
|
||
* */
|
||
static consumeComment(data, index) {
|
||
while (data[index] !== 13 && data[index] != 10 && index < data.length)
|
||
++index;
|
||
index = Util.skipSpaces(data, index);
|
||
if (data[index] == 37) //%
|
||
return Util.consumeComment(data, index);
|
||
return index;
|
||
}
|
||
/**
|
||
* Returns the next word. These are bytes that are not separated by a delimiter and a ptr to the position where the word ends
|
||
* It ignores/skips comments.
|
||
* */
|
||
static readNextWord(data, index = 0) {
|
||
if (index >= data.length) {
|
||
return { result: undefined, start_index: index, end_index: data.length - 1 };
|
||
}
|
||
index = Util.skipSpaces(data, index);
|
||
if (data[index] === 37) { //%
|
||
index = Util.consumeComment(data, index);
|
||
}
|
||
let start_index = index;
|
||
index++;
|
||
while (!Util.isDelimiter(data[index]) && index < data.length)
|
||
++index;
|
||
if (index <= data.length)
|
||
return { result: data.slice(start_index, index), start_index: start_index, end_index: index - 1 };
|
||
return { result: undefined, start_index: start_index, end_index: index - 1 };
|
||
}
|
||
/**
|
||
* Assumes that at position index is a delimiter and than runs as long forward until it finds
|
||
* another delimiter or reaches the end of the document
|
||
* */
|
||
static skipDelimiter(data, index = 0) {
|
||
while (index < data.length && this.isDelimiter(data[index]))
|
||
++index;
|
||
return index;
|
||
}
|
||
/**
|
||
* Skips only spaces
|
||
* */
|
||
static skipSpaces(data, index = 0) {
|
||
while (index < data.length && (data[index] === 10 || data[index] === 9 || data[index] === 13 || data[index] === 32))
|
||
++index;
|
||
return index;
|
||
}
|
||
/**
|
||
* Skips only spaces
|
||
* */
|
||
static skipSpacesReverse(data, index = 0) {
|
||
while (index > 0 && (data[index] === 10 || data[index] === 9 || data[index] === 13 || data[index] === 32))
|
||
--index;
|
||
return index;
|
||
}
|
||
/**
|
||
* Assumes that at position index is a delimiter and than runs as long backwards until it finds
|
||
* another delimiter or reaches the end of the document
|
||
* */
|
||
static skipDelimiterReverse(data, index = 0) {
|
||
while (index > 0 && this.isDelimiter(data[index]))
|
||
--index;
|
||
return index;
|
||
}
|
||
/**
|
||
* Transforms a string into an array of the corresponding ascii values
|
||
* */
|
||
static convertStringToAscii(toConvert) {
|
||
let asciis = [];
|
||
for (let i = 0; i < toConvert.length; ++i) {
|
||
asciis.push(+toConvert.charCodeAt(i));
|
||
}
|
||
return asciis;
|
||
}
|
||
static isSpace(value) {
|
||
return value === Util.LF ||
|
||
value === Util.CR ||
|
||
value === Util.SPACE;
|
||
}
|
||
static isDelimiter(value) {
|
||
return Util.isSpace(value) ||
|
||
value === 47 || // /
|
||
value === 37 || // %
|
||
value === 60 || // <
|
||
value === 62 || // >
|
||
value === 91 || // [
|
||
value === 93 || // ]
|
||
value === 40 || // (
|
||
value === 41; // )
|
||
}
|
||
static isNumber(value) {
|
||
return value >= 48 && value <= 57; // 0 <= value <= 9
|
||
}
|
||
/**
|
||
* Search the sequence in data starting at the offset
|
||
*
|
||
* Set the 'closed' flag to check if the suceeding char after the sequence is a line feed (10), a carriage return (13), the end
|
||
* of the whole sequence or a space (32)
|
||
* */
|
||
static locateSequence(sequence, data, offset = 0, closed = false) {
|
||
let i = offset;
|
||
for (let j = 0; i < data.length; ++i) {
|
||
if (data[i] == sequence[j]) {
|
||
if (j == sequence.length - 1) {
|
||
if (!closed || data.length == i + 1 || this.isDelimiter(data[i + 1])) {
|
||
return i - (sequence.length - 1);
|
||
}
|
||
else {
|
||
j = -1;
|
||
}
|
||
}
|
||
++j;
|
||
}
|
||
else {
|
||
j = 0;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
/**
|
||
* Search the sequence in data starting at the offset in reverse direction
|
||
*
|
||
* Set the 'closed' flag to check if the preceding char before the sequence is a line feed (10), a carriage return (13), the start
|
||
* of the whole data sequence or a space (32)
|
||
* */
|
||
static locateSequenceReversed(sequence, data, offset = data.length - 1, closed = false) {
|
||
let i = offset;
|
||
for (let j = sequence.length - 1; i >= 0; --i) {
|
||
if (data[i] == sequence[j]) {
|
||
if (j == 0) {
|
||
if (!closed || i - 1 < 0 || this.isDelimiter(data[i - 1])) {
|
||
return i;
|
||
}
|
||
else {
|
||
j = sequence.length;
|
||
}
|
||
}
|
||
--j;
|
||
}
|
||
else {
|
||
j = sequence.length - 1;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
/**
|
||
* Locates the index before the next delimiter. Delimiters can be a line feed (10), a carriage return (13), the end of the whole sequence
|
||
* or a space (32)
|
||
* */
|
||
static locateDelimiter(data, offset = 0) {
|
||
while (offset < data.length && !this.isDelimiter(data[offset]))
|
||
++offset;
|
||
return offset - 1;
|
||
}
|
||
/**
|
||
* Locates the index after the last delimiter. Delimiters can be a line feed (10), a carriage return (13), the end of the whole sequence
|
||
* or a space (32)
|
||
* */
|
||
static locateDelimiterReversed(data, offset = data.length - 1) {
|
||
while (offset > 0 && !this.isDelimiter(data[offset]))
|
||
--offset;
|
||
if (offset <= 0)
|
||
return offset;
|
||
return offset - 1;
|
||
}
|
||
/**
|
||
* Extract an object identifier
|
||
* <ID> <GEN> obj
|
||
* */
|
||
static extractObjectId(data, index) {
|
||
index = Util.skipDelimiter(data, index);
|
||
let end_obj_ptr = Util.locateDelimiter(data, index + 1);
|
||
let obj = Util.extractNumber(data, index, end_obj_ptr).result;
|
||
let start_gen_ptr = Util.skipDelimiter(data, end_obj_ptr + 1);
|
||
let end_gen_ptr = Util.locateDelimiter(data, start_gen_ptr + 1);
|
||
let gen = Util.extractNumber(data, start_gen_ptr, end_gen_ptr).result;
|
||
return { obj: obj, generation: gen };
|
||
}
|
||
/**
|
||
* Extract the reference starting at position 'index'
|
||
* */
|
||
static extractReference(data, index) {
|
||
index = Util.skipDelimiter(data, index);
|
||
let r_index = this.locateSequence(this.convertStringToAscii(" R"), data, index, true);
|
||
return data.slice(index, r_index);
|
||
}
|
||
/**
|
||
* Returns a reference as typed object
|
||
* */
|
||
static extractReferenceTyped(data, index) {
|
||
let ref_data = this.extractReference(data, index);
|
||
let del_index = this.locateDelimiter(ref_data, 0);
|
||
let id = this.extractNumber(ref_data, 0, del_index).result;
|
||
let gen = this.extractNumber(ref_data, del_index + 2).result;
|
||
return { result: { obj: id, generation: gen }, start_index: index, end_index: index + ref_data.length + 1 }; // + _R
|
||
}
|
||
/**
|
||
* Extracts a string in Hex notation <...>
|
||
* */
|
||
static extractHexString(data, index) {
|
||
let string_start = Util.locateSequence(Util.HEX_STRING_START, data, index);
|
||
let string_end = Util.locateSequence(Util.HEX_STRING_END, data, index);
|
||
data = data.slice(string_start + 1, string_end);
|
||
return { result: new Uint8Array(Util.convertHexStringToByteArray(data)), start_index: string_start, end_index: string_end };
|
||
}
|
||
/**
|
||
* Extratcs a string (...)
|
||
* */
|
||
static extractString(data, index) {
|
||
let string_start = Util.locateSequence(Util.LITERAL_STRING_START, data, index);
|
||
let string_end = Util.locateSequence(Util.LITERAL_STRING_END, data, index);
|
||
while (data[string_end - 1] === 92) { // "\" escape
|
||
string_end = Util.locateSequence(Util.LITERAL_STRING_END, data, string_end + 1);
|
||
}
|
||
data = data.slice(string_start + 1, string_end);
|
||
return { result: Util.unescapeString(data), start_index: string_start, end_index: string_end };
|
||
}
|
||
/**
|
||
* Returns the value of an option
|
||
* /<option>
|
||
*
|
||
* so for instance for /Highlight it would return 'Highlight'
|
||
*
|
||
* The index must point to the "/"
|
||
* */
|
||
static extractOptionValue(data, index = 0) {
|
||
if (data[index] !== 47)
|
||
throw Error("misplaced option value pointer");
|
||
let end = Util.locateDelimiter(data, index + 1);
|
||
return { result: Util.convertAsciiToString(Array.from(data.slice(index + 1, end + 1))), start_index: index, end_index: end };
|
||
}
|
||
/**
|
||
* Parses the ascii encoded number of the PDF file
|
||
* */
|
||
static extractNumber(data, start, end = -1) {
|
||
start = Util.skipDelimiter(data, start);
|
||
if (-1 == end) {
|
||
end = Util.locateDelimiter(data, start);
|
||
}
|
||
if (end < start) {
|
||
throw Error(`Could not identify number bounds: [${start},${end}]`);
|
||
}
|
||
let str_id = "";
|
||
for (let i = start; i <= end; ++i) {
|
||
str_id += String.fromCharCode(data[i]);
|
||
}
|
||
if ("" === str_id) {
|
||
throw Error(`Could not parse number at position ${start}`);
|
||
}
|
||
return { result: +str_id, start_index: start, end_index: end };
|
||
}
|
||
/**
|
||
* Converts the given date into PDF formatting
|
||
* */
|
||
static convertDateToPDFDate(date) {
|
||
let date_str = "D:";
|
||
date_str += date.getFullYear();
|
||
let month = String(date.getMonth() + 1);
|
||
date_str += (month.length == 1 ? "0" : "") + month;
|
||
let day = String(date.getDate());
|
||
date_str += (day.length == 1 ? "0" : "") + day;
|
||
let hours = String(date.getHours());
|
||
date_str += (hours.length == 1 ? "0" : "") + hours;
|
||
let minutes = String(date.getMinutes());
|
||
date_str += (minutes.length == 1 ? "0" : "") + minutes;
|
||
let seconds = String(date.getSeconds());
|
||
date_str += (seconds.length == 1 ? "0" : "") + seconds;
|
||
return date_str;
|
||
}
|
||
/**
|
||
* Converts a unicode sequence into a string
|
||
* */
|
||
static convertUnicodeToString(val) {
|
||
if (val instanceof Uint8Array)
|
||
val = new Uint8Array(val);
|
||
if (val[0] === 254 && val[1] === 255) {
|
||
val = val.slice(2, val.length);
|
||
let uintToString = (uintArray) => {
|
||
let ret = "";
|
||
for (let i = 0; i < uintArray.length - 1; i += 2) {
|
||
ret += String.fromCharCode((uintArray[i] << 8) | uintArray[i + 1] & 0xFF);
|
||
}
|
||
return ret;
|
||
};
|
||
let ret = uintToString(val);
|
||
return ret;
|
||
}
|
||
// handle utf-8 compression
|
||
let Utf8ArrayToStr = (array) => {
|
||
let ret = "";
|
||
let i = 0;
|
||
while (i < array.length) {
|
||
let char1 = array[i++];
|
||
let char2;
|
||
switch (char1 >> 4) {
|
||
case 0:
|
||
case 1:
|
||
case 2:
|
||
case 3:
|
||
case 4:
|
||
case 5:
|
||
case 6:
|
||
case 7:
|
||
// one byte
|
||
ret += String.fromCharCode(char1);
|
||
break;
|
||
case 12:
|
||
case 13:
|
||
// two byte sequence
|
||
char2 = array[i++];
|
||
ret += String.fromCharCode(((char1 & 0x1F) << 6) | (char2 & 0x3F));
|
||
break;
|
||
case 14:
|
||
// three byte sequence
|
||
char2 = array[i++];
|
||
let char3 = array[i++];
|
||
ret += String.fromCharCode(((char1 & 0x0F) << 12) |
|
||
((char2 & 0x3F) << 6) |
|
||
((char3 & 0x3F) << 0));
|
||
break;
|
||
}
|
||
}
|
||
return ret;
|
||
};
|
||
let ret = Utf8ArrayToStr(Array.from(val));
|
||
return ret;
|
||
}
|
||
static convertAsciiToString(val) {
|
||
let ret = "";
|
||
for (let i = 0; i < val.length; ++i) {
|
||
ret += String.fromCharCode(val[i]);
|
||
}
|
||
return ret;
|
||
}
|
||
/**
|
||
* takes a number and returns an array of its char representations
|
||
* */
|
||
static convertNumberToCharArray(nbr) {
|
||
return Util.convertStringToAscii(String(nbr));
|
||
}
|
||
/**
|
||
* Converts a hex string into a byte array
|
||
* That means two consecutive hex values are merged into one byte that is appended to the array
|
||
* */
|
||
static convertHexStringToByteArray(hex_string) {
|
||
let ret_val = [];
|
||
if (typeof hex_string !== "string") {
|
||
hex_string = Util.convertAsciiToString(hex_string);
|
||
}
|
||
for (let i = 0; i < hex_string.length - 1; i += 2) {
|
||
ret_val.push((parseInt(hex_string.charAt(i), 16) << 4) + parseInt(hex_string.charAt(i + 1), 16));
|
||
}
|
||
if (hex_string.length % 2 !== 0) {
|
||
ret_val.push(parseInt(hex_string.charAt(hex_string.length - 1), 16));
|
||
}
|
||
return ret_val;
|
||
}
|
||
/**
|
||
* Converts an array of byte values into a hex string
|
||
* */
|
||
static convertByteArrayToHexString(values) {
|
||
let ret_val = "";
|
||
let HEX_VALUES = "0123456789ABCDEF";
|
||
for (let i = 0; i < values.length; ++i) {
|
||
ret_val += HEX_VALUES.charAt(values[i] >> 4);
|
||
ret_val += HEX_VALUES.charAt(values[i] & 15);
|
||
}
|
||
// remove leading zeros
|
||
let i = 0;
|
||
while ('0' === ret_val.charAt(i) && i < ret_val.length)
|
||
++i;
|
||
return ret_val.slice(i, ret_val.length);
|
||
}
|
||
/**
|
||
* takes two arrays and checks their equality
|
||
* */
|
||
static areArraysEqual(array_one, array_two) {
|
||
if (array_one.length !== array_two.length)
|
||
return false;
|
||
for (let i = 0; i < array_one.length; ++i) {
|
||
if (array_one[i] !== array_two[i])
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
/**
|
||
* Prints the array with leading indexes 10 bytes in a row
|
||
* Delimiter are substituted by '.'
|
||
* */
|
||
static debug_printIndexed(array) {
|
||
let outp = "";
|
||
for (let i = 0; i < array.length; ++i) {
|
||
if (i % 10 === 0) {
|
||
outp += "\n" + i + ":";
|
||
}
|
||
if (Util.isSpace(array[i]))
|
||
outp += " .";
|
||
else
|
||
outp += " " + String.fromCharCode(array[i]);
|
||
}
|
||
console.log(outp);
|
||
}
|
||
/**
|
||
* Converts a list of 8 bit integers into a list of 32 bit integers
|
||
* */
|
||
static convertUint8ArrayToInt32Array(a) {
|
||
let ret_val = new Int32Array(Math.ceil(a.length / 4));
|
||
let i = 0;
|
||
let index = 0;
|
||
while (i < a.length) {
|
||
if (a[i] > 255 || a[i + 1] > 255 || a[i + 2] >> 255 || a[i + 3] > 255)
|
||
throw Error("Invalid byte size");
|
||
ret_val[index++] = (a[i++] << 24) + (a[i++] << 16) + (a[i++] << 8) + (a[i++] << 0);
|
||
}
|
||
return ret_val;
|
||
}
|
||
/**
|
||
* Converts a list of 32 bit integers into a list of 8 bit UNSIGNED integers
|
||
* */
|
||
static convertInt32ArrayToUint8Array(a) {
|
||
let ret_val = new Uint8Array(a.length * 4);
|
||
for (let i = 0; i < a.length; ++i) {
|
||
for (let j = 0; j < 4; ++j) {
|
||
ret_val[i * 4 + j] = (a[i] >> 8 * (4 - j - 1)) & 0xFF;
|
||
}
|
||
}
|
||
return ret_val;
|
||
}
|
||
/**
|
||
* Adds escape symbols to specific elements of the provided string
|
||
*
|
||
* Symbols that needs to be escaped are: \ ) (
|
||
* */
|
||
static escapeString(array) {
|
||
let ret_val = [];
|
||
for (let i = 0; i < array.length; ++i) {
|
||
switch (array[i]) {
|
||
case Util.LITERAL_STRING_START[0]:
|
||
case Util.LITERAL_STRING_END[0]:
|
||
case 92: // 92 = '\'
|
||
ret_val.push(92);
|
||
ret_val.push(array[i]);
|
||
break;
|
||
case 9: // 9 = TAB
|
||
ret_val.push(92);
|
||
ret_val.push(116); // \t
|
||
break;
|
||
case 10: // 10 = LINE FEED
|
||
ret_val.push(92);
|
||
ret_val.push(110); // \n
|
||
break;
|
||
case 13: // 13 = CARRIAGE RETURN
|
||
ret_val.push(92);
|
||
ret_val.push(114); // \r
|
||
break;
|
||
case 8: // 8 = BACKSPACE
|
||
ret_val.push(92);
|
||
ret_val.push(98); // \b
|
||
break;
|
||
case 12: // 255 = FORM FEED
|
||
ret_val.push(92);
|
||
ret_val.push(102); // \f
|
||
break;
|
||
default:
|
||
ret_val.push(array[i]);
|
||
}
|
||
}
|
||
return new Uint8Array(ret_val);
|
||
}
|
||
/**
|
||
* Removes escape symbols from the given string
|
||
*
|
||
* Symbols that needs to be escaped are: \ ) (
|
||
* */
|
||
static unescapeString(array) {
|
||
let ret_val = [];
|
||
let in_escape = false;
|
||
for (let i = 0; i < array.length; ++i) {
|
||
if (in_escape) {
|
||
in_escape = false;
|
||
switch (array[i]) {
|
||
case 92: // \
|
||
ret_val.push(92);
|
||
break;
|
||
case Util.LITERAL_STRING_START[0]:
|
||
ret_val.push(Util.LITERAL_STRING_START[0]);
|
||
break;
|
||
case Util.LITERAL_STRING_END[0]:
|
||
ret_val.push(Util.LITERAL_STRING_END[0]);
|
||
break;
|
||
case 116: // \t
|
||
ret_val.push(9);
|
||
break;
|
||
case 110: // \n
|
||
ret_val.push(10);
|
||
break;
|
||
case 114: // \r
|
||
ret_val.push(13);
|
||
break;
|
||
case 98: // \b
|
||
ret_val.push(8);
|
||
break;
|
||
case 102: // \f
|
||
ret_val.push(12);
|
||
break;
|
||
default:
|
||
ret_val.push(array[i]);
|
||
}
|
||
}
|
||
else {
|
||
if (array[i] === 92) {
|
||
in_escape = true;
|
||
}
|
||
else {
|
||
ret_val.push(array[i]);
|
||
}
|
||
}
|
||
}
|
||
return new Uint8Array(ret_val);
|
||
}
|
||
}
|
||
exports.Util = Util;
|
||
Util.VERSION = [37, 80, 68, 70, 45]; // %PDF-
|
||
Util.NULL = [110, 117, 108, 108]; // null
|
||
Util.DOT = 46;
|
||
Util.CR = 13;
|
||
Util.LF = 10;
|
||
Util.TYPE = "/Type ";
|
||
Util.SPACE = 32;
|
||
Util.OBJ = [111, 98, 106]; // 'obj'
|
||
Util.ENDOBJ = [101, 110, 100, 111, 98, 106]; // 'endobj'
|
||
Util.ARRAY_START = [91]; // '['
|
||
Util.ARRAY_END = [93]; // ']'
|
||
Util.LITERAL_STRING_START = [40]; // '('
|
||
Util.HEX_STRING_START = [60]; // '<'
|
||
Util.LITERAL_STRING_END = [41]; // ')'
|
||
Util.HEX_STRING_END = [62]; // '>'
|
||
Util.R = [82]; // 'R'
|
||
Util.ANNOTS = [47, 65, 110, 110, 111, 116, 115]; // '/Annot'
|
||
Util.DICT_START = [60, 60]; // '<<'
|
||
Util.DICT_END = [62, 62]; // '>>'
|
||
Util.PAGE = [47, 80, 97, 103, 101];
|
||
Util.SIZE = [47, 83, 105, 122, 101]; // /Size
|
||
Util.ROOT = [47, 82, 111, 111, 116]; // /Root
|
||
Util.PREV = [47, 80, 114, 101, 118]; // /Prev
|
||
Util.STARTXREF = [115, 116, 97, 114, 116, 120, 114, 101, 102]; // = 'startxref'
|
||
Util.XREF = [120, 114, 101, 102]; // = 'xref'
|
||
Util.STREAM = [115, 116, 114, 101, 97, 109]; // = 'stream'
|
||
Util.TRAILER = [116, 114, 97, 105, 108, 101, 114]; // = 'trailer'
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/writer-util.ts":
|
||
/*!****************************!*\
|
||
!*** ./src/writer-util.ts ***!
|
||
\****************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const util_1 = __webpack_require__(/*! ./util */ "./src/util.ts");
|
||
class WriterUtil {
|
||
/**
|
||
* Writes a reference pointer
|
||
*
|
||
* <obj_id> <generation> R
|
||
*
|
||
* The 'R' and the preceding space is only written in case 'referenced' is true
|
||
* */
|
||
static writeReferencePointer(ref, referenced = false) {
|
||
let ret = util_1.Util.convertNumberToCharArray(ref.obj);
|
||
ret.push(util_1.Util.SPACE);
|
||
ret = ret.concat(util_1.Util.convertNumberToCharArray(ref.generation));
|
||
if (referenced) {
|
||
ret.push(util_1.Util.SPACE);
|
||
ret.push(...util_1.Util.R);
|
||
}
|
||
return ret;
|
||
}
|
||
/**
|
||
* Adds preceding zeros (0) in front of the 'value' to match the length
|
||
* */
|
||
static pad(length, value) {
|
||
value = String(value);
|
||
let ret = [];
|
||
for (let i = 0; i < length - value.length; ++i) {
|
||
ret.push(48);
|
||
}
|
||
ret = ret.concat(util_1.Util.convertNumberToCharArray(value));
|
||
return ret;
|
||
}
|
||
/**
|
||
* Writes a nested number array
|
||
* */
|
||
static writeNestedNumberArray(array) {
|
||
let ret = util_1.Util.ARRAY_START;
|
||
for (let subArray of array) {
|
||
ret = ret.concat(WriterUtil.writeNumberArray(subArray));
|
||
ret.push(util_1.Util.SPACE);
|
||
}
|
||
ret.push(...util_1.Util.ARRAY_END);
|
||
return ret;
|
||
}
|
||
/**
|
||
* Writes a javascript number array to a PDF number array
|
||
* */
|
||
static writeNumberArray(array) {
|
||
let ret = util_1.Util.ARRAY_START;
|
||
for (let i of array) {
|
||
ret = ret.concat(util_1.Util.convertNumberToCharArray(i));
|
||
ret.push(util_1.Util.SPACE);
|
||
}
|
||
ret.push(...util_1.Util.ARRAY_END);
|
||
return ret;
|
||
}
|
||
/**
|
||
* Replaces the /Annots field in an page object
|
||
*
|
||
* ptr : Pointer to the page object
|
||
* annot_array_reference : The reference to the annotation array
|
||
* */
|
||
static replaceAnnotsFieldInPageObject(data, page, page_ptr, annot_array_reference) {
|
||
let ptr_objend = util_1.Util.locateSequence(util_1.Util.ENDOBJ, data, page_ptr, true);
|
||
let complete_page_object_data = data.slice(page_ptr, ptr_objend + util_1.Util.ENDOBJ.length);
|
||
let ret = [];
|
||
if (page.hasAnnotsField) {
|
||
// in this case the page object directly contains an array of references and
|
||
// does not point to an array array object -- we replace the array of references with a pointer
|
||
// to the reference array
|
||
let ptr_annots = util_1.Util.locateSequence(util_1.Util.ANNOTS, complete_page_object_data, 0, true);
|
||
ret = Array.from(complete_page_object_data.slice(0, ptr_annots + util_1.Util.ANNOTS.length));
|
||
ret.push(util_1.Util.SPACE);
|
||
ret = ret.concat(WriterUtil.writeReferencePointer(annot_array_reference, true));
|
||
ret.push(util_1.Util.SPACE);
|
||
let ptr_annots_array_end = util_1.Util.locateSequence(util_1.Util.ARRAY_END, complete_page_object_data, ptr_annots, true) + util_1.Util.ARRAY_END.length;
|
||
ret = ret.concat(Array.from(complete_page_object_data.slice(ptr_annots_array_end, complete_page_object_data.length)));
|
||
}
|
||
else {
|
||
let ptr_dict_end = util_1.Util.locateSequenceReversed(util_1.Util.DICT_END, complete_page_object_data, complete_page_object_data.length - 1);
|
||
if (-1 === ptr_dict_end)
|
||
throw Error("Could not identify dictionary end");
|
||
ret = Array.from(complete_page_object_data.slice(0, ptr_dict_end));
|
||
ret = ret.concat(util_1.Util.ANNOTS);
|
||
ret.push(util_1.Util.SPACE);
|
||
ret = ret.concat(WriterUtil.writeReferencePointer(annot_array_reference, true));
|
||
ret.push(util_1.Util.SPACE);
|
||
ret = ret.concat(Array.from(complete_page_object_data.slice(ptr_dict_end, complete_page_object_data.length)));
|
||
}
|
||
ret.push(util_1.Util.CR);
|
||
ret.push(util_1.Util.LF);
|
||
return ret;
|
||
}
|
||
}
|
||
exports.WriterUtil = WriterUtil;
|
||
WriterUtil.N = 110;
|
||
WriterUtil.F = 102;
|
||
WriterUtil.SPACE = 32;
|
||
WriterUtil.CR = 13;
|
||
WriterUtil.LF = 10;
|
||
WriterUtil.OBJ = [111, 98, 106];
|
||
WriterUtil.ENDOBJ = [101, 110, 100, 111, 98, 106];
|
||
WriterUtil.ENCRYPT = [47, 69, 110, 99, 114, 121, 112, 116];
|
||
WriterUtil.ARRAY_START = 91;
|
||
WriterUtil.OPEN = [47, 79, 112, 101, 110];
|
||
WriterUtil.ARRAY_END = 93;
|
||
WriterUtil.DICT_START = [60, 60];
|
||
WriterUtil.HEX_STRING_START = [60];
|
||
WriterUtil.HEX_STRING_END = [62];
|
||
WriterUtil.DICT_END = [62, 62];
|
||
WriterUtil.TYPE_ANNOT = [47, 84, 121, 112, 101, WriterUtil.SPACE, 47, 65, 110, 110, 111, 116];
|
||
WriterUtil.RECT = [47, 82, 101, 99, 116];
|
||
WriterUtil.SUBTYPE = [47, 83, 117, 98, 116, 121, 112, 101];
|
||
WriterUtil.UPDATE_DATE = [47, 77]; // = '/M'
|
||
WriterUtil.AUTHOR = [47, 84]; // = '/T'
|
||
WriterUtil.CONTENTS = [47, 67, 111, 110, 116, 101, 110, 116, 115]; // = '/Contents'
|
||
WriterUtil.BRACKET_START = 40;
|
||
WriterUtil.BRACKET_END = 41;
|
||
WriterUtil.FLAG = [47, 70]; // = '/F'
|
||
WriterUtil.ID = [47, 78, 77]; // = '/NM'
|
||
WriterUtil.DOCUMENT_ID = [47, 73, 68]; // = '/ID'
|
||
WriterUtil.COLOR = [47, 67]; // = '/C'
|
||
WriterUtil.FILL = [47, 73, 67]; // = '/IC'
|
||
WriterUtil.STATE = [47, 83, 116, 97, 116, 101]; // = '/State'
|
||
WriterUtil.STATEMODEL = [47, 83, 116, 97, 116, 101, 77, 111, 100, 101, 108]; // = '/StateModel'
|
||
WriterUtil.OPACITY = [47, 67, 65]; // = '/CA'
|
||
WriterUtil.BORDER = [47, 66, 111, 114, 100, 101, 114]; // = '/Border'
|
||
WriterUtil.PAGE_REFERENCE = [47, 80]; // = '/P'
|
||
WriterUtil.DEFAULT_APPEARANCE = [47, 68, 65]; // = '/DA'
|
||
WriterUtil.INKLIST = [47, 73, 110, 107, 76, 105, 115, 116]; // = '/InkList'
|
||
WriterUtil.RC = [47, 82, 67]; // = '/RC'
|
||
WriterUtil.CREATION_DATE = [47, 67, 114, 101, 97, 116, 105, 111, 110, 68, 97, 116, 101]; // = '/CreationDate'
|
||
WriterUtil.SUBJ = [47, 83, 117, 98, 106]; // = '/Subj'
|
||
WriterUtil.TRAILER = [116, 114, 97, 105, 108, 101, 114]; // = 'trailer'
|
||
WriterUtil.SIZE = [47, 83, 105, 122, 101]; // = '/Size'
|
||
WriterUtil.ROOT = [47, 82, 111, 111, 116]; // = '/Root'
|
||
WriterUtil.PREV = [47, 80, 114, 101, 118]; // ='/Prev'
|
||
WriterUtil.STARTXREF = [115, 116, 97, 114, 116, 120, 114, 101, 102]; // = 'startxref'
|
||
WriterUtil.EOF = [37, 37, 69, 79, 70]; // = '%%EOF'
|
||
WriterUtil.TRUE = [116, 114, 117, 101]; // = 'true'
|
||
WriterUtil.XREF = [120, 114, 101, 102]; // = 'xref'
|
||
WriterUtil.TEXT_JUSTIFICATION = [47, 81]; // = '/Q'
|
||
WriterUtil.DEFAULT_STYLE_STRING = [47, 68, 83]; // = '/DS'
|
||
WriterUtil.DIFFERENCE_RECTANGLE = [47, 82, 68]; // = '/RD'
|
||
WriterUtil.IT = [47, 73, 84]; // = '/IT'
|
||
WriterUtil.LINE_ENDING = [47, 76, 69]; // = '/LE'
|
||
WriterUtil.CALLOUT_LINE = [47, 67, 76]; // = '/CL'
|
||
WriterUtil.QUADPOINTS = [47, 81, 117, 97, 100, 80, 111, 105, 110, 116, 115]; // = '/QuadPoints'
|
||
WriterUtil.VERTICES = [47, 86, 101, 114, 116, 105, 99, 101, 115]; // = '/Vertices'
|
||
WriterUtil.NAME = [47, 78, 97, 109, 101]; // = '/Name'
|
||
WriterUtil.DRAFT = [47, 68, 114, 97, 102, 116]; // = '/Draft'
|
||
WriterUtil.SY = [47, 83, 121]; // = '/Sy'
|
||
WriterUtil.P = 80;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/writer.ts":
|
||
/*!***********************!*\
|
||
!*** ./src/writer.ts ***!
|
||
\***********************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const util_1 = __webpack_require__(/*! ./util */ "./src/util.ts");
|
||
const object_util_1 = __webpack_require__(/*! ./object-util */ "./src/object-util.ts");
|
||
const writer_util_1 = __webpack_require__(/*! ./writer-util */ "./src/writer-util.ts");
|
||
/**
|
||
* Creats the byte array that must be attached to the end of the document
|
||
* */
|
||
class Writer {
|
||
/**
|
||
* data : The data representing the original PDF document
|
||
* aannotations : The annotations to add to the document
|
||
* */
|
||
constructor(data, annotations, toDelete, parser) {
|
||
this.data = data;
|
||
this.annotations = annotations;
|
||
this.toDelete = toDelete;
|
||
this.parser = parser;
|
||
/**
|
||
* Holds the crossite reference table
|
||
* */
|
||
this.xrefs = [];
|
||
this.data = new Uint8Array(data);
|
||
this.cryptoInterface = parser.getCryptoInterface();
|
||
}
|
||
/**
|
||
* Sorts the annotations pagewise.
|
||
*
|
||
* This is necessary since the annotation arrays of the sites must be extended
|
||
* and it makes sense to do this update in one step.
|
||
* */
|
||
sortPageWise(annotations) {
|
||
let pageAnnots = {};
|
||
for (let annot of annotations) {
|
||
if (!pageAnnots[annot.page])
|
||
pageAnnots[annot.page] = [];
|
||
pageAnnots[annot.page].push(annot);
|
||
}
|
||
return pageAnnots;
|
||
}
|
||
/**
|
||
* It returns the page object either extended by a /Annots field, if this did not exist yet or with the annots field replaced by a rerference pointer
|
||
* to an array if the page object contains the list of annotations directly
|
||
*
|
||
* ptr : Pointer to the page object
|
||
* annot_array_reference : The reference to the annotation array
|
||
* */
|
||
adaptPageObject(page, annot_array_reference) {
|
||
if (!page.object_id)
|
||
throw Error("Page without object id");
|
||
let ret = [];
|
||
let lookupTable = this.parser.documentHistory.createObjectLookupTable();
|
||
let page_ptr = lookupTable[page.object_id.obj];
|
||
if (page_ptr.compressed) {
|
||
let obj = object_util_1.ObjectUtil.extractObject(this.data, page_ptr, lookupTable);
|
||
let obj_data = obj.stream.getData().slice(obj.pointer_stream_start, obj.pointer_stream_end + 1);
|
||
let ref_ptr = writer_util_1.WriterUtil.writeReferencePointer(obj.id, false).concat(32);
|
||
let new_data = new Uint8Array(ref_ptr.length + writer_util_1.WriterUtil.OBJ.length + obj_data.length + writer_util_1.WriterUtil.ENDOBJ.length);
|
||
new_data.set(ref_ptr);
|
||
new_data.set(writer_util_1.WriterUtil.OBJ, ref_ptr.length);
|
||
new_data.set(obj_data, writer_util_1.WriterUtil.OBJ.length + ref_ptr.length);
|
||
new_data.set(writer_util_1.WriterUtil.ENDOBJ, writer_util_1.WriterUtil.OBJ.length + obj_data.length + ref_ptr.length);
|
||
return writer_util_1.WriterUtil.replaceAnnotsFieldInPageObject(new_data, page, 0, annot_array_reference);
|
||
}
|
||
return writer_util_1.WriterUtil.replaceAnnotsFieldInPageObject(this.data, page, page_ptr.pointer, annot_array_reference);
|
||
}
|
||
/**
|
||
* Takes the annotations of >>one<< page and derives the annotations array from it.
|
||
* Thereby it also considers the potentially existing annotation array.
|
||
*
|
||
* toDelete := contains those annotations that must be deleted. It removes them from the reference array
|
||
* and marks them as removed
|
||
* */
|
||
writeAnnotArray(annots, toDelete) {
|
||
let page = annots[0].pageReference;
|
||
if (!page)
|
||
throw Error("Missing page reference");
|
||
if (!page.object_id)
|
||
throw Error("Page without object id");
|
||
let references = page.annots;
|
||
references = references.concat(annots.map((x) => {
|
||
if (!x.object_id)
|
||
throw Error("Annotation with object_id null");
|
||
return x.object_id;
|
||
}));
|
||
// remove annotation references from the array that must be deleted and mark them as deleted
|
||
references = references.filter((a) => {
|
||
let toDel = toDelete.find((t) => t.object_id.obj === a.obj && t.object_id.generation === a.generation);
|
||
if (toDel) {
|
||
toDel.is_deleted = true;
|
||
return false;
|
||
}
|
||
return true;
|
||
});
|
||
let refArray_id = page.annotsPointer;
|
||
let page_data = [];
|
||
if (!refArray_id) {
|
||
refArray_id = this.parser.getFreeObjectId();
|
||
page_data = this.adaptPageObject(page, refArray_id);
|
||
}
|
||
let ret = writer_util_1.WriterUtil.writeReferencePointer(refArray_id);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.OBJ);
|
||
ret.push(writer_util_1.WriterUtil.CR);
|
||
ret.push(writer_util_1.WriterUtil.LF);
|
||
ret.push(writer_util_1.WriterUtil.ARRAY_START);
|
||
for (let an of references) {
|
||
ret = ret.concat(writer_util_1.WriterUtil.writeReferencePointer(an, true));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
ret.push(writer_util_1.WriterUtil.ARRAY_END);
|
||
ret.push(writer_util_1.WriterUtil.CR);
|
||
ret.push(writer_util_1.WriterUtil.LF);
|
||
ret = ret.concat(writer_util_1.WriterUtil.ENDOBJ);
|
||
ret.push(writer_util_1.WriterUtil.CR);
|
||
ret.push(writer_util_1.WriterUtil.LF);
|
||
return { ptr: refArray_id, data: ret, pageReference: page.object_id, pageData: page_data };
|
||
}
|
||
/**
|
||
* Writes an annotation object
|
||
* */
|
||
writeAnnotationObject(annot) {
|
||
//if ((annot as _Annotation).stampType) {
|
||
// ret = ret.concat(Writer.NAME)
|
||
// ret.push(Writer.SPACE)
|
||
// ret = ret.concat(Writer.DRAFT)
|
||
// ret.push(Writer.SPACE)
|
||
//}
|
||
//if ((annot as _Annotation).caretSymbol) {
|
||
// ret = ret.concat(Writer.SY)
|
||
// ret.push(Writer.SPACE)
|
||
// ret.push(Writer.P)
|
||
// ret.push(Writer.SPACE)
|
||
//}
|
||
let ret = annot.writeAnnotationPreamble();
|
||
ret = ret.concat(annot.writeAnnotationObject(this.cryptoInterface));
|
||
ret = ret.concat(annot.writeAnnotationPostamble());
|
||
return { ptr: annot.object_id, data: ret };
|
||
}
|
||
/**
|
||
* Takes all the cross site reference table entries and extracts the consecutive sequences
|
||
* */
|
||
computeXrefSequences() {
|
||
let seqs = [];
|
||
let ordered_xrefs = this.xrefs.sort((a, b) => {
|
||
if (a.id < b.id)
|
||
return -1;
|
||
if (a.id > b.id)
|
||
return 1;
|
||
return 0;
|
||
});
|
||
let seq = [ordered_xrefs[0]];
|
||
let last_id = ordered_xrefs[0].id;
|
||
seqs.push(seq);
|
||
for (let i = 1; i < ordered_xrefs.length; ++i) {
|
||
if (ordered_xrefs[i].id === last_id + 1) {
|
||
seq.push(ordered_xrefs[i]);
|
||
}
|
||
else {
|
||
seq = [ordered_xrefs[i]];
|
||
seqs.push(seq);
|
||
}
|
||
last_id = ordered_xrefs[i].id;
|
||
}
|
||
return seqs;
|
||
}
|
||
/**
|
||
* Constructs the pointers of the linked list that contains the ids of freed objects
|
||
* */
|
||
applyObjectFreeing(refs) {
|
||
// write free object head
|
||
let head = this.parser.documentHistory.createObjectLookupTable()[0];
|
||
let last_freed_object_id = head.id;
|
||
let freed_objs = refs.filter(r => r.free);
|
||
freed_objs = freed_objs.sort((a, b) => {
|
||
if (a.id < b.id)
|
||
return -1;
|
||
if (a.id > b.id)
|
||
return 1;
|
||
return 0;
|
||
});
|
||
let lastobj = undefined;
|
||
for (let obj of freed_objs) {
|
||
if (!lastobj) {
|
||
// set first object as list header
|
||
head.pointer = obj.id;
|
||
}
|
||
if (lastobj) {
|
||
lastobj.pointer = obj.id;
|
||
}
|
||
lastobj = obj;
|
||
}
|
||
if (freed_objs.length > 0)
|
||
freed_objs[freed_objs.length - 1].pointer = last_freed_object_id;
|
||
refs.push(head);
|
||
return refs;
|
||
}
|
||
/**
|
||
* Writes the crossite reference table
|
||
* */
|
||
writeCrossSiteReferenceTable() {
|
||
let ret = writer_util_1.WriterUtil.XREF;
|
||
ret.push(writer_util_1.WriterUtil.CR);
|
||
ret.push(writer_util_1.WriterUtil.LF);
|
||
this.xrefs = this.applyObjectFreeing(this.xrefs);
|
||
let ordered_sequences = this.computeXrefSequences();
|
||
for (let sequence of ordered_sequences) {
|
||
let head = sequence[0];
|
||
ret = ret.concat(util_1.Util.convertNumberToCharArray(head.id));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(util_1.Util.convertNumberToCharArray(sequence.length));
|
||
ret.push(writer_util_1.WriterUtil.CR);
|
||
ret.push(writer_util_1.WriterUtil.LF);
|
||
for (let i = 0; i < sequence.length; ++i) {
|
||
let _ret = [];
|
||
_ret = _ret.concat(writer_util_1.WriterUtil.pad(10, sequence[i].pointer));
|
||
_ret.push(writer_util_1.WriterUtil.SPACE);
|
||
_ret = _ret.concat(writer_util_1.WriterUtil.pad(5, sequence[i].generation));
|
||
_ret.push(writer_util_1.WriterUtil.SPACE);
|
||
if (sequence[i].free)
|
||
_ret.push(writer_util_1.WriterUtil.F);
|
||
if (sequence[i].update)
|
||
_ret.push(writer_util_1.WriterUtil.N);
|
||
_ret.push(writer_util_1.WriterUtil.CR);
|
||
_ret.push(writer_util_1.WriterUtil.LF);
|
||
if (_ret.length < 20)
|
||
throw Error("XRef entry < 20 bytes");
|
||
ret = ret.concat(_ret);
|
||
}
|
||
}
|
||
return ret;
|
||
}
|
||
/**
|
||
* Writes the trailer
|
||
* */
|
||
writeTrailer(posXref) {
|
||
let ret = writer_util_1.WriterUtil.TRAILER;
|
||
ret.push(writer_util_1.WriterUtil.CR);
|
||
ret.push(writer_util_1.WriterUtil.LF);
|
||
ret = ret.concat(writer_util_1.WriterUtil.DICT_START);
|
||
ret = ret.concat(writer_util_1.WriterUtil.SIZE);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(util_1.Util.convertNumberToCharArray(this.parser.documentHistory.trailerSize));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
if (this.parser.documentHistory.isEncrypted()) {
|
||
ret = ret.concat(writer_util_1.WriterUtil.ENCRYPT);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
let enc_ref = this.parser.getCryptoInterface().getEncryptionDictReference();
|
||
if (!enc_ref)
|
||
throw Error("No reference pointer to encryption dictionary");
|
||
ret = ret.concat(writer_util_1.WriterUtil.writeReferencePointer(enc_ref, true));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
let trailer = this.parser.documentHistory.getRecentUpdate();
|
||
if (trailer.id) {
|
||
ret = ret.concat(writer_util_1.WriterUtil.DOCUMENT_ID);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret.push(writer_util_1.WriterUtil.ARRAY_START);
|
||
for (let val of trailer.id) {
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.HEX_STRING_START);
|
||
ret = ret.concat(util_1.Util.convertStringToAscii(util_1.Util.convertByteArrayToHexString(val)));
|
||
ret = ret.concat(writer_util_1.WriterUtil.HEX_STRING_END);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
ret.push(writer_util_1.WriterUtil.ARRAY_END);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
ret = ret.concat(writer_util_1.WriterUtil.ROOT);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
if (!trailer.root)
|
||
throw Error("No root object in trailer, although this is an cross reference table document");
|
||
ret = ret.concat(writer_util_1.WriterUtil.writeReferencePointer(trailer.root, true));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.PREV);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(util_1.Util.convertNumberToCharArray(this.parser.documentHistory.getRecentUpdate().start_pointer));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.DICT_END);
|
||
ret.push(writer_util_1.WriterUtil.CR);
|
||
ret.push(writer_util_1.WriterUtil.LF);
|
||
ret = ret.concat(writer_util_1.WriterUtil.STARTXREF);
|
||
ret.push(writer_util_1.WriterUtil.CR);
|
||
ret.push(writer_util_1.WriterUtil.LF);
|
||
ret = ret.concat(util_1.Util.convertNumberToCharArray(posXref));
|
||
ret.push(writer_util_1.WriterUtil.CR);
|
||
ret.push(writer_util_1.WriterUtil.LF);
|
||
ret = ret.concat(writer_util_1.WriterUtil.EOF);
|
||
ret.push(writer_util_1.WriterUtil.CR);
|
||
ret.push(writer_util_1.WriterUtil.LF);
|
||
return ret;
|
||
}
|
||
/**
|
||
* Writes the annations at the end of the PDF byte representation and returns
|
||
* the byte array
|
||
* */
|
||
write() {
|
||
let pageWiseSorted = this.sortPageWise(this.annotations);
|
||
let ptr = this.data.length;
|
||
let new_data = [];
|
||
// Fix case that there is no linebreak after the end of the file
|
||
if (this.data[ptr - 1] === 70) { // 70 = 'F' (from [%%EO]F
|
||
new_data.push(writer_util_1.WriterUtil.CR);
|
||
new_data.push(writer_util_1.WriterUtil.LF);
|
||
ptr += 2;
|
||
}
|
||
for (let key in pageWiseSorted) {
|
||
let pageAnnots = pageWiseSorted[key];
|
||
// write the array referencing to annotations of a certain page
|
||
// it also removes references of annotations that must be deleted
|
||
let annot_array = this.writeAnnotArray(pageAnnots, this.toDelete);
|
||
this.xrefs.push({
|
||
id: annot_array.ptr.obj,
|
||
pointer: ptr,
|
||
generation: annot_array.ptr.generation,
|
||
free: false,
|
||
update: true
|
||
});
|
||
new_data = new_data.concat(annot_array.data);
|
||
ptr += annot_array.data.length;
|
||
// add adapted page object if it exists -- In the case the page had no annotation yet there exists
|
||
// no such array referring to its annotations. A pointer to such an array must be added to the
|
||
// page object. If this was done the `pageData` paramater is set and contains the adapted page object
|
||
if (annot_array.pageData.length > 0) {
|
||
this.xrefs.push({
|
||
id: annot_array.pageReference.obj,
|
||
pointer: ptr,
|
||
generation: annot_array.pageReference.generation,
|
||
free: false,
|
||
update: true
|
||
});
|
||
new_data = new_data.concat(annot_array.pageData);
|
||
ptr += annot_array.pageData.length;
|
||
}
|
||
// writes the actual annotation object
|
||
for (let annot of pageAnnots) {
|
||
let annot_obj = this.writeAnnotationObject(annot);
|
||
this.xrefs.push({
|
||
id: annot_obj.ptr.obj,
|
||
pointer: ptr,
|
||
generation: annot_obj.ptr.generation,
|
||
free: false,
|
||
update: true
|
||
});
|
||
new_data = new_data.concat(annot_obj.data);
|
||
ptr += annot_obj.data.length;
|
||
}
|
||
}
|
||
// take all annotations that are not deleted yet
|
||
let _toDelete = this.toDelete.filter((t) => !t.is_deleted);
|
||
let pageWiseSortedToDelete = this.sortPageWise(_toDelete);
|
||
// adapt the remaining annotation reference tables
|
||
for (let key in pageWiseSortedToDelete) {
|
||
let del_data = this.updatePageAnnotationReferenceArray(pageWiseSortedToDelete[key]);
|
||
this.xrefs.push({
|
||
id: del_data.ptr.obj,
|
||
pointer: ptr,
|
||
generation: del_data.ptr.generation,
|
||
free: false,
|
||
update: true
|
||
});
|
||
new_data = new_data.concat(del_data.data);
|
||
ptr += del_data.data.length;
|
||
}
|
||
// at this point all references to annotation objects in pages should be removed and we can free
|
||
// the annotation object ids
|
||
for (let toDel of this.toDelete) {
|
||
if (!toDel.object_id)
|
||
continue;
|
||
this.xrefs.push({
|
||
id: toDel.object_id.obj,
|
||
pointer: -1,
|
||
generation: toDel.object_id.generation + 1,
|
||
free: true,
|
||
update: false
|
||
});
|
||
}
|
||
let crtable = this.writeCrossSiteReferenceTable();
|
||
new_data = new_data.concat(crtable);
|
||
let trailer = this.writeTrailer(ptr);
|
||
new_data = new_data.concat(trailer);
|
||
let new_data_array = new Uint8Array(new_data);
|
||
let ret_array = new Uint8Array(this.data.length + new_data_array.length);
|
||
ret_array.set(this.data);
|
||
ret_array.set(new_data, this.data.length);
|
||
return ret_array;
|
||
}
|
||
/**
|
||
* Removes the given annotation
|
||
* */
|
||
updatePageAnnotationReferenceArray(toDelete) {
|
||
let page = toDelete[0].pageReference;
|
||
if (!page)
|
||
throw Error("Missing page reference");
|
||
if (!page.object_id) {
|
||
throw Error("Page without object id");
|
||
}
|
||
let references = page.annots;
|
||
// remove annotation references from the array that must be deleted and mark them as deleted
|
||
references = references.filter((a) => {
|
||
let toDel = toDelete.find((t) => t.object_id.obj === a.obj && t.object_id.generation === a.generation);
|
||
if (toDel) {
|
||
toDel.is_deleted = true;
|
||
return false;
|
||
}
|
||
return true;
|
||
});
|
||
let refArray_id = page.annotsPointer;
|
||
let ret = writer_util_1.WriterUtil.writeReferencePointer(refArray_id);
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
ret = ret.concat(writer_util_1.WriterUtil.OBJ);
|
||
ret.push(writer_util_1.WriterUtil.CR);
|
||
ret.push(writer_util_1.WriterUtil.LF);
|
||
ret.push(writer_util_1.WriterUtil.ARRAY_START);
|
||
for (let an of references) {
|
||
ret = ret.concat(writer_util_1.WriterUtil.writeReferencePointer(an, true));
|
||
ret.push(writer_util_1.WriterUtil.SPACE);
|
||
}
|
||
ret.push(writer_util_1.WriterUtil.ARRAY_END);
|
||
ret.push(writer_util_1.WriterUtil.CR);
|
||
ret.push(writer_util_1.WriterUtil.LF);
|
||
ret = ret.concat(writer_util_1.WriterUtil.ENDOBJ);
|
||
ret.push(writer_util_1.WriterUtil.CR);
|
||
ret.push(writer_util_1.WriterUtil.LF);
|
||
return { ptr: refArray_id, data: ret };
|
||
}
|
||
}
|
||
exports.Writer = Writer;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ 0:
|
||
/*!**********************!*\
|
||
!*** util (ignored) ***!
|
||
\**********************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
/* (ignored) */
|
||
|
||
/***/ }),
|
||
|
||
/***/ 1:
|
||
/*!**********************!*\
|
||
!*** util (ignored) ***!
|
||
\**********************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
/* (ignored) */
|
||
|
||
/***/ }),
|
||
|
||
/***/ 2:
|
||
/*!************************!*\
|
||
!*** buffer (ignored) ***!
|
||
\************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
/* (ignored) */
|
||
|
||
/***/ }),
|
||
|
||
/***/ 3:
|
||
/*!************************!*\
|
||
!*** crypto (ignored) ***!
|
||
\************************/
|
||
/*! no static exports found */
|
||
/***/ (function(module, exports) {
|
||
|
||
/* (ignored) */
|
||
|
||
/***/ })
|
||
|
||
/******/ });
|
||
});
|
||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS93ZWJwYWNrL3VuaXZlcnNhbE1vZHVsZURlZmluaXRpb24iLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2FwaS5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2Jhc2UvYnVmZmVyLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvYmFzZS9pbmRleC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2Jhc2Uvbm9kZS5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2Jhc2UvcmVwb3J0ZXIuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9jb25zdGFudHMvZGVyLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvY29uc3RhbnRzL2luZGV4LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvZGVjb2RlcnMvZGVyLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvZGVjb2RlcnMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9kZWNvZGVycy9wZW0uanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9lbmNvZGVycy9kZXIuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9lbmNvZGVycy9pbmRleC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2VuY29kZXJzL3BlbS5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9iYXNlNjQtanMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvYm4uanMvbGliL2JuLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2Jyb3JhbmQvaW5kZXguanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvYWVzLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2F1dGhDaXBoZXIuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvYnJvd3Nlci5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9kZWNyeXB0ZXIuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvZW5jcnlwdGVyLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2doYXNoLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2luY3IzMi5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jYmMuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2ZiLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL2NmYjEuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2ZiOC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jdHIuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvZWNiLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL2luZGV4LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL29mYi5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9zdHJlYW1DaXBoZXIuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvYnJvd3Nlci5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWRlcy9pbmRleC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWRlcy9tb2Rlcy5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXJzYS9pbmRleC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vYWxnb3MuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL2Jyb3dzZXIvaW5kZXguanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL2Jyb3dzZXIvc2lnbi5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vYnJvd3Nlci92ZXJpZnkuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvYnVmZmVyLXhvci9pbmRleC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9idWZmZXIvaW5kZXguanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvY2lwaGVyLWJhc2UvaW5kZXguanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvY29yZS11dGlsLWlzL2xpYi91dGlsLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2NyZWF0ZS1lY2RoL2Jyb3dzZXIuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvY3JlYXRlLWhhc2gvYnJvd3Nlci5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9tZDUuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvY3JlYXRlLWhtYWMvYnJvd3Nlci5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9jcmVhdGUtaG1hYy9sZWdhY3kuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvaW5kZXguanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvY3J5cHRvLWpzL2Flcy5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9jcnlwdG8tanMvY2lwaGVyLWNvcmUuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvY3J5cHRvLWpzL2NvcmUuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvY3J5cHRvLWpzL2VuYy1iYXNlNjQuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvY3J5cHRvLWpzL2VuYy11dGYxNi5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9jcnlwdG8tanMvZXZwa2RmLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2NyeXB0by1qcy9mb3JtYXQtaGV4LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2NyeXB0by1qcy9obWFjLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2NyeXB0by1qcy9pbmRleC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9jcnlwdG8tanMvbGliLXR5cGVkYXJyYXlzLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2NyeXB0by1qcy9tZDUuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvY3J5cHRvLWpzL21vZGUtY2ZiLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2NyeXB0by1qcy9tb2RlLWN0ci1nbGFkbWFuLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2NyeXB0by1qcy9tb2RlLWN0ci5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9jcnlwdG8tanMvbW9kZS1lY2IuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvY3J5cHRvLWpzL21vZGUtb2ZiLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2NyeXB0by1qcy9wYWQtYW5zaXg5MjMuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvY3J5cHRvLWpzL3BhZC1pc28xMDEyNi5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9jcnlwdG8tanMvcGFkLWlzbzk3OTcxLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2NyeXB0by1qcy9wYWQtbm9wYWRkaW5nLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2NyeXB0by1qcy9wYWQtemVyb3BhZGRpbmcuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvY3J5cHRvLWpzL3Bia2RmMi5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9jcnlwdG8tanMvcmFiYml0LWxlZ2FjeS5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9jcnlwdG8tanMvcmFiYml0LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2NyeXB0by1qcy9yYzQuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvY3J5cHRvLWpzL3JpcGVtZDE2MC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9jcnlwdG8tanMvc2hhMS5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9jcnlwdG8tanMvc2hhMjI0LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2NyeXB0by1qcy9zaGEyNTYuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvY3J5cHRvLWpzL3NoYTMuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvY3J5cHRvLWpzL3NoYTM4NC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9jcnlwdG8tanMvc2hhNTEyLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2NyeXB0by1qcy90cmlwbGVkZXMuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvY3J5cHRvLWpzL3g2NC1jb3JlLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2Rlcy5qcy9saWIvZGVzLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2Rlcy5qcy9saWIvZGVzL2NiYy5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9kZXMuanMvbGliL2Rlcy9jaXBoZXIuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvZGVzLmpzL2xpYi9kZXMvZGVzLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2Rlcy5qcy9saWIvZGVzL2VkZS5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9kZXMuanMvbGliL2Rlcy91dGlscy5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9kaWZmaWUtaGVsbG1hbi9icm93c2VyLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2RpZmZpZS1oZWxsbWFuL2xpYi9kaC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9kaWZmaWUtaGVsbG1hbi9saWIvZ2VuZXJhdGVQcmltZS5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2N1cnZlL2Jhc2UuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2N1cnZlL2Vkd2FyZHMuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2N1cnZlL2luZGV4LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9jdXJ2ZS9tb250LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9jdXJ2ZS9zaG9ydC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvY3VydmVzLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9lYy9pbmRleC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvZWMva2V5LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9lYy9zaWduYXR1cmUuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2VkZHNhL2luZGV4LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9lZGRzYS9rZXkuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2VkZHNhL3NpZ25hdHVyZS5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvcHJlY29tcHV0ZWQvc2VjcDI1NmsxLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy91dGlscy5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9ldmVudHMvZXZlbnRzLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2V2cF9ieXRlc3Rva2V5L2luZGV4LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2hhc2gtYmFzZS9pbmRleC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvY29tbW9uLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvaG1hYy5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3JpcGVtZC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS8xLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzIyNC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS8yNTYuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9zaGEvMzg0LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzUxMi5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS9jb21tb24uanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC91dGlscy5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9obWFjLWRyYmcvbGliL2htYWMtZHJiZy5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9pZWVlNzU0L2luZGV4LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvaXNhcnJheS9pbmRleC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9tZDUuanMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvbWlsbGVyLXJhYmluL2xpYi9tci5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9taW5pbWFsaXN0aWMtYXNzZXJ0L2luZGV4LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL21pbmltYWxpc3RpYy1jcnlwdG8tdXRpbHMvbGliL3V0aWxzLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3Bha28vaW5kZXguanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvcGFrby9saWIvZGVmbGF0ZS5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi9pbmZsYXRlLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3V0aWxzL2NvbW1vbi5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi91dGlscy9zdHJpbmdzLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvYWRsZXIzMi5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL2NvbnN0YW50cy5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL2NyYzMyLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvZGVmbGF0ZS5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL2d6aGVhZGVyLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvaW5mZmFzdC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL2luZmxhdGUuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYi9pbmZ0cmVlcy5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL21lc3NhZ2VzLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvdHJlZXMuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvcGFrby9saWIvemxpYi96c3RyZWFtLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvYXNuMS5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL2NlcnRpZmljYXRlLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvZml4UHJvYy5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL2luZGV4LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3Bia2RmMi9icm93c2VyLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3Bia2RmMi9saWIvYXN5bmMuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvcGJrZGYyL2xpYi9kZWZhdWx0LWVuY29kaW5nLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3Bia2RmMi9saWIvcHJlY29uZGl0aW9uLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3Bia2RmMi9saWIvc3luYy1icm93c2VyLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3Byb2Nlc3MtbmV4dGljay1hcmdzL2luZGV4LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9icm93c2VyLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L21nZi5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9wcml2YXRlRGVjcnlwdC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9wdWJsaWNFbmNyeXB0LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L3dpdGhQdWJsaWMuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQveG9yLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3JhbmRvbWJ5dGVzL2Jyb3dzZXIuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvcmFuZG9tZmlsbC9icm93c2VyLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9kdXBsZXgtYnJvd3Nlci5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fZHVwbGV4LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fcmVhZGFibGUuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fd3JpdGFibGUuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL0J1ZmZlckxpc3QuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL2Rlc3Ryb3kuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL3N0cmVhbS1icm93c2VyLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9wYXNzdGhyb3VnaC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vcmVhZGFibGUtYnJvd3Nlci5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vdHJhbnNmb3JtLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS93cml0YWJsZS1icm93c2VyLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3JpcGVtZDE2MC9pbmRleC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9zYWZlLWJ1ZmZlci9pbmRleC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9zZXRpbW1lZGlhdGUvc2V0SW1tZWRpYXRlLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3NoYS5qcy9oYXNoLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3NoYS5qcy9pbmRleC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9zaGEuanMvc2hhLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3NoYS5qcy9zaGExLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3NoYS5qcy9zaGEyMjQuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvc2hhLmpzL3NoYTI1Ni5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy9zaGEuanMvc2hhMzg0LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3NoYS5qcy9zaGE1MTIuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvc3RyZWFtLWJyb3dzZXJpZnkvaW5kZXguanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvc3RyaW5nX2RlY29kZXIvbGliL3N0cmluZ19kZWNvZGVyLmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vbm9kZV9tb2R1bGVzL3RpbWVycy1icm93c2VyaWZ5L21haW4uanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9ub2RlX21vZHVsZXMvdXRpbC1kZXByZWNhdGUvYnJvd3Nlci5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL25vZGVfbW9kdWxlcy92bS1icm93c2VyaWZ5L2luZGV4LmpzIiwid2VicGFjazovL3BkZkFubm90YXRlLyh3ZWJwYWNrKS9idWlsZGluL2dsb2JhbC5qcyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8od2VicGFjaykvYnVpbGRpbi9tb2R1bGUuanMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9zcmMvYW5ub3RhdGlvbi50cyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL3NyYy9hbm5vdGF0aW9ucy9hbm5vdGF0aW9uX2Vycm9ycy50cyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL3NyYy9hbm5vdGF0aW9ucy9hbm5vdGF0aW9uX3R5cGVzLnRzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vc3JjL2Fubm90YXRpb25zL2NpcmNsZV9zcXVhcmVfYW5ub3RhdGlvbi50cyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL3NyYy9hbm5vdGF0aW9ucy9mcmVldGV4dF9hbm5vdGF0aW9uLnRzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vc3JjL2Fubm90YXRpb25zL2lua19hbm5vdGF0aW9uLnRzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vc3JjL2Fubm90YXRpb25zL3BvbHlnb25fcG9seWxpbmVfYW5ub3RhdGlvbi50cyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL3NyYy9hbm5vdGF0aW9ucy90ZXh0X2Fubm90YXRpb24udHMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9zcmMvYW5ub3RhdGlvbnMvdGV4dF9tYXJrdXBfYW5ub3RhdGlvbi50cyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL3NyYy9hcnJheS11dGlsLnRzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vc3JjL2NyeXB0by11dGlsLnRzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vc3JjL2NyeXB0by50cyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL3NyYy9kb2N1bWVudC1oaXN0b3J5LnRzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vc3JjL2luZGV4LnRzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vc3JjL29iamVjdC11dGlsLnRzIiwid2VicGFjazovL3BkZkFubm90YXRlLy4vc3JjL3BhcnNlci50cyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL3NyYy9zdHJlYW0udHMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvLi9zcmMvdXRpbC50cyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL3NyYy93cml0ZXItdXRpbC50cyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS8uL3NyYy93cml0ZXIudHMiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvdXRpbCAoaWdub3JlZCkiLCJ3ZWJwYWNrOi8vcGRmQW5ub3RhdGUvdXRpbCAoaWdub3JlZCk/YmYxYyIsIndlYnBhY2s6Ly9wZGZBbm5vdGF0ZS9idWZmZXIgKGlnbm9yZWQpIiwid2VicGFjazovL3BkZkFubm90YXRlL2NyeXB0byAoaWdub3JlZCkiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNELE87UUNWQTtRQUNBOztRQUVBO1FBQ0E7O1FBRUE7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7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Q0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGdCQUFnQjtBQUNoQjtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FB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Q0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNuVUE7O0FBRUEsZUFBZSxtQkFBTyxDQUFDLDhEQUFP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QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLGlCQUFpQjtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLDRCQUE0QjtBQUM3QztBQUNBOztBQUVBLGlCQUFpQixhQUFhO0FBQzlCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTCxpQkFBaUIsYUFBYTtBQUM5QjtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsWUFBWSxlQUFlO0FBQzNCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLHFCQUFxQixnQkFBZ0I7QUFDckM7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsbUJBQW1CLGlCQUFpQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsZ0JBQWdCO0FBQ25DO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBLG1CQUFtQixjQUFjO0FBQ2pDO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixjQUFjO0FBQ2pDO0FBQ0E7O0FBRUE7QUFDQSxZQUFZLGNBQWM7QUFDMUI7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixpQkFBaUI7QUFDcEM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixjQUFjO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVSw2QkFBNkI7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxZQUFZLGNBQWM7QUFDMUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxtQkFBbUIsY0FBYztBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVUsNkJBQTZCO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxZQUFZLGNBQWM7QUFDMUI7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvREFBb0QsV0FBVztBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1CQUFtQixvQkFBb0I7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0RBQW9ELFdBQVc7QUFDL0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLE9BQU87QUFDMUI7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixPQUFPO0FBQzFCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixPQUFPO0FBQzFCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsbUJBQW1CLE9BQU87QUFDMUI7O0FBRUE7QUFDQTs7QUFFQSxxQkFBcUIsT0FBTztBQUM1QjtBQUNBOztBQUVBLHVCQUF1QixPQUFPO0FBQzlCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsR0FBRztBQUMxQjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxtQkFBbUIs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O0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlDQUFpQyxRQUFRO0FBQ3pDO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQ0FBaUMsUUFBUTtBQUN6QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSw2QkFBNkIsbUNBQW1DO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDZCQUE2QixtQ0FBbUM7QUFDaEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSw2QkFBNkIsbUNBQW1DO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsNkJBQTZCLG1DQUFtQztBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx1QkFBdUIsMEJBQTBCO0FBQ2pEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1CQUFtQixnQ0FBZ0M7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlDQUFpQyxRQUFRO0FBQ3pDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixZQUFZO0FBQy9CO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxnQkFBZ0Isa0JBQWtCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1CQUFtQixnQkFBZ0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsZ0JBQWdCO0FBQ25DO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsb0JBQW9CO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsZ0JBQWdCO0FBQ25DO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsNEJB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QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixtREFBbUQ7QUFDeEU7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixVQUFVO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixZQUFZO0FBQzdCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUEsdUNBQXVDLFNBQVM7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxpQkFBaUI7QUFDaEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhLGlCQUFpQjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsRUFBRTtBQUNsRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsZUFBZTtBQUN2QztBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBLHFCQUFxQixlQUFlO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixZQUFZO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxxQkFBcUIsU0FBUztBQUM5QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLGtCQUFrQjtBQUNuQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsbUJBQW1CLGNBQWM7QUFDakM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHVEQUF1RCxPQUFPO0FBQzlEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1REFBdUQsT0FBTztBQUM5RDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0I7QUFDbEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FB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bEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDMUdBLDZEQUFlLG1CQUFPLENBQUMseURBQVU7QUFDakMsU0FBUyxtQkFBTyxDQUFDLDZDQUFPOztBQUV4QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTs7QUFFVjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw0QkFBNEIsT0FBTztBQUNuQztBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsVUFBVTs7QUFFVjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07O0FBRU47QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGlCQUFpQjtBQUNqQztBQUNBLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsaUJB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QUFHLG1CQUFPLENBQUMsOENBQU8sR0FBRyxtQkFBTyxDQUFDLG9EQUFVLEdBQUcsbUJBQU8sQ0FBQyw4REFBZTtBQUMvSTtBQUNBLE1BQU0sRUFPSjtBQUNGLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDdERhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsaUJBQWlCLFFBQVE7QUFDekIsbUJBQW1CLFNBQVM7QUFDNUI7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLFNBQVM7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsaUJBQWlCLFFBQVE7QUFDekIsbUJBQW1CLFNBQVM7QUFDNUI7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLFNBQVM7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIsT0FBTztBQUN4QixvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsT0FBTztBQUN4QixvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixRQUFRO0FBQ3pCLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFFBQVE7QUFDekIsbUJBQW1CLFNBQVM7QUFDNUI7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLFNBQVM7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtB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OztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsU0FBUztBQUM1QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1CQUFtQixRQUFRO0FBQzNCOztBQUVBO0FBQ0E7QUFDQSxxQkFBcUIsU0FBUztBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsU0FBUztBQUMxQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCLFdBQVc7QUFDNUIsbUJBQW1CLFVBQVU7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCLE9BQU87QUFDeEI7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDdlhhOztBQUViLFlBQVksbUJBQU8sQ0FBQywrREFBVTtBQUM5QixTQUFTLG1CQUFPLENBQUMsNkNBQU87QUFDeEIsZUFBZSxtQkFBTyxDQUFDLDZEQUFVO0FBQ2pDLFdBQVcsbUJBQU8sQ0FBQyxrRUFBUTs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUssZUFBZTtBQUNwQixLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsbUJBQW1CO0FBQ3BDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQixXQUFXO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsU0FBUztBQUM1QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQjtBQUN0QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7QUMzd0JhOztBQUViO0FBQ0EsU0FBUyxtQkFBTyxDQUFDLDZDQUFPO0FBQ3hCLGdCQUFnQixtQkFBTyxDQUFDLHdFQUFxQjtBQUM3QyxlQUFlLG1CQUFPLENBQUMsd0ZBQTJCOztBQUVsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsaUJBQWlCLGdCQUFnQjtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDckhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGlCQUFpQixzQkFBc0I7QUFDdkM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsbUJBQW1CLFNBQVM7QUFDNUI7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLFFBQVE7QUFDekI7QUFDQSxRQUFRLGNBQWM7QUFDdEIsOENBQThDO0FBQzlDO0FBQ0EsMEJBQTBCO0FBQzFCO0FBQ0EsZ0RBQWdEO0FBQ2hEO0FBQ0EsMEJBQTBCO0FBQzFCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLGNBQWM7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDaEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFdBQVc7O0FBRW5CO0FBQ0E7QUFDQTtBQUNBLFFBQVEsV0FBVzs7QUFFbkI7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFFBQVEsV0FBVzs7QUFFbkI7QUFDQTtBQUNBLFFBQVEsVUFBVTs7QUFFbEI7QUFDQTs7Ozs7Ozs7Ozs7O0FDbkZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUN0QkEsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7Ozs7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QUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLGtFQUFrRTs7QUFFdkY7O0FBRUEsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEdBQUc7O0FBRUg7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLHFCQUFxQix5Q0FBeUM7O0FBRTlEO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7OztBQ3RhYTs7O0FB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QTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxzREFBc0Q7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtFQUFrRTtBQUNsRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCLGFBQWE7O0FBRWIsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1EO0FBQ25EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUVBQW1FOztBQUVuRTtBQUNBLHlEQUF5RDtBQUN6RDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0EsdURBQXVEO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJEO0FBQzNEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSwwREFBMEQ7QUFDMUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkI7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEIsYUFBYTs7QUFFYjs7QUFFQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QixPQUFPLEVBQUU7QUFDdkM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1EQUFtRDtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLHdEQUF3RDtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVEQUF1RDtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLCtCQUErQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0REFBNEQ7QUFDNUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBEQUEwRDtBQUMxRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsV0FBVztBQUNYLG1CQUFtQjs7QUFFbkI7O0FBRUEsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QixPQUFPLEVBQUU7QUFDdkM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLG9FQUFvRTtBQUNwRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLDBEQUEwRDtBQUMxRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkI7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHdEQUF3RDtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkI7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEscUJBQXFCO0FBQ3JCLGVBQWU7O0FBRWY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0EsbUJBQW1CO0FBQ25CLGtCQUFrQjtBQUNsQiwwQkFBMEI7QUFDMUIsNEJBQTRCO0FBQzVCLHVCQUF1QjtBQUN2QixtQkFBbUI7QUFDbkIsZ0JBQWdCO0FBQ2hCLHFCQUFxQjtBQUNyQixtQkFBbUI7QUFDbkIsMkJBQTJCO0FBQzNCLHVCQUF1Qjs7QUFFdkIsa0JBQWtCO0FBQ2xCLGtCQUFrQjtBQUNsQixrQkFBa0I7O0FBRWxCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsbUJBQW1COztBQUVuQixpQkFBaUI7QUFDakIscUJBQXFCO0FBQ3JCLHFCQUFxQjtBQUNyQixxQkFBcUI7O0FBRXJCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSx3QkFBd0I7QUFDeEIsc0JBQXNCO0FBQ3RCLDJCQUEyQjtBQUMzQixvQkFBb0I7QUFDcEIsdUJBQXVCO0FBQ3ZCLHFCQUFxQjs7QUFFckI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGlCQUFpQjtBQUNqQixvQkFBb0I7O0FBRXBCO0FBQ0E7O0FBRUEsc0JBQXNCOztBQUV0Qjs7QUFFQTs7QUFFQSwyQ0FBMkM7QUFDM0MsNkNBQTZDO0FBQzdDLDRDQUE0Qzs7QUFFNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSx1QkFBdUI7QUFDdkIsdUJBQXVCO0FBQ3ZCLHVCQUF1Qjs7QUFFdkI7QUFDQTtBQUNBOztBQUVBLDBCQUEwQjtBQUMxQiwrQ0FBK0M7QUFDL0M7O0FBRUEsb0JBQW9CO0FBQ3BCLG9CQUFvQjtBQUNwQjtBQUNBO0FBQ0E7O0FBRUEsZ0RBQWdEO0FBQ2hEO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG9CQUFvQjs7QUFFcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUI7QUFDbkIsc0JBQXNCO0FBQ3RCLG1CQUFtQjtBQUNuQixrQkFBa0I7OztBQUdsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1EQUFtRDtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQSw2QkFBNkIsdUJBQXVCO0FBQ3BELDhCQUE4Qix1QkFBdUI7QUFDckQ7QUFDQTtBQUNBOzs7QUFHQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHVCQUF1QjtBQUN2QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhO0FBQ2I7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHFCQUFxQjs7QUFFckIsc0NBQXNDOztBQUV0Qzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0EsZUFBZTs7QUFFZjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsdUJBQXVCO0FBQ3ZCLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsT0FBTztBQUNQO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLDZCQUE2Qix1QkFBdUI7QUFDcEQ7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCOztBQUV0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQjtBQUN0Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkI7QUFDM0I7QUFDQSwyQkFBMkIsaUJBQWlCO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBLDJCQUEyQixpQkFBaUI7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0EsMkJBQTJCLGlCQUFpQjtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQSw2QkFBNkIsaUJBQWlCO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsYUFBYTtBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRFQUE0RTtBQUM1RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkRBQTZEO0FBQzdEO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxzQ0FBc0M7O0FBRXRDO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3REFBd0Q7QUFDeEQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsNENBQTRDOztBQUU1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0I7O0FBRXBCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsbUJBQW1CLFNBQVM7QUFDNUI7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDRFQUE0RTs7QUFFNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLHlCQUF5QjtBQUMxQztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxtREFBbUQ7QUFDbkQ7QUFDQSxtREFBbUQsaUVBQWlFO0FBQ3BIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDO0FBQ3ZDLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDO0FBQ3ZDLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxnQ0FBZ0MsT0FBTztBQUN2QztBQUNBO0FBQ0E7QUFDQSxDOzs7Ozs7Ozs7Ozs7O0FDMS9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLFlBQVk7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVh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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTCxHQUFHO0FBQ0gsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUIsbUJBQU8sQ0FBQyw4RUFBa0I7O0FBRS9DO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQ0FBaUM7O0FBRWpDOztBQUVBLDJDQUEyQztBQUMzQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1EO0FBQ25EO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLG9EQUFvRDtBQUNwRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0EsUUFBUSxTQUFTO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7Ozs7Ozs7Ozs7OztBQ25RQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLFNBQVMsbUJBQU8sQ0FBQywrQ0FBUTtBQUN6QixlQUFlLG1CQUFPLENBQUMsNkRBQVU7O0FBRWpDO0FBQ0Esa0JBQWtCLG1CQUFPLENBQUMsdUZBQTZCO0FBQ3ZELGtCQUFrQixtQkFBTyxDQUFDLHVGQUE2QjtBQUN2RCxnQkFBZ0IsbUJBQU8sQ0FBQyxtRkFBMkI7QUFDbkQsbUJBQW1CLG1CQUFPLENBQUMsaUZBQThCO0FBQ3pELHFCQUFxQixtQkFBTyxDQUFDLHFGQUFnQzs7QUFFN0Q7QUFDQTs7OztBQUlBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7QUM5SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFYTs7QUFFYjs7QUFFQSxhQUFhLG1CQUFPLENBQUMsd0RBQWE7QUFDbEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixzQ0FBc0Msc0NBQXNDO0FBQ3pHO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxDOzs7Ozs7Ozs7OztBQ3ZTQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0EsbUJBQU8sQ0FBQyxpRUFBYztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FDN0RBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFNBQVM7QUFDcEIsV0FBVyxPQUFPO0FBQ2xCLGFBQWEsU0FBUztBQUN0QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCLGFBQWE7QUFDYjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7OztBQ2xFQTtBQUNBO0FBQ0Esd0JBQXdCLGVBQWU7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx3QkFBd0IsZUFBZTtBQUN2QztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGdDQUFnQyxTQUFTO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsMkJBQTJCO0FBQzNCOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNwSkE7O0FB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LENBQUMsTUFBTSxDQUFDLFlBQVksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xLLEdBQUcsQ0FBQyxJQUFJLENBQUMsd0JBQVUsQ0FBQyxLQUFLLENBQUM7U0FDN0I7UUFFRCxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDWixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUM7Z0JBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksR0FBRztZQUN6QyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUM7Z0JBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksR0FBRztZQUN6QyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUM7Z0JBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksR0FBRztZQUV6QyxHQUFHLENBQUMsSUFBSSxDQUFDLHdCQUFVLENBQUMsS0FBSyxDQUFDO1lBQzFCLEdBQUcsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLHdCQUFVLENBQUMsS0FBSyxDQUFDO1lBQ2xDLEdBQUcsQ0FBQyxJQUFJLENBQUMsd0JBQVUsQ0FBQyxLQUFLLENBQUM7WUFDMUIsR0FBRyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsd0JBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN6RixHQUFHLENBQUMsSUFBSSxDQUFDLHdCQUFVLENBQUMsS0FBSyxDQUFDO1NBQzdCO1FBRUQsSUFBSSxJQUFJLENBQUMsY0FBYyxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUN2RCxLQUFJLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUU7Z0JBQzlCLEdBQUcsQ0FBQyxJQUFJLENBQUMs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QUFDLHFCQUFxQixDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUM1RCxHQUFHLENBQUMsSUFBSSxDQUFDLHdCQUFVLENBQUMsS0FBSyxDQUFDO1NBQzdCO1FBRUQsR0FBRyxDQUFDLElBQUksQ0FBQyx3QkFBVSxDQUFDLFNBQVMsQ0FBQztRQUM5QixHQUFHLENBQUMsSUFBSSxDQUFDLHdCQUFVLENBQUMsRUFBRSxDQUFDO1FBQ3ZCLEdBQUcsQ0FBQyxJQUFJLENBQUMsd0JBQVUsQ0FBQyxFQUFFLENBQUM7UUFFdkIsR0FBRyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsd0JBQVUsQ0FBQyxNQUFNLENBQUM7UUFDbkMsR0FBRyxDQUFDLElBQUksQ0FBQyx3QkFBVSxDQUFDLEVBQUUsQ0FBQztRQUN2QixHQUFHLENBQUMsSUFBSSxDQUFDLHdCQUFVLENBQUMsRUFBRSxDQUFDO1FBRXZCLE9BQU8sRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUU7SUFDMUMsQ0FBQztDQUNKO0FBNWdCRCx3QkE0Z0JDOzs7Ozs7Ozs7Ozs7QUN2aEJELGU7Ozs7Ozs7Ozs7O0FDQUEsZTs7Ozs7Ozs7Ozs7QUNBQSxlOzs7Ozs7Ozs7OztBQ0FBLGUiLCJmaWxlIjoicGRmQW5ub3RhdGUuanMiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gd2VicGFja1VuaXZlcnNhbE1vZHVsZURlZmluaXRpb24ocm9vdCwgZmFjdG9yeSkge1xuXHRpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcpXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCk7XG5cdGVsc2UgaWYodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKVxuXHRcdGRlZmluZShcInBkZkFubm90YXRlXCIsIFtdLCBmYWN0b3J5KTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcInBkZkFubm90YXRlXCJdID0gZmFjdG9yeSgpO1xuXHRlbHNlXG5cdFx0cm9vdFtcInBkZkFubm90YXRlXCJdID0gZmFjdG9yeSgpO1xufSkod2luZG93LCBmdW5jdGlvbigpIHtcbnJldHVybiAiLCIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBnZXR0ZXIgfSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uciA9IGZ1bmN0aW9uKGV4cG9ydHMpIHtcbiBcdFx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG4gXHRcdH1cbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbiBcdH07XG5cbiBcdC8vIGNyZWF0ZSBhIGZha2UgbmFtZXNwYWNlIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDE6IHZhbHVlIGlzIGEgbW9kdWxlIGlkLCByZXF1aXJlIGl0XG4gXHQvLyBtb2RlICYgMjogbWVyZ2UgYWxsIHByb3BlcnRpZXMgb2YgdmFsdWUgaW50byB0aGUgbnNcbiBcdC8vIG1vZGUgJiA0OiByZXR1cm4gdmFsdWUgd2hlbiBhbHJlYWR5IG5zIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDh8MTogYmVoYXZlIGxpa2UgcmVxdWlyZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy50ID0gZnVuY3Rpb24odmFsdWUsIG1vZGUpIHtcbiBcdFx0aWYobW9kZSAmIDEpIHZhbHVlID0gX193ZWJwYWNrX3JlcXVpcmVfXyh2YWx1ZSk7XG4gXHRcdGlmKG1vZGUgJiA4KSByZXR1cm4gdmFsdWU7XG4gXHRcdGlmKChtb2RlICYgNCkgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAmJiB2YWx1ZS5fX2VzTW9kdWxlKSByZXR1cm4gdmFsdWU7XG4gXHRcdHZhciBucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18ucihucyk7XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShucywgJ2RlZmF1bHQnLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2YWx1ZSB9KTtcbiBcdFx0aWYobW9kZSAmIDIgJiYgdHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSBmb3IodmFyIGtleSBpbiB2YWx1ZSkgX193ZWJwYWNrX3JlcXVpcmVfXy5kKG5zLCBrZXksIGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gdmFsdWVba2V5XTsgfS5iaW5kKG51bGwsIGtleSkpO1xuIFx0XHRyZXR1cm4gbnM7XG4gXHR9O1xuXG4gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuIFx0XHRyZXR1cm4gZ2V0dGVyO1xuIFx0fTtcblxuIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuXG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gXCIuL3NyYy9pbmRleC50c1wiKTtcbiIsInZhciBhc24xID0gZXhwb3J0cztcblxuYXNuMS5iaWdudW0gPSByZXF1aXJlKCdibi5qcycpO1xuXG5hc24xLmRlZmluZSA9IHJlcXVpcmUoJy4vYXNuMS9hcGknKS5kZWZpbmU7XG5hc24xLmJhc2UgPSByZXF1aXJlKCcuL2FzbjEvYmFzZScpO1xuYXNuMS5jb25zdGFudHMgPSByZXF1aXJlKCcuL2FzbjEvY29uc3RhbnRzJyk7XG5hc24xLmRlY29kZXJzID0gcmVxdWlyZSgnLi9hc24xL2RlY29kZXJzJyk7XG5hc24xLmVuY29kZXJzID0gcmVxdWlyZSgnLi9hc24xL2VuY29kZXJzJyk7XG4iLCJ2YXIgYXNuMSA9IHJlcXVpcmUoJy4uL2FzbjEnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbnZhciBhcGkgPSBleHBvcnRzO1xuXG5hcGkuZGVmaW5lID0gZnVuY3Rpb24gZGVmaW5lKG5hbWUsIGJvZHkpIHtcbiAgcmV0dXJuIG5ldyBFbnRpdHkobmFtZSwgYm9keSk7XG59O1xuXG5mdW5jdGlvbiBFbnRpdHkobmFtZSwgYm9keSkge1xuICB0aGlzLm5hbWUgPSBuYW1lO1xuICB0aGlzLmJvZHkgPSBib2R5O1xuXG4gIHRoaXMuZGVjb2RlcnMgPSB7fTtcbiAgdGhpcy5lbmNvZGVycyA9IHt9O1xufTtcblxuRW50aXR5LnByb3RvdHlwZS5fY3JlYXRlTmFtZWQgPSBmdW5jdGlvbiBjcmVhdGVOYW1lZChiYXNlKSB7XG4gIHZhciBuYW1lZDtcbiAgdHJ5IHtcbiAgICBuYW1lZCA9IHJlcXVpcmUoJ3ZtJykucnVuSW5UaGlzQ29udGV4dChcbiAgICAgICcoZnVuY3Rpb24gJyArIHRoaXMubmFtZSArICcoZW50aXR5KSB7XFxuJyArXG4gICAgICAnICB0aGlzLl9pbml0TmFtZWQoZW50aXR5KTtcXG4nICtcbiAgICAgICd9KSdcbiAgICApO1xuICB9IGNhdGNoIChlKSB7XG4gICAgbmFtZWQgPSBmdW5jdGlvbiAoZW50aXR5KSB7XG4gICAgICB0aGlzLl9pbml0TmFtZWQoZW50aXR5KTtcbiAgICB9O1xuICB9XG4gIGluaGVyaXRzKG5hbWVkLCBiYXNlKTtcbiAgbmFtZWQucHJvdG90eXBlLl9pbml0TmFtZWQgPSBmdW5jdGlvbiBpbml0bmFtZWQoZW50aXR5KSB7XG4gICAgYmFzZS5jYWxsKHRoaXMsIGVudGl0eSk7XG4gIH07XG5cbiAgcmV0dXJuIG5ldyBuYW1lZCh0aGlzKTtcbn07XG5cbkVudGl0eS5wcm90b3R5cGUuX2dldERlY29kZXIgPSBmdW5jdGlvbiBfZ2V0RGVjb2RlcihlbmMpIHtcbiAgZW5jID0gZW5jIHx8ICdkZXInO1xuICAvLyBMYXppbHkgY3JlYXRlIGRlY29kZXJcbiAgaWYgKCF0aGlzLmRlY29kZXJzLmhhc093blByb3BlcnR5KGVuYykpXG4gICAgdGhpcy5kZWNvZGVyc1tlbmNdID0gdGhpcy5fY3JlYXRlTmFtZWQoYXNuMS5kZWNvZGVyc1tlbmNdKTtcbiAgcmV0dXJuIHRoaXMuZGVjb2RlcnNbZW5jXTtcbn07XG5cbkVudGl0eS5wcm90b3R5cGUuZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKGRhdGEsIGVuYywgb3B0aW9ucykge1xuICByZXR1cm4gdGhpcy5fZ2V0RGVjb2RlcihlbmMpLmRlY29kZShkYXRhLCBvcHRpb25zKTtcbn07XG5cbkVudGl0eS5wcm90b3R5cGUuX2dldEVuY29kZXIgPSBmdW5jdGlvbiBfZ2V0RW5jb2RlcihlbmMpIHtcbiAgZW5jID0gZW5jIHx8ICdkZXInO1xuICAvLyBMYXppbHkgY3JlYXRlIGVuY29kZXJcbiAgaWYgKCF0aGlzLmVuY29kZXJzLmhhc093blByb3BlcnR5KGVuYykpXG4gICAgdGhpcy5lbmNvZGVyc1tlbmNdID0gdGhpcy5fY3JlYXRlTmFtZWQoYXNuMS5lbmNvZGVyc1tlbmNdKTtcbiAgcmV0dXJuIHRoaXMuZW5jb2RlcnNbZW5jXTtcbn07XG5cbkVudGl0eS5wcm90b3R5cGUuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKGRhdGEsIGVuYywgLyogaW50ZXJuYWwgKi8gcmVwb3J0ZXIpIHtcbiAgcmV0dXJuIHRoaXMuX2dldEVuY29kZXIoZW5jKS5lbmNvZGUoZGF0YSwgcmVwb3J0ZXIpO1xufTtcbiIsInZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG52YXIgUmVwb3J0ZXIgPSByZXF1aXJlKCcuLi9iYXNlJykuUmVwb3J0ZXI7XG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuXG5mdW5jdGlvbiBEZWNvZGVyQnVmZmVyKGJhc2UsIG9wdGlvbnMpIHtcbiAgUmVwb3J0ZXIuY2FsbCh0aGlzLCBvcHRpb25zKTtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYmFzZSkpIHtcbiAgICB0aGlzLmVycm9yKCdJbnB1dCBub3QgQnVmZmVyJyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5iYXNlID0gYmFzZTtcbiAgdGhpcy5vZmZzZXQgPSAwO1xuICB0aGlzLmxlbmd0aCA9IGJhc2UubGVuZ3RoO1xufVxuaW5oZXJpdHMoRGVjb2RlckJ1ZmZlciwgUmVwb3J0ZXIpO1xuZXhwb3J0cy5EZWNvZGVyQnVmZmVyID0gRGVjb2RlckJ1ZmZlcjtcblxuRGVjb2RlckJ1ZmZlci5wcm90b3R5cGUuc2F2ZSA9IGZ1bmN0aW9uIHNhdmUoKSB7XG4gIHJldHVybiB7IG9mZnNldDogdGhpcy5vZmZzZXQsIHJlcG9ydGVyOiBSZXBvcnRlci5wcm90b3R5cGUuc2F2ZS5jYWxsKHRoaXMpIH07XG59O1xuXG5EZWNvZGVyQnVmZmVyLnByb3RvdHlwZS5yZXN0b3JlID0gZnVuY3Rpb24gcmVzdG9yZShzYXZlKSB7XG4gIC8vIFJldHVybiBza2lwcGVkIGRhdGFcbiAgdmFyIHJlcyA9IG5ldyBEZWNvZGVyQnVmZmVyKHRoaXMuYmFzZSk7XG4gIHJlcy5vZmZzZXQgPSBzYXZlLm9mZnNldDtcbiAgcmVzLmxlbmd0aCA9IHRoaXMub2Zmc2V0O1xuXG4gIHRoaXMub2Zmc2V0ID0gc2F2ZS5vZmZzZXQ7XG4gIFJlcG9ydGVyLnByb3RvdHlwZS5yZXN0b3JlLmNhbGwodGhpcywgc2F2ZS5yZXBvcnRlcik7XG5cbiAgcmV0dXJuIHJlcztcbn07XG5cbkRlY29kZXJCdWZmZXIucHJvdG90eXBlLmlzRW1wdHkgPSBmdW5jdGlvbiBpc0VtcHR5KCkge1xuICByZXR1cm4gdGhpcy5vZmZzZXQgPT09IHRoaXMubGVuZ3RoO1xufTtcblxuRGVjb2RlckJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gcmVhZFVJbnQ4KGZhaWwpIHtcbiAgaWYgKHRoaXMub2Zmc2V0ICsgMSA8PSB0aGlzLmxlbmd0aClcbiAgICByZXR1cm4gdGhpcy5iYXNlLnJlYWRVSW50OCh0aGlzLm9mZnNldCsrLCB0cnVlKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmVycm9yKGZhaWwgfHwgJ0RlY29kZXJCdWZmZXIgb3ZlcnJ1bicpO1xufVxuXG5EZWNvZGVyQnVmZmVyLnByb3RvdHlwZS5za2lwID0gZnVuY3Rpb24gc2tpcChieXRlcywgZmFpbCkge1xuICBpZiAoISh0aGlzLm9mZnNldCArIGJ5dGVzIDw9IHRoaXMubGVuZ3RoKSlcbiAgICByZXR1cm4gdGhpcy5lcnJvcihmYWlsIHx8ICdEZWNvZGVyQnVmZmVyIG92ZXJydW4nKTtcblxuICB2YXIgcmVzID0gbmV3IERlY29kZXJCdWZmZXIodGhpcy5iYXNlKTtcblxuICAvLyBTaGFyZSByZXBvcnRlciBzdGF0ZVxuICByZXMuX3JlcG9ydGVyU3RhdGUgPSB0aGlzLl9yZXBvcnRlclN0YXRlO1xuXG4gIHJlcy5vZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgcmVzLmxlbmd0aCA9IHRoaXMub2Zmc2V0ICsgYnl0ZXM7XG4gIHRoaXMub2Zmc2V0ICs9IGJ5dGVzO1xuICByZXR1cm4gcmVzO1xufVxuXG5EZWNvZGVyQnVmZmVyLnByb3RvdHlwZS5yYXcgPSBmdW5jdGlvbiByYXcoc2F2ZSkge1xuICByZXR1cm4gdGhpcy5iYXNlLnNsaWNlKHNhdmUgPyBzYXZlLm9mZnNldCA6IHRoaXMub2Zmc2V0LCB0aGlzLmxlbmd0aCk7XG59XG5cbmZ1bmN0aW9uIEVuY29kZXJCdWZmZXIodmFsdWUsIHJlcG9ydGVyKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHRoaXMubGVuZ3RoID0gMDtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWUubWFwKGZ1bmN0aW9uKGl0ZW0pIHtcbiAgICAgIGlmICghKGl0ZW0gaW5zdGFuY2VvZiBFbmNvZGVyQnVmZmVyKSlcbiAgICAgICAgaXRlbSA9IG5ldyBFbmNvZGVyQnVmZmVyKGl0ZW0sIHJlcG9ydGVyKTtcbiAgICAgIHRoaXMubGVuZ3RoICs9IGl0ZW0ubGVuZ3RoO1xuICAgICAgcmV0dXJuIGl0ZW07XG4gICAgfSwgdGhpcyk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIGlmICghKDAgPD0gdmFsdWUgJiYgdmFsdWUgPD0gMHhmZikpXG4gICAgICByZXR1cm4gcmVwb3J0ZXIuZXJyb3IoJ25vbi1ieXRlIEVuY29kZXJCdWZmZXIgdmFsdWUnKTtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgdGhpcy5sZW5ndGggPSAxO1xuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgdGhpcy5sZW5ndGggPSBCdWZmZXIuYnl0ZUxlbmd0aCh2YWx1ZSk7XG4gIH0gZWxzZSBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbHVlKSkge1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLmxlbmd0aCA9IHZhbHVlLmxlbmd0aDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcmVwb3J0ZXIuZXJyb3IoJ1Vuc3VwcG9ydGVkIHR5cGU6ICcgKyB0eXBlb2YgdmFsdWUpO1xuICB9XG59XG5leHBvcnRzLkVuY29kZXJCdWZmZXIgPSBFbmNvZGVyQnVmZmVyO1xuXG5FbmNvZGVyQnVmZmVyLnByb3RvdHlwZS5qb2luID0gZnVuY3Rpb24gam9pbihvdXQsIG9mZnNldCkge1xuICBpZiAoIW91dClcbiAgICBvdXQgPSBuZXcgQnVmZmVyKHRoaXMubGVuZ3RoKTtcbiAgaWYgKCFvZmZzZXQpXG4gICAgb2Zmc2V0ID0gMDtcblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApXG4gICAgcmV0dXJuIG91dDtcblxuICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLnZhbHVlKSkge1xuICAgIHRoaXMudmFsdWUuZm9yRWFjaChmdW5jdGlvbihpdGVtKSB7XG4gICAgICBpdGVtLmpvaW4ob3V0LCBvZmZzZXQpO1xuICAgICAgb2Zmc2V0ICs9IGl0ZW0ubGVuZ3RoO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGlmICh0eXBlb2YgdGhpcy52YWx1ZSA9PT0gJ251bWJlcicpXG4gICAgICBvdXRbb2Zmc2V0XSA9IHRoaXMudmFsdWU7XG4gICAgZWxzZSBpZiAodHlwZW9mIHRoaXMudmFsdWUgPT09ICdzdHJpbmcnKVxuICAgICAgb3V0LndyaXRlKHRoaXMudmFsdWUsIG9mZnNldCk7XG4gICAgZWxzZSBpZiAoQnVmZmVyLmlzQnVmZmVyKHRoaXMudmFsdWUpKVxuICAgICAgdGhpcy52YWx1ZS5jb3B5KG91dCwgb2Zmc2V0KTtcbiAgICBvZmZzZXQgKz0gdGhpcy5sZW5ndGg7XG4gIH1cblxuICByZXR1cm4gb3V0O1xufTtcbiIsInZhciBiYXNlID0gZXhwb3J0cztcblxuYmFzZS5SZXBvcnRlciA9IHJlcXVpcmUoJy4vcmVwb3J0ZXInKS5SZXBvcnRlcjtcbmJhc2UuRGVjb2RlckJ1ZmZlciA9IHJlcXVpcmUoJy4vYnVmZmVyJykuRGVjb2RlckJ1ZmZlcjtcbmJhc2UuRW5jb2RlckJ1ZmZlciA9IHJlcXVpcmUoJy4vYnVmZmVyJykuRW5jb2RlckJ1ZmZlcjtcbmJhc2UuTm9kZSA9IHJlcXVpcmUoJy4vbm9kZScpO1xuIiwidmFyIFJlcG9ydGVyID0gcmVxdWlyZSgnLi4vYmFzZScpLlJlcG9ydGVyO1xudmFyIEVuY29kZXJCdWZmZXIgPSByZXF1aXJlKCcuLi9iYXNlJykuRW5jb2RlckJ1ZmZlcjtcbnZhciBEZWNvZGVyQnVmZmVyID0gcmVxdWlyZSgnLi4vYmFzZScpLkRlY29kZXJCdWZmZXI7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG4vLyBTdXBwb3J0ZWQgdGFnc1xudmFyIHRhZ3MgPSBbXG4gICdzZXEnLCAnc2Vxb2YnLCAnc2V0JywgJ3NldG9mJywgJ29iamlkJywgJ2Jvb2wnLFxuICAnZ2VudGltZScsICd1dGN0aW1lJywgJ251bGxfJywgJ2VudW0nLCAnaW50JywgJ29iakRlc2MnLFxuICAnYml0c3RyJywgJ2JtcHN0cicsICdjaGFyc3RyJywgJ2dlbnN0cicsICdncmFwaHN0cicsICdpYTVzdHInLCAnaXNvNjQ2c3RyJyxcbiAgJ251bXN0cicsICdvY3RzdHInLCAncHJpbnRzdHInLCAndDYxc3RyJywgJ3VuaXN0cicsICd1dGY4c3RyJywgJ3ZpZGVvc3RyJ1xuXTtcblxuLy8gUHVibGljIG1ldGhvZHMgbGlzdFxudmFyIG1ldGhvZHMgPSBbXG4gICdrZXknLCAnb2JqJywgJ3VzZScsICdvcHRpb25hbCcsICdleHBsaWNpdCcsICdpbXBsaWNpdCcsICdkZWYnLCAnY2hvaWNlJyxcbiAgJ2FueScsICdjb250YWlucydcbl0uY29uY2F0KHRhZ3MpO1xuXG4vLyBPdmVycmlkZWQgbWV0aG9kcyBsaXN0XG52YXIgb3ZlcnJpZGVkID0gW1xuICAnX3BlZWtUYWcnLCAnX2RlY29kZVRhZycsICdfdXNlJyxcbiAgJ19kZWNvZGVTdHInLCAnX2RlY29kZU9iamlkJywgJ19kZWNvZGVUaW1lJyxcbiAgJ19kZWNvZGVOdWxsJywgJ19kZWNvZGVJbnQnLCAnX2RlY29kZUJvb2wnLCAnX2RlY29kZUxpc3QnLFxuXG4gICdfZW5jb2RlQ29tcG9zaXRlJywgJ19lbmNvZGVTdHInLCAnX2VuY29kZU9iamlkJywgJ19lbmNvZGVUaW1lJyxcbiAgJ19lbmNvZGVOdWxsJywgJ19lbmNvZGVJbnQnLCAnX2VuY29kZUJvb2wnXG5dO1xuXG5mdW5jdGlvbiBOb2RlKGVuYywgcGFyZW50KSB7XG4gIHZhciBzdGF0ZSA9IHt9O1xuICB0aGlzLl9iYXNlU3RhdGUgPSBzdGF0ZTtcblxuICBzdGF0ZS5lbmMgPSBlbmM7XG5cbiAgc3RhdGUucGFyZW50ID0gcGFyZW50IHx8IG51bGw7XG4gIHN0YXRlLmNoaWxkcmVuID0gbnVsbDtcblxuICAvLyBTdGF0ZVxuICBzdGF0ZS50YWcgPSBudWxsO1xuICBzdGF0ZS5hcmdzID0gbnVsbDtcbiAgc3RhdGUucmV2ZXJzZUFyZ3MgPSBudWxsO1xuICBzdGF0ZS5jaG9pY2UgPSBudWxsO1xuICBzdGF0ZS5vcHRpb25hbCA9IGZhbHNlO1xuICBzdGF0ZS5hbnkgPSBmYWxzZTtcbiAgc3RhdGUub2JqID0gZmFsc2U7XG4gIHN0YXRlLnVzZSA9IG51bGw7XG4gIHN0YXRlLnVzZURlY29kZXIgPSBudWxsO1xuICBzdGF0ZS5rZXkgPSBudWxsO1xuICBzdGF0ZVsnZGVmYXVsdCddID0gbnVsbDtcbiAgc3RhdGUuZXhwbGljaXQgPSBudWxsO1xuICBzdGF0ZS5pbXBsaWNpdCA9IG51bGw7XG4gIHN0YXRlLmNvbnRhaW5zID0gbnVsbDtcblxuICAvLyBTaG91bGQgY3JlYXRlIG5ldyBpbnN0YW5jZSBvbiBlYWNoIG1ldGhvZFxuICBpZiAoIXN0YXRlLnBhcmVudCkge1xuICAgIHN0YXRlLmNoaWxkcmVuID0gW107XG4gICAgdGhpcy5fd3JhcCgpO1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IE5vZGU7XG5cbnZhciBzdGF0ZVByb3BzID0gW1xuICAnZW5jJywgJ3BhcmVudCcsICdjaGlsZHJlbicsICd0YWcnLCAnYXJncycsICdyZXZlcnNlQXJncycsICdjaG9pY2UnLFxuICAnb3B0aW9uYWwnLCAnYW55JywgJ29iaicsICd1c2UnLCAnYWx0ZXJlZFVzZScsICdrZXknLCAnZGVmYXVsdCcsICdleHBsaWNpdCcsXG4gICdpbXBsaWNpdCcsICdjb250YWlucydcbl07XG5cbk5vZGUucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gY2xvbmUoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgdmFyIGNzdGF0ZSA9IHt9O1xuICBzdGF0ZVByb3BzLmZvckVhY2goZnVuY3Rpb24ocHJvcCkge1xuICAgIGNzdGF0ZVtwcm9wXSA9IHN0YXRlW3Byb3BdO1xuICB9KTtcbiAgdmFyIHJlcyA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKGNzdGF0ZS5wYXJlbnQpO1xuICByZXMuX2Jhc2VTdGF0ZSA9IGNzdGF0ZTtcbiAgcmV0dXJuIHJlcztcbn07XG5cbk5vZGUucHJvdG90eXBlLl93cmFwID0gZnVuY3Rpb24gd3JhcCgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuICBtZXRob2RzLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgdGhpc1ttZXRob2RdID0gZnVuY3Rpb24gX3dyYXBwZWRNZXRob2QoKSB7XG4gICAgICB2YXIgY2xvbmUgPSBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgIHN0YXRlLmNoaWxkcmVuLnB1c2goY2xvbmUpO1xuICAgICAgcmV0dXJuIGNsb25lW21ldGhvZF0uYXBwbHkoY2xvbmUsIGFyZ3VtZW50cyk7XG4gICAgfTtcbiAgfSwgdGhpcyk7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uIGluaXQoYm9keSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlLnBhcmVudCA9PT0gbnVsbCk7XG4gIGJvZHkuY2FsbCh0aGlzKTtcblxuICAvLyBGaWx0ZXIgY2hpbGRyZW5cbiAgc3RhdGUuY2hpbGRyZW4gPSBzdGF0ZS5jaGlsZHJlbi5maWx0ZXIoZnVuY3Rpb24oY2hpbGQpIHtcbiAgICByZXR1cm4gY2hpbGQuX2Jhc2VTdGF0ZS5wYXJlbnQgPT09IHRoaXM7XG4gIH0sIHRoaXMpO1xuICBhc3NlcnQuZXF1YWwoc3RhdGUuY2hpbGRyZW4ubGVuZ3RoLCAxLCAnUm9vdCBub2RlIGNhbiBoYXZlIG9ubHkgb25lIGNoaWxkJyk7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5fdXNlQXJncyA9IGZ1bmN0aW9uIHVzZUFyZ3MoYXJncykge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgLy8gRmlsdGVyIGNoaWxkcmVuIGFuZCBhcmdzXG4gIHZhciBjaGlsZHJlbiA9IGFyZ3MuZmlsdGVyKGZ1bmN0aW9uKGFyZykge1xuICAgIHJldHVybiBhcmcgaW5zdGFuY2VvZiB0aGlzLmNvbnN0cnVjdG9yO1xuICB9LCB0aGlzKTtcbiAgYXJncyA9IGFyZ3MuZmlsdGVyKGZ1bmN0aW9uKGFyZykge1xuICAgIHJldHVybiAhKGFyZyBpbnN0YW5jZW9mIHRoaXMuY29uc3RydWN0b3IpO1xuICB9LCB0aGlzKTtcblxuICBpZiAoY2hpbGRyZW4ubGVuZ3RoICE9PSAwKSB7XG4gICAgYXNzZXJ0KHN0YXRlLmNoaWxkcmVuID09PSBudWxsKTtcbiAgICBzdGF0ZS5jaGlsZHJlbiA9IGNoaWxkcmVuO1xuXG4gICAgLy8gUmVwbGFjZSBwYXJlbnQgdG8gbWFpbnRhaW4gYmFja3dhcmQgbGlua1xuICAgIGNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24oY2hpbGQpIHtcbiAgICAgIGNoaWxkLl9iYXNlU3RhdGUucGFyZW50ID0gdGhpcztcbiAgICB9LCB0aGlzKTtcbiAgfVxuICBpZiAoYXJncy5sZW5ndGggIT09IDApIHtcbiAgICBhc3NlcnQoc3RhdGUuYXJncyA9PT0gbnVsbCk7XG4gICAgc3RhdGUuYXJncyA9IGFyZ3M7XG4gICAgc3RhdGUucmV2ZXJzZUFyZ3MgPSBhcmdzLm1hcChmdW5jdGlvbihhcmcpIHtcbiAgICAgIGlmICh0eXBlb2YgYXJnICE9PSAnb2JqZWN0JyB8fCBhcmcuY29uc3RydWN0b3IgIT09IE9iamVjdClcbiAgICAgICAgcmV0dXJuIGFyZztcblxuICAgICAgdmFyIHJlcyA9IHt9O1xuICAgICAgT2JqZWN0LmtleXMoYXJnKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBpZiAoa2V5ID09IChrZXkgfCAwKSlcbiAgICAgICAgICBrZXkgfD0gMDtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJnW2tleV07XG4gICAgICAgIHJlc1t2YWx1ZV0gPSBrZXk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXM7XG4gICAgfSk7XG4gIH1cbn07XG5cbi8vXG4vLyBPdmVycmlkZWQgbWV0aG9kc1xuLy9cblxub3ZlcnJpZGVkLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gIE5vZGUucHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbiBfb3ZlcnJpZGVkKCkge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgICB0aHJvdyBuZXcgRXJyb3IobWV0aG9kICsgJyBub3QgaW1wbGVtZW50ZWQgZm9yIGVuY29kaW5nOiAnICsgc3RhdGUuZW5jKTtcbiAgfTtcbn0pO1xuXG4vL1xuLy8gUHVibGljIG1ldGhvZHNcbi8vXG5cbnRhZ3MuZm9yRWFjaChmdW5jdGlvbih0YWcpIHtcbiAgTm9kZS5wcm90b3R5cGVbdGFnXSA9IGZ1bmN0aW9uIF90YWdNZXRob2QoKSB7XG4gICAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblxuICAgIGFzc2VydChzdGF0ZS50YWcgPT09IG51bGwpO1xuICAgIHN0YXRlLnRhZyA9IHRhZztcblxuICAgIHRoaXMuX3VzZUFyZ3MoYXJncyk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcbn0pO1xuXG5Ob2RlLnByb3RvdHlwZS51c2UgPSBmdW5jdGlvbiB1c2UoaXRlbSkge1xuICBhc3NlcnQoaXRlbSk7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICBhc3NlcnQoc3RhdGUudXNlID09PSBudWxsKTtcbiAgc3RhdGUudXNlID0gaXRlbTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbk5vZGUucHJvdG90eXBlLm9wdGlvbmFsID0gZnVuY3Rpb24gb3B0aW9uYWwoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICBzdGF0ZS5vcHRpb25hbCA9IHRydWU7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5kZWYgPSBmdW5jdGlvbiBkZWYodmFsKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICBhc3NlcnQoc3RhdGVbJ2RlZmF1bHQnXSA9PT0gbnVsbCk7XG4gIHN0YXRlWydkZWZhdWx0J10gPSB2YWw7XG4gIHN0YXRlLm9wdGlvbmFsID0gdHJ1ZTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbk5vZGUucHJvdG90eXBlLmV4cGxpY2l0ID0gZnVuY3Rpb24gZXhwbGljaXQobnVtKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICBhc3NlcnQoc3RhdGUuZXhwbGljaXQgPT09IG51bGwgJiYgc3RhdGUuaW1wbGljaXQgPT09IG51bGwpO1xuICBzdGF0ZS5leHBsaWNpdCA9IG51bTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbk5vZGUucHJvdG90eXBlLmltcGxpY2l0ID0gZnVuY3Rpb24gaW1wbGljaXQobnVtKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICBhc3NlcnQoc3RhdGUuZXhwbGljaXQgPT09IG51bGwgJiYgc3RhdGUuaW1wbGljaXQgPT09IG51bGwpO1xuICBzdGF0ZS5pbXBsaWNpdCA9IG51bTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbk5vZGUucHJvdG90eXBlLm9iaiA9IGZ1bmN0aW9uIG9iaigpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cbiAgc3RhdGUub2JqID0gdHJ1ZTtcblxuICBpZiAoYXJncy5sZW5ndGggIT09IDApXG4gICAgdGhpcy5fdXNlQXJncyhhcmdzKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbk5vZGUucHJvdG90eXBlLmtleSA9IGZ1bmN0aW9uIGtleShuZXdLZXkpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIGFzc2VydChzdGF0ZS5rZXkgPT09IG51bGwpO1xuICBzdGF0ZS5rZXkgPSBuZXdLZXk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5hbnkgPSBmdW5jdGlvbiBhbnkoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICBzdGF0ZS5hbnkgPSB0cnVlO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuTm9kZS5wcm90b3R5cGUuY2hvaWNlID0gZnVuY3Rpb24gY2hvaWNlKG9iaikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlLmNob2ljZSA9PT0gbnVsbCk7XG4gIHN0YXRlLmNob2ljZSA9IG9iajtcbiAgdGhpcy5fdXNlQXJncyhPYmplY3Qua2V5cyhvYmopLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgICByZXR1cm4gb2JqW2tleV07XG4gIH0pKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbk5vZGUucHJvdG90eXBlLmNvbnRhaW5zID0gZnVuY3Rpb24gY29udGFpbnMoaXRlbSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlLnVzZSA9PT0gbnVsbCk7XG4gIHN0YXRlLmNvbnRhaW5zID0gaXRlbTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vXG4vLyBEZWNvZGluZ1xuLy9cblxuTm9kZS5wcm90b3R5cGUuX2RlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShpbnB1dCwgb3B0aW9ucykge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgLy8gRGVjb2RlIHJvb3Qgbm9kZVxuICBpZiAoc3RhdGUucGFyZW50ID09PSBudWxsKVxuICAgIHJldHVybiBpbnB1dC53cmFwUmVzdWx0KHN0YXRlLmNoaWxkcmVuWzBdLl9kZWNvZGUoaW5wdXQsIG9wdGlvbnMpKTtcblxuICB2YXIgcmVzdWx0ID0gc3RhdGVbJ2RlZmF1bHQnXTtcbiAgdmFyIHByZXNlbnQgPSB0cnVlO1xuXG4gIHZhciBwcmV2S2V5ID0gbnVsbDtcbiAgaWYgKHN0YXRlLmtleSAhPT0gbnVsbClcbiAgICBwcmV2S2V5ID0gaW5wdXQuZW50ZXJLZXkoc3RhdGUua2V5KTtcblxuICAvLyBDaGVjayBpZiB0YWcgaXMgdGhlcmVcbiAgaWYgKHN0YXRlLm9wdGlvbmFsKSB7XG4gICAgdmFyIHRhZyA9IG51bGw7XG4gICAgaWYgKHN0YXRlLmV4cGxpY2l0ICE9PSBudWxsKVxuICAgICAgdGFnID0gc3RhdGUuZXhwbGljaXQ7XG4gICAgZWxzZSBpZiAoc3RhdGUuaW1wbGljaXQgIT09IG51bGwpXG4gICAgICB0YWcgPSBzdGF0ZS5pbXBsaWNpdDtcbiAgICBlbHNlIGlmIChzdGF0ZS50YWcgIT09IG51bGwpXG4gICAgICB0YWcgPSBzdGF0ZS50YWc7XG5cbiAgICBpZiAodGFnID09PSBudWxsICYmICFzdGF0ZS5hbnkpIHtcbiAgICAgIC8vIFRyaWFsIGFuZCBFcnJvclxuICAgICAgdmFyIHNhdmUgPSBpbnB1dC5zYXZlKCk7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoc3RhdGUuY2hvaWNlID09PSBudWxsKVxuICAgICAgICAgIHRoaXMuX2RlY29kZUdlbmVyaWMoc3RhdGUudGFnLCBpbnB1dCwgb3B0aW9ucyk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICB0aGlzLl9kZWNvZGVDaG9pY2UoaW5wdXQsIG9wdGlvbnMpO1xuICAgICAgICBwcmVzZW50ID0gdHJ1ZTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcHJlc2VudCA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgaW5wdXQucmVzdG9yZShzYXZlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJlc2VudCA9IHRoaXMuX3BlZWtUYWcoaW5wdXQsIHRhZywgc3RhdGUuYW55KTtcblxuICAgICAgaWYgKGlucHV0LmlzRXJyb3IocHJlc2VudCkpXG4gICAgICAgIHJldHVybiBwcmVzZW50O1xuICAgIH1cbiAgfVxuXG4gIC8vIFB1c2ggb2JqZWN0IG9uIHN0YWNrXG4gIHZhciBwcmV2T2JqO1xuICBpZiAoc3RhdGUub2JqICYmIHByZXNlbnQpXG4gICAgcHJldk9iaiA9IGlucHV0LmVudGVyT2JqZWN0KCk7XG5cbiAgaWYgKHByZXNlbnQpIHtcbiAgICAvLyBVbndyYXAgZXhwbGljaXQgdmFsdWVzXG4gICAgaWYgKHN0YXRlLmV4cGxpY2l0ICE9PSBudWxsKSB7XG4gICAgICB2YXIgZXhwbGljaXQgPSB0aGlzLl9kZWNvZGVUYWcoaW5wdXQsIHN0YXRlLmV4cGxpY2l0KTtcbiAgICAgIGlmIChpbnB1dC5pc0Vycm9yKGV4cGxpY2l0KSlcbiAgICAgICAgcmV0dXJuIGV4cGxpY2l0O1xuICAgICAgaW5wdXQgPSBleHBsaWNpdDtcbiAgICB9XG5cbiAgICB2YXIgc3RhcnQgPSBpbnB1dC5vZmZzZXQ7XG5cbiAgICAvLyBVbndyYXAgaW1wbGljaXQgYW5kIG5vcm1hbCB2YWx1ZXNcbiAgICBpZiAoc3RhdGUudXNlID09PSBudWxsICYmIHN0YXRlLmNob2ljZSA9PT0gbnVsbCkge1xuICAgICAgaWYgKHN0YXRlLmFueSlcbiAgICAgICAgdmFyIHNhdmUgPSBpbnB1dC5zYXZlKCk7XG4gICAgICB2YXIgYm9keSA9IHRoaXMuX2RlY29kZVRhZyhcbiAgICAgICAgaW5wdXQsXG4gICAgICAgIHN0YXRlLmltcGxpY2l0ICE9PSBudWxsID8gc3RhdGUuaW1wbGljaXQgOiBzdGF0ZS50YWcsXG4gICAgICAgIHN0YXRlLmFueVxuICAgICAgKTtcbiAgICAgIGlmIChpbnB1dC5pc0Vycm9yKGJvZHkpKVxuICAgICAgICByZXR1cm4gYm9keTtcblxuICAgICAgaWYgKHN0YXRlLmFueSlcbiAgICAgICAgcmVzdWx0ID0gaW5wdXQucmF3KHNhdmUpO1xuICAgICAgZWxzZVxuICAgICAgICBpbnB1dCA9IGJvZHk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy50cmFjayAmJiBzdGF0ZS50YWcgIT09IG51bGwpXG4gICAgICBvcHRpb25zLnRyYWNrKGlucHV0LnBhdGgoKSwgc3RhcnQsIGlucHV0Lmxlbmd0aCwgJ3RhZ2dlZCcpO1xuXG4gICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy50cmFjayAmJiBzdGF0ZS50YWcgIT09IG51bGwpXG4gICAgICBvcHRpb25zLnRyYWNrKGlucHV0LnBhdGgoKSwgaW5wdXQub2Zmc2V0LCBpbnB1dC5sZW5ndGgsICdjb250ZW50Jyk7XG5cbiAgICAvLyBTZWxlY3QgcHJvcGVyIG1ldGhvZCBmb3IgdGFnXG4gICAgaWYgKHN0YXRlLmFueSlcbiAgICAgIHJlc3VsdCA9IHJlc3VsdDtcbiAgICBlbHNlIGlmIChzdGF0ZS5jaG9pY2UgPT09IG51bGwpXG4gICAgICByZXN1bHQgPSB0aGlzLl9kZWNvZGVHZW5lcmljKHN0YXRlLnRhZywgaW5wdXQsIG9wdGlvbnMpO1xuICAgIGVsc2VcbiAgICAgIHJlc3VsdCA9IHRoaXMuX2RlY29kZUNob2ljZShpbnB1dCwgb3B0aW9ucyk7XG5cbiAgICBpZiAoaW5wdXQuaXNFcnJvcihyZXN1bHQpKVxuICAgICAgcmV0dXJuIHJlc3VsdDtcblxuICAgIC8vIERlY29kZSBjaGlsZHJlblxuICAgIGlmICghc3RhdGUuYW55ICYmIHN0YXRlLmNob2ljZSA9PT0gbnVsbCAmJiBzdGF0ZS5jaGlsZHJlbiAhPT0gbnVsbCkge1xuICAgICAgc3RhdGUuY2hpbGRyZW4uZm9yRWFjaChmdW5jdGlvbiBkZWNvZGVDaGlsZHJlbihjaGlsZCkge1xuICAgICAgICAvLyBOT1RFOiBXZSBhcmUgaWdub3JpbmcgZXJyb3JzIGhlcmUsIHRvIGxldCBwYXJzZXIgY29udGludWUgd2l0aCBvdGhlclxuICAgICAgICAvLyBwYXJ0cyBvZiBlbmNvZGVkIGRhdGFcbiAgICAgICAgY2hpbGQuX2RlY29kZShpbnB1dCwgb3B0aW9ucyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBEZWNvZGUgY29udGFpbmVkL2VuY29kZWQgYnkgc2NoZW1hLCBvbmx5IGluIGJpdCBvciBvY3RldCBzdHJpbmdzXG4gICAgaWYgKHN0YXRlLmNvbnRhaW5zICYmIChzdGF0ZS50YWcgPT09ICdvY3RzdHInIHx8IHN0YXRlLnRhZyA9PT0gJ2JpdHN0cicpKSB7XG4gICAgICB2YXIgZGF0YSA9IG5ldyBEZWNvZGVyQnVmZmVyKHJlc3VsdCk7XG4gICAgICByZXN1bHQgPSB0aGlzLl9nZXRVc2Uoc3RhdGUuY29udGFpbnMsIGlucHV0Ll9yZXBvcnRlclN0YXRlLm9iailcbiAgICAgICAgICAuX2RlY29kZShkYXRhLCBvcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICAvLyBQb3Agb2JqZWN0XG4gIGlmIChzdGF0ZS5vYmogJiYgcHJlc2VudClcbiAgICByZXN1bHQgPSBpbnB1dC5sZWF2ZU9iamVjdChwcmV2T2JqKTtcblxuICAvLyBTZXQga2V5XG4gIGlmIChzdGF0ZS5rZXkgIT09IG51bGwgJiYgKHJlc3VsdCAhPT0gbnVsbCB8fCBwcmVzZW50ID09PSB0cnVlKSlcbiAgICBpbnB1dC5sZWF2ZUtleShwcmV2S2V5LCBzdGF0ZS5rZXksIHJlc3VsdCk7XG4gIGVsc2UgaWYgKHByZXZLZXkgIT09IG51bGwpXG4gICAgaW5wdXQuZXhpdEtleShwcmV2S2V5KTtcblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuTm9kZS5wcm90b3R5cGUuX2RlY29kZUdlbmVyaWMgPSBmdW5jdGlvbiBkZWNvZGVHZW5lcmljKHRhZywgaW5wdXQsIG9wdGlvbnMpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIGlmICh0YWcgPT09ICdzZXEnIHx8IHRhZyA9PT0gJ3NldCcpXG4gICAgcmV0dXJuIG51bGw7XG4gIGlmICh0YWcgPT09ICdzZXFvZicgfHwgdGFnID09PSAnc2V0b2YnKVxuICAgIHJldHVybiB0aGlzLl9kZWNvZGVMaXN0KGlucHV0LCB0YWcsIHN0YXRlLmFyZ3NbMF0sIG9wdGlvbnMpO1xuICBlbHNlIGlmICgvc3RyJC8udGVzdCh0YWcpKVxuICAgIHJldHVybiB0aGlzLl9kZWNvZGVTdHIoaW5wdXQsIHRhZywgb3B0aW9ucyk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ29iamlkJyAmJiBzdGF0ZS5hcmdzKVxuICAgIHJldHVybiB0aGlzLl9kZWNvZGVPYmppZChpbnB1dCwgc3RhdGUuYXJnc1swXSwgc3RhdGUuYXJnc1sxXSwgb3B0aW9ucyk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ29iamlkJylcbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlT2JqaWQoaW5wdXQsIG51bGwsIG51bGwsIG9wdGlvbnMpO1xuICBlbHNlIGlmICh0YWcgPT09ICdnZW50aW1lJyB8fCB0YWcgPT09ICd1dGN0aW1lJylcbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlVGltZShpbnB1dCwgdGFnLCBvcHRpb25zKTtcbiAgZWxzZSBpZiAodGFnID09PSAnbnVsbF8nKVxuICAgIHJldHVybiB0aGlzLl9kZWNvZGVOdWxsKGlucHV0LCBvcHRpb25zKTtcbiAgZWxzZSBpZiAodGFnID09PSAnYm9vbCcpXG4gICAgcmV0dXJuIHRoaXMuX2RlY29kZUJvb2woaW5wdXQsIG9wdGlvbnMpO1xuICBlbHNlIGlmICh0YWcgPT09ICdvYmpEZXNjJylcbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlU3RyKGlucHV0LCB0YWcsIG9wdGlvbnMpO1xuICBlbHNlIGlmICh0YWcgPT09ICdpbnQnIHx8IHRhZyA9PT0gJ2VudW0nKVxuICAgIHJldHVybiB0aGlzLl9kZWNvZGVJbnQoaW5wdXQsIHN0YXRlLmFyZ3MgJiYgc3RhdGUuYXJnc1swXSwgb3B0aW9ucyk7XG5cbiAgaWYgKHN0YXRlLnVzZSAhPT0gbnVsbCkge1xuICAgIHJldHVybiB0aGlzLl9nZXRVc2Uoc3RhdGUudXNlLCBpbnB1dC5fcmVwb3J0ZXJTdGF0ZS5vYmopXG4gICAgICAgIC5fZGVjb2RlKGlucHV0LCBvcHRpb25zKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gaW5wdXQuZXJyb3IoJ3Vua25vd24gdGFnOiAnICsgdGFnKTtcbiAgfVxufTtcblxuTm9kZS5wcm90b3R5cGUuX2dldFVzZSA9IGZ1bmN0aW9uIF9nZXRVc2UoZW50aXR5LCBvYmopIHtcblxuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG4gIC8vIENyZWF0ZSBhbHRlcmVkIHVzZSBkZWNvZGVyIGlmIGltcGxpY2l0IGlzIHNldFxuICBzdGF0ZS51c2VEZWNvZGVyID0gdGhpcy5fdXNlKGVudGl0eSwgb2JqKTtcbiAgYXNzZXJ0KHN0YXRlLnVzZURlY29kZXIuX2Jhc2VTdGF0ZS5wYXJlbnQgPT09IG51bGwpO1xuICBzdGF0ZS51c2VEZWNvZGVyID0gc3RhdGUudXNlRGVjb2Rlci5fYmFzZVN0YXRlLmNoaWxkcmVuWzBdO1xuICBpZiAoc3RhdGUuaW1wbGljaXQgIT09IHN0YXRlLnVzZURlY29kZXIuX2Jhc2VTdGF0ZS5pbXBsaWNpdCkge1xuICAgIHN0YXRlLnVzZURlY29kZXIgPSBzdGF0ZS51c2VEZWNvZGVyLmNsb25lKCk7XG4gICAgc3RhdGUudXNlRGVjb2Rlci5fYmFzZVN0YXRlLmltcGxpY2l0ID0gc3RhdGUuaW1wbGljaXQ7XG4gIH1cbiAgcmV0dXJuIHN0YXRlLnVzZURlY29kZXI7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5fZGVjb2RlQ2hvaWNlID0gZnVuY3Rpb24gZGVjb2RlQ2hvaWNlKGlucHV0LCBvcHRpb25zKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgdmFyIHJlc3VsdCA9IG51bGw7XG4gIHZhciBtYXRjaCA9IGZhbHNlO1xuXG4gIE9iamVjdC5rZXlzKHN0YXRlLmNob2ljZSkuc29tZShmdW5jdGlvbihrZXkpIHtcbiAgICB2YXIgc2F2ZSA9IGlucHV0LnNhdmUoKTtcbiAgICB2YXIgbm9kZSA9IHN0YXRlLmNob2ljZVtrZXldO1xuICAgIHRyeSB7XG4gICAgICB2YXIgdmFsdWUgPSBub2RlLl9kZWNvZGUoaW5wdXQsIG9wdGlvbnMpO1xuICAgICAgaWYgKGlucHV0LmlzRXJyb3IodmFsdWUpKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICAgIHJlc3VsdCA9IHsgdHlwZToga2V5LCB2YWx1ZTogdmFsdWUgfTtcbiAgICAgIG1hdGNoID0gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpbnB1dC5yZXN0b3JlKHNhdmUpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSwgdGhpcyk7XG5cbiAgaWYgKCFtYXRjaClcbiAgICByZXR1cm4gaW5wdXQuZXJyb3IoJ0Nob2ljZSBub3QgbWF0Y2hlZCcpO1xuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG4vL1xuLy8gRW5jb2Rpbmdcbi8vXG5cbk5vZGUucHJvdG90eXBlLl9jcmVhdGVFbmNvZGVyQnVmZmVyID0gZnVuY3Rpb24gY3JlYXRlRW5jb2RlckJ1ZmZlcihkYXRhKSB7XG4gIHJldHVybiBuZXcgRW5jb2RlckJ1ZmZlcihkYXRhLCB0aGlzLnJlcG9ydGVyKTtcbn07XG5cbk5vZGUucHJvdG90eXBlLl9lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUoZGF0YSwgcmVwb3J0ZXIsIHBhcmVudCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG4gIGlmIChzdGF0ZVsnZGVmYXVsdCddICE9PSBudWxsICYmIHN0YXRlWydkZWZhdWx0J10gPT09IGRhdGEpXG4gICAgcmV0dXJuO1xuXG4gIHZhciByZXN1bHQgPSB0aGlzLl9lbmNvZGVWYWx1ZShkYXRhLCByZXBvcnRlciwgcGFyZW50KTtcbiAgaWYgKHJlc3VsdCA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybjtcblxuICBpZiAodGhpcy5fc2tpcERlZmF1bHQocmVzdWx0LCByZXBvcnRlciwgcGFyZW50KSlcbiAgICByZXR1cm47XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbk5vZGUucHJvdG90eXBlLl9lbmNvZGVWYWx1ZSA9IGZ1bmN0aW9uIGVuY29kZShkYXRhLCByZXBvcnRlciwgcGFyZW50KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICAvLyBEZWNvZGUgcm9vdCBub2RlXG4gIGlmIChzdGF0ZS5wYXJlbnQgPT09IG51bGwpXG4gICAgcmV0dXJuIHN0YXRlLmNoaWxkcmVuWzBdLl9lbmNvZGUoZGF0YSwgcmVwb3J0ZXIgfHwgbmV3IFJlcG9ydGVyKCkpO1xuXG4gIHZhciByZXN1bHQgPSBudWxsO1xuXG4gIC8vIFNldCByZXBvcnRlciB0byBzaGFyZSBpdCB3aXRoIGEgY2hpbGQgY2xhc3NcbiAgdGhpcy5yZXBvcnRlciA9IHJlcG9ydGVyO1xuXG4gIC8vIENoZWNrIGlmIGRhdGEgaXMgdGhlcmVcbiAgaWYgKHN0YXRlLm9wdGlvbmFsICYmIGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChzdGF0ZVsnZGVmYXVsdCddICE9PSBudWxsKVxuICAgICAgZGF0YSA9IHN0YXRlWydkZWZhdWx0J11cbiAgICBlbHNlXG4gICAgICByZXR1cm47XG4gIH1cblxuICAvLyBFbmNvZGUgY2hpbGRyZW4gZmlyc3RcbiAgdmFyIGNvbnRlbnQgPSBudWxsO1xuICB2YXIgcHJpbWl0aXZlID0gZmFsc2U7XG4gIGlmIChzdGF0ZS5hbnkpIHtcbiAgICAvLyBBbnl0aGluZyB0aGF0IHdhcyBnaXZlbiBpcyB0cmFuc2xhdGVkIHRvIGJ1ZmZlclxuICAgIHJlc3VsdCA9IHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoZGF0YSk7XG4gIH0gZWxzZSBpZiAoc3RhdGUuY2hvaWNlKSB7XG4gICAgcmVzdWx0ID0gdGhpcy5fZW5jb2RlQ2hvaWNlKGRhdGEsIHJlcG9ydGVyKTtcbiAgfSBlbHNlIGlmIChzdGF0ZS5jb250YWlucykge1xuICAgIGNvbnRlbnQgPSB0aGlzLl9nZXRVc2Uoc3RhdGUuY29udGFpbnMsIHBhcmVudCkuX2VuY29kZShkYXRhLCByZXBvcnRlcik7XG4gICAgcHJpbWl0aXZlID0gdHJ1ZTtcbiAgfSBlbHNlIGlmIChzdGF0ZS5jaGlsZHJlbikge1xuICAgIGNvbnRlbnQgPSBzdGF0ZS5jaGlsZHJlbi5tYXAoZnVuY3Rpb24oY2hpbGQpIHtcbiAgICAgIGlmIChjaGlsZC5fYmFzZVN0YXRlLnRhZyA9PT0gJ251bGxfJylcbiAgICAgICAgcmV0dXJuIGNoaWxkLl9lbmNvZGUobnVsbCwgcmVwb3J0ZXIsIGRhdGEpO1xuXG4gICAgICBpZiAoY2hpbGQuX2Jhc2VTdGF0ZS5rZXkgPT09IG51bGwpXG4gICAgICAgIHJldHVybiByZXBvcnRlci5lcnJvcignQ2hpbGQgc2hvdWxkIGhhdmUgYSBrZXknKTtcbiAgICAgIHZhciBwcmV2S2V5ID0gcmVwb3J0ZXIuZW50ZXJLZXkoY2hpbGQuX2Jhc2VTdGF0ZS5rZXkpO1xuXG4gICAgICBpZiAodHlwZW9mIGRhdGEgIT09ICdvYmplY3QnKVxuICAgICAgICByZXR1cm4gcmVwb3J0ZXIuZXJyb3IoJ0NoaWxkIGV4cGVjdGVkLCBidXQgaW5wdXQgaXMgbm90IG9iamVjdCcpO1xuXG4gICAgICB2YXIgcmVzID0gY2hpbGQuX2VuY29kZShkYXRhW2NoaWxkLl9iYXNlU3RhdGUua2V5XSwgcmVwb3J0ZXIsIGRhdGEpO1xuICAgICAgcmVwb3J0ZXIubGVhdmVLZXkocHJldktleSk7XG5cbiAgICAgIHJldHVybiByZXM7XG4gICAgfSwgdGhpcykuZmlsdGVyKGZ1bmN0aW9uKGNoaWxkKSB7XG4gICAgICByZXR1cm4gY2hpbGQ7XG4gICAgfSk7XG4gICAgY29udGVudCA9IHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoY29udGVudCk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHN0YXRlLnRhZyA9PT0gJ3NlcW9mJyB8fCBzdGF0ZS50YWcgPT09ICdzZXRvZicpIHtcbiAgICAgIC8vIFRPRE8oaW5kdXRueSk6IHRoaXMgc2hvdWxkIGJlIHRocm93biBvbiBEU0wgbGV2ZWxcbiAgICAgIGlmICghKHN0YXRlLmFyZ3MgJiYgc3RhdGUuYXJncy5sZW5ndGggPT09IDEpKVxuICAgICAgICByZXR1cm4gcmVwb3J0ZXIuZXJyb3IoJ1RvbyBtYW55IGFyZ3MgZm9yIDogJyArIHN0YXRlLnRhZyk7XG5cbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShkYXRhKSlcbiAgICAgICAgcmV0dXJuIHJlcG9ydGVyLmVycm9yKCdzZXFvZi9zZXRvZiwgYnV0IGRhdGEgaXMgbm90IEFycmF5Jyk7XG5cbiAgICAgIHZhciBjaGlsZCA9IHRoaXMuY2xvbmUoKTtcbiAgICAgIGNoaWxkLl9iYXNlU3RhdGUuaW1wbGljaXQgPSBudWxsO1xuICAgICAgY29udGVudCA9IHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoZGF0YS5tYXAoZnVuY3Rpb24oaXRlbSkge1xuICAgICAgICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldFVzZShzdGF0ZS5hcmdzWzBdLCBkYXRhKS5fZW5jb2RlKGl0ZW0sIHJlcG9ydGVyKTtcbiAgICAgIH0sIGNoaWxkKSk7XG4gICAgfSBlbHNlIGlmIChzdGF0ZS51c2UgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCA9IHRoaXMuX2dldFVzZShzdGF0ZS51c2UsIHBhcmVudCkuX2VuY29kZShkYXRhLCByZXBvcnRlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnRlbnQgPSB0aGlzLl9lbmNvZGVQcmltaXRpdmUoc3RhdGUudGFnLCBkYXRhKTtcbiAgICAgIHByaW1pdGl2ZSA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgLy8gRW5jb2RlIGRhdGEgaXRzZWxmXG4gIHZhciByZXN1bHQ7XG4gIGlmICghc3RhdGUuYW55ICYmIHN0YXRlLmNob2ljZSA9PT0gbnVsbCkge1xuICAgIHZhciB0YWcgPSBzdGF0ZS5pbXBsaWNpdCAhPT0gbnVsbCA/IHN0YXRlLmltcGxpY2l0IDogc3RhdGUudGFnO1xuICAgIHZhciBjbHMgPSBzdGF0ZS5pbXBsaWNpdCA9PT0gbnVsbCA/ICd1bml2ZXJzYWwnIDogJ2NvbnRleHQnO1xuXG4gICAgaWYgKHRhZyA9PT0gbnVsbCkge1xuICAgICAgaWYgKHN0YXRlLnVzZSA9PT0gbnVsbClcbiAgICAgICAgcmVwb3J0ZXIuZXJyb3IoJ1RhZyBjb3VsZCBiZSBvbWl0dGVkIG9ubHkgZm9yIC51c2UoKScpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoc3RhdGUudXNlID09PSBudWxsKVxuICAgICAgICByZXN1bHQgPSB0aGlzLl9lbmNvZGVDb21wb3NpdGUodGFnLCBwcmltaXRpdmUsIGNscywgY29udGVudCk7XG4gICAgfVxuICB9XG5cbiAgLy8gV3JhcCBpbiBleHBsaWNpdFxuICBpZiAoc3RhdGUuZXhwbGljaXQgIT09IG51bGwpXG4gICAgcmVzdWx0ID0gdGhpcy5fZW5jb2RlQ29tcG9zaXRlKHN0YXRlLmV4cGxpY2l0LCBmYWxzZSwgJ2NvbnRleHQnLCByZXN1bHQpO1xuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5fZW5jb2RlQ2hvaWNlID0gZnVuY3Rpb24gZW5jb2RlQ2hvaWNlKGRhdGEsIHJlcG9ydGVyKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICB2YXIgbm9kZSA9IHN0YXRlLmNob2ljZVtkYXRhLnR5cGVdO1xuICBpZiAoIW5vZGUpIHtcbiAgICBhc3NlcnQoXG4gICAgICAgIGZhbHNlLFxuICAgICAgICBkYXRhLnR5cGUgKyAnIG5vdCBmb3VuZCBpbiAnICtcbiAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHN0YXRlLmNob2ljZSkpKTtcbiAgfVxuICByZXR1cm4gbm9kZS5fZW5jb2RlKGRhdGEudmFsdWUsIHJlcG9ydGVyKTtcbn07XG5cbk5vZGUucHJvdG90eXBlLl9lbmNvZGVQcmltaXRpdmUgPSBmdW5jdGlvbiBlbmNvZGVQcmltaXRpdmUodGFnLCBkYXRhKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICBpZiAoL3N0ciQvLnRlc3QodGFnKSlcbiAgICByZXR1cm4gdGhpcy5fZW5jb2RlU3RyKGRhdGEsIHRhZyk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ29iamlkJyAmJiBzdGF0ZS5hcmdzKVxuICAgIHJldHVybiB0aGlzLl9lbmNvZGVPYmppZChkYXRhLCBzdGF0ZS5yZXZlcnNlQXJnc1swXSwgc3RhdGUuYXJnc1sxXSk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ29iamlkJylcbiAgICByZXR1cm4gdGhpcy5fZW5jb2RlT2JqaWQoZGF0YSwgbnVsbCwgbnVsbCk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ2dlbnRpbWUnIHx8IHRhZyA9PT0gJ3V0Y3RpbWUnKVxuICAgIHJldHVybiB0aGlzLl9lbmNvZGVUaW1lKGRhdGEsIHRhZyk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ251bGxfJylcbiAgICByZXR1cm4gdGhpcy5fZW5jb2RlTnVsbCgpO1xuICBlbHNlIGlmICh0YWcgPT09ICdpbnQnIHx8IHRhZyA9PT0gJ2VudW0nKVxuICAgIHJldHVybiB0aGlzLl9lbmNvZGVJbnQoZGF0YSwgc3RhdGUuYXJncyAmJiBzdGF0ZS5yZXZlcnNlQXJnc1swXSk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ2Jvb2wnKVxuICAgIHJldHVybiB0aGlzLl9lbmNvZGVCb29sKGRhdGEpO1xuICBlbHNlIGlmICh0YWcgPT09ICdvYmpEZXNjJylcbiAgICByZXR1cm4gdGhpcy5fZW5jb2RlU3RyKGRhdGEsIHRhZyk7XG4gIGVsc2VcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIHRhZzogJyArIHRhZyk7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5faXNOdW1zdHIgPSBmdW5jdGlvbiBpc051bXN0cihzdHIpIHtcbiAgcmV0dXJuIC9eWzAtOSBdKiQvLnRlc3Qoc3RyKTtcbn07XG5cbk5vZGUucHJvdG90eXBlLl9pc1ByaW50c3RyID0gZnVuY3Rpb24gaXNQcmludHN0cihzdHIpIHtcbiAgcmV0dXJuIC9eW0EtWmEtejAtOSAnXFwoXFwpXFwrLFxcLVxcLlxcLzo9XFw/XSokLy50ZXN0KHN0cik7XG59O1xuIiwidmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxuZnVuY3Rpb24gUmVwb3J0ZXIob3B0aW9ucykge1xuICB0aGlzLl9yZXBvcnRlclN0YXRlID0ge1xuICAgIG9iajogbnVsbCxcbiAgICBwYXRoOiBbXSxcbiAgICBvcHRpb25zOiBvcHRpb25zIHx8IHt9LFxuICAgIGVycm9yczogW11cbiAgfTtcbn1cbmV4cG9ydHMuUmVwb3J0ZXIgPSBSZXBvcnRlcjtcblxuUmVwb3J0ZXIucHJvdG90eXBlLmlzRXJyb3IgPSBmdW5jdGlvbiBpc0Vycm9yKG9iaikge1xuICByZXR1cm4gb2JqIGluc3RhbmNlb2YgUmVwb3J0ZXJFcnJvcjtcbn07XG5cblJlcG9ydGVyLnByb3RvdHlwZS5zYXZlID0gZnVuY3Rpb24gc2F2ZSgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVwb3J0ZXJTdGF0ZTtcblxuICByZXR1cm4geyBvYmo6IHN0YXRlLm9iaiwgcGF0aExlbjogc3RhdGUucGF0aC5sZW5ndGggfTtcbn07XG5cblJlcG9ydGVyLnByb3RvdHlwZS5yZXN0b3JlID0gZnVuY3Rpb24gcmVzdG9yZShkYXRhKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlcG9ydGVyU3RhdGU7XG5cbiAgc3RhdGUub2JqID0gZGF0YS5vYmo7XG4gIHN0YXRlLnBhdGggPSBzdGF0ZS5wYXRoLnNsaWNlKDAsIGRhdGEucGF0aExlbik7XG59O1xuXG5SZXBvcnRlci5wcm90b3R5cGUuZW50ZXJLZXkgPSBmdW5jdGlvbiBlbnRlcktleShrZXkpIHtcbiAgcmV0dXJuIHRoaXMuX3JlcG9ydGVyU3RhdGUucGF0aC5wdXNoKGtleSk7XG59O1xuXG5SZXBvcnRlci5wcm90b3R5cGUuZXhpdEtleSA9IGZ1bmN0aW9uIGV4aXRLZXkoaW5kZXgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVwb3J0ZXJTdGF0ZTtcblxuICBzdGF0ZS5wYXRoID0gc3RhdGUucGF0aC5zbGljZSgwLCBpbmRleCAtIDEpO1xufTtcblxuUmVwb3J0ZXIucHJvdG90eXBlLmxlYXZlS2V5ID0gZnVuY3Rpb24gbGVhdmVLZXkoaW5kZXgsIGtleSwgdmFsdWUpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVwb3J0ZXJTdGF0ZTtcblxuICB0aGlzLmV4aXRLZXkoaW5kZXgpO1xuICBpZiAoc3RhdGUub2JqICE9PSBudWxsKVxuICAgIHN0YXRlLm9ialtrZXldID0gdmFsdWU7XG59O1xuXG5SZXBvcnRlci5wcm90b3R5cGUucGF0aCA9IGZ1bmN0aW9uIHBhdGgoKSB7XG4gIHJldHVybiB0aGlzLl9yZXBvcnRlclN0YXRlLnBhdGguam9pbignLycpO1xufTtcblxuUmVwb3J0ZXIucHJvdG90eXBlLmVudGVyT2JqZWN0ID0gZnVuY3Rpb24gZW50ZXJPYmplY3QoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlcG9ydGVyU3RhdGU7XG5cbiAgdmFyIHByZXYgPSBzdGF0ZS5vYmo7XG4gIHN0YXRlLm9iaiA9IHt9O1xuICByZXR1cm4gcHJldjtcbn07XG5cblJlcG9ydGVyLnByb3RvdHlwZS5sZWF2ZU9iamVjdCA9IGZ1bmN0aW9uIGxlYXZlT2JqZWN0KHByZXYpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVwb3J0ZXJTdGF0ZTtcblxuICB2YXIgbm93ID0gc3RhdGUub2JqO1xuICBzdGF0ZS5vYmogPSBwcmV2O1xuICByZXR1cm4gbm93O1xufTtcblxuUmVwb3J0ZXIucHJvdG90eXBlLmVycm9yID0gZnVuY3Rpb24gZXJyb3IobXNnKSB7XG4gIHZhciBlcnI7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlcG9ydGVyU3RhdGU7XG5cbiAgdmFyIGluaGVyaXRlZCA9IG1zZyBpbnN0YW5jZW9mIFJlcG9ydGVyRXJyb3I7XG4gIGlmIChpbmhlcml0ZWQpIHtcbiAgICBlcnIgPSBtc2c7XG4gIH0gZWxzZSB7XG4gICAgZXJyID0gbmV3IFJlcG9ydGVyRXJyb3Ioc3RhdGUucGF0aC5tYXAoZnVuY3Rpb24oZWxlbSkge1xuICAgICAgcmV0dXJuICdbJyArIEpTT04uc3RyaW5naWZ5KGVsZW0pICsgJ10nO1xuICAgIH0pLmpvaW4oJycpLCBtc2cubWVzc2FnZSB8fCBtc2csIG1zZy5zdGFjayk7XG4gIH1cblxuICBpZiAoIXN0YXRlLm9wdGlvbnMucGFydGlhbClcbiAgICB0aHJvdyBlcnI7XG5cbiAgaWYgKCFpbmhlcml0ZWQpXG4gICAgc3RhdGUuZXJyb3JzLnB1c2goZXJyKTtcblxuICByZXR1cm4gZXJyO1xufTtcblxuUmVwb3J0ZXIucHJvdG90eXBlLndyYXBSZXN1bHQgPSBmdW5jdGlvbiB3cmFwUmVzdWx0KHJlc3VsdCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZXBvcnRlclN0YXRlO1xuICBpZiAoIXN0YXRlLm9wdGlvbnMucGFydGlhbClcbiAgICByZXR1cm4gcmVzdWx0O1xuXG4gIHJldHVybiB7XG4gICAgcmVzdWx0OiB0aGlzLmlzRXJyb3IocmVzdWx0KSA/IG51bGwgOiByZXN1bHQsXG4gICAgZXJyb3JzOiBzdGF0ZS5lcnJvcnNcbiAgfTtcbn07XG5cbmZ1bmN0aW9uIFJlcG9ydGVyRXJyb3IocGF0aCwgbXNnKSB7XG4gIHRoaXMucGF0aCA9IHBhdGg7XG4gIHRoaXMucmV0aHJvdyhtc2cpO1xufTtcbmluaGVyaXRzKFJlcG9ydGVyRXJyb3IsIEVycm9yKTtcblxuUmVwb3J0ZXJFcnJvci5wcm90b3R5cGUucmV0aHJvdyA9IGZ1bmN0aW9uIHJldGhyb3cobXNnKSB7XG4gIHRoaXMubWVzc2FnZSA9IG1zZyArICcgYXQ6ICcgKyAodGhpcy5wYXRoIHx8ICcoc2hhbGxvdyknKTtcbiAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKVxuICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIFJlcG9ydGVyRXJyb3IpO1xuXG4gIGlmICghdGhpcy5zdGFjaykge1xuICAgIHRyeSB7XG4gICAgICAvLyBJRSBvbmx5IGFkZHMgc3RhY2sgd2hlbiB0aHJvd25cbiAgICAgIHRocm93IG5ldyBFcnJvcih0aGlzLm1lc3NhZ2UpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuc3RhY2sgPSBlLnN0YWNrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG4iLCJ2YXIgY29uc3RhbnRzID0gcmVxdWlyZSgnLi4vY29uc3RhbnRzJyk7XG5cbmV4cG9ydHMudGFnQ2xhc3MgPSB7XG4gIDA6ICd1bml2ZXJzYWwnLFxuICAxOiAnYXBwbGljYXRpb24nLFxuICAyOiAnY29udGV4dCcsXG4gIDM6ICdwcml2YXRlJ1xufTtcbmV4cG9ydHMudGFnQ2xhc3NCeU5hbWUgPSBjb25zdGFudHMuX3JldmVyc2UoZXhwb3J0cy50YWdDbGFzcyk7XG5cbmV4cG9ydHMudGFnID0ge1xuICAweDAwOiAnZW5kJyxcbiAgMHgwMTogJ2Jvb2wnLFxuICAweDAyOiAnaW50JyxcbiAgMHgwMzogJ2JpdHN0cicsXG4gIDB4MDQ6ICdvY3RzdHInLFxuICAweDA1OiAnbnVsbF8nLFxuICAweDA2OiAnb2JqaWQnLFxuICAweDA3OiAnb2JqRGVzYycsXG4gIDB4MDg6ICdleHRlcm5hbCcsXG4gIDB4MDk6ICdyZWFsJyxcbiAgMHgwYTogJ2VudW0nLFxuICAweDBiOiAnZW1iZWQnLFxuICAweDBjOiAndXRmOHN0cicsXG4gIDB4MGQ6ICdyZWxhdGl2ZU9pZCcsXG4gIDB4MTA6ICdzZXEnLFxuICAweDExOiAnc2V0JyxcbiAgMHgxMjogJ251bXN0cicsXG4gIDB4MTM6ICdwcmludHN0cicsXG4gIDB4MTQ6ICd0NjFzdHInLFxuICAweDE1OiAndmlkZW9zdHInLFxuICAweDE2OiAnaWE1c3RyJyxcbiAgMHgxNzogJ3V0Y3RpbWUnLFxuICAweDE4OiAnZ2VudGltZScsXG4gIDB4MTk6ICdncmFwaHN0cicsXG4gIDB4MWE6ICdpc282NDZzdHInLFxuICAweDFiOiAnZ2Vuc3RyJyxcbiAgMHgxYzogJ3VuaXN0cicsXG4gIDB4MWQ6ICdjaGFyc3RyJyxcbiAgMHgxZTogJ2JtcHN0cidcbn07XG5leHBvcnRzLnRhZ0J5TmFtZSA9IGNvbnN0YW50cy5fcmV2ZXJzZShleHBvcnRzLnRhZyk7XG4iLCJ2YXIgY29uc3RhbnRzID0gZXhwb3J0cztcblxuLy8gSGVscGVyXG5jb25zdGFudHMuX3JldmVyc2UgPSBmdW5jdGlvbiByZXZlcnNlKG1hcCkge1xuICB2YXIgcmVzID0ge307XG5cbiAgT2JqZWN0LmtleXMobWFwKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIC8vIENvbnZlcnQga2V5IHRvIGludGVnZXIgaWYgaXQgaXMgc3RyaW5naWZpZWRcbiAgICBpZiAoKGtleSB8IDApID09IGtleSlcbiAgICAgIGtleSA9IGtleSB8IDA7XG5cbiAgICB2YXIgdmFsdWUgPSBtYXBba2V5XTtcbiAgICByZXNbdmFsdWVdID0ga2V5O1xuICB9KTtcblxuICByZXR1cm4gcmVzO1xufTtcblxuY29uc3RhbnRzLmRlciA9IHJlcXVpcmUoJy4vZGVyJyk7XG4iLCJ2YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG52YXIgYXNuMSA9IHJlcXVpcmUoJy4uLy4uL2FzbjEnKTtcbnZhciBiYXNlID0gYXNuMS5iYXNlO1xudmFyIGJpZ251bSA9IGFzbjEuYmlnbnVtO1xuXG4vLyBJbXBvcnQgREVSIGNvbnN0YW50c1xudmFyIGRlciA9IGFzbjEuY29uc3RhbnRzLmRlcjtcblxuZnVuY3Rpb24gREVSRGVjb2RlcihlbnRpdHkpIHtcbiAgdGhpcy5lbmMgPSAnZGVyJztcbiAgdGhpcy5uYW1lID0gZW50aXR5Lm5hbWU7XG4gIHRoaXMuZW50aXR5ID0gZW50aXR5O1xuXG4gIC8vIENvbnN0cnVjdCBiYXNlIHRyZWVcbiAgdGhpcy50cmVlID0gbmV3IERFUk5vZGUoKTtcbiAgdGhpcy50cmVlLl9pbml0KGVudGl0eS5ib2R5KTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IERFUkRlY29kZXI7XG5cbkRFUkRlY29kZXIucHJvdG90eXBlLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShkYXRhLCBvcHRpb25zKSB7XG4gIGlmICghKGRhdGEgaW5zdGFuY2VvZiBiYXNlLkRlY29kZXJCdWZmZXIpKVxuICAgIGRhdGEgPSBuZXcgYmFzZS5EZWNvZGVyQnVmZmVyKGRhdGEsIG9wdGlvbnMpO1xuXG4gIHJldHVybiB0aGlzLnRyZWUuX2RlY29kZShkYXRhLCBvcHRpb25zKTtcbn07XG5cbi8vIFRyZWUgbWV0aG9kc1xuXG5mdW5jdGlvbiBERVJOb2RlKHBhcmVudCkge1xuICBiYXNlLk5vZGUuY2FsbCh0aGlzLCAnZGVyJywgcGFyZW50KTtcbn1cbmluaGVyaXRzKERFUk5vZGUsIGJhc2UuTm9kZSk7XG5cbkRFUk5vZGUucHJvdG90eXBlLl9wZWVrVGFnID0gZnVuY3Rpb24gcGVla1RhZyhidWZmZXIsIHRhZywgYW55KSB7XG4gIGlmIChidWZmZXIuaXNFbXB0eSgpKVxuICAgIHJldHVybiBmYWxzZTtcblxuICB2YXIgc3RhdGUgPSBidWZmZXIuc2F2ZSgpO1xuICB2YXIgZGVjb2RlZFRhZyA9IGRlckRlY29kZVRhZyhidWZmZXIsICdGYWlsZWQgdG8gcGVlayB0YWc6IFwiJyArIHRhZyArICdcIicpO1xuICBpZiAoYnVmZmVyLmlzRXJyb3IoZGVjb2RlZFRhZykpXG4gICAgcmV0dXJuIGRlY29kZWRUYWc7XG5cbiAgYnVmZmVyLnJlc3RvcmUoc3RhdGUpO1xuXG4gIHJldHVybiBkZWNvZGVkVGFnLnRhZyA9PT0gdGFnIHx8IGRlY29kZWRUYWcudGFnU3RyID09PSB0YWcgfHxcbiAgICAoZGVjb2RlZFRhZy50YWdTdHIgKyAnb2YnKSA9PT0gdGFnIHx8IGFueTtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9kZWNvZGVUYWcgPSBmdW5jdGlvbiBkZWNvZGVUYWcoYnVmZmVyLCB0YWcsIGFueSkge1xuICB2YXIgZGVjb2RlZFRhZyA9IGRlckRlY29kZVRhZyhidWZmZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdGYWlsZWQgdG8gZGVjb2RlIHRhZyBvZiBcIicgKyB0YWcgKyAnXCInKTtcbiAgaWYgKGJ1ZmZlci5pc0Vycm9yKGRlY29kZWRUYWcpKVxuICAgIHJldHVybiBkZWNvZGVkVGFnO1xuXG4gIHZhciBsZW4gPSBkZXJEZWNvZGVMZW4oYnVmZmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgIGRlY29kZWRUYWcucHJpbWl0aXZlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICdGYWlsZWQgdG8gZ2V0IGxlbmd0aCBvZiBcIicgKyB0YWcgKyAnXCInKTtcblxuICAvLyBGYWlsdXJlXG4gIGlmIChidWZmZXIuaXNFcnJvcihsZW4pKVxuICAgIHJldHVybiBsZW47XG5cbiAgaWYgKCFhbnkgJiZcbiAgICAgIGRlY29kZWRUYWcudGFnICE9PSB0YWcgJiZcbiAgICAgIGRlY29kZWRUYWcudGFnU3RyICE9PSB0YWcgJiZcbiAgICAgIGRlY29kZWRUYWcudGFnU3RyICsgJ29mJyAhPT0gdGFnKSB7XG4gICAgcmV0dXJuIGJ1ZmZlci5lcnJvcignRmFpbGVkIHRvIG1hdGNoIHRhZzogXCInICsgdGFnICsgJ1wiJyk7XG4gIH1cblxuICBpZiAoZGVjb2RlZFRhZy5wcmltaXRpdmUgfHwgbGVuICE9PSBudWxsKVxuICAgIHJldHVybiBidWZmZXIuc2tpcChsZW4sICdGYWlsZWQgdG8gbWF0Y2ggYm9keSBvZjogXCInICsgdGFnICsgJ1wiJyk7XG5cbiAgLy8gSW5kZWZpbml0ZSBsZW5ndGguLi4gZmluZCBFTkQgdGFnXG4gIHZhciBzdGF0ZSA9IGJ1ZmZlci5zYXZlKCk7XG4gIHZhciByZXMgPSB0aGlzLl9za2lwVW50aWxFbmQoXG4gICAgICBidWZmZXIsXG4gICAgICAnRmFpbGVkIHRvIHNraXAgaW5kZWZpbml0ZSBsZW5ndGggYm9keTogXCInICsgdGhpcy50YWcgKyAnXCInKTtcbiAgaWYgKGJ1ZmZlci5pc0Vycm9yKHJlcykpXG4gICAgcmV0dXJuIHJlcztcblxuICBsZW4gPSBidWZmZXIub2Zmc2V0IC0gc3RhdGUub2Zmc2V0O1xuICBidWZmZXIucmVzdG9yZShzdGF0ZSk7XG4gIHJldHVybiBidWZmZXIuc2tpcChsZW4sICdGYWlsZWQgdG8gbWF0Y2ggYm9keSBvZjogXCInICsgdGFnICsgJ1wiJyk7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fc2tpcFVudGlsRW5kID0gZnVuY3Rpb24gc2tpcFVudGlsRW5kKGJ1ZmZlciwgZmFpbCkge1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIHZhciB0YWcgPSBkZXJEZWNvZGVUYWcoYnVmZmVyLCBmYWlsKTtcbiAgICBpZiAoYnVmZmVyLmlzRXJyb3IodGFnKSlcbiAgICAgIHJldHVybiB0YWc7XG4gICAgdmFyIGxlbiA9IGRlckRlY29kZUxlbihidWZmZXIsIHRhZy5wcmltaXRpdmUsIGZhaWwpO1xuICAgIGlmIChidWZmZXIuaXNFcnJvcihsZW4pKVxuICAgICAgcmV0dXJuIGxlbjtcblxuICAgIHZhciByZXM7XG4gICAgaWYgKHRhZy5wcmltaXRpdmUgfHwgbGVuICE9PSBudWxsKVxuICAgICAgcmVzID0gYnVmZmVyLnNraXAobGVuKVxuICAgIGVsc2VcbiAgICAgIHJlcyA9IHRoaXMuX3NraXBVbnRpbEVuZChidWZmZXIsIGZhaWwpO1xuXG4gICAgLy8gRmFpbHVyZVxuICAgIGlmIChidWZmZXIuaXNFcnJvcihyZXMpKVxuICAgICAgcmV0dXJuIHJlcztcblxuICAgIGlmICh0YWcudGFnU3RyID09PSAnZW5kJylcbiAgICAgIGJyZWFrO1xuICB9XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZGVjb2RlTGlzdCA9IGZ1bmN0aW9uIGRlY29kZUxpc3QoYnVmZmVyLCB0YWcsIGRlY29kZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucykge1xuICB2YXIgcmVzdWx0ID0gW107XG4gIHdoaWxlICghYnVmZmVyLmlzRW1wdHkoKSkge1xuICAgIHZhciBwb3NzaWJsZUVuZCA9IHRoaXMuX3BlZWtUYWcoYnVmZmVyLCAnZW5kJyk7XG4gICAgaWYgKGJ1ZmZlci5pc0Vycm9yKHBvc3NpYmxlRW5kKSlcbiAgICAgIHJldHVybiBwb3NzaWJsZUVuZDtcblxuICAgIHZhciByZXMgPSBkZWNvZGVyLmRlY29kZShidWZmZXIsICdkZXInLCBvcHRpb25zKTtcbiAgICBpZiAoYnVmZmVyLmlzRXJyb3IocmVzKSAmJiBwb3NzaWJsZUVuZClcbiAgICAgIGJyZWFrO1xuICAgIHJlc3VsdC5wdXNoKHJlcyk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9kZWNvZGVTdHIgPSBmdW5jdGlvbiBkZWNvZGVTdHIoYnVmZmVyLCB0YWcpIHtcbiAgaWYgKHRhZyA9PT0gJ2JpdHN0cicpIHtcbiAgICB2YXIgdW51c2VkID0gYnVmZmVyLnJlYWRVSW50OCgpO1xuICAgIGlmIChidWZmZXIuaXNFcnJvcih1bnVzZWQpKVxuICAgICAgcmV0dXJuIHVudXNlZDtcbiAgICByZXR1cm4geyB1bnVzZWQ6IHVudXNlZCwgZGF0YTogYnVmZmVyLnJhdygpIH07XG4gIH0gZWxzZSBpZiAodGFnID09PSAnYm1wc3RyJykge1xuICAgIHZhciByYXcgPSBidWZmZXIucmF3KCk7XG4gICAgaWYgKHJhdy5sZW5ndGggJSAyID09PSAxKVxuICAgICAgcmV0dXJuIGJ1ZmZlci5lcnJvcignRGVjb2Rpbmcgb2Ygc3RyaW5nIHR5cGU6IGJtcHN0ciBsZW5ndGggbWlzbWF0Y2gnKTtcblxuICAgIHZhciBzdHIgPSAnJztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJhdy5sZW5ndGggLyAyOyBpKyspIHtcbiAgICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHJhdy5yZWFkVUludDE2QkUoaSAqIDIpKTtcbiAgICB9XG4gICAgcmV0dXJuIHN0cjtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICdudW1zdHInKSB7XG4gICAgdmFyIG51bXN0ciA9IGJ1ZmZlci5yYXcoKS50b1N0cmluZygnYXNjaWknKTtcbiAgICBpZiAoIXRoaXMuX2lzTnVtc3RyKG51bXN0cikpIHtcbiAgICAgIHJldHVybiBidWZmZXIuZXJyb3IoJ0RlY29kaW5nIG9mIHN0cmluZyB0eXBlOiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ251bXN0ciB1bnN1cHBvcnRlZCBjaGFyYWN0ZXJzJyk7XG4gICAgfVxuICAgIHJldHVybiBudW1zdHI7XG4gIH0gZWxzZSBpZiAodGFnID09PSAnb2N0c3RyJykge1xuICAgIHJldHVybiBidWZmZXIucmF3KCk7XG4gIH0gZWxzZSBpZiAodGFnID09PSAnb2JqRGVzYycpIHtcbiAgICByZXR1cm4gYnVmZmVyLnJhdygpO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ3ByaW50c3RyJykge1xuICAgIHZhciBwcmludHN0ciA9IGJ1ZmZlci5yYXcoKS50b1N0cmluZygnYXNjaWknKTtcbiAgICBpZiAoIXRoaXMuX2lzUHJpbnRzdHIocHJpbnRzdHIpKSB7XG4gICAgICByZXR1cm4gYnVmZmVyLmVycm9yKCdEZWNvZGluZyBvZiBzdHJpbmcgdHlwZTogJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdwcmludHN0ciB1bnN1cHBvcnRlZCBjaGFyYWN0ZXJzJyk7XG4gICAgfVxuICAgIHJldHVybiBwcmludHN0cjtcbiAgfSBlbHNlIGlmICgvc3RyJC8udGVzdCh0YWcpKSB7XG4gICAgcmV0dXJuIGJ1ZmZlci5yYXcoKS50b1N0cmluZygpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBidWZmZXIuZXJyb3IoJ0RlY29kaW5nIG9mIHN0cmluZyB0eXBlOiAnICsgdGFnICsgJyB1bnN1cHBvcnRlZCcpO1xuICB9XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZGVjb2RlT2JqaWQgPSBmdW5jdGlvbiBkZWNvZGVPYmppZChidWZmZXIsIHZhbHVlcywgcmVsYXRpdmUpIHtcbiAgdmFyIHJlc3VsdDtcbiAgdmFyIGlkZW50aWZpZXJzID0gW107XG4gIHZhciBpZGVudCA9IDA7XG4gIHdoaWxlICghYnVmZmVyLmlzRW1wdHkoKSkge1xuICAgIHZhciBzdWJpZGVudCA9IGJ1ZmZlci5yZWFkVUludDgoKTtcbiAgICBpZGVudCA8PD0gNztcbiAgICBpZGVudCB8PSBzdWJpZGVudCAmIDB4N2Y7XG4gICAgaWYgKChzdWJpZGVudCAmIDB4ODApID09PSAwKSB7XG4gICAgICBpZGVudGlmaWVycy5wdXNoKGlkZW50KTtcbiAgICAgIGlkZW50ID0gMDtcbiAgICB9XG4gIH1cbiAgaWYgKHN1YmlkZW50ICYgMHg4MClcbiAgICBpZGVudGlmaWVycy5wdXNoKGlkZW50KTtcblxuICB2YXIgZmlyc3QgPSAoaWRlbnRpZmllcnNbMF0gLyA0MCkgfCAwO1xuICB2YXIgc2Vjb25kID0gaWRlbnRpZmllcnNbMF0gJSA0MDtcblxuICBpZiAocmVsYXRpdmUpXG4gICAgcmVzdWx0ID0gaWRlbnRpZmllcnM7XG4gIGVsc2VcbiAgICByZXN1bHQgPSBbZmlyc3QsIHNlY29uZF0uY29uY2F0KGlkZW50aWZpZXJzLnNsaWNlKDEpKTtcblxuICBpZiAodmFsdWVzKSB7XG4gICAgdmFyIHRtcCA9IHZhbHVlc1tyZXN1bHQuam9pbignICcpXTtcbiAgICBpZiAodG1wID09PSB1bmRlZmluZWQpXG4gICAgICB0bXAgPSB2YWx1ZXNbcmVzdWx0LmpvaW4oJy4nKV07XG4gICAgaWYgKHRtcCAhPT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0ID0gdG1wO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9kZWNvZGVUaW1lID0gZnVuY3Rpb24gZGVjb2RlVGltZShidWZmZXIsIHRhZykge1xuICB2YXIgc3RyID0gYnVmZmVyLnJhdygpLnRvU3RyaW5nKCk7XG4gIGlmICh0YWcgPT09ICdnZW50aW1lJykge1xuICAgIHZhciB5ZWFyID0gc3RyLnNsaWNlKDAsIDQpIHwgMDtcbiAgICB2YXIgbW9uID0gc3RyLnNsaWNlKDQsIDYpIHwgMDtcbiAgICB2YXIgZGF5ID0gc3RyLnNsaWNlKDYsIDgpIHwgMDtcbiAgICB2YXIgaG91ciA9IHN0ci5zbGljZSg4LCAxMCkgfCAwO1xuICAgIHZhciBtaW4gPSBzdHIuc2xpY2UoMTAsIDEyKSB8IDA7XG4gICAgdmFyIHNlYyA9IHN0ci5zbGljZSgxMiwgMTQpIHwgMDtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICd1dGN0aW1lJykge1xuICAgIHZhciB5ZWFyID0gc3RyLnNsaWNlKDAsIDIpIHwgMDtcbiAgICB2YXIgbW9uID0gc3RyLnNsaWNlKDIsIDQpIHwgMDtcbiAgICB2YXIgZGF5ID0gc3RyLnNsaWNlKDQsIDYpIHwgMDtcbiAgICB2YXIgaG91ciA9IHN0ci5zbGljZSg2LCA4KSB8IDA7XG4gICAgdmFyIG1pbiA9IHN0ci5zbGljZSg4LCAxMCkgfCAwO1xuICAgIHZhciBzZWMgPSBzdHIuc2xpY2UoMTAsIDEyKSB8IDA7XG4gICAgaWYgKHllYXIgPCA3MClcbiAgICAgIHllYXIgPSAyMDAwICsgeWVhcjtcbiAgICBlbHNlXG4gICAgICB5ZWFyID0gMTkwMCArIHllYXI7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJ1ZmZlci5lcnJvcignRGVjb2RpbmcgJyArIHRhZyArICcgdGltZSBpcyBub3Qgc3VwcG9ydGVkIHlldCcpO1xuICB9XG5cbiAgcmV0dXJuIERhdGUuVVRDKHllYXIsIG1vbiAtIDEsIGRheSwgaG91ciwgbWluLCBzZWMsIDApO1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2RlY29kZU51bGwgPSBmdW5jdGlvbiBkZWNvZGVOdWxsKGJ1ZmZlcikge1xuICByZXR1cm4gbnVsbDtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9kZWNvZGVCb29sID0gZnVuY3Rpb24gZGVjb2RlQm9vbChidWZmZXIpIHtcbiAgdmFyIHJlcyA9IGJ1ZmZlci5yZWFkVUludDgoKTtcbiAgaWYgKGJ1ZmZlci5pc0Vycm9yKHJlcykpXG4gICAgcmV0dXJuIHJlcztcbiAgZWxzZVxuICAgIHJldHVybiByZXMgIT09IDA7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZGVjb2RlSW50ID0gZnVuY3Rpb24gZGVjb2RlSW50KGJ1ZmZlciwgdmFsdWVzKSB7XG4gIC8vIEJpZ2ludCwgcmV0dXJuIGFzIGl0IGlzIChhc3N1bWUgYmlnIGVuZGlhbilcbiAgdmFyIHJhdyA9IGJ1ZmZlci5yYXcoKTtcbiAgdmFyIHJlcyA9IG5ldyBiaWdudW0ocmF3KTtcblxuICBpZiAodmFsdWVzKVxuICAgIHJlcyA9IHZhbHVlc1tyZXMudG9TdHJpbmcoMTApXSB8fCByZXM7XG5cbiAgcmV0dXJuIHJlcztcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl91c2UgPSBmdW5jdGlvbiB1c2UoZW50aXR5LCBvYmopIHtcbiAgaWYgKHR5cGVvZiBlbnRpdHkgPT09ICdmdW5jdGlvbicpXG4gICAgZW50aXR5ID0gZW50aXR5KG9iaik7XG4gIHJldHVybiBlbnRpdHkuX2dldERlY29kZXIoJ2RlcicpLnRyZWU7XG59O1xuXG4vLyBVdGlsaXR5IG1ldGhvZHNcblxuZnVuY3Rpb24gZGVyRGVjb2RlVGFnKGJ1ZiwgZmFpbCkge1xuICB2YXIgdGFnID0gYnVmLnJlYWRVSW50OChmYWlsKTtcbiAgaWYgKGJ1Zi5pc0Vycm9yKHRhZykpXG4gICAgcmV0dXJuIHRhZztcblxuICB2YXIgY2xzID0gZGVyLnRhZ0NsYXNzW3RhZyA+PiA2XTtcbiAgdmFyIHByaW1pdGl2ZSA9ICh0YWcgJiAweDIwKSA9PT0gMDtcblxuICAvLyBNdWx0aS1vY3RldCB0YWcgLSBsb2FkXG4gIGlmICgodGFnICYgMHgxZikgPT09IDB4MWYpIHtcbiAgICB2YXIgb2N0ID0gdGFnO1xuICAgIHRhZyA9IDA7XG4gICAgd2hpbGUgKChvY3QgJiAweDgwKSA9PT0gMHg4MCkge1xuICAgICAgb2N0ID0gYnVmLnJlYWRVSW50OChmYWlsKTtcbiAgICAgIGlmIChidWYuaXNFcnJvcihvY3QpKVxuICAgICAgICByZXR1cm4gb2N0O1xuXG4gICAgICB0YWcgPDw9IDc7XG4gICAgICB0YWcgfD0gb2N0ICYgMHg3ZjtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGFnICY9IDB4MWY7XG4gIH1cbiAgdmFyIHRhZ1N0ciA9IGRlci50YWdbdGFnXTtcblxuICByZXR1cm4ge1xuICAgIGNsczogY2xzLFxuICAgIHByaW1pdGl2ZTogcHJpbWl0aXZlLFxuICAgIHRhZzogdGFnLFxuICAgIHRhZ1N0cjogdGFnU3RyXG4gIH07XG59XG5cbmZ1bmN0aW9uIGRlckRlY29kZUxlbihidWYsIHByaW1pdGl2ZSwgZmFpbCkge1xuICB2YXIgbGVuID0gYnVmLnJlYWRVSW50OChmYWlsKTtcbiAgaWYgKGJ1Zi5pc0Vycm9yKGxlbikpXG4gICAgcmV0dXJuIGxlbjtcblxuICAvLyBJbmRlZmluaXRlIGZvcm1cbiAgaWYgKCFwcmltaXRpdmUgJiYgbGVuID09PSAweDgwKVxuICAgIHJldHVybiBudWxsO1xuXG4gIC8vIERlZmluaXRlIGZvcm1cbiAgaWYgKChsZW4gJiAweDgwKSA9PT0gMCkge1xuICAgIC8vIFNob3J0IGZvcm1cbiAgICByZXR1cm4gbGVuO1xuICB9XG5cbiAgLy8gTG9uZyBmb3JtXG4gIHZhciBudW0gPSBsZW4gJiAweDdmO1xuICBpZiAobnVtID4gNClcbiAgICByZXR1cm4gYnVmLmVycm9yKCdsZW5ndGggb2N0ZWN0IGlzIHRvbyBsb25nJyk7XG5cbiAgbGVuID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW07IGkrKykge1xuICAgIGxlbiA8PD0gODtcbiAgICB2YXIgaiA9IGJ1Zi5yZWFkVUludDgoZmFpbCk7XG4gICAgaWYgKGJ1Zi5pc0Vycm9yKGopKVxuICAgICAgcmV0dXJuIGo7XG4gICAgbGVuIHw9IGo7XG4gIH1cblxuICByZXR1cm4gbGVuO1xufVxuIiwidmFyIGRlY29kZXJzID0gZXhwb3J0cztcblxuZGVjb2RlcnMuZGVyID0gcmVxdWlyZSgnLi9kZXInKTtcbmRlY29kZXJzLnBlbSA9IHJlcXVpcmUoJy4vcGVtJyk7XG4iLCJ2YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcblxudmFyIERFUkRlY29kZXIgPSByZXF1aXJlKCcuL2RlcicpO1xuXG5mdW5jdGlvbiBQRU1EZWNvZGVyKGVudGl0eSkge1xuICBERVJEZWNvZGVyLmNhbGwodGhpcywgZW50aXR5KTtcbiAgdGhpcy5lbmMgPSAncGVtJztcbn07XG5pbmhlcml0cyhQRU1EZWNvZGVyLCBERVJEZWNvZGVyKTtcbm1vZHVsZS5leHBvcnRzID0gUEVNRGVjb2RlcjtcblxuUEVNRGVjb2Rlci5wcm90b3R5cGUuZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKGRhdGEsIG9wdGlvbnMpIHtcbiAgdmFyIGxpbmVzID0gZGF0YS50b1N0cmluZygpLnNwbGl0KC9bXFxyXFxuXSsvZyk7XG5cbiAgdmFyIGxhYmVsID0gb3B0aW9ucy5sYWJlbC50b1VwcGVyQ2FzZSgpO1xuXG4gIHZhciByZSA9IC9eLS0tLS0oQkVHSU58RU5EKSAoW14tXSspLS0tLS0kLztcbiAgdmFyIHN0YXJ0ID0gLTE7XG4gIHZhciBlbmQgPSAtMTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBtYXRjaCA9IGxpbmVzW2ldLm1hdGNoKHJlKTtcbiAgICBpZiAobWF0Y2ggPT09IG51bGwpXG4gICAgICBjb250aW51ZTtcblxuICAgIGlmIChtYXRjaFsyXSAhPT0gbGFiZWwpXG4gICAgICBjb250aW51ZTtcblxuICAgIGlmIChzdGFydCA9PT0gLTEpIHtcbiAgICAgIGlmIChtYXRjaFsxXSAhPT0gJ0JFR0lOJylcbiAgICAgICAgYnJlYWs7XG4gICAgICBzdGFydCA9IGk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChtYXRjaFsxXSAhPT0gJ0VORCcpXG4gICAgICAgIGJyZWFrO1xuICAgICAgZW5kID0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBpZiAoc3RhcnQgPT09IC0xIHx8IGVuZCA9PT0gLTEpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdQRU0gc2VjdGlvbiBub3QgZm91bmQgZm9yOiAnICsgbGFiZWwpO1xuXG4gIHZhciBiYXNlNjQgPSBsaW5lcy5zbGljZShzdGFydCArIDEsIGVuZCkuam9pbignJyk7XG4gIC8vIFJlbW92ZSBleGNlc3NpdmUgc3ltYm9sc1xuICBiYXNlNjQucmVwbGFjZSgvW15hLXowLTlcXCtcXC89XSsvZ2ksICcnKTtcblxuICB2YXIgaW5wdXQgPSBuZXcgQnVmZmVyKGJhc2U2NCwgJ2Jhc2U2NCcpO1xuICByZXR1cm4gREVSRGVjb2Rlci5wcm90b3R5cGUuZGVjb2RlLmNhbGwodGhpcywgaW5wdXQsIG9wdGlvbnMpO1xufTtcbiIsInZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuXG52YXIgYXNuMSA9IHJlcXVpcmUoJy4uLy4uL2FzbjEnKTtcbnZhciBiYXNlID0gYXNuMS5iYXNlO1xuXG4vLyBJbXBvcnQgREVSIGNvbnN0YW50c1xudmFyIGRlciA9IGFzbjEuY29uc3RhbnRzLmRlcjtcblxuZnVuY3Rpb24gREVSRW5jb2RlcihlbnRpdHkpIHtcbiAgdGhpcy5lbmMgPSAnZGVyJztcbiAgdGhpcy5uYW1lID0gZW50aXR5Lm5hbWU7XG4gIHRoaXMuZW50aXR5ID0gZW50aXR5O1xuXG4gIC8vIENvbnN0cnVjdCBiYXNlIHRyZWVcbiAgdGhpcy50cmVlID0gbmV3IERFUk5vZGUoKTtcbiAgdGhpcy50cmVlLl9pbml0KGVudGl0eS5ib2R5KTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IERFUkVuY29kZXI7XG5cbkRFUkVuY29kZXIucHJvdG90eXBlLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShkYXRhLCByZXBvcnRlcikge1xuICByZXR1cm4gdGhpcy50cmVlLl9lbmNvZGUoZGF0YSwgcmVwb3J0ZXIpLmpvaW4oKTtcbn07XG5cbi8vIFRyZWUgbWV0aG9kc1xuXG5mdW5jdGlvbiBERVJOb2RlKHBhcmVudCkge1xuICBiYXNlLk5vZGUuY2FsbCh0aGlzLCAnZGVyJywgcGFyZW50KTtcbn1cbmluaGVyaXRzKERFUk5vZGUsIGJhc2UuTm9kZSk7XG5cbkRFUk5vZGUucHJvdG90eXBlLl9lbmNvZGVDb21wb3NpdGUgPSBmdW5jdGlvbiBlbmNvZGVDb21wb3NpdGUodGFnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmltaXRpdmUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNscyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudCkge1xuICB2YXIgZW5jb2RlZFRhZyA9IGVuY29kZVRhZyh0YWcsIHByaW1pdGl2ZSwgY2xzLCB0aGlzLnJlcG9ydGVyKTtcblxuICAvLyBTaG9ydCBmb3JtXG4gIGlmIChjb250ZW50Lmxlbmd0aCA8IDB4ODApIHtcbiAgICB2YXIgaGVhZGVyID0gbmV3IEJ1ZmZlcigyKTtcbiAgICBoZWFkZXJbMF0gPSBlbmNvZGVkVGFnO1xuICAgIGhlYWRlclsxXSA9IGNvbnRlbnQubGVuZ3RoO1xuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKFsgaGVhZGVyLCBjb250ZW50IF0pO1xuICB9XG5cbiAgLy8gTG9uZyBmb3JtXG4gIC8vIENvdW50IG9jdGV0cyByZXF1aXJlZCB0byBzdG9yZSBsZW5ndGhcbiAgdmFyIGxlbk9jdGV0cyA9IDE7XG4gIGZvciAodmFyIGkgPSBjb250ZW50Lmxlbmd0aDsgaSA+PSAweDEwMDsgaSA+Pj0gOClcbiAgICBsZW5PY3RldHMrKztcblxuICB2YXIgaGVhZGVyID0gbmV3IEJ1ZmZlcigxICsgMSArIGxlbk9jdGV0cyk7XG4gIGhlYWRlclswXSA9IGVuY29kZWRUYWc7XG4gIGhlYWRlclsxXSA9IDB4ODAgfCBsZW5PY3RldHM7XG5cbiAgZm9yICh2YXIgaSA9IDEgKyBsZW5PY3RldHMsIGogPSBjb250ZW50Lmxlbmd0aDsgaiA+IDA7IGktLSwgaiA+Pj0gOClcbiAgICBoZWFkZXJbaV0gPSBqICYgMHhmZjtcblxuICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihbIGhlYWRlciwgY29udGVudCBdKTtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9lbmNvZGVTdHIgPSBmdW5jdGlvbiBlbmNvZGVTdHIoc3RyLCB0YWcpIHtcbiAgaWYgKHRhZyA9PT0gJ2JpdHN0cicpIHtcbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihbIHN0ci51bnVzZWQgfCAwLCBzdHIuZGF0YSBdKTtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICdibXBzdHInKSB7XG4gICAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoc3RyLmxlbmd0aCAqIDIpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBidWYud3JpdGVVSW50MTZCRShzdHIuY2hhckNvZGVBdChpKSwgaSAqIDIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihidWYpO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ251bXN0cicpIHtcbiAgICBpZiAoIXRoaXMuX2lzTnVtc3RyKHN0cikpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlcG9ydGVyLmVycm9yKCdFbmNvZGluZyBvZiBzdHJpbmcgdHlwZTogbnVtc3RyIHN1cHBvcnRzICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ29ubHkgZGlnaXRzIGFuZCBzcGFjZScpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihzdHIpO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ3ByaW50c3RyJykge1xuICAgIGlmICghdGhpcy5faXNQcmludHN0cihzdHIpKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXBvcnRlci5lcnJvcignRW5jb2Rpbmcgb2Ygc3RyaW5nIHR5cGU6IHByaW50c3RyIHN1cHBvcnRzICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ29ubHkgbGF0aW4gdXBwZXIgYW5kIGxvd2VyIGNhc2UgbGV0dGVycywgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGlnaXRzLCBzcGFjZSwgYXBvc3Ryb3BoZSwgbGVmdCBhbmQgcmlndGggJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncGFyZW50aGVzaXMsIHBsdXMgc2lnbiwgY29tbWEsIGh5cGhlbiwgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZG90LCBzbGFzaCwgY29sb24sIGVxdWFsIHNpZ24sICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3F1ZXN0aW9uIG1hcmsnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoc3RyKTtcbiAgfSBlbHNlIGlmICgvc3RyJC8udGVzdCh0YWcpKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoc3RyKTtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICdvYmpEZXNjJykge1xuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKHN0cik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHRoaXMucmVwb3J0ZXIuZXJyb3IoJ0VuY29kaW5nIG9mIHN0cmluZyB0eXBlOiAnICsgdGFnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnIHVuc3VwcG9ydGVkJyk7XG4gIH1cbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9lbmNvZGVPYmppZCA9IGZ1bmN0aW9uIGVuY29kZU9iamlkKGlkLCB2YWx1ZXMsIHJlbGF0aXZlKSB7XG4gIGlmICh0eXBlb2YgaWQgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKCF2YWx1ZXMpXG4gICAgICByZXR1cm4gdGhpcy5yZXBvcnRlci5lcnJvcignc3RyaW5nIG9iamlkIGdpdmVuLCBidXQgbm8gdmFsdWVzIG1hcCBmb3VuZCcpO1xuICAgIGlmICghdmFsdWVzLmhhc093blByb3BlcnR5KGlkKSlcbiAgICAgIHJldHVybiB0aGlzLnJlcG9ydGVyLmVycm9yKCdvYmppZCBub3QgZm91bmQgaW4gdmFsdWVzIG1hcCcpO1xuICAgIGlkID0gdmFsdWVzW2lkXS5zcGxpdCgvW1xcc1xcLl0rL2cpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaWQubGVuZ3RoOyBpKyspXG4gICAgICBpZFtpXSB8PSAwO1xuICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoaWQpKSB7XG4gICAgaWQgPSBpZC5zbGljZSgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaWQubGVuZ3RoOyBpKyspXG4gICAgICBpZFtpXSB8PSAwO1xuICB9XG5cbiAgaWYgKCFBcnJheS5pc0FycmF5KGlkKSkge1xuICAgIHJldHVybiB0aGlzLnJlcG9ydGVyLmVycm9yKCdvYmppZCgpIHNob3VsZCBiZSBlaXRoZXIgYXJyYXkgb3Igc3RyaW5nLCAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZ290OiAnICsgSlNPTi5zdHJpbmdpZnkoaWQpKTtcbiAgfVxuXG4gIGlmICghcmVsYXRpdmUpIHtcbiAgICBpZiAoaWRbMV0gPj0gNDApXG4gICAgICByZXR1cm4gdGhpcy5yZXBvcnRlci5lcnJvcignU2Vjb25kIG9iamlkIGlkZW50aWZpZXIgT09CJyk7XG4gICAgaWQuc3BsaWNlKDAsIDIsIGlkWzBdICogNDAgKyBpZFsxXSk7XG4gIH1cblxuICAvLyBDb3VudCBudW1iZXIgb2Ygb2N0ZXRzXG4gIHZhciBzaXplID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBpZC5sZW5ndGg7IGkrKykge1xuICAgIHZhciBpZGVudCA9IGlkW2ldO1xuICAgIGZvciAoc2l6ZSsrOyBpZGVudCA+PSAweDgwOyBpZGVudCA+Pj0gNylcbiAgICAgIHNpemUrKztcbiAgfVxuXG4gIHZhciBvYmppZCA9IG5ldyBCdWZmZXIoc2l6ZSk7XG4gIHZhciBvZmZzZXQgPSBvYmppZC5sZW5ndGggLSAxO1xuICBmb3IgKHZhciBpID0gaWQubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICB2YXIgaWRlbnQgPSBpZFtpXTtcbiAgICBvYmppZFtvZmZzZXQtLV0gPSBpZGVudCAmIDB4N2Y7XG4gICAgd2hpbGUgKChpZGVudCA+Pj0gNykgPiAwKVxuICAgICAgb2JqaWRbb2Zmc2V0LS1dID0gMHg4MCB8IChpZGVudCAmIDB4N2YpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIob2JqaWQpO1xufTtcblxuZnVuY3Rpb24gdHdvKG51bSkge1xuICBpZiAobnVtIDwgMTApXG4gICAgcmV0dXJuICcwJyArIG51bTtcbiAgZWxzZVxuICAgIHJldHVybiBudW07XG59XG5cbkRFUk5vZGUucHJvdG90eXBlLl9lbmNvZGVUaW1lID0gZnVuY3Rpb24gZW5jb2RlVGltZSh0aW1lLCB0YWcpIHtcbiAgdmFyIHN0cjtcbiAgdmFyIGRhdGUgPSBuZXcgRGF0ZSh0aW1lKTtcblxuICBpZiAodGFnID09PSAnZ2VudGltZScpIHtcbiAgICBzdHIgPSBbXG4gICAgICB0d28oZGF0ZS5nZXRGdWxsWWVhcigpKSxcbiAgICAgIHR3byhkYXRlLmdldFVUQ01vbnRoKCkgKyAxKSxcbiAgICAgIHR3byhkYXRlLmdldFVUQ0RhdGUoKSksXG4gICAgICB0d28oZGF0ZS5nZXRVVENIb3VycygpKSxcbiAgICAgIHR3byhkYXRlLmdldFVUQ01pbnV0ZXMoKSksXG4gICAgICB0d28oZGF0ZS5nZXRVVENTZWNvbmRzKCkpLFxuICAgICAgJ1onXG4gICAgXS5qb2luKCcnKTtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICd1dGN0aW1lJykge1xuICAgIHN0ciA9IFtcbiAgICAgIHR3byhkYXRlLmdldEZ1bGxZZWFyKCkgJSAxMDApLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDTW9udGgoKSArIDEpLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDRGF0ZSgpKSxcbiAgICAgIHR3byhkYXRlLmdldFVUQ0hvdXJzKCkpLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDTWludXRlcygpKSxcbiAgICAgIHR3byhkYXRlLmdldFVUQ1NlY29uZHMoKSksXG4gICAgICAnWidcbiAgICBdLmpvaW4oJycpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMucmVwb3J0ZXIuZXJyb3IoJ0VuY29kaW5nICcgKyB0YWcgKyAnIHRpbWUgaXMgbm90IHN1cHBvcnRlZCB5ZXQnKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9lbmNvZGVTdHIoc3RyLCAnb2N0c3RyJyk7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZW5jb2RlTnVsbCA9IGZ1bmN0aW9uIGVuY29kZU51bGwoKSB7XG4gIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKCcnKTtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9lbmNvZGVJbnQgPSBmdW5jdGlvbiBlbmNvZGVJbnQobnVtLCB2YWx1ZXMpIHtcbiAgaWYgKHR5cGVvZiBudW0gPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKCF2YWx1ZXMpXG4gICAgICByZXR1cm4gdGhpcy5yZXBvcnRlci5lcnJvcignU3RyaW5nIGludCBvciBlbnVtIGdpdmVuLCBidXQgbm8gdmFsdWVzIG1hcCcpO1xuICAgIGlmICghdmFsdWVzLmhhc093blByb3BlcnR5KG51bSkpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlcG9ydGVyLmVycm9yKCdWYWx1ZXMgbWFwIGRvZXNuXFwndCBjb250YWluOiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KG51bSkpO1xuICAgIH1cbiAgICBudW0gPSB2YWx1ZXNbbnVtXTtcbiAgfVxuXG4gIC8vIEJpZ251bSwgYXNzdW1lIGJpZyBlbmRpYW5cbiAgaWYgKHR5cGVvZiBudW0gIT09ICdudW1iZXInICYmICFCdWZmZXIuaXNCdWZmZXIobnVtKSkge1xuICAgIHZhciBudW1BcnJheSA9IG51bS50b0FycmF5KCk7XG4gICAgaWYgKCFudW0uc2lnbiAmJiBudW1BcnJheVswXSAmIDB4ODApIHtcbiAgICAgIG51bUFycmF5LnVuc2hpZnQoMCk7XG4gICAgfVxuICAgIG51bSA9IG5ldyBCdWZmZXIobnVtQXJyYXkpO1xuICB9XG5cbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihudW0pKSB7XG4gICAgdmFyIHNpemUgPSBudW0ubGVuZ3RoO1xuICAgIGlmIChudW0ubGVuZ3RoID09PSAwKVxuICAgICAgc2l6ZSsrO1xuXG4gICAgdmFyIG91dCA9IG5ldyBCdWZmZXIoc2l6ZSk7XG4gICAgbnVtLmNvcHkob3V0KTtcbiAgICBpZiAobnVtLmxlbmd0aCA9PT0gMClcbiAgICAgIG91dFswXSA9IDBcbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihvdXQpO1xuICB9XG5cbiAgaWYgKG51bSA8IDB4ODApXG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIobnVtKTtcblxuICBpZiAobnVtIDwgMHgxMDApXG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoWzAsIG51bV0pO1xuXG4gIHZhciBzaXplID0gMTtcbiAgZm9yICh2YXIgaSA9IG51bTsgaSA+PSAweDEwMDsgaSA+Pj0gOClcbiAgICBzaXplKys7XG5cbiAgdmFyIG91dCA9IG5ldyBBcnJheShzaXplKTtcbiAgZm9yICh2YXIgaSA9IG91dC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIG91dFtpXSA9IG51bSAmIDB4ZmY7XG4gICAgbnVtID4+PSA4O1xuICB9XG4gIGlmKG91dFswXSAmIDB4ODApIHtcbiAgICBvdXQudW5zaGlmdCgwKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKG5ldyBCdWZmZXIob3V0KSk7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZW5jb2RlQm9vbCA9IGZ1bmN0aW9uIGVuY29kZUJvb2wodmFsdWUpIHtcbiAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIodmFsdWUgPyAweGZmIDogMCk7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fdXNlID0gZnVuY3Rpb24gdXNlKGVudGl0eSwgb2JqKSB7XG4gIGlmICh0eXBlb2YgZW50aXR5ID09PSAnZnVuY3Rpb24nKVxuICAgIGVudGl0eSA9IGVudGl0eShvYmopO1xuICByZXR1cm4gZW50aXR5Ll9nZXRFbmNvZGVyKCdkZXInKS50cmVlO1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX3NraXBEZWZhdWx0ID0gZnVuY3Rpb24gc2tpcERlZmF1bHQoZGF0YUJ1ZmZlciwgcmVwb3J0ZXIsIHBhcmVudCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG4gIHZhciBpO1xuICBpZiAoc3RhdGVbJ2RlZmF1bHQnXSA9PT0gbnVsbClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGRhdGEgPSBkYXRhQnVmZmVyLmpvaW4oKTtcbiAgaWYgKHN0YXRlLmRlZmF1bHRCdWZmZXIgPT09IHVuZGVmaW5lZClcbiAgICBzdGF0ZS5kZWZhdWx0QnVmZmVyID0gdGhpcy5fZW5jb2RlVmFsdWUoc3RhdGVbJ2RlZmF1bHQnXSwgcmVwb3J0ZXIsIHBhcmVudCkuam9pbigpO1xuXG4gIGlmIChkYXRhLmxlbmd0aCAhPT0gc3RhdGUuZGVmYXVsdEJ1ZmZlci5sZW5ndGgpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIGZvciAoaT0wOyBpIDwgZGF0YS5sZW5ndGg7IGkrKylcbiAgICBpZiAoZGF0YVtpXSAhPT0gc3RhdGUuZGVmYXVsdEJ1ZmZlcltpXSlcbiAgICAgIHJldHVybiBmYWxzZTtcblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8vIFV0aWxpdHkgbWV0aG9kc1xuXG5mdW5jdGlvbiBlbmNvZGVUYWcodGFnLCBwcmltaXRpdmUsIGNscywgcmVwb3J0ZXIpIHtcbiAgdmFyIHJlcztcblxuICBpZiAodGFnID09PSAnc2Vxb2YnKVxuICAgIHRhZyA9ICdzZXEnO1xuICBlbHNlIGlmICh0YWcgPT09ICdzZXRvZicpXG4gICAgdGFnID0gJ3NldCc7XG5cbiAgaWYgKGRlci50YWdCeU5hbWUuaGFzT3duUHJvcGVydHkodGFnKSlcbiAgICByZXMgPSBkZXIudGFnQnlOYW1lW3RhZ107XG4gIGVsc2UgaWYgKHR5cGVvZiB0YWcgPT09ICdudW1iZXInICYmICh0YWcgfCAwKSA9PT0gdGFnKVxuICAgIHJlcyA9IHRhZztcbiAgZWxzZVxuICAgIHJldHVybiByZXBvcnRlci5lcnJvcignVW5rbm93biB0YWc6ICcgKyB0YWcpO1xuXG4gIGlmIChyZXMgPj0gMHgxZilcbiAgICByZXR1cm4gcmVwb3J0ZXIuZXJyb3IoJ011bHRpLW9jdGV0IHRhZyBlbmNvZGluZyB1bnN1cHBvcnRlZCcpO1xuXG4gIGlmICghcHJpbWl0aXZlKVxuICAgIHJlcyB8PSAweDIwO1xuXG4gIHJlcyB8PSAoZGVyLnRhZ0NsYXNzQnlOYW1lW2NscyB8fCAndW5pdmVyc2FsJ10gPDwgNik7XG5cbiAgcmV0dXJuIHJlcztcbn1cbiIsInZhciBlbmNvZGVycyA9IGV4cG9ydHM7XG5cbmVuY29kZXJzLmRlciA9IHJlcXVpcmUoJy4vZGVyJyk7XG5lbmNvZGVycy5wZW0gPSByZXF1aXJlKCcuL3BlbScpO1xuIiwidmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxudmFyIERFUkVuY29kZXIgPSByZXF1aXJlKCcuL2RlcicpO1xuXG5mdW5jdGlvbiBQRU1FbmNvZGVyKGVudGl0eSkge1xuICBERVJFbmNvZGVyLmNhbGwodGhpcywgZW50aXR5KTtcbiAgdGhpcy5lbmMgPSAncGVtJztcbn07XG5pbmhlcml0cyhQRU1FbmNvZGVyLCBERVJFbmNvZGVyKTtcbm1vZHVsZS5leHBvcnRzID0gUEVNRW5jb2RlcjtcblxuUEVNRW5jb2Rlci5wcm90b3R5cGUuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKGRhdGEsIG9wdGlvbnMpIHtcbiAgdmFyIGJ1ZiA9IERFUkVuY29kZXIucHJvdG90eXBlLmVuY29kZS5jYWxsKHRoaXMsIGRhdGEpO1xuXG4gIHZhciBwID0gYnVmLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgdmFyIG91dCA9IFsgJy0tLS0tQkVHSU4gJyArIG9wdGlvbnMubGFiZWwgKyAnLS0tLS0nIF07XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkgKz0gNjQpXG4gICAgb3V0LnB1c2gocC5zbGljZShpLCBpICsgNjQpKTtcbiAgb3V0LnB1c2goJy0tLS0tRU5EICcgKyBvcHRpb25zLmxhYmVsICsgJy0tLS0tJyk7XG4gIHJldHVybiBvdXQuam9pbignXFxuJyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnXG5cbmV4cG9ydHMuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcbmV4cG9ydHMudG9CeXRlQXJyYXkgPSB0b0J5dGVBcnJheVxuZXhwb3J0cy5mcm9tQnl0ZUFycmF5ID0gZnJvbUJ5dGVBcnJheVxuXG52YXIgbG9va3VwID0gW11cbnZhciByZXZMb29rdXAgPSBbXVxudmFyIEFyciA9IHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJyA/IFVpbnQ4QXJyYXkgOiBBcnJheVxuXG52YXIgY29kZSA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJ1xuZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNvZGUubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgbG9va3VwW2ldID0gY29kZVtpXVxuICByZXZMb29rdXBbY29kZS5jaGFyQ29kZUF0KGkpXSA9IGlcbn1cblxuLy8gU3VwcG9ydCBkZWNvZGluZyBVUkwtc2FmZSBiYXNlNjQgc3RyaW5ncywgYXMgTm9kZS5qcyBkb2VzLlxuLy8gU2VlOiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9CYXNlNjQjVVJMX2FwcGxpY2F0aW9uc1xucmV2TG9va3VwWyctJy5jaGFyQ29kZUF0KDApXSA9IDYyXG5yZXZMb29rdXBbJ18nLmNoYXJDb2RlQXQoMCldID0gNjNcblxuZnVuY3Rpb24gZ2V0TGVucyAoYjY0KSB7XG4gIHZhciBsZW4gPSBiNjQubGVuZ3RoXG5cbiAgaWYgKGxlbiAlIDQgPiAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN0cmluZy4gTGVuZ3RoIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA0JylcbiAgfVxuXG4gIC8vIFRyaW0gb2ZmIGV4dHJhIGJ5dGVzIGFmdGVyIHBsYWNlaG9sZGVyIGJ5dGVzIGFyZSBmb3VuZFxuICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9iZWF0Z2FtbWl0L2Jhc2U2NC1qcy9pc3N1ZXMvNDJcbiAgdmFyIHZhbGlkTGVuID0gYjY0LmluZGV4T2YoJz0nKVxuICBpZiAodmFsaWRMZW4gPT09IC0xKSB2YWxpZExlbiA9IGxlblxuXG4gIHZhciBwbGFjZUhvbGRlcnNMZW4gPSB2YWxpZExlbiA9PT0gbGVuXG4gICAgPyAwXG4gICAgOiA0IC0gKHZhbGlkTGVuICUgNClcblxuICByZXR1cm4gW3ZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW5dXG59XG5cbi8vIGJhc2U2NCBpcyA0LzMgKyB1cCB0byB0d28gY2hhcmFjdGVycyBvZiB0aGUgb3JpZ2luYWwgZGF0YVxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoYjY0KSB7XG4gIHZhciBsZW5zID0gZ2V0TGVucyhiNjQpXG4gIHZhciB2YWxpZExlbiA9IGxlbnNbMF1cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IGxlbnNbMV1cbiAgcmV0dXJuICgodmFsaWRMZW4gKyBwbGFjZUhvbGRlcnNMZW4pICogMyAvIDQpIC0gcGxhY2VIb2xkZXJzTGVuXG59XG5cbmZ1bmN0aW9uIF9ieXRlTGVuZ3RoIChiNjQsIHZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW4pIHtcbiAgcmV0dXJuICgodmFsaWRMZW4gKyBwbGFjZUhvbGRlcnNMZW4pICogMyAvIDQpIC0gcGxhY2VIb2xkZXJzTGVuXG59XG5cbmZ1bmN0aW9uIHRvQnl0ZUFycmF5IChiNjQpIHtcbiAgdmFyIHRtcFxuICB2YXIgbGVucyA9IGdldExlbnMoYjY0KVxuICB2YXIgdmFsaWRMZW4gPSBsZW5zWzBdXG4gIHZhciBwbGFjZUhvbGRlcnNMZW4gPSBsZW5zWzFdXG5cbiAgdmFyIGFyciA9IG5ldyBBcnIoX2J5dGVMZW5ndGgoYjY0LCB2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuKSlcblxuICB2YXIgY3VyQnl0ZSA9IDBcblxuICAvLyBpZiB0aGVyZSBhcmUgcGxhY2Vob2xkZXJzLCBvbmx5IGdldCB1cCB0byB0aGUgbGFzdCBjb21wbGV0ZSA0IGNoYXJzXG4gIHZhciBsZW4gPSBwbGFjZUhvbGRlcnNMZW4gPiAwXG4gICAgPyB2YWxpZExlbiAtIDRcbiAgICA6IHZhbGlkTGVuXG5cbiAgdmFyIGlcbiAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDE4KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPDwgMTIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA8PCA2KSB8XG4gICAgICByZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDMpXVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiAxNikgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDgpICYgMHhGRlxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMikge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAyKSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPj4gNClcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIGlmIChwbGFjZUhvbGRlcnNMZW4gPT09IDEpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTApIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCA0KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAyKV0gPj4gMilcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICByZXR1cm4gYXJyXG59XG5cbmZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NCAobnVtKSB7XG4gIHJldHVybiBsb29rdXBbbnVtID4+IDE4ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gPj4gMTIgJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiA2ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gJiAweDNGXVxufVxuXG5mdW5jdGlvbiBlbmNvZGVDaHVuayAodWludDgsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHRtcFxuICB2YXIgb3V0cHV0ID0gW11cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpICs9IDMpIHtcbiAgICB0bXAgPVxuICAgICAgKCh1aW50OFtpXSA8PCAxNikgJiAweEZGMDAwMCkgK1xuICAgICAgKCh1aW50OFtpICsgMV0gPDwgOCkgJiAweEZGMDApICtcbiAgICAgICh1aW50OFtpICsgMl0gJiAweEZGKVxuICAgIG91dHB1dC5wdXNoKHRyaXBsZXRUb0Jhc2U2NCh0bXApKVxuICB9XG4gIHJldHVybiBvdXRwdXQuam9pbignJylcbn1cblxuZnVuY3Rpb24gZnJvbUJ5dGVBcnJheSAodWludDgpIHtcbiAgdmFyIHRtcFxuICB2YXIgbGVuID0gdWludDgubGVuZ3RoXG4gIHZhciBleHRyYUJ5dGVzID0gbGVuICUgMyAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuICB2YXIgcGFydHMgPSBbXVxuICB2YXIgbWF4Q2h1bmtMZW5ndGggPSAxNjM4MyAvLyBtdXN0IGJlIG11bHRpcGxlIG9mIDNcblxuICAvLyBnbyB0aHJvdWdoIHRoZSBhcnJheSBldmVyeSB0aHJlZSBieXRlcywgd2UnbGwgZGVhbCB3aXRoIHRyYWlsaW5nIHN0dWZmIGxhdGVyXG4gIGZvciAodmFyIGkgPSAwLCBsZW4yID0gbGVuIC0gZXh0cmFCeXRlczsgaSA8IGxlbjI7IGkgKz0gbWF4Q2h1bmtMZW5ndGgpIHtcbiAgICBwYXJ0cy5wdXNoKGVuY29kZUNodW5rKFxuICAgICAgdWludDgsIGksIChpICsgbWF4Q2h1bmtMZW5ndGgpID4gbGVuMiA/IGxlbjIgOiAoaSArIG1heENodW5rTGVuZ3RoKVxuICAgICkpXG4gIH1cblxuICAvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG4gIGlmIChleHRyYUJ5dGVzID09PSAxKSB7XG4gICAgdG1wID0gdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAyXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCA0KSAmIDB4M0ZdICtcbiAgICAgICc9PSdcbiAgICApXG4gIH0gZWxzZSBpZiAoZXh0cmFCeXRlcyA9PT0gMikge1xuICAgIHRtcCA9ICh1aW50OFtsZW4gLSAyXSA8PCA4KSArIHVpbnQ4W2xlbiAtIDFdXG4gICAgcGFydHMucHVzaChcbiAgICAgIGxvb2t1cFt0bXAgPj4gMTBdICtcbiAgICAgIGxvb2t1cFsodG1wID4+IDQpICYgMHgzRl0gK1xuICAgICAgbG9va3VwWyh0bXAgPDwgMikgJiAweDNGXSArXG4gICAgICAnPSdcbiAgICApXG4gIH1cblxuICByZXR1cm4gcGFydHMuam9pbignJylcbn1cbiIsIihmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvLyBVdGlsc1xuICBmdW5jdGlvbiBhc3NlcnQgKHZhbCwgbXNnKSB7XG4gICAgaWYgKCF2YWwpIHRocm93IG5ldyBFcnJvcihtc2cgfHwgJ0Fzc2VydGlvbiBmYWlsZWQnKTtcbiAgfVxuXG4gIC8vIENvdWxkIHVzZSBgaW5oZXJpdHNgIG1vZHVsZSwgYnV0IGRvbid0IHdhbnQgdG8gbW92ZSBmcm9tIHNpbmdsZSBmaWxlXG4gIC8vIGFyY2hpdGVjdHVyZSB5ZXQuXG4gIGZ1bmN0aW9uIGluaGVyaXRzIChjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvcjtcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlO1xuICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKCk7XG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yO1xuICB9XG5cbiAgLy8gQk5cblxuICBmdW5jdGlvbiBCTiAobnVtYmVyLCBiYXNlLCBlbmRpYW4pIHtcbiAgICBpZiAoQk4uaXNCTihudW1iZXIpKSB7XG4gICAgICByZXR1cm4gbnVtYmVyO1xuICAgIH1cblxuICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgIHRoaXMud29yZHMgPSBudWxsO1xuICAgIHRoaXMubGVuZ3RoID0gMDtcblxuICAgIC8vIFJlZHVjdGlvbiBjb250ZXh0XG4gICAgdGhpcy5yZWQgPSBudWxsO1xuXG4gICAgaWYgKG51bWJlciAhPT0gbnVsbCkge1xuICAgICAgaWYgKGJhc2UgPT09ICdsZScgfHwgYmFzZSA9PT0gJ2JlJykge1xuICAgICAgICBlbmRpYW4gPSBiYXNlO1xuICAgICAgICBiYXNlID0gMTA7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2luaXQobnVtYmVyIHx8IDAsIGJhc2UgfHwgMTAsIGVuZGlhbiB8fCAnYmUnKTtcbiAgICB9XG4gIH1cbiAgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBCTjtcbiAgfSBlbHNlIHtcbiAgICBleHBvcnRzLkJOID0gQk47XG4gIH1cblxuICBCTi5CTiA9IEJOO1xuICBCTi53b3JkU2l6ZSA9IDI2O1xuXG4gIHZhciBCdWZmZXI7XG4gIHRyeSB7XG4gICAgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuICB9IGNhdGNoIChlKSB7XG4gIH1cblxuICBCTi5pc0JOID0gZnVuY3Rpb24gaXNCTiAobnVtKSB7XG4gICAgaWYgKG51bSBpbnN0YW5jZW9mIEJOKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gbnVtICE9PSBudWxsICYmIHR5cGVvZiBudW0gPT09ICdvYmplY3QnICYmXG4gICAgICBudW0uY29uc3RydWN0b3Iud29yZFNpemUgPT09IEJOLndvcmRTaXplICYmIEFycmF5LmlzQXJyYXkobnVtLndvcmRzKTtcbiAgfTtcblxuICBCTi5tYXggPSBmdW5jdGlvbiBtYXggKGxlZnQsIHJpZ2h0KSB7XG4gICAgaWYgKGxlZnQuY21wKHJpZ2h0KSA+IDApIHJldHVybiBsZWZ0O1xuICAgIHJldHVybiByaWdodDtcbiAgfTtcblxuICBCTi5taW4gPSBmdW5jdGlvbiBtaW4gKGxlZnQsIHJpZ2h0KSB7XG4gICAgaWYgKGxlZnQuY21wKHJpZ2h0KSA8IDApIHJldHVybiBsZWZ0O1xuICAgIHJldHVybiByaWdodDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiBpbml0IChudW1iZXIsIGJhc2UsIGVuZGlhbikge1xuICAgIGlmICh0eXBlb2YgbnVtYmVyID09PSAnbnVtYmVyJykge1xuICAgICAgcmV0dXJuIHRoaXMuX2luaXROdW1iZXIobnVtYmVyLCBiYXNlLCBlbmRpYW4pO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgbnVtYmVyID09PSAnb2JqZWN0Jykge1xuICAgICAgcmV0dXJuIHRoaXMuX2luaXRBcnJheShudW1iZXIsIGJhc2UsIGVuZGlhbik7XG4gICAgfVxuXG4gICAgaWYgKGJhc2UgPT09ICdoZXgnKSB7XG4gICAgICBiYXNlID0gMTY7XG4gICAgfVxuICAgIGFzc2VydChiYXNlID09PSAoYmFzZSB8IDApICYmIGJhc2UgPj0gMiAmJiBiYXNlIDw9IDM2KTtcblxuICAgIG51bWJlciA9IG51bWJlci50b1N0cmluZygpLnJlcGxhY2UoL1xccysvZywgJycpO1xuICAgIHZhciBzdGFydCA9IDA7XG4gICAgaWYgKG51bWJlclswXSA9PT0gJy0nKSB7XG4gICAgICBzdGFydCsrO1xuICAgIH1cblxuICAgIGlmIChiYXNlID09PSAxNikge1xuICAgICAgdGhpcy5fcGFyc2VIZXgobnVtYmVyLCBzdGFydCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3BhcnNlQmFzZShudW1iZXIsIGJhc2UsIHN0YXJ0KTtcbiAgICB9XG5cbiAgICBpZiAobnVtYmVyWzBdID09PSAnLScpIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAxO1xuICAgIH1cblxuICAgIHRoaXMuc3RyaXAoKTtcblxuICAgIGlmIChlbmRpYW4gIT09ICdsZScpIHJldHVybjtcblxuICAgIHRoaXMuX2luaXRBcnJheSh0aGlzLnRvQXJyYXkoKSwgYmFzZSwgZW5kaWFuKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuX2luaXROdW1iZXIgPSBmdW5jdGlvbiBfaW5pdE51bWJlciAobnVtYmVyLCBiYXNlLCBlbmRpYW4pIHtcbiAgICBpZiAobnVtYmVyIDwgMCkge1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDE7XG4gICAgICBudW1iZXIgPSAtbnVtYmVyO1xuICAgIH1cbiAgICBpZiAobnVtYmVyIDwgMHg0MDAwMDAwKSB7XG4gICAgICB0aGlzLndvcmRzID0gWyBudW1iZXIgJiAweDNmZmZmZmYgXTtcbiAgICAgIHRoaXMubGVuZ3RoID0gMTtcbiAgICB9IGVsc2UgaWYgKG51bWJlciA8IDB4MTAwMDAwMDAwMDAwMDApIHtcbiAgICAgIHRoaXMud29yZHMgPSBbXG4gICAgICAgIG51bWJlciAmIDB4M2ZmZmZmZixcbiAgICAgICAgKG51bWJlciAvIDB4NDAwMDAwMCkgJiAweDNmZmZmZmZcbiAgICAgIF07XG4gICAgICB0aGlzLmxlbmd0aCA9IDI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFzc2VydChudW1iZXIgPCAweDIwMDAwMDAwMDAwMDAwKTsgLy8gMiBeIDUzICh1bnNhZmUpXG4gICAgICB0aGlzLndvcmRzID0gW1xuICAgICAgICBudW1iZXIgJiAweDNmZmZmZmYsXG4gICAgICAgIChudW1iZXIgLyAweDQwMDAwMDApICYgMHgzZmZmZmZmLFxuICAgICAgICAxXG4gICAgICBdO1xuICAgICAgdGhpcy5sZW5ndGggPSAzO1xuICAgIH1cblxuICAgIGlmIChlbmRpYW4gIT09ICdsZScpIHJldHVybjtcblxuICAgIC8vIFJldmVyc2UgdGhlIGJ5dGVzXG4gICAgdGhpcy5faW5pdEFycmF5KHRoaXMudG9BcnJheSgpLCBiYXNlLCBlbmRpYW4pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5faW5pdEFycmF5ID0gZnVuY3Rpb24gX2luaXRBcnJheSAobnVtYmVyLCBiYXNlLCBlbmRpYW4pIHtcbiAgICAvLyBQZXJoYXBzIGEgVWludDhBcnJheVxuICAgIGFzc2VydCh0eXBlb2YgbnVtYmVyLmxlbmd0aCA9PT0gJ251bWJlcicpO1xuICAgIGlmIChudW1iZXIubGVuZ3RoIDw9IDApIHtcbiAgICAgIHRoaXMud29yZHMgPSBbIDAgXTtcbiAgICAgIHRoaXMubGVuZ3RoID0gMTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHRoaXMubGVuZ3RoID0gTWF0aC5jZWlsKG51bWJlci5sZW5ndGggLyAzKTtcbiAgICB0aGlzLndvcmRzID0gbmV3IEFycmF5KHRoaXMubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMud29yZHNbaV0gPSAwO1xuICAgIH1cblxuICAgIHZhciBqLCB3O1xuICAgIHZhciBvZmYgPSAwO1xuICAgIGlmIChlbmRpYW4gPT09ICdiZScpIHtcbiAgICAgIGZvciAoaSA9IG51bWJlci5sZW5ndGggLSAxLCBqID0gMDsgaSA+PSAwOyBpIC09IDMpIHtcbiAgICAgICAgdyA9IG51bWJlcltpXSB8IChudW1iZXJbaSAtIDFdIDw8IDgpIHwgKG51bWJlcltpIC0gMl0gPDwgMTYpO1xuICAgICAgICB0aGlzLndvcmRzW2pdIHw9ICh3IDw8IG9mZikgJiAweDNmZmZmZmY7XG4gICAgICAgIHRoaXMud29yZHNbaiArIDFdID0gKHcgPj4+ICgyNiAtIG9mZikpICYgMHgzZmZmZmZmO1xuICAgICAgICBvZmYgKz0gMjQ7XG4gICAgICAgIGlmIChvZmYgPj0gMjYpIHtcbiAgICAgICAgICBvZmYgLT0gMjY7XG4gICAgICAgICAgaisrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChlbmRpYW4gPT09ICdsZScpIHtcbiAgICAgIGZvciAoaSA9IDAsIGogPSAwOyBpIDwgbnVtYmVyLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgICAgIHcgPSBudW1iZXJbaV0gfCAobnVtYmVyW2kgKyAxXSA8PCA4KSB8IChudW1iZXJbaSArIDJdIDw8IDE2KTtcbiAgICAgICAgdGhpcy53b3Jkc1tqXSB8PSAodyA8PCBvZmYpICYgMHgzZmZmZmZmO1xuICAgICAgICB0aGlzLndvcmRzW2ogKyAxXSA9ICh3ID4+PiAoMjYgLSBvZmYpKSAmIDB4M2ZmZmZmZjtcbiAgICAgICAgb2ZmICs9IDI0O1xuICAgICAgICBpZiAob2ZmID49IDI2KSB7XG4gICAgICAgICAgb2ZmIC09IDI2O1xuICAgICAgICAgIGorKztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHBhcnNlSGV4IChzdHIsIHN0YXJ0LCBlbmQpIHtcbiAgICB2YXIgciA9IDA7XG4gICAgdmFyIGxlbiA9IE1hdGgubWluKHN0ci5sZW5ndGgsIGVuZCk7XG4gICAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIHZhciBjID0gc3RyLmNoYXJDb2RlQXQoaSkgLSA0ODtcblxuICAgICAgciA8PD0gNDtcblxuICAgICAgLy8gJ2EnIC0gJ2YnXG4gICAgICBpZiAoYyA+PSA0OSAmJiBjIDw9IDU0KSB7XG4gICAgICAgIHIgfD0gYyAtIDQ5ICsgMHhhO1xuXG4gICAgICAvLyAnQScgLSAnRidcbiAgICAgIH0gZWxzZSBpZiAoYyA+PSAxNyAmJiBjIDw9IDIyKSB7XG4gICAgICAgIHIgfD0gYyAtIDE3ICsgMHhhO1xuXG4gICAgICAvLyAnMCcgLSAnOSdcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHIgfD0gYyAmIDB4ZjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHI7XG4gIH1cblxuICBCTi5wcm90b3R5cGUuX3BhcnNlSGV4ID0gZnVuY3Rpb24gX3BhcnNlSGV4IChudW1iZXIsIHN0YXJ0KSB7XG4gICAgLy8gQ3JlYXRlIHBvc3NpYmx5IGJpZ2dlciBhcnJheSB0byBlbnN1cmUgdGhhdCBpdCBmaXRzIHRoZSBudW1iZXJcbiAgICB0aGlzLmxlbmd0aCA9IE1hdGguY2VpbCgobnVtYmVyLmxlbmd0aCAtIHN0YXJ0KSAvIDYpO1xuICAgIHRoaXMud29yZHMgPSBuZXcgQXJyYXkodGhpcy5sZW5ndGgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IDA7XG4gICAgfVxuXG4gICAgdmFyIGosIHc7XG4gICAgLy8gU2NhbiAyNC1iaXQgY2h1bmtzIGFuZCBhZGQgdGhlbSB0byB0aGUgbnVtYmVyXG4gICAgdmFyIG9mZiA9IDA7XG4gICAgZm9yIChpID0gbnVtYmVyLmxlbmd0aCAtIDYsIGogPSAwOyBpID49IHN0YXJ0OyBpIC09IDYpIHtcbiAgICAgIHcgPSBwYXJzZUhleChudW1iZXIsIGksIGkgKyA2KTtcbiAgICAgIHRoaXMud29yZHNbal0gfD0gKHcgPDwgb2ZmKSAmIDB4M2ZmZmZmZjtcbiAgICAgIC8vIE5PVEU6IGAweDNmZmZmZmAgaXMgaW50ZW50aW9uYWwgaGVyZSwgMjZiaXRzIG1heCBzaGlmdCArIDI0Yml0IGhleCBsaW1iXG4gICAgICB0aGlzLndvcmRzW2ogKyAxXSB8PSB3ID4+PiAoMjYgLSBvZmYpICYgMHgzZmZmZmY7XG4gICAgICBvZmYgKz0gMjQ7XG4gICAgICBpZiAob2ZmID49IDI2KSB7XG4gICAgICAgIG9mZiAtPSAyNjtcbiAgICAgICAgaisrO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaSArIDYgIT09IHN0YXJ0KSB7XG4gICAgICB3ID0gcGFyc2VIZXgobnVtYmVyLCBzdGFydCwgaSArIDYpO1xuICAgICAgdGhpcy53b3Jkc1tqXSB8PSAodyA8PCBvZmYpICYgMHgzZmZmZmZmO1xuICAgICAgdGhpcy53b3Jkc1tqICsgMV0gfD0gdyA+Pj4gKDI2IC0gb2ZmKSAmIDB4M2ZmZmZmO1xuICAgIH1cbiAgICB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgZnVuY3Rpb24gcGFyc2VCYXNlIChzdHIsIHN0YXJ0LCBlbmQsIG11bCkge1xuICAgIHZhciByID0gMDtcbiAgICB2YXIgbGVuID0gTWF0aC5taW4oc3RyLmxlbmd0aCwgZW5kKTtcbiAgICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBsZW47IGkrKykge1xuICAgICAgdmFyIGMgPSBzdHIuY2hhckNvZGVBdChpKSAtIDQ4O1xuXG4gICAgICByICo9IG11bDtcblxuICAgICAgLy8gJ2EnXG4gICAgICBpZiAoYyA+PSA0OSkge1xuICAgICAgICByICs9IGMgLSA0OSArIDB4YTtcblxuICAgICAgLy8gJ0EnXG4gICAgICB9IGVsc2UgaWYgKGMgPj0gMTcpIHtcbiAgICAgICAgciArPSBjIC0gMTcgKyAweGE7XG5cbiAgICAgIC8vICcwJyAtICc5J1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgciArPSBjO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcjtcbiAgfVxuXG4gIEJOLnByb3RvdHlwZS5fcGFyc2VCYXNlID0gZnVuY3Rpb24gX3BhcnNlQmFzZSAobnVtYmVyLCBiYXNlLCBzdGFydCkge1xuICAgIC8vIEluaXRpYWxpemUgYXMgemVyb1xuICAgIHRoaXMud29yZHMgPSBbIDAgXTtcbiAgICB0aGlzLmxlbmd0aCA9IDE7XG5cbiAgICAvLyBGaW5kIGxlbmd0aCBvZiBsaW1iIGluIGJhc2VcbiAgICBmb3IgKHZhciBsaW1iTGVuID0gMCwgbGltYlBvdyA9IDE7IGxpbWJQb3cgPD0gMHgzZmZmZmZmOyBsaW1iUG93ICo9IGJhc2UpIHtcbiAgICAgIGxpbWJMZW4rKztcbiAgICB9XG4gICAgbGltYkxlbi0tO1xuICAgIGxpbWJQb3cgPSAobGltYlBvdyAvIGJhc2UpIHwgMDtcblxuICAgIHZhciB0b3RhbCA9IG51bWJlci5sZW5ndGggLSBzdGFydDtcbiAgICB2YXIgbW9kID0gdG90YWwgJSBsaW1iTGVuO1xuICAgIHZhciBlbmQgPSBNYXRoLm1pbih0b3RhbCwgdG90YWwgLSBtb2QpICsgc3RhcnQ7XG5cbiAgICB2YXIgd29yZCA9IDA7XG4gICAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpICs9IGxpbWJMZW4pIHtcbiAgICAgIHdvcmQgPSBwYXJzZUJhc2UobnVtYmVyLCBpLCBpICsgbGltYkxlbiwgYmFzZSk7XG5cbiAgICAgIHRoaXMuaW11bG4obGltYlBvdyk7XG4gICAgICBpZiAodGhpcy53b3Jkc1swXSArIHdvcmQgPCAweDQwMDAwMDApIHtcbiAgICAgICAgdGhpcy53b3Jkc1swXSArPSB3b3JkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5faWFkZG4od29yZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG1vZCAhPT0gMCkge1xuICAgICAgdmFyIHBvdyA9IDE7XG4gICAgICB3b3JkID0gcGFyc2VCYXNlKG51bWJlciwgaSwgbnVtYmVyLmxlbmd0aCwgYmFzZSk7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBtb2Q7IGkrKykge1xuICAgICAgICBwb3cgKj0gYmFzZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5pbXVsbihwb3cpO1xuICAgICAgaWYgKHRoaXMud29yZHNbMF0gKyB3b3JkIDwgMHg0MDAwMDAwKSB7XG4gICAgICAgIHRoaXMud29yZHNbMF0gKz0gd29yZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2lhZGRuKHdvcmQpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBCTi5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uIGNvcHkgKGRlc3QpIHtcbiAgICBkZXN0LndvcmRzID0gbmV3IEFycmF5KHRoaXMubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGRlc3Qud29yZHNbaV0gPSB0aGlzLndvcmRzW2ldO1xuICAgIH1cbiAgICBkZXN0Lmxlbmd0aCA9IHRoaXMubGVuZ3RoO1xuICAgIGRlc3QubmVnYXRpdmUgPSB0aGlzLm5lZ2F0aXZlO1xuICAgIGRlc3QucmVkID0gdGhpcy5yZWQ7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gY2xvbmUgKCkge1xuICAgIHZhciByID0gbmV3IEJOKG51bGwpO1xuICAgIHRoaXMuY29weShyKTtcbiAgICByZXR1cm4gcjtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuX2V4cGFuZCA9IGZ1bmN0aW9uIF9leHBhbmQgKHNpemUpIHtcbiAgICB3aGlsZSAodGhpcy5sZW5ndGggPCBzaXplKSB7XG4gICAgICB0aGlzLndvcmRzW3RoaXMubGVuZ3RoKytdID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgLy8gUmVtb3ZlIGxlYWRpbmcgYDBgIGZyb20gYHRoaXNgXG4gIEJOLnByb3RvdHlwZS5zdHJpcCA9IGZ1bmN0aW9uIHN0cmlwICgpIHtcbiAgICB3aGlsZSAodGhpcy5sZW5ndGggPiAxICYmIHRoaXMud29yZHNbdGhpcy5sZW5ndGggLSAxXSA9PT0gMCkge1xuICAgICAgdGhpcy5sZW5ndGgtLTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX25vcm1TaWduKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLl9ub3JtU2lnbiA9IGZ1bmN0aW9uIF9ub3JtU2lnbiAoKSB7XG4gICAgLy8gLTAgPSAwXG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAxICYmIHRoaXMud29yZHNbMF0gPT09IDApIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QgKCkge1xuICAgIHJldHVybiAodGhpcy5yZWQgPyAnPEJOLVI6ICcgOiAnPEJOOiAnKSArIHRoaXMudG9TdHJpbmcoMTYpICsgJz4nO1xuICB9O1xuXG4gIC8qXG5cbiAgdmFyIHplcm9zID0gW107XG4gIHZhciBncm91cFNpemVzID0gW107XG4gIHZhciBncm91cEJhc2VzID0gW107XG5cbiAgdmFyIHMgPSAnJztcbiAgdmFyIGkgPSAtMTtcbiAgd2hpbGUgKCsraSA8IEJOLndvcmRTaXplKSB7XG4gICAgemVyb3NbaV0gPSBzO1xuICAgIHMgKz0gJzAnO1xuICB9XG4gIGdyb3VwU2l6ZXNbMF0gPSAwO1xuICBncm91cFNpemVzWzFdID0gMDtcbiAgZ3JvdXBCYXNlc1swXSA9IDA7XG4gIGdyb3VwQmFzZXNbMV0gPSAwO1xuICB2YXIgYmFzZSA9IDIgLSAxO1xuICB3aGlsZSAoKytiYXNlIDwgMzYgKyAxKSB7XG4gICAgdmFyIGdyb3VwU2l6ZSA9IDA7XG4gICAgdmFyIGdyb3VwQmFzZSA9IDE7XG4gICAgd2hpbGUgKGdyb3VwQmFzZSA8ICgxIDw8IEJOLndvcmRTaXplKSAvIGJhc2UpIHtcbiAgICAgIGdyb3VwQmFzZSAqPSBiYXNlO1xuICAgICAgZ3JvdXBTaXplICs9IDE7XG4gICAgfVxuICAgIGdyb3VwU2l6ZXNbYmFzZV0gPSBncm91cFNpemU7XG4gICAgZ3JvdXBCYXNlc1tiYXNlXSA9IGdyb3VwQmFzZTtcbiAgfVxuXG4gICovXG5cbiAgdmFyIHplcm9zID0gW1xuICAgICcnLFxuICAgICcwJyxcbiAgICAnMDAnLFxuICAgICcwMDAnLFxuICAgICcwMDAwJyxcbiAgICAnMDAwMDAnLFxuICAgICcwMDAwMDAnLFxuICAgICcwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJ1xuICBdO1xuXG4gIHZhciBncm91cFNpemVzID0gW1xuICAgIDAsIDAsXG4gICAgMjUsIDE2LCAxMiwgMTEsIDEwLCA5LCA4LFxuICAgIDgsIDcsIDcsIDcsIDcsIDYsIDYsXG4gICAgNiwgNiwgNiwgNiwgNiwgNSwgNSxcbiAgICA1LCA1LCA1LCA1LCA1LCA1LCA1LFxuICAgIDUsIDUsIDUsIDUsIDUsIDUsIDVcbiAgXTtcblxuICB2YXIgZ3JvdXBCYXNlcyA9IFtcbiAgICAwLCAwLFxuICAgIDMzNTU0NDMyLCA0MzA0NjcyMSwgMTY3NzcyMTYsIDQ4ODI4MTI1LCA2MDQ2NjE3NiwgNDAzNTM2MDcsIDE2Nzc3MjE2LFxuICAgIDQzMDQ2NzIxLCAxMDAwMDAwMCwgMTk0ODcxNzEsIDM1ODMxODA4LCA2Mjc0ODUxNywgNzUyOTUzNiwgMTEzOTA2MjUsXG4gICAgMTY3NzcyMTYsIDI0MTM3NTY5LCAzNDAxMjIyNCwgNDcwNDU4ODEsIDY0MDAwMDAwLCA0MDg0MTAxLCA1MTUzNjMyLFxuICAgIDY0MzYzNDMsIDc5NjI2MjQsIDk3NjU2MjUsIDExODgxMzc2LCAxNDM0ODkwNywgMTcyMTAzNjgsIDIwNTExMTQ5LFxuICAgIDI0MzAwMDAwLCAyODYyOTE1MSwgMzM1NTQ0MzIsIDM5MTM1MzkzLCA0NTQzNTQyNCwgNTI1MjE4NzUsIDYwNDY2MTc2XG4gIF07XG5cbiAgQk4ucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcgKGJhc2UsIHBhZGRpbmcpIHtcbiAgICBiYXNlID0gYmFzZSB8fCAxMDtcbiAgICBwYWRkaW5nID0gcGFkZGluZyB8IDAgfHwgMTtcblxuICAgIHZhciBvdXQ7XG4gICAgaWYgKGJhc2UgPT09IDE2IHx8IGJhc2UgPT09ICdoZXgnKSB7XG4gICAgICBvdXQgPSAnJztcbiAgICAgIHZhciBvZmYgPSAwO1xuICAgICAgdmFyIGNhcnJ5ID0gMDtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgdyA9IHRoaXMud29yZHNbaV07XG4gICAgICAgIHZhciB3b3JkID0gKCgodyA8PCBvZmYpIHwgY2FycnkpICYgMHhmZmZmZmYpLnRvU3RyaW5nKDE2KTtcbiAgICAgICAgY2FycnkgPSAodyA+Pj4gKDI0IC0gb2ZmKSkgJiAweGZmZmZmZjtcbiAgICAgICAgaWYgKGNhcnJ5ICE9PSAwIHx8IGkgIT09IHRoaXMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgIG91dCA9IHplcm9zWzYgLSB3b3JkLmxlbmd0aF0gKyB3b3JkICsgb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG91dCA9IHdvcmQgKyBvdXQ7XG4gICAgICAgIH1cbiAgICAgICAgb2ZmICs9IDI7XG4gICAgICAgIGlmIChvZmYgPj0gMjYpIHtcbiAgICAgICAgICBvZmYgLT0gMjY7XG4gICAgICAgICAgaS0tO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoY2FycnkgIT09IDApIHtcbiAgICAgICAgb3V0ID0gY2FycnkudG9TdHJpbmcoMTYpICsgb3V0O1xuICAgICAgfVxuICAgICAgd2hpbGUgKG91dC5sZW5ndGggJSBwYWRkaW5nICE9PSAwKSB7XG4gICAgICAgIG91dCA9ICcwJyArIG91dDtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICAgIG91dCA9ICctJyArIG91dDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvdXQ7XG4gICAgfVxuXG4gICAgaWYgKGJhc2UgPT09IChiYXNlIHwgMCkgJiYgYmFzZSA+PSAyICYmIGJhc2UgPD0gMzYpIHtcbiAgICAgIC8vIHZhciBncm91cFNpemUgPSBNYXRoLmZsb29yKEJOLndvcmRTaXplICogTWF0aC5MTjIgLyBNYXRoLmxvZyhiYXNlKSk7XG4gICAgICB2YXIgZ3JvdXBTaXplID0gZ3JvdXBTaXplc1tiYXNlXTtcbiAgICAgIC8vIHZhciBncm91cEJhc2UgPSBNYXRoLnBvdyhiYXNlLCBncm91cFNpemUpO1xuICAgICAgdmFyIGdyb3VwQmFzZSA9IGdyb3VwQmFzZXNbYmFzZV07XG4gICAgICBvdXQgPSAnJztcbiAgICAgIHZhciBjID0gdGhpcy5jbG9uZSgpO1xuICAgICAgYy5uZWdhdGl2ZSA9IDA7XG4gICAgICB3aGlsZSAoIWMuaXNaZXJvKCkpIHtcbiAgICAgICAgdmFyIHIgPSBjLm1vZG4oZ3JvdXBCYXNlKS50b1N0cmluZyhiYXNlKTtcbiAgICAgICAgYyA9IGMuaWRpdm4oZ3JvdXBCYXNlKTtcblxuICAgICAgICBpZiAoIWMuaXNaZXJvKCkpIHtcbiAgICAgICAgICBvdXQgPSB6ZXJvc1tncm91cFNpemUgLSByLmxlbmd0aF0gKyByICsgb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG91dCA9IHIgKyBvdXQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmlzWmVybygpKSB7XG4gICAgICAgIG91dCA9ICcwJyArIG91dDtcbiAgICAgIH1cbiAgICAgIHdoaWxlIChvdXQubGVuZ3RoICUgcGFkZGluZyAhPT0gMCkge1xuICAgICAgICBvdXQgPSAnMCcgKyBvdXQ7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgICBvdXQgPSAnLScgKyBvdXQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gb3V0O1xuICAgIH1cblxuICAgIGFzc2VydChmYWxzZSwgJ0Jhc2Ugc2hvdWxkIGJlIGJldHdlZW4gMiBhbmQgMzYnKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUudG9OdW1iZXIgPSBmdW5jdGlvbiB0b051bWJlciAoKSB7XG4gICAgdmFyIHJldCA9IHRoaXMud29yZHNbMF07XG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAyKSB7XG4gICAgICByZXQgKz0gdGhpcy53b3Jkc1sxXSAqIDB4NDAwMDAwMDtcbiAgICB9IGVsc2UgaWYgKHRoaXMubGVuZ3RoID09PSAzICYmIHRoaXMud29yZHNbMl0gPT09IDB4MDEpIHtcbiAgICAgIC8vIE5PVEU6IGF0IHRoaXMgc3RhZ2UgaXQgaXMga25vd24gdGhhdCB0aGUgdG9wIGJpdCBpcyBzZXRcbiAgICAgIHJldCArPSAweDEwMDAwMDAwMDAwMDAwICsgKHRoaXMud29yZHNbMV0gKiAweDQwMDAwMDApO1xuICAgIH0gZWxzZSBpZiAodGhpcy5sZW5ndGggPiAyKSB7XG4gICAgICBhc3NlcnQoZmFsc2UsICdOdW1iZXIgY2FuIG9ubHkgc2FmZWx5IHN0b3JlIHVwIHRvIDUzIGJpdHMnKTtcbiAgICB9XG4gICAgcmV0dXJuICh0aGlzLm5lZ2F0aXZlICE9PSAwKSA/IC1yZXQgOiByZXQ7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG9TdHJpbmcoMTYpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS50b0J1ZmZlciA9IGZ1bmN0aW9uIHRvQnVmZmVyIChlbmRpYW4sIGxlbmd0aCkge1xuICAgIGFzc2VydCh0eXBlb2YgQnVmZmVyICE9PSAndW5kZWZpbmVkJyk7XG4gICAgcmV0dXJuIHRoaXMudG9BcnJheUxpa2UoQnVmZmVyLCBlbmRpYW4sIGxlbmd0aCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnRvQXJyYXkgPSBmdW5jdGlvbiB0b0FycmF5IChlbmRpYW4sIGxlbmd0aCkge1xuICAgIHJldHVybiB0aGlzLnRvQXJyYXlMaWtlKEFycmF5LCBlbmRpYW4sIGxlbmd0aCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnRvQXJyYXlMaWtlID0gZnVuY3Rpb24gdG9BcnJheUxpa2UgKEFycmF5VHlwZSwgZW5kaWFuLCBsZW5ndGgpIHtcbiAgICB2YXIgYnl0ZUxlbmd0aCA9IHRoaXMuYnl0ZUxlbmd0aCgpO1xuICAgIHZhciByZXFMZW5ndGggPSBsZW5ndGggfHwgTWF0aC5tYXgoMSwgYnl0ZUxlbmd0aCk7XG4gICAgYXNzZXJ0KGJ5dGVMZW5ndGggPD0gcmVxTGVuZ3RoLCAnYnl0ZSBhcnJheSBsb25nZXIgdGhhbiBkZXNpcmVkIGxlbmd0aCcpO1xuICAgIGFzc2VydChyZXFMZW5ndGggPiAwLCAnUmVxdWVzdGVkIGFycmF5IGxlbmd0aCA8PSAwJyk7XG5cbiAgICB0aGlzLnN0cmlwKCk7XG4gICAgdmFyIGxpdHRsZUVuZGlhbiA9IGVuZGlhbiA9PT0gJ2xlJztcbiAgICB2YXIgcmVzID0gbmV3IEFycmF5VHlwZShyZXFMZW5ndGgpO1xuXG4gICAgdmFyIGIsIGk7XG4gICAgdmFyIHEgPSB0aGlzLmNsb25lKCk7XG4gICAgaWYgKCFsaXR0bGVFbmRpYW4pIHtcbiAgICAgIC8vIEFzc3VtZSBiaWctZW5kaWFuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgcmVxTGVuZ3RoIC0gYnl0ZUxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJlc1tpXSA9IDA7XG4gICAgICB9XG5cbiAgICAgIGZvciAoaSA9IDA7ICFxLmlzWmVybygpOyBpKyspIHtcbiAgICAgICAgYiA9IHEuYW5kbG4oMHhmZik7XG4gICAgICAgIHEuaXVzaHJuKDgpO1xuXG4gICAgICAgIHJlc1tyZXFMZW5ndGggLSBpIC0gMV0gPSBiO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGkgPSAwOyAhcS5pc1plcm8oKTsgaSsrKSB7XG4gICAgICAgIGIgPSBxLmFuZGxuKDB4ZmYpO1xuICAgICAgICBxLml1c2hybig4KTtcblxuICAgICAgICByZXNbaV0gPSBiO1xuICAgICAgfVxuXG4gICAgICBmb3IgKDsgaSA8IHJlcUxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJlc1tpXSA9IDA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcztcbiAgfTtcblxuICBpZiAoTWF0aC5jbHozMikge1xuICAgIEJOLnByb3RvdHlwZS5fY291bnRCaXRzID0gZnVuY3Rpb24gX2NvdW50Qml0cyAodykge1xuICAgICAgcmV0dXJuIDMyIC0gTWF0aC5jbHozMih3KTtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIEJOLnByb3RvdHlwZS5fY291bnRCaXRzID0gZnVuY3Rpb24gX2NvdW50Qml0cyAodykge1xuICAgICAgdmFyIHQgPSB3O1xuICAgICAgdmFyIHIgPSAwO1xuICAgICAgaWYgKHQgPj0gMHgxMDAwKSB7XG4gICAgICAgIHIgKz0gMTM7XG4gICAgICAgIHQgPj4+PSAxMztcbiAgICAgIH1cbiAgICAgIGlmICh0ID49IDB4NDApIHtcbiAgICAgICAgciArPSA3O1xuICAgICAgICB0ID4+Pj0gNztcbiAgICAgIH1cbiAgICAgIGlmICh0ID49IDB4OCkge1xuICAgICAgICByICs9IDQ7XG4gICAgICAgIHQgPj4+PSA0O1xuICAgICAgfVxuICAgICAgaWYgKHQgPj0gMHgwMikge1xuICAgICAgICByICs9IDI7XG4gICAgICAgIHQgPj4+PSAyO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHIgKyB0O1xuICAgIH07XG4gIH1cblxuICBCTi5wcm90b3R5cGUuX3plcm9CaXRzID0gZnVuY3Rpb24gX3plcm9CaXRzICh3KSB7XG4gICAgLy8gU2hvcnQtY3V0XG4gICAgaWYgKHcgPT09IDApIHJldHVybiAyNjtcblxuICAgIHZhciB0ID0gdztcbiAgICB2YXIgciA9IDA7XG4gICAgaWYgKCh0ICYgMHgxZmZmKSA9PT0gMCkge1xuICAgICAgciArPSAxMztcbiAgICAgIHQgPj4+PSAxMztcbiAgICB9XG4gICAgaWYgKCh0ICYgMHg3ZikgPT09IDApIHtcbiAgICAgIHIgKz0gNztcbiAgICAgIHQgPj4+PSA3O1xuICAgIH1cbiAgICBpZiAoKHQgJiAweGYpID09PSAwKSB7XG4gICAgICByICs9IDQ7XG4gICAgICB0ID4+Pj0gNDtcbiAgICB9XG4gICAgaWYgKCh0ICYgMHgzKSA9PT0gMCkge1xuICAgICAgciArPSAyO1xuICAgICAgdCA+Pj49IDI7XG4gICAgfVxuICAgIGlmICgodCAmIDB4MSkgPT09IDApIHtcbiAgICAgIHIrKztcbiAgICB9XG4gICAgcmV0dXJuIHI7XG4gIH07XG5cbiAgLy8gUmV0dXJuIG51bWJlciBvZiB1c2VkIGJpdHMgaW4gYSBCTlxuICBCTi5wcm90b3R5cGUuYml0TGVuZ3RoID0gZnVuY3Rpb24gYml0TGVuZ3RoICgpIHtcbiAgICB2YXIgdyA9IHRoaXMud29yZHNbdGhpcy5sZW5ndGggLSAxXTtcbiAgICB2YXIgaGkgPSB0aGlzLl9jb3VudEJpdHModyk7XG4gICAgcmV0dXJuICh0aGlzLmxlbmd0aCAtIDEpICogMjYgKyBoaTtcbiAgfTtcblxuICBmdW5jdGlvbiB0b0JpdEFycmF5IChudW0pIHtcbiAgICB2YXIgdyA9IG5ldyBBcnJheShudW0uYml0TGVuZ3RoKCkpO1xuXG4gICAgZm9yICh2YXIgYml0ID0gMDsgYml0IDwgdy5sZW5ndGg7IGJpdCsrKSB7XG4gICAgICB2YXIgb2ZmID0gKGJpdCAvIDI2KSB8IDA7XG4gICAgICB2YXIgd2JpdCA9IGJpdCAlIDI2O1xuXG4gICAgICB3W2JpdF0gPSAobnVtLndvcmRzW29mZl0gJiAoMSA8PCB3Yml0KSkgPj4+IHdiaXQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHc7XG4gIH1cblxuICAvLyBOdW1iZXIgb2YgdHJhaWxpbmcgemVybyBiaXRzXG4gIEJOLnByb3RvdHlwZS56ZXJvQml0cyA9IGZ1bmN0aW9uIHplcm9CaXRzICgpIHtcbiAgICBpZiAodGhpcy5pc1plcm8oKSkgcmV0dXJuIDA7XG5cbiAgICB2YXIgciA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgYiA9IHRoaXMuX3plcm9CaXRzKHRoaXMud29yZHNbaV0pO1xuICAgICAgciArPSBiO1xuICAgICAgaWYgKGIgIT09IDI2KSBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIHI7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmJ5dGVMZW5ndGggPSBmdW5jdGlvbiBieXRlTGVuZ3RoICgpIHtcbiAgICByZXR1cm4gTWF0aC5jZWlsKHRoaXMuYml0TGVuZ3RoKCkgLyA4KTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUudG9Ud29zID0gZnVuY3Rpb24gdG9Ud29zICh3aWR0aCkge1xuICAgIGlmICh0aGlzLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICByZXR1cm4gdGhpcy5hYnMoKS5pbm90bih3aWR0aCkuaWFkZG4oMSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNsb25lKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmZyb21Ud29zID0gZnVuY3Rpb24gZnJvbVR3b3MgKHdpZHRoKSB7XG4gICAgaWYgKHRoaXMudGVzdG4od2lkdGggLSAxKSkge1xuICAgICAgcmV0dXJuIHRoaXMubm90bih3aWR0aCkuaWFkZG4oMSkuaW5lZygpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5pc05lZyA9IGZ1bmN0aW9uIGlzTmVnICgpIHtcbiAgICByZXR1cm4gdGhpcy5uZWdhdGl2ZSAhPT0gMDtcbiAgfTtcblxuICAvLyBSZXR1cm4gbmVnYXRpdmUgY2xvbmUgb2YgYHRoaXNgXG4gIEJOLnByb3RvdHlwZS5uZWcgPSBmdW5jdGlvbiBuZWcgKCkge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaW5lZygpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5pbmVnID0gZnVuY3Rpb24gaW5lZyAoKSB7XG4gICAgaWYgKCF0aGlzLmlzWmVybygpKSB7XG4gICAgICB0aGlzLm5lZ2F0aXZlIF49IDE7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgLy8gT3IgYG51bWAgd2l0aCBgdGhpc2AgaW4tcGxhY2VcbiAgQk4ucHJvdG90eXBlLml1b3IgPSBmdW5jdGlvbiBpdW9yIChudW0pIHtcbiAgICB3aGlsZSAodGhpcy5sZW5ndGggPCBudW0ubGVuZ3RoKSB7XG4gICAgICB0aGlzLndvcmRzW3RoaXMubGVuZ3RoKytdID0gMDtcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG51bS5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IHRoaXMud29yZHNbaV0gfCBudW0ud29yZHNbaV07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaW9yID0gZnVuY3Rpb24gaW9yIChudW0pIHtcbiAgICBhc3NlcnQoKHRoaXMubmVnYXRpdmUgfCBudW0ubmVnYXRpdmUpID09PSAwKTtcbiAgICByZXR1cm4gdGhpcy5pdW9yKG51bSk7XG4gIH07XG5cbiAgLy8gT3IgYG51bWAgd2l0aCBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLm9yID0gZnVuY3Rpb24gb3IgKG51bSkge1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHJldHVybiB0aGlzLmNsb25lKCkuaW9yKG51bSk7XG4gICAgcmV0dXJuIG51bS5jbG9uZSgpLmlvcih0aGlzKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUudW9yID0gZnVuY3Rpb24gdW9yIChudW0pIHtcbiAgICBpZiAodGhpcy5sZW5ndGggPiBudW0ubGVuZ3RoKSByZXR1cm4gdGhpcy5jbG9uZSgpLml1b3IobnVtKTtcbiAgICByZXR1cm4gbnVtLmNsb25lKCkuaXVvcih0aGlzKTtcbiAgfTtcblxuICAvLyBBbmQgYG51bWAgd2l0aCBgdGhpc2AgaW4tcGxhY2VcbiAgQk4ucHJvdG90eXBlLml1YW5kID0gZnVuY3Rpb24gaXVhbmQgKG51bSkge1xuICAgIC8vIGIgPSBtaW4tbGVuZ3RoKG51bSwgdGhpcylcbiAgICB2YXIgYjtcbiAgICBpZiAodGhpcy5sZW5ndGggPiBudW0ubGVuZ3RoKSB7XG4gICAgICBiID0gbnVtO1xuICAgIH0gZWxzZSB7XG4gICAgICBiID0gdGhpcztcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGIubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMud29yZHNbaV0gPSB0aGlzLndvcmRzW2ldICYgbnVtLndvcmRzW2ldO1xuICAgIH1cblxuICAgIHRoaXMubGVuZ3RoID0gYi5sZW5ndGg7XG5cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5pYW5kID0gZnVuY3Rpb24gaWFuZCAobnVtKSB7XG4gICAgYXNzZXJ0KCh0aGlzLm5lZ2F0aXZlIHwgbnVtLm5lZ2F0aXZlKSA9PT0gMCk7XG4gICAgcmV0dXJuIHRoaXMuaXVhbmQobnVtKTtcbiAgfTtcblxuICAvLyBBbmQgYG51bWAgd2l0aCBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLmFuZCA9IGZ1bmN0aW9uIGFuZCAobnVtKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkgcmV0dXJuIHRoaXMuY2xvbmUoKS5pYW5kKG51bSk7XG4gICAgcmV0dXJuIG51bS5jbG9uZSgpLmlhbmQodGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnVhbmQgPSBmdW5jdGlvbiB1YW5kIChudW0pIHtcbiAgICBpZiAodGhpcy5sZW5ndGggPiBudW0ubGVuZ3RoKSByZXR1cm4gdGhpcy5jbG9uZSgpLml1YW5kKG51bSk7XG4gICAgcmV0dXJuIG51bS5jbG9uZSgpLml1YW5kKHRoaXMpO1xuICB9O1xuXG4gIC8vIFhvciBgbnVtYCB3aXRoIGB0aGlzYCBpbi1wbGFjZVxuICBCTi5wcm90b3R5cGUuaXV4b3IgPSBmdW5jdGlvbiBpdXhvciAobnVtKSB7XG4gICAgLy8gYS5sZW5ndGggPiBiLmxlbmd0aFxuICAgIHZhciBhO1xuICAgIHZhciBiO1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHtcbiAgICAgIGEgPSB0aGlzO1xuICAgICAgYiA9IG51bTtcbiAgICB9IGVsc2Uge1xuICAgICAgYSA9IG51bTtcbiAgICAgIGIgPSB0aGlzO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYi5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IGEud29yZHNbaV0gXiBiLndvcmRzW2ldO1xuICAgIH1cblxuICAgIGlmICh0aGlzICE9PSBhKSB7XG4gICAgICBmb3IgKDsgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpcy53b3Jkc1tpXSA9IGEud29yZHNbaV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5sZW5ndGggPSBhLmxlbmd0aDtcblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLml4b3IgPSBmdW5jdGlvbiBpeG9yIChudW0pIHtcbiAgICBhc3NlcnQoKHRoaXMubmVnYXRpdmUgfCBudW0ubmVnYXRpdmUpID09PSAwKTtcbiAgICByZXR1cm4gdGhpcy5pdXhvcihudW0pO1xuICB9O1xuXG4gIC8vIFhvciBgbnVtYCB3aXRoIGB0aGlzYFxuICBCTi5wcm90b3R5cGUueG9yID0gZnVuY3Rpb24geG9yIChudW0pIHtcbiAgICBpZiAodGhpcy5sZW5ndGggPiBudW0ubGVuZ3RoKSByZXR1cm4gdGhpcy5jbG9uZSgpLml4b3IobnVtKTtcbiAgICByZXR1cm4gbnVtLmNsb25lKCkuaXhvcih0aGlzKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUudXhvciA9IGZ1bmN0aW9uIHV4b3IgKG51bSkge1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHJldHVybiB0aGlzLmNsb25lKCkuaXV4b3IobnVtKTtcbiAgICByZXR1cm4gbnVtLmNsb25lKCkuaXV4b3IodGhpcyk7XG4gIH07XG5cbiAgLy8gTm90IGBgdGhpc2BgIHdpdGggYGB3aWR0aGBgIGJpdHdpZHRoXG4gIEJOLnByb3RvdHlwZS5pbm90biA9IGZ1bmN0aW9uIGlub3RuICh3aWR0aCkge1xuICAgIGFzc2VydCh0eXBlb2Ygd2lkdGggPT09ICdudW1iZXInICYmIHdpZHRoID49IDApO1xuXG4gICAgdmFyIGJ5dGVzTmVlZGVkID0gTWF0aC5jZWlsKHdpZHRoIC8gMjYpIHwgMDtcbiAgICB2YXIgYml0c0xlZnQgPSB3aWR0aCAlIDI2O1xuXG4gICAgLy8gRXh0ZW5kIHRoZSBidWZmZXIgd2l0aCBsZWFkaW5nIHplcm9lc1xuICAgIHRoaXMuX2V4cGFuZChieXRlc05lZWRlZCk7XG5cbiAgICBpZiAoYml0c0xlZnQgPiAwKSB7XG4gICAgICBieXRlc05lZWRlZC0tO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBjb21wbGV0ZSB3b3Jkc1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXNOZWVkZWQ7IGkrKykge1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IH50aGlzLndvcmRzW2ldICYgMHgzZmZmZmZmO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSB0aGUgcmVzaWR1ZVxuICAgIGlmIChiaXRzTGVmdCA+IDApIHtcbiAgICAgIHRoaXMud29yZHNbaV0gPSB+dGhpcy53b3Jkc1tpXSAmICgweDNmZmZmZmYgPj4gKDI2IC0gYml0c0xlZnQpKTtcbiAgICB9XG5cbiAgICAvLyBBbmQgcmVtb3ZlIGxlYWRpbmcgemVyb2VzXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUubm90biA9IGZ1bmN0aW9uIG5vdG4gKHdpZHRoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pbm90bih3aWR0aCk7XG4gIH07XG5cbiAgLy8gU2V0IGBiaXRgIG9mIGB0aGlzYFxuICBCTi5wcm90b3R5cGUuc2V0biA9IGZ1bmN0aW9uIHNldG4gKGJpdCwgdmFsKSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBiaXQgPT09ICdudW1iZXInICYmIGJpdCA+PSAwKTtcblxuICAgIHZhciBvZmYgPSAoYml0IC8gMjYpIHwgMDtcbiAgICB2YXIgd2JpdCA9IGJpdCAlIDI2O1xuXG4gICAgdGhpcy5fZXhwYW5kKG9mZiArIDEpO1xuXG4gICAgaWYgKHZhbCkge1xuICAgICAgdGhpcy53b3Jkc1tvZmZdID0gdGhpcy53b3Jkc1tvZmZdIHwgKDEgPDwgd2JpdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMud29yZHNbb2ZmXSA9IHRoaXMud29yZHNbb2ZmXSAmIH4oMSA8PCB3Yml0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIC8vIEFkZCBgbnVtYCB0byBgdGhpc2AgaW4tcGxhY2VcbiAgQk4ucHJvdG90eXBlLmlhZGQgPSBmdW5jdGlvbiBpYWRkIChudW0pIHtcbiAgICB2YXIgcjtcblxuICAgIC8vIG5lZ2F0aXZlICsgcG9zaXRpdmVcbiAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCAmJiBudW0ubmVnYXRpdmUgPT09IDApIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgICAgciA9IHRoaXMuaXN1YihudW0pO1xuICAgICAgdGhpcy5uZWdhdGl2ZSBePSAxO1xuICAgICAgcmV0dXJuIHRoaXMuX25vcm1TaWduKCk7XG5cbiAgICAvLyBwb3NpdGl2ZSArIG5lZ2F0aXZlXG4gICAgfSBlbHNlIGlmICh0aGlzLm5lZ2F0aXZlID09PSAwICYmIG51bS5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgbnVtLm5lZ2F0aXZlID0gMDtcbiAgICAgIHIgPSB0aGlzLmlzdWIobnVtKTtcbiAgICAgIG51bS5uZWdhdGl2ZSA9IDE7XG4gICAgICByZXR1cm4gci5fbm9ybVNpZ24oKTtcbiAgICB9XG5cbiAgICAvLyBhLmxlbmd0aCA+IGIubGVuZ3RoXG4gICAgdmFyIGEsIGI7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkge1xuICAgICAgYSA9IHRoaXM7XG4gICAgICBiID0gbnVtO1xuICAgIH0gZWxzZSB7XG4gICAgICBhID0gbnVtO1xuICAgICAgYiA9IHRoaXM7XG4gICAgfVxuXG4gICAgdmFyIGNhcnJ5ID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGIubGVuZ3RoOyBpKyspIHtcbiAgICAgIHIgPSAoYS53b3Jkc1tpXSB8IDApICsgKGIud29yZHNbaV0gfCAwKSArIGNhcnJ5O1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IHIgJiAweDNmZmZmZmY7XG4gICAgICBjYXJyeSA9IHIgPj4+IDI2O1xuICAgIH1cbiAgICBmb3IgKDsgY2FycnkgIT09IDAgJiYgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIHIgPSAoYS53b3Jkc1tpXSB8IDApICsgY2Fycnk7XG4gICAgICB0aGlzLndvcmRzW2ldID0gciAmIDB4M2ZmZmZmZjtcbiAgICAgIGNhcnJ5ID0gciA+Pj4gMjY7XG4gICAgfVxuXG4gICAgdGhpcy5sZW5ndGggPSBhLmxlbmd0aDtcbiAgICBpZiAoY2FycnkgIT09IDApIHtcbiAgICAgIHRoaXMud29yZHNbdGhpcy5sZW5ndGhdID0gY2Fycnk7XG4gICAgICB0aGlzLmxlbmd0aCsrO1xuICAgIC8vIENvcHkgdGhlIHJlc3Qgb2YgdGhlIHdvcmRzXG4gICAgfSBlbHNlIGlmIChhICE9PSB0aGlzKSB7XG4gICAgICBmb3IgKDsgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpcy53b3Jkc1tpXSA9IGEud29yZHNbaV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgLy8gQWRkIGBudW1gIHRvIGB0aGlzYFxuICBCTi5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gYWRkIChudW0pIHtcbiAgICB2YXIgcmVzO1xuICAgIGlmIChudW0ubmVnYXRpdmUgIT09IDAgJiYgdGhpcy5uZWdhdGl2ZSA9PT0gMCkge1xuICAgICAgbnVtLm5lZ2F0aXZlID0gMDtcbiAgICAgIHJlcyA9IHRoaXMuc3ViKG51bSk7XG4gICAgICBudW0ubmVnYXRpdmUgXj0gMTtcbiAgICAgIHJldHVybiByZXM7XG4gICAgfSBlbHNlIGlmIChudW0ubmVnYXRpdmUgPT09IDAgJiYgdGhpcy5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDA7XG4gICAgICByZXMgPSBudW0uc3ViKHRoaXMpO1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDE7XG4gICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHJldHVybiB0aGlzLmNsb25lKCkuaWFkZChudW0pO1xuXG4gICAgcmV0dXJuIG51bS5jbG9uZSgpLmlhZGQodGhpcyk7XG4gIH07XG5cbiAgLy8gU3VidHJhY3QgYG51bWAgZnJvbSBgdGhpc2AgaW4tcGxhY2VcbiAgQk4ucHJvdG90eXBlLmlzdWIgPSBmdW5jdGlvbiBpc3ViIChudW0pIHtcbiAgICAvLyB0aGlzIC0gKC1udW0pID0gdGhpcyArIG51bVxuICAgIGlmIChudW0ubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIG51bS5uZWdhdGl2ZSA9IDA7XG4gICAgICB2YXIgciA9IHRoaXMuaWFkZChudW0pO1xuICAgICAgbnVtLm5lZ2F0aXZlID0gMTtcbiAgICAgIHJldHVybiByLl9ub3JtU2lnbigpO1xuXG4gICAgLy8gLXRoaXMgLSBudW0gPSAtKHRoaXMgKyBudW0pXG4gICAgfSBlbHNlIGlmICh0aGlzLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMDtcbiAgICAgIHRoaXMuaWFkZChudW0pO1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDE7XG4gICAgICByZXR1cm4gdGhpcy5fbm9ybVNpZ24oKTtcbiAgICB9XG5cbiAgICAvLyBBdCB0aGlzIHBvaW50IGJvdGggbnVtYmVycyBhcmUgcG9zaXRpdmVcbiAgICB2YXIgY21wID0gdGhpcy5jbXAobnVtKTtcblxuICAgIC8vIE9wdGltaXphdGlvbiAtIHplcm9pZnlcbiAgICBpZiAoY21wID09PSAwKSB7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMDtcbiAgICAgIHRoaXMubGVuZ3RoID0gMTtcbiAgICAgIHRoaXMud29yZHNbMF0gPSAwO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gYSA+IGJcbiAgICB2YXIgYSwgYjtcbiAgICBpZiAoY21wID4gMCkge1xuICAgICAgYSA9IHRoaXM7XG4gICAgICBiID0gbnVtO1xuICAgIH0gZWxzZSB7XG4gICAgICBhID0gbnVtO1xuICAgICAgYiA9IHRoaXM7XG4gICAgfVxuXG4gICAgdmFyIGNhcnJ5ID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGIubGVuZ3RoOyBpKyspIHtcbiAgICAgIHIgPSAoYS53b3Jkc1tpXSB8IDApIC0gKGIud29yZHNbaV0gfCAwKSArIGNhcnJ5O1xuICAgICAgY2FycnkgPSByID4+IDI2O1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IHIgJiAweDNmZmZmZmY7XG4gICAgfVxuICAgIGZvciAoOyBjYXJyeSAhPT0gMCAmJiBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgICAgciA9IChhLndvcmRzW2ldIHwgMCkgKyBjYXJyeTtcbiAgICAgIGNhcnJ5ID0gciA+PiAyNjtcbiAgICAgIHRoaXMud29yZHNbaV0gPSByICYgMHgzZmZmZmZmO1xuICAgIH1cblxuICAgIC8vIENvcHkgcmVzdCBvZiB0aGUgd29yZHNcbiAgICBpZiAoY2FycnkgPT09IDAgJiYgaSA8IGEubGVuZ3RoICYmIGEgIT09IHRoaXMpIHtcbiAgICAgIGZvciAoOyBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgICAgICB0aGlzLndvcmRzW2ldID0gYS53b3Jkc1tpXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmxlbmd0aCA9IE1hdGgubWF4KHRoaXMubGVuZ3RoLCBpKTtcblxuICAgIGlmIChhICE9PSB0aGlzKSB7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIC8vIFN1YnRyYWN0IGBudW1gIGZyb20gYHRoaXNgXG4gIEJOLnByb3RvdHlwZS5zdWIgPSBmdW5jdGlvbiBzdWIgKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaXN1YihudW0pO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHNtYWxsTXVsVG8gKHNlbGYsIG51bSwgb3V0KSB7XG4gICAgb3V0Lm5lZ2F0aXZlID0gbnVtLm5lZ2F0aXZlIF4gc2VsZi5uZWdhdGl2ZTtcbiAgICB2YXIgbGVuID0gKHNlbGYubGVuZ3RoICsgbnVtLmxlbmd0aCkgfCAwO1xuICAgIG91dC5sZW5ndGggPSBsZW47XG4gICAgbGVuID0gKGxlbiAtIDEpIHwgMDtcblxuICAgIC8vIFBlZWwgb25lIGl0ZXJhdGlvbiAoY29tcGlsZXIgY2FuJ3QgZG8gaXQsIGJlY2F1c2Ugb2YgY29kZSBjb21wbGV4aXR5KVxuICAgIHZhciBhID0gc2VsZi53b3Jkc1swXSB8IDA7XG4gICAgdmFyIGIgPSBudW0ud29yZHNbMF0gfCAwO1xuICAgIHZhciByID0gYSAqIGI7XG5cbiAgICB2YXIgbG8gPSByICYgMHgzZmZmZmZmO1xuICAgIHZhciBjYXJyeSA9IChyIC8gMHg0MDAwMDAwKSB8IDA7XG4gICAgb3V0LndvcmRzWzBdID0gbG87XG5cbiAgICBmb3IgKHZhciBrID0gMTsgayA8IGxlbjsgaysrKSB7XG4gICAgICAvLyBTdW0gYWxsIHdvcmRzIHdpdGggdGhlIHNhbWUgYGkgKyBqID0ga2AgYW5kIGFjY3VtdWxhdGUgYG5jYXJyeWAsXG4gICAgICAvLyBub3RlIHRoYXQgbmNhcnJ5IGNvdWxkIGJlID49IDB4M2ZmZmZmZlxuICAgICAgdmFyIG5jYXJyeSA9IGNhcnJ5ID4+PiAyNjtcbiAgICAgIHZhciByd29yZCA9IGNhcnJ5ICYgMHgzZmZmZmZmO1xuICAgICAgdmFyIG1heEogPSBNYXRoLm1pbihrLCBudW0ubGVuZ3RoIC0gMSk7XG4gICAgICBmb3IgKHZhciBqID0gTWF0aC5tYXgoMCwgayAtIHNlbGYubGVuZ3RoICsgMSk7IGogPD0gbWF4SjsgaisrKSB7XG4gICAgICAgIHZhciBpID0gKGsgLSBqKSB8IDA7XG4gICAgICAgIGEgPSBzZWxmLndvcmRzW2ldIHwgMDtcbiAgICAgICAgYiA9IG51bS53b3Jkc1tqXSB8IDA7XG4gICAgICAgIHIgPSBhICogYiArIHJ3b3JkO1xuICAgICAgICBuY2FycnkgKz0gKHIgLyAweDQwMDAwMDApIHwgMDtcbiAgICAgICAgcndvcmQgPSByICYgMHgzZmZmZmZmO1xuICAgICAgfVxuICAgICAgb3V0LndvcmRzW2tdID0gcndvcmQgfCAwO1xuICAgICAgY2FycnkgPSBuY2FycnkgfCAwO1xuICAgIH1cbiAgICBpZiAoY2FycnkgIT09IDApIHtcbiAgICAgIG91dC53b3Jkc1trXSA9IGNhcnJ5IHwgMDtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0Lmxlbmd0aC0tO1xuICAgIH1cblxuICAgIHJldHVybiBvdXQuc3RyaXAoKTtcbiAgfVxuXG4gIC8vIFRPRE8oaW5kdXRueSk6IGl0IG1heSBiZSByZWFzb25hYmxlIHRvIG9taXQgaXQgZm9yIHVzZXJzIHdobyBkb24ndCBuZWVkXG4gIC8vIHRvIHdvcmsgd2l0aCAyNTYtYml0IG51bWJlcnMsIG90aGVyd2lzZSBpdCBnaXZlcyAyMCUgaW1wcm92ZW1lbnQgZm9yIDI1Ni1iaXRcbiAgLy8gbXVsdGlwbGljYXRpb24gKGxpa2UgZWxsaXB0aWMgc2VjcDI1NmsxKS5cbiAgdmFyIGNvbWIxME11bFRvID0gZnVuY3Rpb24gY29tYjEwTXVsVG8gKHNlbGYsIG51bSwgb3V0KSB7XG4gICAgdmFyIGEgPSBzZWxmLndvcmRzO1xuICAgIHZhciBiID0gbnVtLndvcmRzO1xuICAgIHZhciBvID0gb3V0LndvcmRzO1xuICAgIHZhciBjID0gMDtcbiAgICB2YXIgbG87XG4gICAgdmFyIG1pZDtcbiAgICB2YXIgaGk7XG4gICAgdmFyIGEwID0gYVswXSB8IDA7XG4gICAgdmFyIGFsMCA9IGEwICYgMHgxZmZmO1xuICAgIHZhciBhaDAgPSBhMCA+Pj4gMTM7XG4gICAgdmFyIGExID0gYVsxXSB8IDA7XG4gICAgdmFyIGFsMSA9IGExICYgMHgxZmZmO1xuICAgIHZhciBhaDEgPSBhMSA+Pj4gMTM7XG4gICAgdmFyIGEyID0gYVsyXSB8IDA7XG4gICAgdmFyIGFsMiA9IGEyICYgMHgxZmZmO1xuICAgIHZhciBhaDIgPSBhMiA+Pj4gMTM7XG4gICAgdmFyIGEzID0gYVszXSB8IDA7XG4gICAgdmFyIGFsMyA9IGEzICYgMHgxZmZmO1xuICAgIHZhciBhaDMgPSBhMyA+Pj4gMTM7XG4gICAgdmFyIGE0ID0gYVs0XSB8IDA7XG4gICAgdmFyIGFsNCA9IGE0ICYgMHgxZmZmO1xuICAgIHZhciBhaDQgPSBhNCA+Pj4gMTM7XG4gICAgdmFyIGE1ID0gYVs1XSB8IDA7XG4gICAgdmFyIGFsNSA9IGE1ICYgMHgxZmZmO1xuICAgIHZhciBhaDUgPSBhNSA+Pj4gMTM7XG4gICAgdmFyIGE2ID0gYVs2XSB8IDA7XG4gICAgdmFyIGFsNiA9IGE2ICYgMHgxZmZmO1xuICAgIHZhciBhaDYgPSBhNiA+Pj4gMTM7XG4gICAgdmFyIGE3ID0gYVs3XSB8IDA7XG4gICAgdmFyIGFsNyA9IGE3ICYgMHgxZmZmO1xuICAgIHZhciBhaDcgPSBhNyA+Pj4gMTM7XG4gICAgdmFyIGE4ID0gYVs4XSB8IDA7XG4gICAgdmFyIGFsOCA9IGE4ICYgMHgxZmZmO1xuICAgIHZhciBhaDggPSBhOCA+Pj4gMTM7XG4gICAgdmFyIGE5ID0gYVs5XSB8IDA7XG4gICAgdmFyIGFsOSA9IGE5ICYgMHgxZmZmO1xuICAgIHZhciBhaDkgPSBhOSA+Pj4gMTM7XG4gICAgdmFyIGIwID0gYlswXSB8IDA7XG4gICAgdmFyIGJsMCA9IGIwICYgMHgxZmZmO1xuICAgIHZhciBiaDAgPSBiMCA+Pj4gMTM7XG4gICAgdmFyIGIxID0gYlsxXSB8IDA7XG4gICAgdmFyIGJsMSA9IGIxICYgMHgxZmZmO1xuICAgIHZhciBiaDEgPSBiMSA+Pj4gMTM7XG4gICAgdmFyIGIyID0gYlsyXSB8IDA7XG4gICAgdmFyIGJsMiA9IGIyICYgMHgxZmZmO1xuICAgIHZhciBiaDIgPSBiMiA+Pj4gMTM7XG4gICAgdmFyIGIzID0gYlszXSB8IDA7XG4gICAgdmFyIGJsMyA9IGIzICYgMHgxZmZmO1xuICAgIHZhciBiaDMgPSBiMyA+Pj4gMTM7XG4gICAgdmFyIGI0ID0gYls0XSB8IDA7XG4gICAgdmFyIGJsNCA9IGI0ICYgMHgxZmZmO1xuICAgIHZhciBiaDQgPSBiNCA+Pj4gMTM7XG4gICAgdmFyIGI1ID0gYls1XSB8IDA7XG4gICAgdmFyIGJsNSA9IGI1ICYgMHgxZmZmO1xuICAgIHZhciBiaDUgPSBiNSA+Pj4gMTM7XG4gICAgdmFyIGI2ID0gYls2XSB8IDA7XG4gICAgdmFyIGJsNiA9IGI2ICYgMHgxZmZmO1xuICAgIHZhciBiaDYgPSBiNiA+Pj4gMTM7XG4gICAgdmFyIGI3ID0gYls3XSB8IDA7XG4gICAgdmFyIGJsNyA9IGI3ICYgMHgxZmZmO1xuICAgIHZhciBiaDcgPSBiNyA+Pj4gMTM7XG4gICAgdmFyIGI4ID0gYls4XSB8IDA7XG4gICAgdmFyIGJsOCA9IGI4ICYgMHgxZmZmO1xuICAgIHZhciBiaDggPSBiOCA+Pj4gMTM7XG4gICAgdmFyIGI5ID0gYls5XSB8IDA7XG4gICAgdmFyIGJsOSA9IGI5ICYgMHgxZmZmO1xuICAgIHZhciBiaDkgPSBiOSA+Pj4gMTM7XG5cbiAgICBvdXQubmVnYXRpdmUgPSBzZWxmLm5lZ2F0aXZlIF4gbnVtLm5lZ2F0aXZlO1xuICAgIG91dC5sZW5ndGggPSAxOTtcbiAgICAvKiBrID0gMCAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsMCwgYmwwKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWwwLCBiaDApO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgwLCBibDApKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWgwLCBiaDApO1xuICAgIHZhciB3MCA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzAgPj4+IDI2KSkgfCAwO1xuICAgIHcwICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gMSAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsMSwgYmwwKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWwxLCBiaDApO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgxLCBibDApKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWgxLCBiaDApO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMCwgYmwxKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwwLCBiaDEpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDAsIGJsMSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDAsIGJoMSkpIHwgMDtcbiAgICB2YXIgdzEgPSAoKChjICsgbG8pIHwgMCkgKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpKSB8IDA7XG4gICAgYyA9ICgoKGhpICsgKG1pZCA+Pj4gMTMpKSB8IDApICsgKHcxID4+PiAyNikpIHwgMDtcbiAgICB3MSAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDIgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDIsIGJsMCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsMiwgYmgwKTtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMiwgYmwwKSkgfCAwO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoMiwgYmgwKTtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDEsIGJsMSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMSwgYmgxKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgxLCBibDEpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgxLCBiaDEpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwwLCBibDIpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDAsIGJoMikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMCwgYmwyKSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMCwgYmgyKSkgfCAwO1xuICAgIHZhciB3MiA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzIgPj4+IDI2KSkgfCAwO1xuICAgIHcyICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gMyAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsMywgYmwwKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWwzLCBiaDApO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgzLCBibDApKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWgzLCBiaDApO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMiwgYmwxKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwyLCBiaDEpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDIsIGJsMSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDIsIGJoMSkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDEsIGJsMikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMSwgYmgyKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgxLCBibDIpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgxLCBiaDIpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwwLCBibDMpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDAsIGJoMykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMCwgYmwzKSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMCwgYmgzKSkgfCAwO1xuICAgIHZhciB3MyA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzMgPj4+IDI2KSkgfCAwO1xuICAgIHczICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gNCAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsNCwgYmwwKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw0LCBiaDApO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg0LCBibDApKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg0LCBiaDApO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMywgYmwxKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwzLCBiaDEpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDMsIGJsMSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDMsIGJoMSkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDIsIGJsMikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMiwgYmgyKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgyLCBibDIpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgyLCBiaDIpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwxLCBibDMpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDEsIGJoMykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMSwgYmwzKSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMSwgYmgzKSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMCwgYmw0KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwwLCBiaDQpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDAsIGJsNCkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDAsIGJoNCkpIHwgMDtcbiAgICB2YXIgdzQgPSAoKChjICsgbG8pIHwgMCkgKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpKSB8IDA7XG4gICAgYyA9ICgoKGhpICsgKG1pZCA+Pj4gMTMpKSB8IDApICsgKHc0ID4+PiAyNikpIHwgMDtcbiAgICB3NCAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDUgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDUsIGJsMCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsNSwgYmgwKTtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNSwgYmwwKSkgfCAwO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoNSwgYmgwKTtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDQsIGJsMSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNCwgYmgxKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg0LCBibDEpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg0LCBiaDEpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwzLCBibDIpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDMsIGJoMikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMywgYmwyKSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMywgYmgyKSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMiwgYmwzKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwyLCBiaDMpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDIsIGJsMykpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDIsIGJoMykpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDEsIGJsNCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMSwgYmg0KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgxLCBibDQpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgxLCBiaDQpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwwLCBibDUpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDAsIGJoNSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMCwgYmw1KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMCwgYmg1KSkgfCAwO1xuICAgIHZhciB3NSA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzUgPj4+IDI2KSkgfCAwO1xuICAgIHc1ICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gNiAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsNiwgYmwwKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw2LCBiaDApO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg2LCBibDApKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg2LCBiaDApO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNSwgYmwxKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw1LCBiaDEpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDUsIGJsMSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDUsIGJoMSkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDQsIGJsMikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNCwgYmgyKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg0LCBibDIpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg0LCBiaDIpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwzLCBibDMpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDMsIGJoMykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMywgYmwzKSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMywgYmgzKSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMiwgYmw0KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwyLCBiaDQpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDIsIGJsNCkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDIsIGJoNCkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDEsIGJsNSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMSwgYmg1KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgxLCBibDUpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgxLCBiaDUpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwwLCBibDYpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDAsIGJoNikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMCwgYmw2KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMCwgYmg2KSkgfCAwO1xuICAgIHZhciB3NiA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzYgPj4+IDI2KSkgfCAwO1xuICAgIHc2ICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gNyAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsNywgYmwwKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw3LCBiaDApO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg3LCBibDApKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg3LCBiaDApO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNiwgYmwxKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw2LCBiaDEpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDYsIGJsMSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDYsIGJoMSkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDUsIGJsMikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNSwgYmgyKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg1LCBibDIpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg1LCBiaDIpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw0LCBibDMpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDQsIGJoMykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNCwgYmwzKSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNCwgYmgzKSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMywgYmw0KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwzLCBiaDQpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDMsIGJsNCkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDMsIGJoNCkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDIsIGJsNSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMiwgYmg1KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgyLCBibDUpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgyLCBiaDUpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwxLCBibDYpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDEsIGJoNikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMSwgYmw2KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMSwgYmg2KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMCwgYmw3KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwwLCBiaDcpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDAsIGJsNykpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDAsIGJoNykpIHwgMDtcbiAgICB2YXIgdzcgPSAoKChjICsgbG8pIHwgMCkgKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpKSB8IDA7XG4gICAgYyA9ICgoKGhpICsgKG1pZCA+Pj4gMTMpKSB8IDApICsgKHc3ID4+PiAyNikpIHwgMDtcbiAgICB3NyAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDggKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDgsIGJsMCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsOCwgYmgwKTtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoOCwgYmwwKSkgfCAwO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoOCwgYmgwKTtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDcsIGJsMSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNywgYmgxKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg3LCBibDEpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg3LCBiaDEpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw2LCBibDIpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDYsIGJoMikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNiwgYmwyKSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNiwgYmgyKSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNSwgYmwzKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw1LCBiaDMpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDUsIGJsMykpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDUsIGJoMykpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDQsIGJsNCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNCwgYmg0KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg0LCBibDQpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg0LCBiaDQpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwzLCBibDUpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDMsIGJoNSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMywgYmw1KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMywgYmg1KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMiwgYmw2KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwyLCBiaDYpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDIsIGJsNikpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDIsIGJoNikpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDEsIGJsNykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMSwgYmg3KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgxLCBibDcpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgxLCBiaDcpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwwLCBibDgpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDAsIGJoOCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMCwgYmw4KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMCwgYmg4KSkgfCAwO1xuICAgIHZhciB3OCA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzggPj4+IDI2KSkgfCAwO1xuICAgIHc4ICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gOSAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOSwgYmwwKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw5LCBiaDApO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg5LCBibDApKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDApO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsOCwgYmwxKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw4LCBiaDEpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDgsIGJsMSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDgsIGJoMSkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDcsIGJsMikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNywgYmgyKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg3LCBibDIpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg3LCBiaDIpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw2LCBibDMpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDYsIGJoMykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNiwgYmwzKSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNiwgYmgzKSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNSwgYmw0KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw1LCBiaDQpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDUsIGJsNCkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDUsIGJoNCkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDQsIGJsNSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNCwgYmg1KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg0LCBibDUpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg0LCBiaDUpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwzLCBibDYpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDMsIGJoNikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMywgYmw2KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMywgYmg2KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMiwgYmw3KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwyLCBiaDcpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDIsIGJsNykpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDIsIGJoNykpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDEsIGJsOCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMSwgYmg4KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgxLCBibDgpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgxLCBiaDgpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwwLCBibDkpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDAsIGJoOSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMCwgYmw5KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMCwgYmg5KSkgfCAwO1xuICAgIHZhciB3OSA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzkgPj4+IDI2KSkgfCAwO1xuICAgIHc5ICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gMTAgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDksIGJsMSk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsOSwgYmgxKTtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoOSwgYmwxKSkgfCAwO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoOSwgYmgxKTtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDgsIGJsMikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsOCwgYmgyKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg4LCBibDIpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg4LCBiaDIpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw3LCBibDMpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDcsIGJoMykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNywgYmwzKSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNywgYmgzKSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNiwgYmw0KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw2LCBiaDQpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDYsIGJsNCkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDYsIGJoNCkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDUsIGJsNSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNSwgYmg1KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg1LCBibDUpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg1LCBiaDUpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw0LCBibDYpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDQsIGJoNikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNCwgYmw2KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNCwgYmg2KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMywgYmw3KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwzLCBiaDcpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDMsIGJsNykpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDMsIGJoNykpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDIsIGJsOCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMiwgYmg4KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgyLCBibDgpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgyLCBiaDgpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwxLCBibDkpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDEsIGJoOSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMSwgYmw5KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMSwgYmg5KSkgfCAwO1xuICAgIHZhciB3MTAgPSAoKChjICsgbG8pIHwgMCkgKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpKSB8IDA7XG4gICAgYyA9ICgoKGhpICsgKG1pZCA+Pj4gMTMpKSB8IDApICsgKHcxMCA+Pj4gMjYpKSB8IDA7XG4gICAgdzEwICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gMTEgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDksIGJsMik7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsOSwgYmgyKTtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoOSwgYmwyKSkgfCAwO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoOSwgYmgyKTtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDgsIGJsMykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsOCwgYmgzKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg4LCBibDMpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg4LCBiaDMpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw3LCBibDQpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDcsIGJoNCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNywgYmw0KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNywgYmg0KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNiwgYmw1KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw2LCBiaDUpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDYsIGJsNSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDYsIGJoNSkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDUsIGJsNikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNSwgYmg2KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg1LCBibDYpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg1LCBiaDYpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw0LCBibDcpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDQsIGJoNykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNCwgYmw3KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNCwgYmg3KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMywgYmw4KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwzLCBiaDgpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDMsIGJsOCkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDMsIGJoOCkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDIsIGJsOSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMiwgYmg5KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgyLCBibDkpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgyLCBiaDkpKSB8IDA7XG4gICAgdmFyIHcxMSA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzExID4+PiAyNikpIHwgMDtcbiAgICB3MTEgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAxMiAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOSwgYmwzKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw5LCBiaDMpO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg5LCBibDMpKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDMpO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsOCwgYmw0KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw4LCBiaDQpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDgsIGJsNCkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDgsIGJoNCkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDcsIGJsNSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNywgYmg1KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg3LCBibDUpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg3LCBiaDUpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw2LCBibDYpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDYsIGJoNikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNiwgYmw2KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNiwgYmg2KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNSwgYmw3KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw1LCBiaDcpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDUsIGJsNykpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDUsIGJoNykpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDQsIGJsOCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNCwgYmg4KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg0LCBibDgpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg0LCBiaDgpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwzLCBibDkpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDMsIGJoOSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMywgYmw5KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMywgYmg5KSkgfCAwO1xuICAgIHZhciB3MTIgPSAoKChjICsgbG8pIHwgMCkgKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpKSB8IDA7XG4gICAgYyA9ICgoKGhpICsgKG1pZCA+Pj4gMTMpKSB8IDApICsgKHcxMiA+Pj4gMjYpKSB8IDA7XG4gICAgdzEyICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gMTMgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDksIGJsNCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsOSwgYmg0KTtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoOSwgYmw0KSkgfCAwO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoOSwgYmg0KTtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDgsIGJsNSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsOCwgYmg1KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg4LCBibDUpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg4LCBiaDUpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw3LCBibDYpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDcsIGJoNikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNywgYmw2KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNywgYmg2KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNiwgYmw3KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw2LCBiaDcpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDYsIGJsNykpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDYsIGJoNykpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDUsIGJsOCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNSwgYmg4KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg1LCBibDgpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg1LCBiaDgpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw0LCBibDkpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDQsIGJoOSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNCwgYmw5KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNCwgYmg5KSkgfCAwO1xuICAgIHZhciB3MTMgPSAoKChjICsgbG8pIHwgMCkgKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpKSB8IDA7XG4gICAgYyA9ICgoKGhpICsgKG1pZCA+Pj4gMTMpKSB8IDApICsgKHcxMyA+Pj4gMjYpKSB8IDA7XG4gICAgdzEzICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gMTQgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDksIGJsNSk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsOSwgYmg1KTtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoOSwgYmw1KSkgfCAwO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoOSwgYmg1KTtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDgsIGJsNikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsOCwgYmg2KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg4LCBibDYpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg4LCBiaDYpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw3LCBibDcpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDcsIGJoNykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNywgYmw3KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNywgYmg3KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNiwgYmw4KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw2LCBiaDgpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDYsIGJsOCkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDYsIGJoOCkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDUsIGJsOSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNSwgYmg5KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg1LCBibDkpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg1LCBiaDkpKSB8IDA7XG4gICAgdmFyIHcxNCA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzE0ID4+PiAyNikpIHwgMDtcbiAgICB3MTQgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAxNSAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOSwgYmw2KTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw5LCBiaDYpO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg5LCBibDYpKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDYpO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsOCwgYmw3KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw4LCBiaDcpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDgsIGJsNykpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDgsIGJoNykpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDcsIGJsOCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNywgYmg4KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg3LCBibDgpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg3LCBiaDgpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw2LCBibDkpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDYsIGJoOSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNiwgYmw5KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNiwgYmg5KSkgfCAwO1xuICAgIHZhciB3MTUgPSAoKChjICsgbG8pIHwgMCkgKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpKSB8IDA7XG4gICAgYyA9ICgoKGhpICsgKG1pZCA+Pj4gMTMpKSB8IDApICsgKHcxNSA+Pj4gMjYpKSB8IDA7XG4gICAgdzE1ICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gMTYgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDksIGJsNyk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsOSwgYmg3KTtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoOSwgYmw3KSkgfCAwO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoOSwgYmg3KTtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDgsIGJsOCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsOCwgYmg4KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg4LCBibDgpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg4LCBiaDgpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw3LCBibDkpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDcsIGJoOSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNywgYmw5KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNywgYmg5KSkgfCAwO1xuICAgIHZhciB3MTYgPSAoKChjICsgbG8pIHwgMCkgKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpKSB8IDA7XG4gICAgYyA9ICgoKGhpICsgKG1pZCA+Pj4gMTMpKSB8IDApICsgKHcxNiA+Pj4gMjYpKSB8IDA7XG4gICAgdzE2ICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gMTcgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDksIGJsOCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsOSwgYmg4KTtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoOSwgYmw4KSkgfCAwO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoOSwgYmg4KTtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDgsIGJsOSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsOCwgYmg5KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg4LCBibDkpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg4LCBiaDkpKSB8IDA7XG4gICAgdmFyIHcxNyA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzE3ID4+PiAyNikpIHwgMDtcbiAgICB3MTcgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAxOCAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOSwgYmw5KTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw5LCBiaDkpO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg5LCBibDkpKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDkpO1xuICAgIHZhciB3MTggPSAoKChjICsgbG8pIHwgMCkgKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpKSB8IDA7XG4gICAgYyA9ICgoKGhpICsgKG1pZCA+Pj4gMTMpKSB8IDApICsgKHcxOCA+Pj4gMjYpKSB8IDA7XG4gICAgdzE4ICY9IDB4M2ZmZmZmZjtcbiAgICBvWzBdID0gdzA7XG4gICAgb1sxXSA9IHcxO1xuICAgIG9bMl0gPSB3MjtcbiAgICBvWzNdID0gdzM7XG4gICAgb1s0XSA9IHc0O1xuICAgIG9bNV0gPSB3NTtcbiAgICBvWzZdID0gdzY7XG4gICAgb1s3XSA9IHc3O1xuICAgIG9bOF0gPSB3ODtcbiAgICBvWzldID0gdzk7XG4gICAgb1sxMF0gPSB3MTA7XG4gICAgb1sxMV0gPSB3MTE7XG4gICAgb1sxMl0gPSB3MTI7XG4gICAgb1sxM10gPSB3MTM7XG4gICAgb1sxNF0gPSB3MTQ7XG4gICAgb1sxNV0gPSB3MTU7XG4gICAgb1sxNl0gPSB3MTY7XG4gICAgb1sxN10gPSB3MTc7XG4gICAgb1sxOF0gPSB3MTg7XG4gICAgaWYgKGMgIT09IDApIHtcbiAgICAgIG9bMTldID0gYztcbiAgICAgIG91dC5sZW5ndGgrKztcbiAgICB9XG4gICAgcmV0dXJuIG91dDtcbiAgfTtcblxuICAvLyBQb2x5ZmlsbCBjb21iXG4gIGlmICghTWF0aC5pbXVsKSB7XG4gICAgY29tYjEwTXVsVG8gPSBzbWFsbE11bFRvO1xuICB9XG5cbiAgZnVuY3Rpb24gYmlnTXVsVG8gKHNlbGYsIG51bSwgb3V0KSB7XG4gICAgb3V0Lm5lZ2F0aXZlID0gbnVtLm5lZ2F0aXZlIF4gc2VsZi5uZWdhdGl2ZTtcbiAgICBvdXQubGVuZ3RoID0gc2VsZi5sZW5ndGggKyBudW0ubGVuZ3RoO1xuXG4gICAgdmFyIGNhcnJ5ID0gMDtcbiAgICB2YXIgaG5jYXJyeSA9IDA7XG4gICAgZm9yICh2YXIgayA9IDA7IGsgPCBvdXQubGVuZ3RoIC0gMTsgaysrKSB7XG4gICAgICAvLyBTdW0gYWxsIHdvcmRzIHdpdGggdGhlIHNhbWUgYGkgKyBqID0ga2AgYW5kIGFjY3VtdWxhdGUgYG5jYXJyeWAsXG4gICAgICAvLyBub3RlIHRoYXQgbmNhcnJ5IGNvdWxkIGJlID49IDB4M2ZmZmZmZlxuICAgICAgdmFyIG5jYXJyeSA9IGhuY2Fycnk7XG4gICAgICBobmNhcnJ5ID0gMDtcbiAgICAgIHZhciByd29yZCA9IGNhcnJ5ICYgMHgzZmZmZmZmO1xuICAgICAgdmFyIG1heEogPSBNYXRoLm1pbihrLCBudW0ubGVuZ3RoIC0gMSk7XG4gICAgICBmb3IgKHZhciBqID0gTWF0aC5tYXgoMCwgayAtIHNlbGYubGVuZ3RoICsgMSk7IGogPD0gbWF4SjsgaisrKSB7XG4gICAgICAgIHZhciBpID0gayAtIGo7XG4gICAgICAgIHZhciBhID0gc2VsZi53b3Jkc1tpXSB8IDA7XG4gICAgICAgIHZhciBiID0gbnVtLndvcmRzW2pdIHwgMDtcbiAgICAgICAgdmFyIHIgPSBhICogYjtcblxuICAgICAgICB2YXIgbG8gPSByICYgMHgzZmZmZmZmO1xuICAgICAgICBuY2FycnkgPSAobmNhcnJ5ICsgKChyIC8gMHg0MDAwMDAwKSB8IDApKSB8IDA7XG4gICAgICAgIGxvID0gKGxvICsgcndvcmQpIHwgMDtcbiAgICAgICAgcndvcmQgPSBsbyAmIDB4M2ZmZmZmZjtcbiAgICAgICAgbmNhcnJ5ID0gKG5jYXJyeSArIChsbyA+Pj4gMjYpKSB8IDA7XG5cbiAgICAgICAgaG5jYXJyeSArPSBuY2FycnkgPj4+IDI2O1xuICAgICAgICBuY2FycnkgJj0gMHgzZmZmZmZmO1xuICAgICAgfVxuICAgICAgb3V0LndvcmRzW2tdID0gcndvcmQ7XG4gICAgICBjYXJyeSA9IG5jYXJyeTtcbiAgICAgIG5jYXJyeSA9IGhuY2Fycnk7XG4gICAgfVxuICAgIGlmIChjYXJyeSAhPT0gMCkge1xuICAgICAgb3V0LndvcmRzW2tdID0gY2Fycnk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dC5sZW5ndGgtLTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0LnN0cmlwKCk7XG4gIH1cblxuICBmdW5jdGlvbiBqdW1ib011bFRvIChzZWxmLCBudW0sIG91dCkge1xuICAgIHZhciBmZnRtID0gbmV3IEZGVE0oKTtcbiAgICByZXR1cm4gZmZ0bS5tdWxwKHNlbGYsIG51bSwgb3V0KTtcbiAgfVxuXG4gIEJOLnByb3RvdHlwZS5tdWxUbyA9IGZ1bmN0aW9uIG11bFRvIChudW0sIG91dCkge1xuICAgIHZhciByZXM7XG4gICAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoICsgbnVtLmxlbmd0aDtcbiAgICBpZiAodGhpcy5sZW5ndGggPT09IDEwICYmIG51bS5sZW5ndGggPT09IDEwKSB7XG4gICAgICByZXMgPSBjb21iMTBNdWxUbyh0aGlzLCBudW0sIG91dCk7XG4gICAgfSBlbHNlIGlmIChsZW4gPCA2Mykge1xuICAgICAgcmVzID0gc21hbGxNdWxUbyh0aGlzLCBudW0sIG91dCk7XG4gICAgfSBlbHNlIGlmIChsZW4gPCAxMDI0KSB7XG4gICAgICByZXMgPSBiaWdNdWxUbyh0aGlzLCBudW0sIG91dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlcyA9IGp1bWJvTXVsVG8odGhpcywgbnVtLCBvdXQpO1xuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgLy8gQ29vbGV5LVR1a2V5IGFsZ29yaXRobSBmb3IgRkZUXG4gIC8vIHNsaWdodGx5IHJldmlzaXRlZCB0byByZWx5IG9uIGxvb3BpbmcgaW5zdGVhZCBvZiByZWN1cnNpb25cblxuICBmdW5jdGlvbiBGRlRNICh4LCB5KSB7XG4gICAgdGhpcy54ID0geDtcbiAgICB0aGlzLnkgPSB5O1xuICB9XG5cbiAgRkZUTS5wcm90b3R5cGUubWFrZVJCVCA9IGZ1bmN0aW9uIG1ha2VSQlQgKE4pIHtcbiAgICB2YXIgdCA9IG5ldyBBcnJheShOKTtcbiAgICB2YXIgbCA9IEJOLnByb3RvdHlwZS5fY291bnRCaXRzKE4pIC0gMTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IE47IGkrKykge1xuICAgICAgdFtpXSA9IHRoaXMucmV2QmluKGksIGwsIE4pO1xuICAgIH1cblxuICAgIHJldHVybiB0O1xuICB9O1xuXG4gIC8vIFJldHVybnMgYmluYXJ5LXJldmVyc2VkIHJlcHJlc2VudGF0aW9uIG9mIGB4YFxuICBGRlRNLnByb3RvdHlwZS5yZXZCaW4gPSBmdW5jdGlvbiByZXZCaW4gKHgsIGwsIE4pIHtcbiAgICBpZiAoeCA9PT0gMCB8fCB4ID09PSBOIC0gMSkgcmV0dXJuIHg7XG5cbiAgICB2YXIgcmIgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbDsgaSsrKSB7XG4gICAgICByYiB8PSAoeCAmIDEpIDw8IChsIC0gaSAtIDEpO1xuICAgICAgeCA+Pj0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmI7XG4gIH07XG5cbiAgLy8gUGVyZm9ybXMgXCJ0d2VlZGxpbmdcIiBwaGFzZSwgdGhlcmVmb3JlICdlbXVsYXRpbmcnXG4gIC8vIGJlaGF2aW91ciBvZiB0aGUgcmVjdXJzaXZlIGFsZ29yaXRobVxuICBGRlRNLnByb3RvdHlwZS5wZXJtdXRlID0gZnVuY3Rpb24gcGVybXV0ZSAocmJ0LCByd3MsIGl3cywgcnR3cywgaXR3cywgTikge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgTjsgaSsrKSB7XG4gICAgICBydHdzW2ldID0gcndzW3JidFtpXV07XG4gICAgICBpdHdzW2ldID0gaXdzW3JidFtpXV07XG4gICAgfVxuICB9O1xuXG4gIEZGVE0ucHJvdG90eXBlLnRyYW5zZm9ybSA9IGZ1bmN0aW9uIHRyYW5zZm9ybSAocndzLCBpd3MsIHJ0d3MsIGl0d3MsIE4sIHJidCkge1xuICAgIHRoaXMucGVybXV0ZShyYnQsIHJ3cywgaXdzLCBydHdzLCBpdHdzLCBOKTtcblxuICAgIGZvciAodmFyIHMgPSAxOyBzIDwgTjsgcyA8PD0gMSkge1xuICAgICAgdmFyIGwgPSBzIDw8IDE7XG5cbiAgICAgIHZhciBydHdkZiA9IE1hdGguY29zKDIgKiBNYXRoLlBJIC8gbCk7XG4gICAgICB2YXIgaXR3ZGYgPSBNYXRoLnNpbigyICogTWF0aC5QSSAvIGwpO1xuXG4gICAgICBmb3IgKHZhciBwID0gMDsgcCA8IE47IHAgKz0gbCkge1xuICAgICAgICB2YXIgcnR3ZGZfID0gcnR3ZGY7XG4gICAgICAgIHZhciBpdHdkZl8gPSBpdHdkZjtcblxuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHM7IGorKykge1xuICAgICAgICAgIHZhciByZSA9IHJ0d3NbcCArIGpdO1xuICAgICAgICAgIHZhciBpZSA9IGl0d3NbcCArIGpdO1xuXG4gICAgICAgICAgdmFyIHJvID0gcnR3c1twICsgaiArIHNdO1xuICAgICAgICAgIHZhciBpbyA9IGl0d3NbcCArIGogKyBzXTtcblxuICAgICAgICAgIHZhciByeCA9IHJ0d2RmXyAqIHJvIC0gaXR3ZGZfICogaW87XG5cbiAgICAgICAgICBpbyA9IHJ0d2RmXyAqIGlvICsgaXR3ZGZfICogcm87XG4gICAgICAgICAgcm8gPSByeDtcblxuICAgICAgICAgIHJ0d3NbcCArIGpdID0gcmUgKyBybztcbiAgICAgICAgICBpdHdzW3AgKyBqXSA9IGllICsgaW87XG5cbiAgICAgICAgICBydHdzW3AgKyBqICsgc10gPSByZSAtIHJvO1xuICAgICAgICAgIGl0d3NbcCArIGogKyBzXSA9IGllIC0gaW87XG5cbiAgICAgICAgICAvKiBqc2hpbnQgbWF4ZGVwdGggOiBmYWxzZSAqL1xuICAgICAgICAgIGlmIChqICE9PSBsKSB7XG4gICAgICAgICAgICByeCA9IHJ0d2RmICogcnR3ZGZfIC0gaXR3ZGYgKiBpdHdkZl87XG5cbiAgICAgICAgICAgIGl0d2RmXyA9IHJ0d2RmICogaXR3ZGZfICsgaXR3ZGYgKiBydHdkZl87XG4gICAgICAgICAgICBydHdkZl8gPSByeDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgRkZUTS5wcm90b3R5cGUuZ3Vlc3NMZW4xM2IgPSBmdW5jdGlvbiBndWVzc0xlbjEzYiAobiwgbSkge1xuICAgIHZhciBOID0gTWF0aC5tYXgobSwgbikgfCAxO1xuICAgIHZhciBvZGQgPSBOICYgMTtcbiAgICB2YXIgaSA9IDA7XG4gICAgZm9yIChOID0gTiAvIDIgfCAwOyBOOyBOID0gTiA+Pj4gMSkge1xuICAgICAgaSsrO1xuICAgIH1cblxuICAgIHJldHVybiAxIDw8IGkgKyAxICsgb2RkO1xuICB9O1xuXG4gIEZGVE0ucHJvdG90eXBlLmNvbmp1Z2F0ZSA9IGZ1bmN0aW9uIGNvbmp1Z2F0ZSAocndzLCBpd3MsIE4pIHtcbiAgICBpZiAoTiA8PSAxKSByZXR1cm47XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IE4gLyAyOyBpKyspIHtcbiAgICAgIHZhciB0ID0gcndzW2ldO1xuXG4gICAgICByd3NbaV0gPSByd3NbTiAtIGkgLSAxXTtcbiAgICAgIHJ3c1tOIC0gaSAtIDFdID0gdDtcblxuICAgICAgdCA9IGl3c1tpXTtcblxuICAgICAgaXdzW2ldID0gLWl3c1tOIC0gaSAtIDFdO1xuICAgICAgaXdzW04gLSBpIC0gMV0gPSAtdDtcbiAgICB9XG4gIH07XG5cbiAgRkZUTS5wcm90b3R5cGUubm9ybWFsaXplMTNiID0gZnVuY3Rpb24gbm9ybWFsaXplMTNiICh3cywgTikge1xuICAgIHZhciBjYXJyeSA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBOIC8gMjsgaSsrKSB7XG4gICAgICB2YXIgdyA9IE1hdGgucm91bmQod3NbMiAqIGkgKyAxXSAvIE4pICogMHgyMDAwICtcbiAgICAgICAgTWF0aC5yb3VuZCh3c1syICogaV0gLyBOKSArXG4gICAgICAgIGNhcnJ5O1xuXG4gICAgICB3c1tpXSA9IHcgJiAweDNmZmZmZmY7XG5cbiAgICAgIGlmICh3IDwgMHg0MDAwMDAwKSB7XG4gICAgICAgIGNhcnJ5ID0gMDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNhcnJ5ID0gdyAvIDB4NDAwMDAwMCB8IDA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHdzO1xuICB9O1xuXG4gIEZGVE0ucHJvdG90eXBlLmNvbnZlcnQxM2IgPSBmdW5jdGlvbiBjb252ZXJ0MTNiICh3cywgbGVuLCByd3MsIE4pIHtcbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGNhcnJ5ID0gY2FycnkgKyAod3NbaV0gfCAwKTtcblxuICAgICAgcndzWzIgKiBpXSA9IGNhcnJ5ICYgMHgxZmZmOyBjYXJyeSA9IGNhcnJ5ID4+PiAxMztcbiAgICAgIHJ3c1syICogaSArIDFdID0gY2FycnkgJiAweDFmZmY7IGNhcnJ5ID0gY2FycnkgPj4+IDEzO1xuICAgIH1cblxuICAgIC8vIFBhZCB3aXRoIHplcm9lc1xuICAgIGZvciAoaSA9IDIgKiBsZW47IGkgPCBOOyArK2kpIHtcbiAgICAgIHJ3c1tpXSA9IDA7XG4gICAgfVxuXG4gICAgYXNzZXJ0KGNhcnJ5ID09PSAwKTtcbiAgICBhc3NlcnQoKGNhcnJ5ICYgfjB4MWZmZikgPT09IDApO1xuICB9O1xuXG4gIEZGVE0ucHJvdG90eXBlLnN0dWIgPSBmdW5jdGlvbiBzdHViIChOKSB7XG4gICAgdmFyIHBoID0gbmV3IEFycmF5KE4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgTjsgaSsrKSB7XG4gICAgICBwaFtpXSA9IDA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBoO1xuICB9O1xuXG4gIEZGVE0ucHJvdG90eXBlLm11bHAgPSBmdW5jdGlvbiBtdWxwICh4LCB5LCBvdXQpIHtcbiAgICB2YXIgTiA9IDIgKiB0aGlzLmd1ZXNzTGVuMTNiKHgubGVuZ3RoLCB5Lmxlbmd0aCk7XG5cbiAgICB2YXIgcmJ0ID0gdGhpcy5tYWtlUkJUKE4pO1xuXG4gICAgdmFyIF8gPSB0aGlzLnN0dWIoTik7XG5cbiAgICB2YXIgcndzID0gbmV3IEFycmF5KE4pO1xuICAgIHZhciByd3N0ID0gbmV3IEFycmF5KE4pO1xuICAgIHZhciBpd3N0ID0gbmV3IEFycmF5KE4pO1xuXG4gICAgdmFyIG5yd3MgPSBuZXcgQXJyYXkoTik7XG4gICAgdmFyIG5yd3N0ID0gbmV3IEFycmF5KE4pO1xuICAgIHZhciBuaXdzdCA9IG5ldyBBcnJheShOKTtcblxuICAgIHZhciBybXdzID0gb3V0LndvcmRzO1xuICAgIHJtd3MubGVuZ3RoID0gTjtcblxuICAgIHRoaXMuY29udmVydDEzYih4LndvcmRzLCB4Lmxlbmd0aCwgcndzLCBOKTtcbiAgICB0aGlzLmNvbnZlcnQxM2IoeS53b3JkcywgeS5sZW5ndGgsIG5yd3MsIE4pO1xuXG4gICAgdGhpcy50cmFuc2Zvcm0ocndzLCBfLCByd3N0LCBpd3N0LCBOLCByYnQpO1xuICAgIHRoaXMudHJhbnNmb3JtKG5yd3MsIF8sIG5yd3N0LCBuaXdzdCwgTiwgcmJ0KTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgTjsgaSsrKSB7XG4gICAgICB2YXIgcnggPSByd3N0W2ldICogbnJ3c3RbaV0gLSBpd3N0W2ldICogbml3c3RbaV07XG4gICAgICBpd3N0W2ldID0gcndzdFtpXSAqIG5pd3N0W2ldICsgaXdzdFtpXSAqIG5yd3N0W2ldO1xuICAgICAgcndzdFtpXSA9IHJ4O1xuICAgIH1cblxuICAgIHRoaXMuY29uanVnYXRlKHJ3c3QsIGl3c3QsIE4pO1xuICAgIHRoaXMudHJhbnNmb3JtKHJ3c3QsIGl3c3QsIHJtd3MsIF8sIE4sIHJidCk7XG4gICAgdGhpcy5jb25qdWdhdGUocm13cywgXywgTik7XG4gICAgdGhpcy5ub3JtYWxpemUxM2Iocm13cywgTik7XG5cbiAgICBvdXQubmVnYXRpdmUgPSB4Lm5lZ2F0aXZlIF4geS5uZWdhdGl2ZTtcbiAgICBvdXQubGVuZ3RoID0geC5sZW5ndGggKyB5Lmxlbmd0aDtcbiAgICByZXR1cm4gb3V0LnN0cmlwKCk7XG4gIH07XG5cbiAgLy8gTXVsdGlwbHkgYHRoaXNgIGJ5IGBudW1gXG4gIEJOLnByb3RvdHlwZS5tdWwgPSBmdW5jdGlvbiBtdWwgKG51bSkge1xuICAgIHZhciBvdXQgPSBuZXcgQk4obnVsbCk7XG4gICAgb3V0LndvcmRzID0gbmV3IEFycmF5KHRoaXMubGVuZ3RoICsgbnVtLmxlbmd0aCk7XG4gICAgcmV0dXJuIHRoaXMubXVsVG8obnVtLCBvdXQpO1xuICB9O1xuXG4gIC8vIE11bHRpcGx5IGVtcGxveWluZyBGRlRcbiAgQk4ucHJvdG90eXBlLm11bGYgPSBmdW5jdGlvbiBtdWxmIChudW0pIHtcbiAgICB2YXIgb3V0ID0gbmV3IEJOKG51bGwpO1xuICAgIG91dC53b3JkcyA9IG5ldyBBcnJheSh0aGlzLmxlbmd0aCArIG51bS5sZW5ndGgpO1xuICAgIHJldHVybiBqdW1ib011bFRvKHRoaXMsIG51bSwgb3V0KTtcbiAgfTtcblxuICAvLyBJbi1wbGFjZSBNdWx0aXBsaWNhdGlvblxuICBCTi5wcm90b3R5cGUuaW11bCA9IGZ1bmN0aW9uIGltdWwgKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkubXVsVG8obnVtLCB0aGlzKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaW11bG4gPSBmdW5jdGlvbiBpbXVsbiAobnVtKSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBudW0gPT09ICdudW1iZXInKTtcbiAgICBhc3NlcnQobnVtIDwgMHg0MDAwMDAwKTtcblxuICAgIC8vIENhcnJ5XG4gICAgdmFyIGNhcnJ5ID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciB3ID0gKHRoaXMud29yZHNbaV0gfCAwKSAqIG51bTtcbiAgICAgIHZhciBsbyA9ICh3ICYgMHgzZmZmZmZmKSArIChjYXJyeSAmIDB4M2ZmZmZmZik7XG4gICAgICBjYXJyeSA+Pj0gMjY7XG4gICAgICBjYXJyeSArPSAodyAvIDB4NDAwMDAwMCkgfCAwO1xuICAgICAgLy8gTk9URTogbG8gaXMgMjdiaXQgbWF4aW11bVxuICAgICAgY2FycnkgKz0gbG8gPj4+IDI2O1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IGxvICYgMHgzZmZmZmZmO1xuICAgIH1cblxuICAgIGlmIChjYXJyeSAhPT0gMCkge1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IGNhcnJ5O1xuICAgICAgdGhpcy5sZW5ndGgrKztcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBCTi5wcm90b3R5cGUubXVsbiA9IGZ1bmN0aW9uIG11bG4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaW11bG4obnVtKTtcbiAgfTtcblxuICAvLyBgdGhpc2AgKiBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLnNxciA9IGZ1bmN0aW9uIHNxciAoKSB7XG4gICAgcmV0dXJuIHRoaXMubXVsKHRoaXMpO1xuICB9O1xuXG4gIC8vIGB0aGlzYCAqIGB0aGlzYCBpbi1wbGFjZVxuICBCTi5wcm90b3R5cGUuaXNxciA9IGZ1bmN0aW9uIGlzcXIgKCkge1xuICAgIHJldHVybiB0aGlzLmltdWwodGhpcy5jbG9uZSgpKTtcbiAgfTtcblxuICAvLyBNYXRoLnBvdyhgdGhpc2AsIGBudW1gKVxuICBCTi5wcm90b3R5cGUucG93ID0gZnVuY3Rpb24gcG93IChudW0pIHtcbiAgICB2YXIgdyA9IHRvQml0QXJyYXkobnVtKTtcbiAgICBpZiAody5sZW5ndGggPT09IDApIHJldHVybiBuZXcgQk4oMSk7XG5cbiAgICAvLyBTa2lwIGxlYWRpbmcgemVyb2VzXG4gICAgdmFyIHJlcyA9IHRoaXM7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB3Lmxlbmd0aDsgaSsrLCByZXMgPSByZXMuc3FyKCkpIHtcbiAgICAgIGlmICh3W2ldICE9PSAwKSBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoKytpIDwgdy5sZW5ndGgpIHtcbiAgICAgIGZvciAodmFyIHEgPSByZXMuc3FyKCk7IGkgPCB3Lmxlbmd0aDsgaSsrLCBxID0gcS5zcXIoKSkge1xuICAgICAgICBpZiAod1tpXSA9PT0gMCkgY29udGludWU7XG5cbiAgICAgICAgcmVzID0gcmVzLm11bChxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIC8vIFNoaWZ0LWxlZnQgaW4tcGxhY2VcbiAgQk4ucHJvdG90eXBlLml1c2hsbiA9IGZ1bmN0aW9uIGl1c2hsbiAoYml0cykge1xuICAgIGFzc2VydCh0eXBlb2YgYml0cyA9PT0gJ251bWJlcicgJiYgYml0cyA+PSAwKTtcbiAgICB2YXIgciA9IGJpdHMgJSAyNjtcbiAgICB2YXIgcyA9IChiaXRzIC0gcikgLyAyNjtcbiAgICB2YXIgY2FycnlNYXNrID0gKDB4M2ZmZmZmZiA+Pj4gKDI2IC0gcikpIDw8ICgyNiAtIHIpO1xuICAgIHZhciBpO1xuXG4gICAgaWYgKHIgIT09IDApIHtcbiAgICAgIHZhciBjYXJyeSA9IDA7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBuZXdDYXJyeSA9IHRoaXMud29yZHNbaV0gJiBjYXJyeU1hc2s7XG4gICAgICAgIHZhciBjID0gKCh0aGlzLndvcmRzW2ldIHwgMCkgLSBuZXdDYXJyeSkgPDwgcjtcbiAgICAgICAgdGhpcy53b3Jkc1tpXSA9IGMgfCBjYXJyeTtcbiAgICAgICAgY2FycnkgPSBuZXdDYXJyeSA+Pj4gKDI2IC0gcik7XG4gICAgICB9XG5cbiAgICAgIGlmIChjYXJyeSkge1xuICAgICAgICB0aGlzLndvcmRzW2ldID0gY2Fycnk7XG4gICAgICAgIHRoaXMubGVuZ3RoKys7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHMgIT09IDApIHtcbiAgICAgIGZvciAoaSA9IHRoaXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgdGhpcy53b3Jkc1tpICsgc10gPSB0aGlzLndvcmRzW2ldO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgczsgaSsrKSB7XG4gICAgICAgIHRoaXMud29yZHNbaV0gPSAwO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmxlbmd0aCArPSBzO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmlzaGxuID0gZnVuY3Rpb24gaXNobG4gKGJpdHMpIHtcbiAgICAvLyBUT0RPKGluZHV0bnkpOiBpbXBsZW1lbnQgbWVcbiAgICBhc3NlcnQodGhpcy5uZWdhdGl2ZSA9PT0gMCk7XG4gICAgcmV0dXJuIHRoaXMuaXVzaGxuKGJpdHMpO1xuICB9O1xuXG4gIC8vIFNoaWZ0LXJpZ2h0IGluLXBsYWNlXG4gIC8vIE5PVEU6IGBoaW50YCBpcyBhIGxvd2VzdCBiaXQgYmVmb3JlIHRyYWlsaW5nIHplcm9lc1xuICAvLyBOT1RFOiBpZiBgZXh0ZW5kZWRgIGlzIHByZXNlbnQgLSBpdCB3aWxsIGJlIGZpbGxlZCB3aXRoIGRlc3Ryb3llZCBiaXRzXG4gIEJOLnByb3RvdHlwZS5pdXNocm4gPSBmdW5jdGlvbiBpdXNocm4gKGJpdHMsIGhpbnQsIGV4dGVuZGVkKSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBiaXRzID09PSAnbnVtYmVyJyAmJiBiaXRzID49IDApO1xuICAgIHZhciBoO1xuICAgIGlmIChoaW50KSB7XG4gICAgICBoID0gKGhpbnQgLSAoaGludCAlIDI2KSkgLyAyNjtcbiAgICB9IGVsc2Uge1xuICAgICAgaCA9IDA7XG4gICAgfVxuXG4gICAgdmFyIHIgPSBiaXRzICUgMjY7XG4gICAgdmFyIHMgPSBNYXRoLm1pbigoYml0cyAtIHIpIC8gMjYsIHRoaXMubGVuZ3RoKTtcbiAgICB2YXIgbWFzayA9IDB4M2ZmZmZmZiBeICgoMHgzZmZmZmZmID4+PiByKSA8PCByKTtcbiAgICB2YXIgbWFza2VkV29yZHMgPSBleHRlbmRlZDtcblxuICAgIGggLT0gcztcbiAgICBoID0gTWF0aC5tYXgoMCwgaCk7XG5cbiAgICAvLyBFeHRlbmRlZCBtb2RlLCBjb3B5IG1hc2tlZCBwYXJ0XG4gICAgaWYgKG1hc2tlZFdvcmRzKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHM7IGkrKykge1xuICAgICAgICBtYXNrZWRXb3Jkcy53b3Jkc1tpXSA9IHRoaXMud29yZHNbaV07XG4gICAgICB9XG4gICAgICBtYXNrZWRXb3Jkcy5sZW5ndGggPSBzO1xuICAgIH1cblxuICAgIGlmIChzID09PSAwKSB7XG4gICAgICAvLyBOby1vcCwgd2Ugc2hvdWxkIG5vdCBtb3ZlIGFueXRoaW5nIGF0IGFsbFxuICAgIH0gZWxzZSBpZiAodGhpcy5sZW5ndGggPiBzKSB7XG4gICAgICB0aGlzLmxlbmd0aCAtPSBzO1xuICAgICAgZm9yIChpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpcy53b3Jkc1tpXSA9IHRoaXMud29yZHNbaSArIHNdO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLndvcmRzWzBdID0gMDtcbiAgICAgIHRoaXMubGVuZ3RoID0gMTtcbiAgICB9XG5cbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIGZvciAoaSA9IHRoaXMubGVuZ3RoIC0gMTsgaSA+PSAwICYmIChjYXJyeSAhPT0gMCB8fCBpID49IGgpOyBpLS0pIHtcbiAgICAgIHZhciB3b3JkID0gdGhpcy53b3Jkc1tpXSB8IDA7XG4gICAgICB0aGlzLndvcmRzW2ldID0gKGNhcnJ5IDw8ICgyNiAtIHIpKSB8ICh3b3JkID4+PiByKTtcbiAgICAgIGNhcnJ5ID0gd29yZCAmIG1hc2s7XG4gICAgfVxuXG4gICAgLy8gUHVzaCBjYXJyaWVkIGJpdHMgYXMgYSBtYXNrXG4gICAgaWYgKG1hc2tlZFdvcmRzICYmIGNhcnJ5ICE9PSAwKSB7XG4gICAgICBtYXNrZWRXb3Jkcy53b3Jkc1ttYXNrZWRXb3Jkcy5sZW5ndGgrK10gPSBjYXJyeTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMud29yZHNbMF0gPSAwO1xuICAgICAgdGhpcy5sZW5ndGggPSAxO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmlzaHJuID0gZnVuY3Rpb24gaXNocm4gKGJpdHMsIGhpbnQsIGV4dGVuZGVkKSB7XG4gICAgLy8gVE9ETyhpbmR1dG55KTogaW1wbGVtZW50IG1lXG4gICAgYXNzZXJ0KHRoaXMubmVnYXRpdmUgPT09IDApO1xuICAgIHJldHVybiB0aGlzLml1c2hybihiaXRzLCBoaW50LCBleHRlbmRlZCk7XG4gIH07XG5cbiAgLy8gU2hpZnQtbGVmdFxuICBCTi5wcm90b3R5cGUuc2hsbiA9IGZ1bmN0aW9uIHNobG4gKGJpdHMpIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmlzaGxuKGJpdHMpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS51c2hsbiA9IGZ1bmN0aW9uIHVzaGxuIChiaXRzKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pdXNobG4oYml0cyk7XG4gIH07XG5cbiAgLy8gU2hpZnQtcmlnaHRcbiAgQk4ucHJvdG90eXBlLnNocm4gPSBmdW5jdGlvbiBzaHJuIChiaXRzKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pc2hybihiaXRzKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUudXNocm4gPSBmdW5jdGlvbiB1c2hybiAoYml0cykge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaXVzaHJuKGJpdHMpO1xuICB9O1xuXG4gIC8vIFRlc3QgaWYgbiBiaXQgaXMgc2V0XG4gIEJOLnByb3RvdHlwZS50ZXN0biA9IGZ1bmN0aW9uIHRlc3RuIChiaXQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGJpdCA9PT0gJ251bWJlcicgJiYgYml0ID49IDApO1xuICAgIHZhciByID0gYml0ICUgMjY7XG4gICAgdmFyIHMgPSAoYml0IC0gcikgLyAyNjtcbiAgICB2YXIgcSA9IDEgPDwgcjtcblxuICAgIC8vIEZhc3QgY2FzZTogYml0IGlzIG11Y2ggaGlnaGVyIHRoYW4gYWxsIGV4aXN0aW5nIHdvcmRzXG4gICAgaWYgKHRoaXMubGVuZ3RoIDw9IHMpIHJldHVybiBmYWxzZTtcblxuICAgIC8vIENoZWNrIGJpdCBhbmQgcmV0dXJuXG4gICAgdmFyIHcgPSB0aGlzLndvcmRzW3NdO1xuXG4gICAgcmV0dXJuICEhKHcgJiBxKTtcbiAgfTtcblxuICAvLyBSZXR1cm4gb25seSBsb3dlcnMgYml0cyBvZiBudW1iZXIgKGluLXBsYWNlKVxuICBCTi5wcm90b3R5cGUuaW1hc2tuID0gZnVuY3Rpb24gaW1hc2tuIChiaXRzKSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBiaXRzID09PSAnbnVtYmVyJyAmJiBiaXRzID49IDApO1xuICAgIHZhciByID0gYml0cyAlIDI2O1xuICAgIHZhciBzID0gKGJpdHMgLSByKSAvIDI2O1xuXG4gICAgYXNzZXJ0KHRoaXMubmVnYXRpdmUgPT09IDAsICdpbWFza24gd29ya3Mgb25seSB3aXRoIHBvc2l0aXZlIG51bWJlcnMnKTtcblxuICAgIGlmICh0aGlzLmxlbmd0aCA8PSBzKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBpZiAociAhPT0gMCkge1xuICAgICAgcysrO1xuICAgIH1cbiAgICB0aGlzLmxlbmd0aCA9IE1hdGgubWluKHMsIHRoaXMubGVuZ3RoKTtcblxuICAgIGlmIChyICE9PSAwKSB7XG4gICAgICB2YXIgbWFzayA9IDB4M2ZmZmZmZiBeICgoMHgzZmZmZmZmID4+PiByKSA8PCByKTtcbiAgICAgIHRoaXMud29yZHNbdGhpcy5sZW5ndGggLSAxXSAmPSBtYXNrO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgLy8gUmV0dXJuIG9ubHkgbG93ZXJzIGJpdHMgb2YgbnVtYmVyXG4gIEJOLnByb3RvdHlwZS5tYXNrbiA9IGZ1bmN0aW9uIG1hc2tuIChiaXRzKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pbWFza24oYml0cyk7XG4gIH07XG5cbiAgLy8gQWRkIHBsYWluIG51bWJlciBgbnVtYCB0byBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLmlhZGRuID0gZnVuY3Rpb24gaWFkZG4gKG51bSkge1xuICAgIGFzc2VydCh0eXBlb2YgbnVtID09PSAnbnVtYmVyJyk7XG4gICAgYXNzZXJ0KG51bSA8IDB4NDAwMDAwMCk7XG4gICAgaWYgKG51bSA8IDApIHJldHVybiB0aGlzLmlzdWJuKC1udW0pO1xuXG4gICAgLy8gUG9zc2libGUgc2lnbiBjaGFuZ2VcbiAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgaWYgKHRoaXMubGVuZ3RoID09PSAxICYmICh0aGlzLndvcmRzWzBdIHwgMCkgPCBudW0pIHtcbiAgICAgICAgdGhpcy53b3Jkc1swXSA9IG51bSAtICh0aGlzLndvcmRzWzBdIHwgMCk7XG4gICAgICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDA7XG4gICAgICB0aGlzLmlzdWJuKG51bSk7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEFkZCB3aXRob3V0IGNoZWNrc1xuICAgIHJldHVybiB0aGlzLl9pYWRkbihudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5faWFkZG4gPSBmdW5jdGlvbiBfaWFkZG4gKG51bSkge1xuICAgIHRoaXMud29yZHNbMF0gKz0gbnVtO1xuXG4gICAgLy8gQ2FycnlcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoICYmIHRoaXMud29yZHNbaV0gPj0gMHg0MDAwMDAwOyBpKyspIHtcbiAgICAgIHRoaXMud29yZHNbaV0gLT0gMHg0MDAwMDAwO1xuICAgICAgaWYgKGkgPT09IHRoaXMubGVuZ3RoIC0gMSkge1xuICAgICAgICB0aGlzLndvcmRzW2kgKyAxXSA9IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLndvcmRzW2kgKyAxXSsrO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmxlbmd0aCA9IE1hdGgubWF4KHRoaXMubGVuZ3RoLCBpICsgMSk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvLyBTdWJ0cmFjdCBwbGFpbiBudW1iZXIgYG51bWAgZnJvbSBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLmlzdWJuID0gZnVuY3Rpb24gaXN1Ym4gKG51bSkge1xuICAgIGFzc2VydCh0eXBlb2YgbnVtID09PSAnbnVtYmVyJyk7XG4gICAgYXNzZXJ0KG51bSA8IDB4NDAwMDAwMCk7XG4gICAgaWYgKG51bSA8IDApIHJldHVybiB0aGlzLmlhZGRuKC1udW0pO1xuXG4gICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgICAgdGhpcy5pYWRkbihudW0pO1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDE7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB0aGlzLndvcmRzWzBdIC09IG51bTtcblxuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMSAmJiB0aGlzLndvcmRzWzBdIDwgMCkge1xuICAgICAgdGhpcy53b3Jkc1swXSA9IC10aGlzLndvcmRzWzBdO1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIENhcnJ5XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoICYmIHRoaXMud29yZHNbaV0gPCAwOyBpKyspIHtcbiAgICAgICAgdGhpcy53b3Jkc1tpXSArPSAweDQwMDAwMDA7XG4gICAgICAgIHRoaXMud29yZHNbaSArIDFdIC09IDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuYWRkbiA9IGZ1bmN0aW9uIGFkZG4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaWFkZG4obnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuc3VibiA9IGZ1bmN0aW9uIHN1Ym4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaXN1Ym4obnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaWFicyA9IGZ1bmN0aW9uIGlhYnMgKCkge1xuICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmFicyA9IGZ1bmN0aW9uIGFicyAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pYWJzKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLl9pc2hsbnN1Ym11bCA9IGZ1bmN0aW9uIF9pc2hsbnN1Ym11bCAobnVtLCBtdWwsIHNoaWZ0KSB7XG4gICAgdmFyIGxlbiA9IG51bS5sZW5ndGggKyBzaGlmdDtcbiAgICB2YXIgaTtcblxuICAgIHRoaXMuX2V4cGFuZChsZW4pO1xuXG4gICAgdmFyIHc7XG4gICAgdmFyIGNhcnJ5ID0gMDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbnVtLmxlbmd0aDsgaSsrKSB7XG4gICAgICB3ID0gKHRoaXMud29yZHNbaSArIHNoaWZ0XSB8IDApICsgY2Fycnk7XG4gICAgICB2YXIgcmlnaHQgPSAobnVtLndvcmRzW2ldIHwgMCkgKiBtdWw7XG4gICAgICB3IC09IHJpZ2h0ICYgMHgzZmZmZmZmO1xuICAgICAgY2FycnkgPSAodyA+PiAyNikgLSAoKHJpZ2h0IC8gMHg0MDAwMDAwKSB8IDApO1xuICAgICAgdGhpcy53b3Jkc1tpICsgc2hpZnRdID0gdyAmIDB4M2ZmZmZmZjtcbiAgICB9XG4gICAgZm9yICg7IGkgPCB0aGlzLmxlbmd0aCAtIHNoaWZ0OyBpKyspIHtcbiAgICAgIHcgPSAodGhpcy53b3Jkc1tpICsgc2hpZnRdIHwgMCkgKyBjYXJyeTtcbiAgICAgIGNhcnJ5ID0gdyA+PiAyNjtcbiAgICAgIHRoaXMud29yZHNbaSArIHNoaWZ0XSA9IHcgJiAweDNmZmZmZmY7XG4gICAgfVxuXG4gICAgaWYgKGNhcnJ5ID09PSAwKSByZXR1cm4gdGhpcy5zdHJpcCgpO1xuXG4gICAgLy8gU3VidHJhY3Rpb24gb3ZlcmZsb3dcbiAgICBhc3NlcnQoY2FycnkgPT09IC0xKTtcbiAgICBjYXJyeSA9IDA7XG4gICAgZm9yIChpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHcgPSAtKHRoaXMud29yZHNbaV0gfCAwKSArIGNhcnJ5O1xuICAgICAgY2FycnkgPSB3ID4+IDI2O1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IHcgJiAweDNmZmZmZmY7XG4gICAgfVxuICAgIHRoaXMubmVnYXRpdmUgPSAxO1xuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuX3dvcmREaXYgPSBmdW5jdGlvbiBfd29yZERpdiAobnVtLCBtb2RlKSB7XG4gICAgdmFyIHNoaWZ0ID0gdGhpcy5sZW5ndGggLSBudW0ubGVuZ3RoO1xuXG4gICAgdmFyIGEgPSB0aGlzLmNsb25lKCk7XG4gICAgdmFyIGIgPSBudW07XG5cbiAgICAvLyBOb3JtYWxpemVcbiAgICB2YXIgYmhpID0gYi53b3Jkc1tiLmxlbmd0aCAtIDFdIHwgMDtcbiAgICB2YXIgYmhpQml0cyA9IHRoaXMuX2NvdW50Qml0cyhiaGkpO1xuICAgIHNoaWZ0ID0gMjYgLSBiaGlCaXRzO1xuICAgIGlmIChzaGlmdCAhPT0gMCkge1xuICAgICAgYiA9IGIudXNobG4oc2hpZnQpO1xuICAgICAgYS5pdXNobG4oc2hpZnQpO1xuICAgICAgYmhpID0gYi53b3Jkc1tiLmxlbmd0aCAtIDFdIHwgMDtcbiAgICB9XG5cbiAgICAvLyBJbml0aWFsaXplIHF1b3RpZW50XG4gICAgdmFyIG0gPSBhLmxlbmd0aCAtIGIubGVuZ3RoO1xuICAgIHZhciBxO1xuXG4gICAgaWYgKG1vZGUgIT09ICdtb2QnKSB7XG4gICAgICBxID0gbmV3IEJOKG51bGwpO1xuICAgICAgcS5sZW5ndGggPSBtICsgMTtcbiAgICAgIHEud29yZHMgPSBuZXcgQXJyYXkocS5sZW5ndGgpO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBxLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHEud29yZHNbaV0gPSAwO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkaWZmID0gYS5jbG9uZSgpLl9pc2hsbnN1Ym11bChiLCAxLCBtKTtcbiAgICBpZiAoZGlmZi5uZWdhdGl2ZSA9PT0gMCkge1xuICAgICAgYSA9IGRpZmY7XG4gICAgICBpZiAocSkge1xuICAgICAgICBxLndvcmRzW21dID0gMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKHZhciBqID0gbSAtIDE7IGogPj0gMDsgai0tKSB7XG4gICAgICB2YXIgcWogPSAoYS53b3Jkc1tiLmxlbmd0aCArIGpdIHwgMCkgKiAweDQwMDAwMDAgK1xuICAgICAgICAoYS53b3Jkc1tiLmxlbmd0aCArIGogLSAxXSB8IDApO1xuXG4gICAgICAvLyBOT1RFOiAocWogLyBiaGkpIGlzICgweDNmZmZmZmYgKiAweDQwMDAwMDAgKyAweDNmZmZmZmYpIC8gMHgyMDAwMDAwIG1heFxuICAgICAgLy8gKDB4N2ZmZmZmZilcbiAgICAgIHFqID0gTWF0aC5taW4oKHFqIC8gYmhpKSB8IDAsIDB4M2ZmZmZmZik7XG5cbiAgICAgIGEuX2lzaGxuc3VibXVsKGIsIHFqLCBqKTtcbiAgICAgIHdoaWxlIChhLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICAgIHFqLS07XG4gICAgICAgIGEubmVnYXRpdmUgPSAwO1xuICAgICAgICBhLl9pc2hsbnN1Ym11bChiLCAxLCBqKTtcbiAgICAgICAgaWYgKCFhLmlzWmVybygpKSB7XG4gICAgICAgICAgYS5uZWdhdGl2ZSBePSAxO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAocSkge1xuICAgICAgICBxLndvcmRzW2pdID0gcWo7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChxKSB7XG4gICAgICBxLnN0cmlwKCk7XG4gICAgfVxuICAgIGEuc3RyaXAoKTtcblxuICAgIC8vIERlbm9ybWFsaXplXG4gICAgaWYgKG1vZGUgIT09ICdkaXYnICYmIHNoaWZ0ICE9PSAwKSB7XG4gICAgICBhLml1c2hybihzaGlmdCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRpdjogcSB8fCBudWxsLFxuICAgICAgbW9kOiBhXG4gICAgfTtcbiAgfTtcblxuICAvLyBOT1RFOiAxKSBgbW9kZWAgY2FuIGJlIHNldCB0byBgbW9kYCB0byByZXF1ZXN0IG1vZCBvbmx5LFxuICAvLyAgICAgICB0byBgZGl2YCB0byByZXF1ZXN0IGRpdiBvbmx5LCBvciBiZSBhYnNlbnQgdG9cbiAgLy8gICAgICAgcmVxdWVzdCBib3RoIGRpdiAmIG1vZFxuICAvLyAgICAgICAyKSBgcG9zaXRpdmVgIGlzIHRydWUgaWYgdW5zaWduZWQgbW9kIGlzIHJlcXVlc3RlZFxuICBCTi5wcm90b3R5cGUuZGl2bW9kID0gZnVuY3Rpb24gZGl2bW9kIChudW0sIG1vZGUsIHBvc2l0aXZlKSB7XG4gICAgYXNzZXJ0KCFudW0uaXNaZXJvKCkpO1xuXG4gICAgaWYgKHRoaXMuaXNaZXJvKCkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRpdjogbmV3IEJOKDApLFxuICAgICAgICBtb2Q6IG5ldyBCTigwKVxuICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgZGl2LCBtb2QsIHJlcztcbiAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCAmJiBudW0ubmVnYXRpdmUgPT09IDApIHtcbiAgICAgIHJlcyA9IHRoaXMubmVnKCkuZGl2bW9kKG51bSwgbW9kZSk7XG5cbiAgICAgIGlmIChtb2RlICE9PSAnbW9kJykge1xuICAgICAgICBkaXYgPSByZXMuZGl2Lm5lZygpO1xuICAgICAgfVxuXG4gICAgICBpZiAobW9kZSAhPT0gJ2RpdicpIHtcbiAgICAgICAgbW9kID0gcmVzLm1vZC5uZWcoKTtcbiAgICAgICAgaWYgKHBvc2l0aXZlICYmIG1vZC5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgICAgIG1vZC5pYWRkKG51bSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGl2OiBkaXYsXG4gICAgICAgIG1vZDogbW9kXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICh0aGlzLm5lZ2F0aXZlID09PSAwICYmIG51bS5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgcmVzID0gdGhpcy5kaXZtb2QobnVtLm5lZygpLCBtb2RlKTtcblxuICAgICAgaWYgKG1vZGUgIT09ICdtb2QnKSB7XG4gICAgICAgIGRpdiA9IHJlcy5kaXYubmVnKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRpdjogZGl2LFxuICAgICAgICBtb2Q6IHJlcy5tb2RcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKCh0aGlzLm5lZ2F0aXZlICYgbnVtLm5lZ2F0aXZlKSAhPT0gMCkge1xuICAgICAgcmVzID0gdGhpcy5uZWcoKS5kaXZtb2QobnVtLm5lZygpLCBtb2RlKTtcblxuICAgICAgaWYgKG1vZGUgIT09ICdkaXYnKSB7XG4gICAgICAgIG1vZCA9IHJlcy5tb2QubmVnKCk7XG4gICAgICAgIGlmIChwb3NpdGl2ZSAmJiBtb2QubmVnYXRpdmUgIT09IDApIHtcbiAgICAgICAgICBtb2QuaXN1YihudW0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRpdjogcmVzLmRpdixcbiAgICAgICAgbW9kOiBtb2RcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gQm90aCBudW1iZXJzIGFyZSBwb3NpdGl2ZSBhdCB0aGlzIHBvaW50XG5cbiAgICAvLyBTdHJpcCBib3RoIG51bWJlcnMgdG8gYXBwcm94aW1hdGUgc2hpZnQgdmFsdWVcbiAgICBpZiAobnVtLmxlbmd0aCA+IHRoaXMubGVuZ3RoIHx8IHRoaXMuY21wKG51bSkgPCAwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBkaXY6IG5ldyBCTigwKSxcbiAgICAgICAgbW9kOiB0aGlzXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIFZlcnkgc2hvcnQgcmVkdWN0aW9uXG4gICAgaWYgKG51bS5sZW5ndGggPT09IDEpIHtcbiAgICAgIGlmIChtb2RlID09PSAnZGl2Jykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGRpdjogdGhpcy5kaXZuKG51bS53b3Jkc1swXSksXG4gICAgICAgICAgbW9kOiBudWxsXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGlmIChtb2RlID09PSAnbW9kJykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGRpdjogbnVsbCxcbiAgICAgICAgICBtb2Q6IG5ldyBCTih0aGlzLm1vZG4obnVtLndvcmRzWzBdKSlcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGl2OiB0aGlzLmRpdm4obnVtLndvcmRzWzBdKSxcbiAgICAgICAgbW9kOiBuZXcgQk4odGhpcy5tb2RuKG51bS53b3Jkc1swXSkpXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl93b3JkRGl2KG51bSwgbW9kZSk7XG4gIH07XG5cbiAgLy8gRmluZCBgdGhpc2AgLyBgbnVtYFxuICBCTi5wcm90b3R5cGUuZGl2ID0gZnVuY3Rpb24gZGl2IChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5kaXZtb2QobnVtLCAnZGl2JywgZmFsc2UpLmRpdjtcbiAgfTtcblxuICAvLyBGaW5kIGB0aGlzYCAlIGBudW1gXG4gIEJOLnByb3RvdHlwZS5tb2QgPSBmdW5jdGlvbiBtb2QgKG51bSkge1xuICAgIHJldHVybiB0aGlzLmRpdm1vZChudW0sICdtb2QnLCBmYWxzZSkubW9kO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS51bW9kID0gZnVuY3Rpb24gdW1vZCAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuZGl2bW9kKG51bSwgJ21vZCcsIHRydWUpLm1vZDtcbiAgfTtcblxuICAvLyBGaW5kIFJvdW5kKGB0aGlzYCAvIGBudW1gKVxuICBCTi5wcm90b3R5cGUuZGl2Um91bmQgPSBmdW5jdGlvbiBkaXZSb3VuZCAobnVtKSB7XG4gICAgdmFyIGRtID0gdGhpcy5kaXZtb2QobnVtKTtcblxuICAgIC8vIEZhc3QgY2FzZSAtIGV4YWN0IGRpdmlzaW9uXG4gICAgaWYgKGRtLm1vZC5pc1plcm8oKSkgcmV0dXJuIGRtLmRpdjtcblxuICAgIHZhciBtb2QgPSBkbS5kaXYubmVnYXRpdmUgIT09IDAgPyBkbS5tb2QuaXN1YihudW0pIDogZG0ubW9kO1xuXG4gICAgdmFyIGhhbGYgPSBudW0udXNocm4oMSk7XG4gICAgdmFyIHIyID0gbnVtLmFuZGxuKDEpO1xuICAgIHZhciBjbXAgPSBtb2QuY21wKGhhbGYpO1xuXG4gICAgLy8gUm91bmQgZG93blxuICAgIGlmIChjbXAgPCAwIHx8IHIyID09PSAxICYmIGNtcCA9PT0gMCkgcmV0dXJuIGRtLmRpdjtcblxuICAgIC8vIFJvdW5kIHVwXG4gICAgcmV0dXJuIGRtLmRpdi5uZWdhdGl2ZSAhPT0gMCA/IGRtLmRpdi5pc3VibigxKSA6IGRtLmRpdi5pYWRkbigxKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUubW9kbiA9IGZ1bmN0aW9uIG1vZG4gKG51bSkge1xuICAgIGFzc2VydChudW0gPD0gMHgzZmZmZmZmKTtcbiAgICB2YXIgcCA9ICgxIDw8IDI2KSAlIG51bTtcblxuICAgIHZhciBhY2MgPSAwO1xuICAgIGZvciAodmFyIGkgPSB0aGlzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBhY2MgPSAocCAqIGFjYyArICh0aGlzLndvcmRzW2ldIHwgMCkpICUgbnVtO1xuICAgIH1cblxuICAgIHJldHVybiBhY2M7XG4gIH07XG5cbiAgLy8gSW4tcGxhY2UgZGl2aXNpb24gYnkgbnVtYmVyXG4gIEJOLnByb3RvdHlwZS5pZGl2biA9IGZ1bmN0aW9uIGlkaXZuIChudW0pIHtcbiAgICBhc3NlcnQobnVtIDw9IDB4M2ZmZmZmZik7XG5cbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIGZvciAodmFyIGkgPSB0aGlzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgdyA9ICh0aGlzLndvcmRzW2ldIHwgMCkgKyBjYXJyeSAqIDB4NDAwMDAwMDtcbiAgICAgIHRoaXMud29yZHNbaV0gPSAodyAvIG51bSkgfCAwO1xuICAgICAgY2FycnkgPSB3ICUgbnVtO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmRpdm4gPSBmdW5jdGlvbiBkaXZuIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmlkaXZuKG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmVnY2QgPSBmdW5jdGlvbiBlZ2NkIChwKSB7XG4gICAgYXNzZXJ0KHAubmVnYXRpdmUgPT09IDApO1xuICAgIGFzc2VydCghcC5pc1plcm8oKSk7XG5cbiAgICB2YXIgeCA9IHRoaXM7XG4gICAgdmFyIHkgPSBwLmNsb25lKCk7XG5cbiAgICBpZiAoeC5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgeCA9IHgudW1vZChwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgeCA9IHguY2xvbmUoKTtcbiAgICB9XG5cbiAgICAvLyBBICogeCArIEIgKiB5ID0geFxuICAgIHZhciBBID0gbmV3IEJOKDEpO1xuICAgIHZhciBCID0gbmV3IEJOKDApO1xuXG4gICAgLy8gQyAqIHggKyBEICogeSA9IHlcbiAgICB2YXIgQyA9IG5ldyBCTigwKTtcbiAgICB2YXIgRCA9IG5ldyBCTigxKTtcblxuICAgIHZhciBnID0gMDtcblxuICAgIHdoaWxlICh4LmlzRXZlbigpICYmIHkuaXNFdmVuKCkpIHtcbiAgICAgIHguaXVzaHJuKDEpO1xuICAgICAgeS5pdXNocm4oMSk7XG4gICAgICArK2c7XG4gICAgfVxuXG4gICAgdmFyIHlwID0geS5jbG9uZSgpO1xuICAgIHZhciB4cCA9IHguY2xvbmUoKTtcblxuICAgIHdoaWxlICgheC5pc1plcm8oKSkge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGltID0gMTsgKHgud29yZHNbMF0gJiBpbSkgPT09IDAgJiYgaSA8IDI2OyArK2ksIGltIDw8PSAxKTtcbiAgICAgIGlmIChpID4gMCkge1xuICAgICAgICB4Lml1c2hybihpKTtcbiAgICAgICAgd2hpbGUgKGktLSA+IDApIHtcbiAgICAgICAgICBpZiAoQS5pc09kZCgpIHx8IEIuaXNPZGQoKSkge1xuICAgICAgICAgICAgQS5pYWRkKHlwKTtcbiAgICAgICAgICAgIEIuaXN1Yih4cCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgQS5pdXNocm4oMSk7XG4gICAgICAgICAgQi5pdXNocm4oMSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIgaiA9IDAsIGptID0gMTsgKHkud29yZHNbMF0gJiBqbSkgPT09IDAgJiYgaiA8IDI2OyArK2osIGptIDw8PSAxKTtcbiAgICAgIGlmIChqID4gMCkge1xuICAgICAgICB5Lml1c2hybihqKTtcbiAgICAgICAgd2hpbGUgKGotLSA+IDApIHtcbiAgICAgICAgICBpZiAoQy5pc09kZCgpIHx8IEQuaXNPZGQoKSkge1xuICAgICAgICAgICAgQy5pYWRkKHlwKTtcbiAgICAgICAgICAgIEQuaXN1Yih4cCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgQy5pdXNocm4oMSk7XG4gICAgICAgICAgRC5pdXNocm4oMSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHguY21wKHkpID49IDApIHtcbiAgICAgICAgeC5pc3ViKHkpO1xuICAgICAgICBBLmlzdWIoQyk7XG4gICAgICAgIEIuaXN1YihEKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHkuaXN1Yih4KTtcbiAgICAgICAgQy5pc3ViKEEpO1xuICAgICAgICBELmlzdWIoQik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGE6IEMsXG4gICAgICBiOiBELFxuICAgICAgZ2NkOiB5Lml1c2hsbihnKVxuICAgIH07XG4gIH07XG5cbiAgLy8gVGhpcyBpcyByZWR1Y2VkIGluY2FybmF0aW9uIG9mIHRoZSBiaW5hcnkgRUVBXG4gIC8vIGFib3ZlLCBkZXNpZ25hdGVkIHRvIGludmVydCBtZW1iZXJzIG9mIHRoZVxuICAvLyBfcHJpbWVfIGZpZWxkcyBGKHApIGF0IGEgbWF4aW1hbCBzcGVlZFxuICBCTi5wcm90b3R5cGUuX2ludm1wID0gZnVuY3Rpb24gX2ludm1wIChwKSB7XG4gICAgYXNzZXJ0KHAubmVnYXRpdmUgPT09IDApO1xuICAgIGFzc2VydCghcC5pc1plcm8oKSk7XG5cbiAgICB2YXIgYSA9IHRoaXM7XG4gICAgdmFyIGIgPSBwLmNsb25lKCk7XG5cbiAgICBpZiAoYS5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgYSA9IGEudW1vZChwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYSA9IGEuY2xvbmUoKTtcbiAgICB9XG5cbiAgICB2YXIgeDEgPSBuZXcgQk4oMSk7XG4gICAgdmFyIHgyID0gbmV3IEJOKDApO1xuXG4gICAgdmFyIGRlbHRhID0gYi5jbG9uZSgpO1xuXG4gICAgd2hpbGUgKGEuY21wbigxKSA+IDAgJiYgYi5jbXBuKDEpID4gMCkge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGltID0gMTsgKGEud29yZHNbMF0gJiBpbSkgPT09IDAgJiYgaSA8IDI2OyArK2ksIGltIDw8PSAxKTtcbiAgICAgIGlmIChpID4gMCkge1xuICAgICAgICBhLml1c2hybihpKTtcbiAgICAgICAgd2hpbGUgKGktLSA+IDApIHtcbiAgICAgICAgICBpZiAoeDEuaXNPZGQoKSkge1xuICAgICAgICAgICAgeDEuaWFkZChkZWx0YSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgeDEuaXVzaHJuKDEpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAodmFyIGogPSAwLCBqbSA9IDE7IChiLndvcmRzWzBdICYgam0pID09PSAwICYmIGogPCAyNjsgKytqLCBqbSA8PD0gMSk7XG4gICAgICBpZiAoaiA+IDApIHtcbiAgICAgICAgYi5pdXNocm4oaik7XG4gICAgICAgIHdoaWxlIChqLS0gPiAwKSB7XG4gICAgICAgICAgaWYgKHgyLmlzT2RkKCkpIHtcbiAgICAgICAgICAgIHgyLmlhZGQoZGVsdGEpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHgyLml1c2hybigxKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoYS5jbXAoYikgPj0gMCkge1xuICAgICAgICBhLmlzdWIoYik7XG4gICAgICAgIHgxLmlzdWIoeDIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYi5pc3ViKGEpO1xuICAgICAgICB4Mi5pc3ViKHgxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcmVzO1xuICAgIGlmIChhLmNtcG4oMSkgPT09IDApIHtcbiAgICAgIHJlcyA9IHgxO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXMgPSB4MjtcbiAgICB9XG5cbiAgICBpZiAocmVzLmNtcG4oMCkgPCAwKSB7XG4gICAgICByZXMuaWFkZChwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5nY2QgPSBmdW5jdGlvbiBnY2QgKG51bSkge1xuICAgIGlmICh0aGlzLmlzWmVybygpKSByZXR1cm4gbnVtLmFicygpO1xuICAgIGlmIChudW0uaXNaZXJvKCkpIHJldHVybiB0aGlzLmFicygpO1xuXG4gICAgdmFyIGEgPSB0aGlzLmNsb25lKCk7XG4gICAgdmFyIGIgPSBudW0uY2xvbmUoKTtcbiAgICBhLm5lZ2F0aXZlID0gMDtcbiAgICBiLm5lZ2F0aXZlID0gMDtcblxuICAgIC8vIFJlbW92ZSBjb21tb24gZmFjdG9yIG9mIHR3b1xuICAgIGZvciAodmFyIHNoaWZ0ID0gMDsgYS5pc0V2ZW4oKSAmJiBiLmlzRXZlbigpOyBzaGlmdCsrKSB7XG4gICAgICBhLml1c2hybigxKTtcbiAgICAgIGIuaXVzaHJuKDEpO1xuICAgIH1cblxuICAgIGRvIHtcbiAgICAgIHdoaWxlIChhLmlzRXZlbigpKSB7XG4gICAgICAgIGEuaXVzaHJuKDEpO1xuICAgICAgfVxuICAgICAgd2hpbGUgKGIuaXNFdmVuKCkpIHtcbiAgICAgICAgYi5pdXNocm4oMSk7XG4gICAgICB9XG5cbiAgICAgIHZhciByID0gYS5jbXAoYik7XG4gICAgICBpZiAociA8IDApIHtcbiAgICAgICAgLy8gU3dhcCBgYWAgYW5kIGBiYCB0byBtYWtlIGBhYCBhbHdheXMgYmlnZ2VyIHRoYW4gYGJgXG4gICAgICAgIHZhciB0ID0gYTtcbiAgICAgICAgYSA9IGI7XG4gICAgICAgIGIgPSB0O1xuICAgICAgfSBlbHNlIGlmIChyID09PSAwIHx8IGIuY21wbigxKSA9PT0gMCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgYS5pc3ViKGIpO1xuICAgIH0gd2hpbGUgKHRydWUpO1xuXG4gICAgcmV0dXJuIGIuaXVzaGxuKHNoaWZ0KTtcbiAgfTtcblxuICAvLyBJbnZlcnQgbnVtYmVyIGluIHRoZSBmaWVsZCBGKG51bSlcbiAgQk4ucHJvdG90eXBlLmludm0gPSBmdW5jdGlvbiBpbnZtIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5lZ2NkKG51bSkuYS51bW9kKG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmlzRXZlbiA9IGZ1bmN0aW9uIGlzRXZlbiAoKSB7XG4gICAgcmV0dXJuICh0aGlzLndvcmRzWzBdICYgMSkgPT09IDA7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmlzT2RkID0gZnVuY3Rpb24gaXNPZGQgKCkge1xuICAgIHJldHVybiAodGhpcy53b3Jkc1swXSAmIDEpID09PSAxO1xuICB9O1xuXG4gIC8vIEFuZCBmaXJzdCB3b3JkIGFuZCBudW1cbiAgQk4ucHJvdG90eXBlLmFuZGxuID0gZnVuY3Rpb24gYW5kbG4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLndvcmRzWzBdICYgbnVtO1xuICB9O1xuXG4gIC8vIEluY3JlbWVudCBhdCB0aGUgYml0IHBvc2l0aW9uIGluLWxpbmVcbiAgQk4ucHJvdG90eXBlLmJpbmNuID0gZnVuY3Rpb24gYmluY24gKGJpdCkge1xuICAgIGFzc2VydCh0eXBlb2YgYml0ID09PSAnbnVtYmVyJyk7XG4gICAgdmFyIHIgPSBiaXQgJSAyNjtcbiAgICB2YXIgcyA9IChiaXQgLSByKSAvIDI2O1xuICAgIHZhciBxID0gMSA8PCByO1xuXG4gICAgLy8gRmFzdCBjYXNlOiBiaXQgaXMgbXVjaCBoaWdoZXIgdGhhbiBhbGwgZXhpc3Rpbmcgd29yZHNcbiAgICBpZiAodGhpcy5sZW5ndGggPD0gcykge1xuICAgICAgdGhpcy5fZXhwYW5kKHMgKyAxKTtcbiAgICAgIHRoaXMud29yZHNbc10gfD0gcTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEFkZCBiaXQgYW5kIHByb3BhZ2F0ZSwgaWYgbmVlZGVkXG4gICAgdmFyIGNhcnJ5ID0gcTtcbiAgICBmb3IgKHZhciBpID0gczsgY2FycnkgIT09IDAgJiYgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciB3ID0gdGhpcy53b3Jkc1tpXSB8IDA7XG4gICAgICB3ICs9IGNhcnJ5O1xuICAgICAgY2FycnkgPSB3ID4+PiAyNjtcbiAgICAgIHcgJj0gMHgzZmZmZmZmO1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IHc7XG4gICAgfVxuICAgIGlmIChjYXJyeSAhPT0gMCkge1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IGNhcnJ5O1xuICAgICAgdGhpcy5sZW5ndGgrKztcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmlzWmVybyA9IGZ1bmN0aW9uIGlzWmVybyAoKSB7XG4gICAgcmV0dXJuIHRoaXMubGVuZ3RoID09PSAxICYmIHRoaXMud29yZHNbMF0gPT09IDA7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmNtcG4gPSBmdW5jdGlvbiBjbXBuIChudW0pIHtcbiAgICB2YXIgbmVnYXRpdmUgPSBudW0gPCAwO1xuXG4gICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDAgJiYgIW5lZ2F0aXZlKSByZXR1cm4gLTE7XG4gICAgaWYgKHRoaXMubmVnYXRpdmUgPT09IDAgJiYgbmVnYXRpdmUpIHJldHVybiAxO1xuXG4gICAgdGhpcy5zdHJpcCgpO1xuXG4gICAgdmFyIHJlcztcbiAgICBpZiAodGhpcy5sZW5ndGggPiAxKSB7XG4gICAgICByZXMgPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAobmVnYXRpdmUpIHtcbiAgICAgICAgbnVtID0gLW51bTtcbiAgICAgIH1cblxuICAgICAgYXNzZXJ0KG51bSA8PSAweDNmZmZmZmYsICdOdW1iZXIgaXMgdG9vIGJpZycpO1xuXG4gICAgICB2YXIgdyA9IHRoaXMud29yZHNbMF0gfCAwO1xuICAgICAgcmVzID0gdyA9PT0gbnVtID8gMCA6IHcgPCBudW0gPyAtMSA6IDE7XG4gICAgfVxuICAgIGlmICh0aGlzLm5lZ2F0aXZlICE9PSAwKSByZXR1cm4gLXJlcyB8IDA7XG4gICAgcmV0dXJuIHJlcztcbiAgfTtcblxuICAvLyBDb21wYXJlIHR3byBudW1iZXJzIGFuZCByZXR1cm46XG4gIC8vIDEgLSBpZiBgdGhpc2AgPiBgbnVtYFxuICAvLyAwIC0gaWYgYHRoaXNgID09IGBudW1gXG4gIC8vIC0xIC0gaWYgYHRoaXNgIDwgYG51bWBcbiAgQk4ucHJvdG90eXBlLmNtcCA9IGZ1bmN0aW9uIGNtcCAobnVtKSB7XG4gICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDAgJiYgbnVtLm5lZ2F0aXZlID09PSAwKSByZXR1cm4gLTE7XG4gICAgaWYgKHRoaXMubmVnYXRpdmUgPT09IDAgJiYgbnVtLm5lZ2F0aXZlICE9PSAwKSByZXR1cm4gMTtcblxuICAgIHZhciByZXMgPSB0aGlzLnVjbXAobnVtKTtcbiAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCkgcmV0dXJuIC1yZXMgfCAwO1xuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgLy8gVW5zaWduZWQgY29tcGFyaXNvblxuICBCTi5wcm90b3R5cGUudWNtcCA9IGZ1bmN0aW9uIHVjbXAgKG51bSkge1xuICAgIC8vIEF0IHRoaXMgcG9pbnQgYm90aCBudW1iZXJzIGhhdmUgdGhlIHNhbWUgc2lnblxuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHJldHVybiAxO1xuICAgIGlmICh0aGlzLmxlbmd0aCA8IG51bS5sZW5ndGgpIHJldHVybiAtMTtcblxuICAgIHZhciByZXMgPSAwO1xuICAgIGZvciAodmFyIGkgPSB0aGlzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgYSA9IHRoaXMud29yZHNbaV0gfCAwO1xuICAgICAgdmFyIGIgPSBudW0ud29yZHNbaV0gfCAwO1xuXG4gICAgICBpZiAoYSA9PT0gYikgY29udGludWU7XG4gICAgICBpZiAoYSA8IGIpIHtcbiAgICAgICAgcmVzID0gLTE7XG4gICAgICB9IGVsc2UgaWYgKGEgPiBiKSB7XG4gICAgICAgIHJlcyA9IDE7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZ3RuID0gZnVuY3Rpb24gZ3RuIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXBuKG51bSkgPT09IDE7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmd0ID0gZnVuY3Rpb24gZ3QgKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNtcChudW0pID09PSAxO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5ndGVuID0gZnVuY3Rpb24gZ3RlbiAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY21wbihudW0pID49IDA7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmd0ZSA9IGZ1bmN0aW9uIGd0ZSAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY21wKG51bSkgPj0gMDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUubHRuID0gZnVuY3Rpb24gbHRuIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXBuKG51bSkgPT09IC0xO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5sdCA9IGZ1bmN0aW9uIGx0IChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXAobnVtKSA9PT0gLTE7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmx0ZW4gPSBmdW5jdGlvbiBsdGVuIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXBuKG51bSkgPD0gMDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUubHRlID0gZnVuY3Rpb24gbHRlIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXAobnVtKSA8PSAwO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5lcW4gPSBmdW5jdGlvbiBlcW4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNtcG4obnVtKSA9PT0gMDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZXEgPSBmdW5jdGlvbiBlcSAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY21wKG51bSkgPT09IDA7XG4gIH07XG5cbiAgLy9cbiAgLy8gQSByZWR1Y2UgY29udGV4dCwgY291bGQgYmUgdXNpbmcgbW9udGdvbWVyeSBvciBzb21ldGhpbmcgYmV0dGVyLCBkZXBlbmRpbmdcbiAgLy8gb24gdGhlIGBtYCBpdHNlbGYuXG4gIC8vXG4gIEJOLnJlZCA9IGZ1bmN0aW9uIHJlZCAobnVtKSB7XG4gICAgcmV0dXJuIG5ldyBSZWQobnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUudG9SZWQgPSBmdW5jdGlvbiB0b1JlZCAoY3R4KSB7XG4gICAgYXNzZXJ0KCF0aGlzLnJlZCwgJ0FscmVhZHkgYSBudW1iZXIgaW4gcmVkdWN0aW9uIGNvbnRleHQnKTtcbiAgICBhc3NlcnQodGhpcy5uZWdhdGl2ZSA9PT0gMCwgJ3JlZCB3b3JrcyBvbmx5IHdpdGggcG9zaXRpdmVzJyk7XG4gICAgcmV0dXJuIGN0eC5jb252ZXJ0VG8odGhpcykuX2ZvcmNlUmVkKGN0eCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmZyb21SZWQgPSBmdW5jdGlvbiBmcm9tUmVkICgpIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdmcm9tUmVkIHdvcmtzIG9ubHkgd2l0aCBudW1iZXJzIGluIHJlZHVjdGlvbiBjb250ZXh0Jyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLmNvbnZlcnRGcm9tKHRoaXMpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5fZm9yY2VSZWQgPSBmdW5jdGlvbiBfZm9yY2VSZWQgKGN0eCkge1xuICAgIHRoaXMucmVkID0gY3R4O1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5mb3JjZVJlZCA9IGZ1bmN0aW9uIGZvcmNlUmVkIChjdHgpIHtcbiAgICBhc3NlcnQoIXRoaXMucmVkLCAnQWxyZWFkeSBhIG51bWJlciBpbiByZWR1Y3Rpb24gY29udGV4dCcpO1xuICAgIHJldHVybiB0aGlzLl9mb3JjZVJlZChjdHgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5yZWRBZGQgPSBmdW5jdGlvbiByZWRBZGQgKG51bSkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZEFkZCB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgICByZXR1cm4gdGhpcy5yZWQuYWRkKHRoaXMsIG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZElBZGQgPSBmdW5jdGlvbiByZWRJQWRkIChudW0pIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWRJQWRkIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHJldHVybiB0aGlzLnJlZC5pYWRkKHRoaXMsIG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZFN1YiA9IGZ1bmN0aW9uIHJlZFN1YiAobnVtKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkU3ViIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHJldHVybiB0aGlzLnJlZC5zdWIodGhpcywgbnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkSVN1YiA9IGZ1bmN0aW9uIHJlZElTdWIgKG51bSkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZElTdWIgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLmlzdWIodGhpcywgbnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkU2hsID0gZnVuY3Rpb24gcmVkU2hsIChudW0pIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWRTaGwgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLnNobCh0aGlzLCBudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5yZWRNdWwgPSBmdW5jdGlvbiByZWRNdWwgKG51bSkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZE11bCB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgICB0aGlzLnJlZC5fdmVyaWZ5Mih0aGlzLCBudW0pO1xuICAgIHJldHVybiB0aGlzLnJlZC5tdWwodGhpcywgbnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkSU11bCA9IGZ1bmN0aW9uIHJlZElNdWwgKG51bSkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZE11bCB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgICB0aGlzLnJlZC5fdmVyaWZ5Mih0aGlzLCBudW0pO1xuICAgIHJldHVybiB0aGlzLnJlZC5pbXVsKHRoaXMsIG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZFNxciA9IGZ1bmN0aW9uIHJlZFNxciAoKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkU3FyIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkxKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnJlZC5zcXIodGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZElTcXIgPSBmdW5jdGlvbiByZWRJU3FyICgpIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWRJU3FyIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkxKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnJlZC5pc3FyKHRoaXMpO1xuICB9O1xuXG4gIC8vIFNxdWFyZSByb290IG92ZXIgcFxuICBCTi5wcm90b3R5cGUucmVkU3FydCA9IGZ1bmN0aW9uIHJlZFNxcnQgKCkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZFNxcnQgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgdGhpcy5yZWQuX3ZlcmlmeTEodGhpcyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLnNxcnQodGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZEludm0gPSBmdW5jdGlvbiByZWRJbnZtICgpIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWRJbnZtIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkxKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnJlZC5pbnZtKHRoaXMpO1xuICB9O1xuXG4gIC8vIFJldHVybiBuZWdhdGl2ZSBjbG9uZSBvZiBgdGhpc2AgJSBgcmVkIG1vZHVsb2BcbiAgQk4ucHJvdG90eXBlLnJlZE5lZyA9IGZ1bmN0aW9uIHJlZE5lZyAoKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkTmVnIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkxKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnJlZC5uZWcodGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZFBvdyA9IGZ1bmN0aW9uIHJlZFBvdyAobnVtKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkICYmICFudW0ucmVkLCAncmVkUG93KG5vcm1hbE51bSknKTtcbiAgICB0aGlzLnJlZC5fdmVyaWZ5MSh0aGlzKTtcbiAgICByZXR1cm4gdGhpcy5yZWQucG93KHRoaXMsIG51bSk7XG4gIH07XG5cbiAgLy8gUHJpbWUgbnVtYmVycyB3aXRoIGVmZmljaWVudCByZWR1Y3Rpb25cbiAgdmFyIHByaW1lcyA9IHtcbiAgICBrMjU2OiBudWxsLFxuICAgIHAyMjQ6IG51bGwsXG4gICAgcDE5MjogbnVsbCxcbiAgICBwMjU1MTk6IG51bGxcbiAgfTtcblxuICAvLyBQc2V1ZG8tTWVyc2VubmUgcHJpbWVcbiAgZnVuY3Rpb24gTVByaW1lIChuYW1lLCBwKSB7XG4gICAgLy8gUCA9IDIgXiBOIC0gS1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgdGhpcy5wID0gbmV3IEJOKHAsIDE2KTtcbiAgICB0aGlzLm4gPSB0aGlzLnAuYml0TGVuZ3RoKCk7XG4gICAgdGhpcy5rID0gbmV3IEJOKDEpLml1c2hsbih0aGlzLm4pLmlzdWIodGhpcy5wKTtcblxuICAgIHRoaXMudG1wID0gdGhpcy5fdG1wKCk7XG4gIH1cblxuICBNUHJpbWUucHJvdG90eXBlLl90bXAgPSBmdW5jdGlvbiBfdG1wICgpIHtcbiAgICB2YXIgdG1wID0gbmV3IEJOKG51bGwpO1xuICAgIHRtcC53b3JkcyA9IG5ldyBBcnJheShNYXRoLmNlaWwodGhpcy5uIC8gMTMpKTtcbiAgICByZXR1cm4gdG1wO1xuICB9O1xuXG4gIE1QcmltZS5wcm90b3R5cGUuaXJlZHVjZSA9IGZ1bmN0aW9uIGlyZWR1Y2UgKG51bSkge1xuICAgIC8vIEFzc3VtZXMgdGhhdCBgbnVtYCBpcyBsZXNzIHRoYW4gYFBeMmBcbiAgICAvLyBudW0gPSBISSAqICgyIF4gTiAtIEspICsgSEkgKiBLICsgTE8gPSBISSAqIEsgKyBMTyAobW9kIFApXG4gICAgdmFyIHIgPSBudW07XG4gICAgdmFyIHJsZW47XG5cbiAgICBkbyB7XG4gICAgICB0aGlzLnNwbGl0KHIsIHRoaXMudG1wKTtcbiAgICAgIHIgPSB0aGlzLmltdWxLKHIpO1xuICAgICAgciA9IHIuaWFkZCh0aGlzLnRtcCk7XG4gICAgICBybGVuID0gci5iaXRMZW5ndGgoKTtcbiAgICB9IHdoaWxlIChybGVuID4gdGhpcy5uKTtcblxuICAgIHZhciBjbXAgPSBybGVuIDwgdGhpcy5uID8gLTEgOiByLnVjbXAodGhpcy5wKTtcbiAgICBpZiAoY21wID09PSAwKSB7XG4gICAgICByLndvcmRzWzBdID0gMDtcbiAgICAgIHIubGVuZ3RoID0gMTtcbiAgICB9IGVsc2UgaWYgKGNtcCA+IDApIHtcbiAgICAgIHIuaXN1Yih0aGlzLnApO1xuICAgIH0gZWxzZSB7XG4gICAgICByLnN0cmlwKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHI7XG4gIH07XG5cbiAgTVByaW1lLnByb3RvdHlwZS5zcGxpdCA9IGZ1bmN0aW9uIHNwbGl0IChpbnB1dCwgb3V0KSB7XG4gICAgaW5wdXQuaXVzaHJuKHRoaXMubiwgMCwgb3V0KTtcbiAgfTtcblxuICBNUHJpbWUucHJvdG90eXBlLmltdWxLID0gZnVuY3Rpb24gaW11bEsgKG51bSkge1xuICAgIHJldHVybiBudW0uaW11bCh0aGlzLmspO1xuICB9O1xuXG4gIGZ1bmN0aW9uIEsyNTYgKCkge1xuICAgIE1QcmltZS5jYWxsKFxuICAgICAgdGhpcyxcbiAgICAgICdrMjU2JyxcbiAgICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZSBmZmZmZmMyZicpO1xuICB9XG4gIGluaGVyaXRzKEsyNTYsIE1QcmltZSk7XG5cbiAgSzI1Ni5wcm90b3R5cGUuc3BsaXQgPSBmdW5jdGlvbiBzcGxpdCAoaW5wdXQsIG91dHB1dCkge1xuICAgIC8vIDI1NiA9IDkgKiAyNiArIDIyXG4gICAgdmFyIG1hc2sgPSAweDNmZmZmZjtcblxuICAgIHZhciBvdXRMZW4gPSBNYXRoLm1pbihpbnB1dC5sZW5ndGgsIDkpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3V0TGVuOyBpKyspIHtcbiAgICAgIG91dHB1dC53b3Jkc1tpXSA9IGlucHV0LndvcmRzW2ldO1xuICAgIH1cbiAgICBvdXRwdXQubGVuZ3RoID0gb3V0TGVuO1xuXG4gICAgaWYgKGlucHV0Lmxlbmd0aCA8PSA5KSB7XG4gICAgICBpbnB1dC53b3Jkc1swXSA9IDA7XG4gICAgICBpbnB1dC5sZW5ndGggPSAxO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFNoaWZ0IGJ5IDkgbGltYnNcbiAgICB2YXIgcHJldiA9IGlucHV0LndvcmRzWzldO1xuICAgIG91dHB1dC53b3Jkc1tvdXRwdXQubGVuZ3RoKytdID0gcHJldiAmIG1hc2s7XG5cbiAgICBmb3IgKGkgPSAxMDsgaSA8IGlucHV0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgbmV4dCA9IGlucHV0LndvcmRzW2ldIHwgMDtcbiAgICAgIGlucHV0LndvcmRzW2kgLSAxMF0gPSAoKG5leHQgJiBtYXNrKSA8PCA0KSB8IChwcmV2ID4+PiAyMik7XG4gICAgICBwcmV2ID0gbmV4dDtcbiAgICB9XG4gICAgcHJldiA+Pj49IDIyO1xuICAgIGlucHV0LndvcmRzW2kgLSAxMF0gPSBwcmV2O1xuICAgIGlmIChwcmV2ID09PSAwICYmIGlucHV0Lmxlbmd0aCA+IDEwKSB7XG4gICAgICBpbnB1dC5sZW5ndGggLT0gMTA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlucHV0Lmxlbmd0aCAtPSA5O1xuICAgIH1cbiAgfTtcblxuICBLMjU2LnByb3RvdHlwZS5pbXVsSyA9IGZ1bmN0aW9uIGltdWxLIChudW0pIHtcbiAgICAvLyBLID0gMHgxMDAwMDAzZDEgPSBbIDB4NDAsIDB4M2QxIF1cbiAgICBudW0ud29yZHNbbnVtLmxlbmd0aF0gPSAwO1xuICAgIG51bS53b3Jkc1tudW0ubGVuZ3RoICsgMV0gPSAwO1xuICAgIG51bS5sZW5ndGggKz0gMjtcblxuICAgIC8vIGJvdW5kZWQgYXQ6IDB4NDAgKiAweDNmZmZmZmYgKyAweDNkMCA9IDB4MTAwMDAwMzkwXG4gICAgdmFyIGxvID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG51bS5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHcgPSBudW0ud29yZHNbaV0gfCAwO1xuICAgICAgbG8gKz0gdyAqIDB4M2QxO1xuICAgICAgbnVtLndvcmRzW2ldID0gbG8gJiAweDNmZmZmZmY7XG4gICAgICBsbyA9IHcgKiAweDQwICsgKChsbyAvIDB4NDAwMDAwMCkgfCAwKTtcbiAgICB9XG5cbiAgICAvLyBGYXN0IGxlbmd0aCByZWR1Y3Rpb25cbiAgICBpZiAobnVtLndvcmRzW251bS5sZW5ndGggLSAxXSA9PT0gMCkge1xuICAgICAgbnVtLmxlbmd0aC0tO1xuICAgICAgaWYgKG51bS53b3Jkc1tudW0ubGVuZ3RoIC0gMV0gPT09IDApIHtcbiAgICAgICAgbnVtLmxlbmd0aC0tO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVtO1xuICB9O1xuXG4gIGZ1bmN0aW9uIFAyMjQgKCkge1xuICAgIE1QcmltZS5jYWxsKFxuICAgICAgdGhpcyxcbiAgICAgICdwMjI0JyxcbiAgICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiAwMDAwMDAwMCAwMDAwMDAwMCAwMDAwMDAwMScpO1xuICB9XG4gIGluaGVyaXRzKFAyMjQsIE1QcmltZSk7XG5cbiAgZnVuY3Rpb24gUDE5MiAoKSB7XG4gICAgTVByaW1lLmNhbGwoXG4gICAgICB0aGlzLFxuICAgICAgJ3AxOTInLFxuICAgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZlIGZmZmZmZmZmIGZmZmZmZmZmJyk7XG4gIH1cbiAgaW5oZXJpdHMoUDE5MiwgTVByaW1lKTtcblxuICBmdW5jdGlvbiBQMjU1MTkgKCkge1xuICAgIC8vIDIgXiAyNTUgLSAxOVxuICAgIE1QcmltZS5jYWxsKFxuICAgICAgdGhpcyxcbiAgICAgICcyNTUxOScsXG4gICAgICAnN2ZmZmZmZmZmZmZmZmZmZiBmZmZmZmZmZmZmZmZmZmZmIGZmZmZmZmZmZmZmZmZmZmYgZmZmZmZmZmZmZmZmZmZlZCcpO1xuICB9XG4gIGluaGVyaXRzKFAyNTUxOSwgTVByaW1lKTtcblxuICBQMjU1MTkucHJvdG90eXBlLmltdWxLID0gZnVuY3Rpb24gaW11bEsgKG51bSkge1xuICAgIC8vIEsgPSAweDEzXG4gICAgdmFyIGNhcnJ5ID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG51bS5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGhpID0gKG51bS53b3Jkc1tpXSB8IDApICogMHgxMyArIGNhcnJ5O1xuICAgICAgdmFyIGxvID0gaGkgJiAweDNmZmZmZmY7XG4gICAgICBoaSA+Pj49IDI2O1xuXG4gICAgICBudW0ud29yZHNbaV0gPSBsbztcbiAgICAgIGNhcnJ5ID0gaGk7XG4gICAgfVxuICAgIGlmIChjYXJyeSAhPT0gMCkge1xuICAgICAgbnVtLndvcmRzW251bS5sZW5ndGgrK10gPSBjYXJyeTtcbiAgICB9XG4gICAgcmV0dXJuIG51bTtcbiAgfTtcblxuICAvLyBFeHBvcnRlZCBtb3N0bHkgZm9yIHRlc3RpbmcgcHVycG9zZXMsIHVzZSBwbGFpbiBuYW1lIGluc3RlYWRcbiAgQk4uX3ByaW1lID0gZnVuY3Rpb24gcHJpbWUgKG5hbWUpIHtcbiAgICAvLyBDYWNoZWQgdmVyc2lvbiBvZiBwcmltZVxuICAgIGlmIChwcmltZXNbbmFtZV0pIHJldHVybiBwcmltZXNbbmFtZV07XG5cbiAgICB2YXIgcHJpbWU7XG4gICAgaWYgKG5hbWUgPT09ICdrMjU2Jykge1xuICAgICAgcHJpbWUgPSBuZXcgSzI1NigpO1xuICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ3AyMjQnKSB7XG4gICAgICBwcmltZSA9IG5ldyBQMjI0KCk7XG4gICAgfSBlbHNlIGlmIChuYW1lID09PSAncDE5MicpIHtcbiAgICAgIHByaW1lID0gbmV3IFAxOTIoKTtcbiAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdwMjU1MTknKSB7XG4gICAgICBwcmltZSA9IG5ldyBQMjU1MTkoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIHByaW1lICcgKyBuYW1lKTtcbiAgICB9XG4gICAgcHJpbWVzW25hbWVdID0gcHJpbWU7XG5cbiAgICByZXR1cm4gcHJpbWU7XG4gIH07XG5cbiAgLy9cbiAgLy8gQmFzZSByZWR1Y3Rpb24gZW5naW5lXG4gIC8vXG4gIGZ1bmN0aW9uIFJlZCAobSkge1xuICAgIGlmICh0eXBlb2YgbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHZhciBwcmltZSA9IEJOLl9wcmltZShtKTtcbiAgICAgIHRoaXMubSA9IHByaW1lLnA7XG4gICAgICB0aGlzLnByaW1lID0gcHJpbWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFzc2VydChtLmd0bigxKSwgJ21vZHVsdXMgbXVzdCBiZSBncmVhdGVyIHRoYW4gMScpO1xuICAgICAgdGhpcy5tID0gbTtcbiAgICAgIHRoaXMucHJpbWUgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIFJlZC5wcm90b3R5cGUuX3ZlcmlmeTEgPSBmdW5jdGlvbiBfdmVyaWZ5MSAoYSkge1xuICAgIGFzc2VydChhLm5lZ2F0aXZlID09PSAwLCAncmVkIHdvcmtzIG9ubHkgd2l0aCBwb3NpdGl2ZXMnKTtcbiAgICBhc3NlcnQoYS5yZWQsICdyZWQgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5fdmVyaWZ5MiA9IGZ1bmN0aW9uIF92ZXJpZnkyIChhLCBiKSB7XG4gICAgYXNzZXJ0KChhLm5lZ2F0aXZlIHwgYi5uZWdhdGl2ZSkgPT09IDAsICdyZWQgd29ya3Mgb25seSB3aXRoIHBvc2l0aXZlcycpO1xuICAgIGFzc2VydChhLnJlZCAmJiBhLnJlZCA9PT0gYi5yZWQsXG4gICAgICAncmVkIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuaW1vZCA9IGZ1bmN0aW9uIGltb2QgKGEpIHtcbiAgICBpZiAodGhpcy5wcmltZSkgcmV0dXJuIHRoaXMucHJpbWUuaXJlZHVjZShhKS5fZm9yY2VSZWQodGhpcyk7XG4gICAgcmV0dXJuIGEudW1vZCh0aGlzLm0pLl9mb3JjZVJlZCh0aGlzKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLm5lZyA9IGZ1bmN0aW9uIG5lZyAoYSkge1xuICAgIGlmIChhLmlzWmVybygpKSB7XG4gICAgICByZXR1cm4gYS5jbG9uZSgpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm0uc3ViKGEpLl9mb3JjZVJlZCh0aGlzKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZCAoYSwgYikge1xuICAgIHRoaXMuX3ZlcmlmeTIoYSwgYik7XG5cbiAgICB2YXIgcmVzID0gYS5hZGQoYik7XG4gICAgaWYgKHJlcy5jbXAodGhpcy5tKSA+PSAwKSB7XG4gICAgICByZXMuaXN1Yih0aGlzLm0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzLl9mb3JjZVJlZCh0aGlzKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmlhZGQgPSBmdW5jdGlvbiBpYWRkIChhLCBiKSB7XG4gICAgdGhpcy5fdmVyaWZ5MihhLCBiKTtcblxuICAgIHZhciByZXMgPSBhLmlhZGQoYik7XG4gICAgaWYgKHJlcy5jbXAodGhpcy5tKSA+PSAwKSB7XG4gICAgICByZXMuaXN1Yih0aGlzLm0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuc3ViID0gZnVuY3Rpb24gc3ViIChhLCBiKSB7XG4gICAgdGhpcy5fdmVyaWZ5MihhLCBiKTtcblxuICAgIHZhciByZXMgPSBhLnN1YihiKTtcbiAgICBpZiAocmVzLmNtcG4oMCkgPCAwKSB7XG4gICAgICByZXMuaWFkZCh0aGlzLm0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzLl9mb3JjZVJlZCh0aGlzKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmlzdWIgPSBmdW5jdGlvbiBpc3ViIChhLCBiKSB7XG4gICAgdGhpcy5fdmVyaWZ5MihhLCBiKTtcblxuICAgIHZhciByZXMgPSBhLmlzdWIoYik7XG4gICAgaWYgKHJlcy5jbXBuKDApIDwgMCkge1xuICAgICAgcmVzLmlhZGQodGhpcy5tKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLnNobCA9IGZ1bmN0aW9uIHNobCAoYSwgbnVtKSB7XG4gICAgdGhpcy5fdmVyaWZ5MShhKTtcbiAgICByZXR1cm4gdGhpcy5pbW9kKGEudXNobG4obnVtKSk7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5pbXVsID0gZnVuY3Rpb24gaW11bCAoYSwgYikge1xuICAgIHRoaXMuX3ZlcmlmeTIoYSwgYik7XG4gICAgcmV0dXJuIHRoaXMuaW1vZChhLmltdWwoYikpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUubXVsID0gZnVuY3Rpb24gbXVsIChhLCBiKSB7XG4gICAgdGhpcy5fdmVyaWZ5MihhLCBiKTtcbiAgICByZXR1cm4gdGhpcy5pbW9kKGEubXVsKGIpKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmlzcXIgPSBmdW5jdGlvbiBpc3FyIChhKSB7XG4gICAgcmV0dXJuIHRoaXMuaW11bChhLCBhLmNsb25lKCkpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuc3FyID0gZnVuY3Rpb24gc3FyIChhKSB7XG4gICAgcmV0dXJuIHRoaXMubXVsKGEsIGEpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuc3FydCA9IGZ1bmN0aW9uIHNxcnQgKGEpIHtcbiAgICBpZiAoYS5pc1plcm8oKSkgcmV0dXJuIGEuY2xvbmUoKTtcblxuICAgIHZhciBtb2QzID0gdGhpcy5tLmFuZGxuKDMpO1xuICAgIGFzc2VydChtb2QzICUgMiA9PT0gMSk7XG5cbiAgICAvLyBGYXN0IGNhc2VcbiAgICBpZiAobW9kMyA9PT0gMykge1xuICAgICAgdmFyIHBvdyA9IHRoaXMubS5hZGQobmV3IEJOKDEpKS5pdXNocm4oMik7XG4gICAgICByZXR1cm4gdGhpcy5wb3coYSwgcG93KTtcbiAgICB9XG5cbiAgICAvLyBUb25lbGxpLVNoYW5rcyBhbGdvcml0aG0gKFRvdGFsbHkgdW5vcHRpbWl6ZWQgYW5kIHNsb3cpXG4gICAgLy9cbiAgICAvLyBGaW5kIFEgYW5kIFMsIHRoYXQgUSAqIDIgXiBTID0gKFAgLSAxKVxuICAgIHZhciBxID0gdGhpcy5tLnN1Ym4oMSk7XG4gICAgdmFyIHMgPSAwO1xuICAgIHdoaWxlICghcS5pc1plcm8oKSAmJiBxLmFuZGxuKDEpID09PSAwKSB7XG4gICAgICBzKys7XG4gICAgICBxLml1c2hybigxKTtcbiAgICB9XG4gICAgYXNzZXJ0KCFxLmlzWmVybygpKTtcblxuICAgIHZhciBvbmUgPSBuZXcgQk4oMSkudG9SZWQodGhpcyk7XG4gICAgdmFyIG5PbmUgPSBvbmUucmVkTmVnKCk7XG5cbiAgICAvLyBGaW5kIHF1YWRyYXRpYyBub24tcmVzaWR1ZVxuICAgIC8vIE5PVEU6IE1heCBpcyBzdWNoIGJlY2F1c2Ugb2YgZ2VuZXJhbGl6ZWQgUmllbWFubiBoeXBvdGhlc2lzLlxuICAgIHZhciBscG93ID0gdGhpcy5tLnN1Ym4oMSkuaXVzaHJuKDEpO1xuICAgIHZhciB6ID0gdGhpcy5tLmJpdExlbmd0aCgpO1xuICAgIHogPSBuZXcgQk4oMiAqIHogKiB6KS50b1JlZCh0aGlzKTtcblxuICAgIHdoaWxlICh0aGlzLnBvdyh6LCBscG93KS5jbXAobk9uZSkgIT09IDApIHtcbiAgICAgIHoucmVkSUFkZChuT25lKTtcbiAgICB9XG5cbiAgICB2YXIgYyA9IHRoaXMucG93KHosIHEpO1xuICAgIHZhciByID0gdGhpcy5wb3coYSwgcS5hZGRuKDEpLml1c2hybigxKSk7XG4gICAgdmFyIHQgPSB0aGlzLnBvdyhhLCBxKTtcbiAgICB2YXIgbSA9IHM7XG4gICAgd2hpbGUgKHQuY21wKG9uZSkgIT09IDApIHtcbiAgICAgIHZhciB0bXAgPSB0O1xuICAgICAgZm9yICh2YXIgaSA9IDA7IHRtcC5jbXAob25lKSAhPT0gMDsgaSsrKSB7XG4gICAgICAgIHRtcCA9IHRtcC5yZWRTcXIoKTtcbiAgICAgIH1cbiAgICAgIGFzc2VydChpIDwgbSk7XG4gICAgICB2YXIgYiA9IHRoaXMucG93KGMsIG5ldyBCTigxKS5pdXNobG4obSAtIGkgLSAxKSk7XG5cbiAgICAgIHIgPSByLnJlZE11bChiKTtcbiAgICAgIGMgPSBiLnJlZFNxcigpO1xuICAgICAgdCA9IHQucmVkTXVsKGMpO1xuICAgICAgbSA9IGk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHI7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5pbnZtID0gZnVuY3Rpb24gaW52bSAoYSkge1xuICAgIHZhciBpbnYgPSBhLl9pbnZtcCh0aGlzLm0pO1xuICAgIGlmIChpbnYubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIGludi5uZWdhdGl2ZSA9IDA7XG4gICAgICByZXR1cm4gdGhpcy5pbW9kKGludikucmVkTmVnKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmltb2QoaW52KTtcbiAgICB9XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5wb3cgPSBmdW5jdGlvbiBwb3cgKGEsIG51bSkge1xuICAgIGlmIChudW0uaXNaZXJvKCkpIHJldHVybiBuZXcgQk4oMSkudG9SZWQodGhpcyk7XG4gICAgaWYgKG51bS5jbXBuKDEpID09PSAwKSByZXR1cm4gYS5jbG9uZSgpO1xuXG4gICAgdmFyIHdpbmRvd1NpemUgPSA0O1xuICAgIHZhciB3bmQgPSBuZXcgQXJyYXkoMSA8PCB3aW5kb3dTaXplKTtcbiAgICB3bmRbMF0gPSBuZXcgQk4oMSkudG9SZWQodGhpcyk7XG4gICAgd25kWzFdID0gYTtcbiAgICBmb3IgKHZhciBpID0gMjsgaSA8IHduZC5sZW5ndGg7IGkrKykge1xuICAgICAgd25kW2ldID0gdGhpcy5tdWwod25kW2kgLSAxXSwgYSk7XG4gICAgfVxuXG4gICAgdmFyIHJlcyA9IHduZFswXTtcbiAgICB2YXIgY3VycmVudCA9IDA7XG4gICAgdmFyIGN1cnJlbnRMZW4gPSAwO1xuICAgIHZhciBzdGFydCA9IG51bS5iaXRMZW5ndGgoKSAlIDI2O1xuICAgIGlmIChzdGFydCA9PT0gMCkge1xuICAgICAgc3RhcnQgPSAyNjtcbiAgICB9XG5cbiAgICBmb3IgKGkgPSBudW0ubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHZhciB3b3JkID0gbnVtLndvcmRzW2ldO1xuICAgICAgZm9yICh2YXIgaiA9IHN0YXJ0IC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICAgICAgdmFyIGJpdCA9ICh3b3JkID4+IGopICYgMTtcbiAgICAgICAgaWYgKHJlcyAhPT0gd25kWzBdKSB7XG4gICAgICAgICAgcmVzID0gdGhpcy5zcXIocmVzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChiaXQgPT09IDAgJiYgY3VycmVudCA9PT0gMCkge1xuICAgICAgICAgIGN1cnJlbnRMZW4gPSAwO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY3VycmVudCA8PD0gMTtcbiAgICAgICAgY3VycmVudCB8PSBiaXQ7XG4gICAgICAgIGN1cnJlbnRMZW4rKztcbiAgICAgICAgaWYgKGN1cnJlbnRMZW4gIT09IHdpbmRvd1NpemUgJiYgKGkgIT09IDAgfHwgaiAhPT0gMCkpIGNvbnRpbnVlO1xuXG4gICAgICAgIHJlcyA9IHRoaXMubXVsKHJlcywgd25kW2N1cnJlbnRdKTtcbiAgICAgICAgY3VycmVudExlbiA9IDA7XG4gICAgICAgIGN1cnJlbnQgPSAwO1xuICAgICAgfVxuICAgICAgc3RhcnQgPSAyNjtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuY29udmVydFRvID0gZnVuY3Rpb24gY29udmVydFRvIChudW0pIHtcbiAgICB2YXIgciA9IG51bS51bW9kKHRoaXMubSk7XG5cbiAgICByZXR1cm4gciA9PT0gbnVtID8gci5jbG9uZSgpIDogcjtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmNvbnZlcnRGcm9tID0gZnVuY3Rpb24gY29udmVydEZyb20gKG51bSkge1xuICAgIHZhciByZXMgPSBudW0uY2xvbmUoKTtcbiAgICByZXMucmVkID0gbnVsbDtcbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIC8vXG4gIC8vIE1vbnRnb21lcnkgbWV0aG9kIGVuZ2luZVxuICAvL1xuXG4gIEJOLm1vbnQgPSBmdW5jdGlvbiBtb250IChudW0pIHtcbiAgICByZXR1cm4gbmV3IE1vbnQobnVtKTtcbiAgfTtcblxuICBmdW5jdGlvbiBNb250IChtKSB7XG4gICAgUmVkLmNhbGwodGhpcywgbSk7XG5cbiAgICB0aGlzLnNoaWZ0ID0gdGhpcy5tLmJpdExlbmd0aCgpO1xuICAgIGlmICh0aGlzLnNoaWZ0ICUgMjYgIT09IDApIHtcbiAgICAgIHRoaXMuc2hpZnQgKz0gMjYgLSAodGhpcy5zaGlmdCAlIDI2KTtcbiAgICB9XG5cbiAgICB0aGlzLnIgPSBuZXcgQk4oMSkuaXVzaGxuKHRoaXMuc2hpZnQpO1xuICAgIHRoaXMucjIgPSB0aGlzLmltb2QodGhpcy5yLnNxcigpKTtcbiAgICB0aGlzLnJpbnYgPSB0aGlzLnIuX2ludm1wKHRoaXMubSk7XG5cbiAgICB0aGlzLm1pbnYgPSB0aGlzLnJpbnYubXVsKHRoaXMucikuaXN1Ym4oMSkuZGl2KHRoaXMubSk7XG4gICAgdGhpcy5taW52ID0gdGhpcy5taW52LnVtb2QodGhpcy5yKTtcbiAgICB0aGlzLm1pbnYgPSB0aGlzLnIuc3ViKHRoaXMubWludik7XG4gIH1cbiAgaW5oZXJpdHMoTW9udCwgUmVkKTtcblxuICBNb250LnByb3RvdHlwZS5jb252ZXJ0VG8gPSBmdW5jdGlvbiBjb252ZXJ0VG8gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmltb2QobnVtLnVzaGxuKHRoaXMuc2hpZnQpKTtcbiAgfTtcblxuICBNb250LnByb3RvdHlwZS5jb252ZXJ0RnJvbSA9IGZ1bmN0aW9uIGNvbnZlcnRGcm9tIChudW0pIHtcbiAgICB2YXIgciA9IHRoaXMuaW1vZChudW0ubXVsKHRoaXMucmludikpO1xuICAgIHIucmVkID0gbnVsbDtcbiAgICByZXR1cm4gcjtcbiAgfTtcblxuICBNb250LnByb3RvdHlwZS5pbXVsID0gZnVuY3Rpb24gaW11bCAoYSwgYikge1xuICAgIGlmIChhLmlzWmVybygpIHx8IGIuaXNaZXJvKCkpIHtcbiAgICAgIGEud29yZHNbMF0gPSAwO1xuICAgICAgYS5sZW5ndGggPSAxO1xuICAgICAgcmV0dXJuIGE7XG4gICAgfVxuXG4gICAgdmFyIHQgPSBhLmltdWwoYik7XG4gICAgdmFyIGMgPSB0Lm1hc2tuKHRoaXMuc2hpZnQpLm11bCh0aGlzLm1pbnYpLmltYXNrbih0aGlzLnNoaWZ0KS5tdWwodGhpcy5tKTtcbiAgICB2YXIgdSA9IHQuaXN1YihjKS5pdXNocm4odGhpcy5zaGlmdCk7XG4gICAgdmFyIHJlcyA9IHU7XG5cbiAgICBpZiAodS5jbXAodGhpcy5tKSA+PSAwKSB7XG4gICAgICByZXMgPSB1LmlzdWIodGhpcy5tKTtcbiAgICB9IGVsc2UgaWYgKHUuY21wbigwKSA8IDApIHtcbiAgICAgIHJlcyA9IHUuaWFkZCh0aGlzLm0pO1xuICAgIH1cblxuICAgIHJldHVybiByZXMuX2ZvcmNlUmVkKHRoaXMpO1xuICB9O1xuXG4gIE1vbnQucHJvdG90eXBlLm11bCA9IGZ1bmN0aW9uIG11bCAoYSwgYikge1xuICAgIGlmIChhLmlzWmVybygpIHx8IGIuaXNaZXJvKCkpIHJldHVybiBuZXcgQk4oMCkuX2ZvcmNlUmVkKHRoaXMpO1xuXG4gICAgdmFyIHQgPSBhLm11bChiKTtcbiAgICB2YXIgYyA9IHQubWFza24odGhpcy5zaGlmdCkubXVsKHRoaXMubWludikuaW1hc2tuKHRoaXMuc2hpZnQpLm11bCh0aGlzLm0pO1xuICAgIHZhciB1ID0gdC5pc3ViKGMpLml1c2hybih0aGlzLnNoaWZ0KTtcbiAgICB2YXIgcmVzID0gdTtcbiAgICBpZiAodS5jbXAodGhpcy5tKSA+PSAwKSB7XG4gICAgICByZXMgPSB1LmlzdWIodGhpcy5tKTtcbiAgICB9IGVsc2UgaWYgKHUuY21wbigwKSA8IDApIHtcbiAgICAgIHJlcyA9IHUuaWFkZCh0aGlzLm0pO1xuICAgIH1cblxuICAgIHJldHVybiByZXMuX2ZvcmNlUmVkKHRoaXMpO1xuICB9O1xuXG4gIE1vbnQucHJvdG90eXBlLmludm0gPSBmdW5jdGlvbiBpbnZtIChhKSB7XG4gICAgLy8gKEFSKV4tMSAqIFJeMiA9IChBXi0xICogUl4tMSkgKiBSXjIgPSBBXi0xICogUlxuICAgIHZhciByZXMgPSB0aGlzLmltb2QoYS5faW52bXAodGhpcy5tKS5tdWwodGhpcy5yMikpO1xuICAgIHJldHVybiByZXMuX2ZvcmNlUmVkKHRoaXMpO1xuICB9O1xufSkodHlwZW9mIG1vZHVsZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbW9kdWxlLCB0aGlzKTtcbiIsInZhciByO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJhbmQobGVuKSB7XG4gIGlmICghcilcbiAgICByID0gbmV3IFJhbmQobnVsbCk7XG5cbiAgcmV0dXJuIHIuZ2VuZXJhdGUobGVuKTtcbn07XG5cbmZ1bmN0aW9uIFJhbmQocmFuZCkge1xuICB0aGlzLnJhbmQgPSByYW5kO1xufVxubW9kdWxlLmV4cG9ydHMuUmFuZCA9IFJhbmQ7XG5cblJhbmQucHJvdG90eXBlLmdlbmVyYXRlID0gZnVuY3Rpb24gZ2VuZXJhdGUobGVuKSB7XG4gIHJldHVybiB0aGlzLl9yYW5kKGxlbik7XG59O1xuXG4vLyBFbXVsYXRlIGNyeXB0byBBUEkgdXNpbmcgcmFuZHlcblJhbmQucHJvdG90eXBlLl9yYW5kID0gZnVuY3Rpb24gX3JhbmQobikge1xuICBpZiAodGhpcy5yYW5kLmdldEJ5dGVzKVxuICAgIHJldHVybiB0aGlzLnJhbmQuZ2V0Qnl0ZXMobik7XG5cbiAgdmFyIHJlcyA9IG5ldyBVaW50OEFycmF5KG4pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJlcy5sZW5ndGg7IGkrKylcbiAgICByZXNbaV0gPSB0aGlzLnJhbmQuZ2V0Qnl0ZSgpO1xuICByZXR1cm4gcmVzO1xufTtcblxuaWYgKHR5cGVvZiBzZWxmID09PSAnb2JqZWN0Jykge1xuICBpZiAoc2VsZi5jcnlwdG8gJiYgc2VsZi5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB7XG4gICAgLy8gTW9kZXJuIGJyb3dzZXJzXG4gICAgUmFuZC5wcm90b3R5cGUuX3JhbmQgPSBmdW5jdGlvbiBfcmFuZChuKSB7XG4gICAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkobik7XG4gICAgICBzZWxmLmNyeXB0by5nZXRSYW5kb21WYWx1ZXMoYXJyKTtcbiAgICAgIHJldHVybiBhcnI7XG4gICAgfTtcbiAgfSBlbHNlIGlmIChzZWxmLm1zQ3J5cHRvICYmIHNlbGYubXNDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB7XG4gICAgLy8gSUVcbiAgICBSYW5kLnByb3RvdHlwZS5fcmFuZCA9IGZ1bmN0aW9uIF9yYW5kKG4pIHtcbiAgICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheShuKTtcbiAgICAgIHNlbGYubXNDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGFycik7XG4gICAgICByZXR1cm4gYXJyO1xuICAgIH07XG5cbiAgLy8gU2FmYXJpJ3MgV2ViV29ya2VycyBkbyBub3QgaGF2ZSBgY3J5cHRvYFxuICB9IGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICdvYmplY3QnKSB7XG4gICAgLy8gT2xkIGp1bmtcbiAgICBSYW5kLnByb3RvdHlwZS5fcmFuZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQgeWV0Jyk7XG4gICAgfTtcbiAgfVxufSBlbHNlIHtcbiAgLy8gTm9kZS5qcyBvciBXZWIgd29ya2VyIHdpdGggbm8gY3J5cHRvIHN1cHBvcnRcbiAgdHJ5IHtcbiAgICB2YXIgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG4gICAgaWYgKHR5cGVvZiBjcnlwdG8ucmFuZG9tQnl0ZXMgIT09ICdmdW5jdGlvbicpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBzdXBwb3J0ZWQnKTtcblxuICAgIFJhbmQucHJvdG90eXBlLl9yYW5kID0gZnVuY3Rpb24gX3JhbmQobikge1xuICAgICAgcmV0dXJuIGNyeXB0by5yYW5kb21CeXRlcyhuKTtcbiAgICB9O1xuICB9IGNhdGNoIChlKSB7XG4gIH1cbn1cbiIsIi8vIGJhc2VkIG9uIHRoZSBhZXMgaW1wbGltZW50YXRpb24gaW4gdHJpcGxlIHNlY1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL2tleWJhc2UvdHJpcGxlc2VjXG4vLyB3aGljaCBpcyBpbiB0dXJuIGJhc2VkIG9uIHRoZSBvbmUgZnJvbSBjcnlwdG8tanNcbi8vIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzL1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcblxuZnVuY3Rpb24gYXNVSW50MzJBcnJheSAoYnVmKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIGJ1ZiA9IEJ1ZmZlci5mcm9tKGJ1ZilcblxuICB2YXIgbGVuID0gKGJ1Zi5sZW5ndGggLyA0KSB8IDBcbiAgdmFyIG91dCA9IG5ldyBBcnJheShsZW4pXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIG91dFtpXSA9IGJ1Zi5yZWFkVUludDMyQkUoaSAqIDQpXG4gIH1cblxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHNjcnViVmVjICh2KSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdi5sZW5ndGg7IHYrKykge1xuICAgIHZbaV0gPSAwXG4gIH1cbn1cblxuZnVuY3Rpb24gY3J5cHRCbG9jayAoTSwga2V5U2NoZWR1bGUsIFNVQl9NSVgsIFNCT1gsIG5Sb3VuZHMpIHtcbiAgdmFyIFNVQl9NSVgwID0gU1VCX01JWFswXVxuICB2YXIgU1VCX01JWDEgPSBTVUJfTUlYWzFdXG4gIHZhciBTVUJfTUlYMiA9IFNVQl9NSVhbMl1cbiAgdmFyIFNVQl9NSVgzID0gU1VCX01JWFszXVxuXG4gIHZhciBzMCA9IE1bMF0gXiBrZXlTY2hlZHVsZVswXVxuICB2YXIgczEgPSBNWzFdIF4ga2V5U2NoZWR1bGVbMV1cbiAgdmFyIHMyID0gTVsyXSBeIGtleVNjaGVkdWxlWzJdXG4gIHZhciBzMyA9IE1bM10gXiBrZXlTY2hlZHVsZVszXVxuICB2YXIgdDAsIHQxLCB0MiwgdDNcbiAgdmFyIGtzUm93ID0gNFxuXG4gIGZvciAodmFyIHJvdW5kID0gMTsgcm91bmQgPCBuUm91bmRzOyByb3VuZCsrKSB7XG4gICAgdDAgPSBTVUJfTUlYMFtzMCA+Pj4gMjRdIF4gU1VCX01JWDFbKHMxID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVgyWyhzMiA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVgzW3MzICYgMHhmZl0gXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICAgIHQxID0gU1VCX01JWDBbczEgPj4+IDI0XSBeIFNVQl9NSVgxWyhzMiA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYMlsoczMgPj4+IDgpICYgMHhmZl0gXiBTVUJfTUlYM1tzMCAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MiA9IFNVQl9NSVgwW3MyID4+PiAyNF0gXiBTVUJfTUlYMVsoczMgPj4+IDE2KSAmIDB4ZmZdIF4gU1VCX01JWDJbKHMwID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWDNbczEgJiAweGZmXSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gICAgdDMgPSBTVUJfTUlYMFtzMyA+Pj4gMjRdIF4gU1VCX01JWDFbKHMwID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVgyWyhzMSA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVgzW3MyICYgMHhmZl0gXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICAgIHMwID0gdDBcbiAgICBzMSA9IHQxXG4gICAgczIgPSB0MlxuICAgIHMzID0gdDNcbiAgfVxuXG4gIHQwID0gKChTQk9YW3MwID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMxID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczIgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MzICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgdDEgPSAoKFNCT1hbczEgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczIgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMyA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczAgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICB0MiA9ICgoU0JPWFtzMiA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMyA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMwID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMSAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gIHQzID0gKChTQk9YW3MzID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMwID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczEgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MyICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgdDAgPSB0MCA+Pj4gMFxuICB0MSA9IHQxID4+PiAwXG4gIHQyID0gdDIgPj4+IDBcbiAgdDMgPSB0MyA+Pj4gMFxuXG4gIHJldHVybiBbdDAsIHQxLCB0MiwgdDNdXG59XG5cbi8vIEFFUyBjb25zdGFudHNcbnZhciBSQ09OID0gWzB4MDAsIDB4MDEsIDB4MDIsIDB4MDQsIDB4MDgsIDB4MTAsIDB4MjAsIDB4NDAsIDB4ODAsIDB4MWIsIDB4MzZdXG52YXIgRyA9IChmdW5jdGlvbiAoKSB7XG4gIC8vIENvbXB1dGUgZG91YmxlIHRhYmxlXG4gIHZhciBkID0gbmV3IEFycmF5KDI1NilcbiAgZm9yICh2YXIgaiA9IDA7IGogPCAyNTY7IGorKykge1xuICAgIGlmIChqIDwgMTI4KSB7XG4gICAgICBkW2pdID0gaiA8PCAxXG4gICAgfSBlbHNlIHtcbiAgICAgIGRbal0gPSAoaiA8PCAxKSBeIDB4MTFiXG4gICAgfVxuICB9XG5cbiAgdmFyIFNCT1ggPSBbXVxuICB2YXIgSU5WX1NCT1ggPSBbXVxuICB2YXIgU1VCX01JWCA9IFtbXSwgW10sIFtdLCBbXV1cbiAgdmFyIElOVl9TVUJfTUlYID0gW1tdLCBbXSwgW10sIFtdXVxuXG4gIC8vIFdhbGsgR0YoMl44KVxuICB2YXIgeCA9IDBcbiAgdmFyIHhpID0gMFxuICBmb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgKytpKSB7XG4gICAgLy8gQ29tcHV0ZSBzYm94XG4gICAgdmFyIHN4ID0geGkgXiAoeGkgPDwgMSkgXiAoeGkgPDwgMikgXiAoeGkgPDwgMykgXiAoeGkgPDwgNClcbiAgICBzeCA9IChzeCA+Pj4gOCkgXiAoc3ggJiAweGZmKSBeIDB4NjNcbiAgICBTQk9YW3hdID0gc3hcbiAgICBJTlZfU0JPWFtzeF0gPSB4XG5cbiAgICAvLyBDb21wdXRlIG11bHRpcGxpY2F0aW9uXG4gICAgdmFyIHgyID0gZFt4XVxuICAgIHZhciB4NCA9IGRbeDJdXG4gICAgdmFyIHg4ID0gZFt4NF1cblxuICAgIC8vIENvbXB1dGUgc3ViIGJ5dGVzLCBtaXggY29sdW1ucyB0YWJsZXNcbiAgICB2YXIgdCA9IChkW3N4XSAqIDB4MTAxKSBeIChzeCAqIDB4MTAxMDEwMClcbiAgICBTVUJfTUlYWzBdW3hdID0gKHQgPDwgMjQpIHwgKHQgPj4+IDgpXG4gICAgU1VCX01JWFsxXVt4XSA9ICh0IDw8IDE2KSB8ICh0ID4+PiAxNilcbiAgICBTVUJfTUlYWzJdW3hdID0gKHQgPDwgOCkgfCAodCA+Pj4gMjQpXG4gICAgU1VCX01JWFszXVt4XSA9IHRcblxuICAgIC8vIENvbXB1dGUgaW52IHN1YiBieXRlcywgaW52IG1peCBjb2x1bW5zIHRhYmxlc1xuICAgIHQgPSAoeDggKiAweDEwMTAxMDEpIF4gKHg0ICogMHgxMDAwMSkgXiAoeDIgKiAweDEwMSkgXiAoeCAqIDB4MTAxMDEwMClcbiAgICBJTlZfU1VCX01JWFswXVtzeF0gPSAodCA8PCAyNCkgfCAodCA+Pj4gOClcbiAgICBJTlZfU1VCX01JWFsxXVtzeF0gPSAodCA8PCAxNikgfCAodCA+Pj4gMTYpXG4gICAgSU5WX1NVQl9NSVhbMl1bc3hdID0gKHQgPDwgOCkgfCAodCA+Pj4gMjQpXG4gICAgSU5WX1NVQl9NSVhbM11bc3hdID0gdFxuXG4gICAgaWYgKHggPT09IDApIHtcbiAgICAgIHggPSB4aSA9IDFcbiAgICB9IGVsc2Uge1xuICAgICAgeCA9IHgyIF4gZFtkW2RbeDggXiB4Ml1dXVxuICAgICAgeGkgXj0gZFtkW3hpXV1cbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIFNCT1g6IFNCT1gsXG4gICAgSU5WX1NCT1g6IElOVl9TQk9YLFxuICAgIFNVQl9NSVg6IFNVQl9NSVgsXG4gICAgSU5WX1NVQl9NSVg6IElOVl9TVUJfTUlYXG4gIH1cbn0pKClcblxuZnVuY3Rpb24gQUVTIChrZXkpIHtcbiAgdGhpcy5fa2V5ID0gYXNVSW50MzJBcnJheShrZXkpXG4gIHRoaXMuX3Jlc2V0KClcbn1cblxuQUVTLmJsb2NrU2l6ZSA9IDQgKiA0XG5BRVMua2V5U2l6ZSA9IDI1NiAvIDhcbkFFUy5wcm90b3R5cGUuYmxvY2tTaXplID0gQUVTLmJsb2NrU2l6ZVxuQUVTLnByb3RvdHlwZS5rZXlTaXplID0gQUVTLmtleVNpemVcbkFFUy5wcm90b3R5cGUuX3Jlc2V0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIga2V5V29yZHMgPSB0aGlzLl9rZXlcbiAgdmFyIGtleVNpemUgPSBrZXlXb3Jkcy5sZW5ndGhcbiAgdmFyIG5Sb3VuZHMgPSBrZXlTaXplICsgNlxuICB2YXIga3NSb3dzID0gKG5Sb3VuZHMgKyAxKSAqIDRcblxuICB2YXIga2V5U2NoZWR1bGUgPSBbXVxuICBmb3IgKHZhciBrID0gMDsgayA8IGtleVNpemU7IGsrKykge1xuICAgIGtleVNjaGVkdWxlW2tdID0ga2V5V29yZHNba11cbiAgfVxuXG4gIGZvciAoayA9IGtleVNpemU7IGsgPCBrc1Jvd3M7IGsrKykge1xuICAgIHZhciB0ID0ga2V5U2NoZWR1bGVbayAtIDFdXG5cbiAgICBpZiAoayAlIGtleVNpemUgPT09IDApIHtcbiAgICAgIHQgPSAodCA8PCA4KSB8ICh0ID4+PiAyNClcbiAgICAgIHQgPVxuICAgICAgICAoRy5TQk9YW3QgPj4+IDI0XSA8PCAyNCkgfFxuICAgICAgICAoRy5TQk9YWyh0ID4+PiAxNikgJiAweGZmXSA8PCAxNikgfFxuICAgICAgICAoRy5TQk9YWyh0ID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHxcbiAgICAgICAgKEcuU0JPWFt0ICYgMHhmZl0pXG5cbiAgICAgIHQgXj0gUkNPTlsoayAvIGtleVNpemUpIHwgMF0gPDwgMjRcbiAgICB9IGVsc2UgaWYgKGtleVNpemUgPiA2ICYmIGsgJSBrZXlTaXplID09PSA0KSB7XG4gICAgICB0ID1cbiAgICAgICAgKEcuU0JPWFt0ID4+PiAyNF0gPDwgMjQpIHxcbiAgICAgICAgKEcuU0JPWFsodCA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHxcbiAgICAgICAgKEcuU0JPWFsodCA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8XG4gICAgICAgIChHLlNCT1hbdCAmIDB4ZmZdKVxuICAgIH1cblxuICAgIGtleVNjaGVkdWxlW2tdID0ga2V5U2NoZWR1bGVbayAtIGtleVNpemVdIF4gdFxuICB9XG5cbiAgdmFyIGludktleVNjaGVkdWxlID0gW11cbiAgZm9yICh2YXIgaWsgPSAwOyBpayA8IGtzUm93czsgaWsrKykge1xuICAgIHZhciBrc1IgPSBrc1Jvd3MgLSBpa1xuICAgIHZhciB0dCA9IGtleVNjaGVkdWxlW2tzUiAtIChpayAlIDQgPyAwIDogNCldXG5cbiAgICBpZiAoaWsgPCA0IHx8IGtzUiA8PSA0KSB7XG4gICAgICBpbnZLZXlTY2hlZHVsZVtpa10gPSB0dFxuICAgIH0gZWxzZSB7XG4gICAgICBpbnZLZXlTY2hlZHVsZVtpa10gPVxuICAgICAgICBHLklOVl9TVUJfTUlYWzBdW0cuU0JPWFt0dCA+Pj4gMjRdXSBeXG4gICAgICAgIEcuSU5WX1NVQl9NSVhbMV1bRy5TQk9YWyh0dCA+Pj4gMTYpICYgMHhmZl1dIF5cbiAgICAgICAgRy5JTlZfU1VCX01JWFsyXVtHLlNCT1hbKHR0ID4+PiA4KSAmIDB4ZmZdXSBeXG4gICAgICAgIEcuSU5WX1NVQl9NSVhbM11bRy5TQk9YW3R0ICYgMHhmZl1dXG4gICAgfVxuICB9XG5cbiAgdGhpcy5fblJvdW5kcyA9IG5Sb3VuZHNcbiAgdGhpcy5fa2V5U2NoZWR1bGUgPSBrZXlTY2hlZHVsZVxuICB0aGlzLl9pbnZLZXlTY2hlZHVsZSA9IGludktleVNjaGVkdWxlXG59XG5cbkFFUy5wcm90b3R5cGUuZW5jcnlwdEJsb2NrUmF3ID0gZnVuY3Rpb24gKE0pIHtcbiAgTSA9IGFzVUludDMyQXJyYXkoTSlcbiAgcmV0dXJuIGNyeXB0QmxvY2soTSwgdGhpcy5fa2V5U2NoZWR1bGUsIEcuU1VCX01JWCwgRy5TQk9YLCB0aGlzLl9uUm91bmRzKVxufVxuXG5BRVMucHJvdG90eXBlLmVuY3J5cHRCbG9jayA9IGZ1bmN0aW9uIChNKSB7XG4gIHZhciBvdXQgPSB0aGlzLmVuY3J5cHRCbG9ja1JhdyhNKVxuICB2YXIgYnVmID0gQnVmZmVyLmFsbG9jVW5zYWZlKDE2KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMF0sIDApXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsxXSwgNClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzJdLCA4KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbM10sIDEyKVxuICByZXR1cm4gYnVmXG59XG5cbkFFUy5wcm90b3R5cGUuZGVjcnlwdEJsb2NrID0gZnVuY3Rpb24gKE0pIHtcbiAgTSA9IGFzVUludDMyQXJyYXkoTSlcblxuICAvLyBzd2FwXG4gIHZhciBtMSA9IE1bMV1cbiAgTVsxXSA9IE1bM11cbiAgTVszXSA9IG0xXG5cbiAgdmFyIG91dCA9IGNyeXB0QmxvY2soTSwgdGhpcy5faW52S2V5U2NoZWR1bGUsIEcuSU5WX1NVQl9NSVgsIEcuSU5WX1NCT1gsIHRoaXMuX25Sb3VuZHMpXG4gIHZhciBidWYgPSBCdWZmZXIuYWxsb2NVbnNhZmUoMTYpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFswXSwgMClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzNdLCA0KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMl0sIDgpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsxXSwgMTIpXG4gIHJldHVybiBidWZcbn1cblxuQUVTLnByb3RvdHlwZS5zY3J1YiA9IGZ1bmN0aW9uICgpIHtcbiAgc2NydWJWZWModGhpcy5fa2V5U2NoZWR1bGUpXG4gIHNjcnViVmVjKHRoaXMuX2ludktleVNjaGVkdWxlKVxuICBzY3J1YlZlYyh0aGlzLl9rZXkpXG59XG5cbm1vZHVsZS5leHBvcnRzLkFFUyA9IEFFU1xuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxudmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ2NpcGhlci1iYXNlJylcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBHSEFTSCA9IHJlcXVpcmUoJy4vZ2hhc2gnKVxudmFyIHhvciA9IHJlcXVpcmUoJ2J1ZmZlci14b3InKVxudmFyIGluY3IzMiA9IHJlcXVpcmUoJy4vaW5jcjMyJylcblxuZnVuY3Rpb24geG9yVGVzdCAoYSwgYikge1xuICB2YXIgb3V0ID0gMFxuICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSBvdXQrK1xuXG4gIHZhciBsZW4gPSBNYXRoLm1pbihhLmxlbmd0aCwgYi5sZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICBvdXQgKz0gKGFbaV0gXiBiW2ldKVxuICB9XG5cbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiBjYWxjSXYgKHNlbGYsIGl2LCBjaykge1xuICBpZiAoaXYubGVuZ3RoID09PSAxMikge1xuICAgIHNlbGYuX2ZpbklEID0gQnVmZmVyLmNvbmNhdChbaXYsIEJ1ZmZlci5mcm9tKFswLCAwLCAwLCAxXSldKVxuICAgIHJldHVybiBCdWZmZXIuY29uY2F0KFtpdiwgQnVmZmVyLmZyb20oWzAsIDAsIDAsIDJdKV0pXG4gIH1cbiAgdmFyIGdoYXNoID0gbmV3IEdIQVNIKGNrKVxuICB2YXIgbGVuID0gaXYubGVuZ3RoXG4gIHZhciB0b1BhZCA9IGxlbiAlIDE2XG4gIGdoYXNoLnVwZGF0ZShpdilcbiAgaWYgKHRvUGFkKSB7XG4gICAgdG9QYWQgPSAxNiAtIHRvUGFkXG4gICAgZ2hhc2gudXBkYXRlKEJ1ZmZlci5hbGxvYyh0b1BhZCwgMCkpXG4gIH1cbiAgZ2hhc2gudXBkYXRlKEJ1ZmZlci5hbGxvYyg4LCAwKSlcbiAgdmFyIGl2Qml0cyA9IGxlbiAqIDhcbiAgdmFyIHRhaWwgPSBCdWZmZXIuYWxsb2MoOClcbiAgdGFpbC53cml0ZVVJbnRCRShpdkJpdHMsIDAsIDgpXG4gIGdoYXNoLnVwZGF0ZSh0YWlsKVxuICBzZWxmLl9maW5JRCA9IGdoYXNoLnN0YXRlXG4gIHZhciBvdXQgPSBCdWZmZXIuZnJvbShzZWxmLl9maW5JRClcbiAgaW5jcjMyKG91dClcbiAgcmV0dXJuIG91dFxufVxuZnVuY3Rpb24gU3RyZWFtQ2lwaGVyIChtb2RlLCBrZXksIGl2LCBkZWNyeXB0KSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG5cbiAgdmFyIGggPSBCdWZmZXIuYWxsb2MoNCwgMClcblxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHZhciBjayA9IHRoaXMuX2NpcGhlci5lbmNyeXB0QmxvY2soaClcbiAgdGhpcy5fZ2hhc2ggPSBuZXcgR0hBU0goY2spXG4gIGl2ID0gY2FsY0l2KHRoaXMsIGl2LCBjaylcblxuICB0aGlzLl9wcmV2ID0gQnVmZmVyLmZyb20oaXYpXG4gIHRoaXMuX2NhY2hlID0gQnVmZmVyLmFsbG9jVW5zYWZlKDApXG4gIHRoaXMuX3NlY0NhY2hlID0gQnVmZmVyLmFsbG9jVW5zYWZlKDApXG4gIHRoaXMuX2RlY3J5cHQgPSBkZWNyeXB0XG4gIHRoaXMuX2FsZW4gPSAwXG4gIHRoaXMuX2xlbiA9IDBcbiAgdGhpcy5fbW9kZSA9IG1vZGVcblxuICB0aGlzLl9hdXRoVGFnID0gbnVsbFxuICB0aGlzLl9jYWxsZWQgPSBmYWxzZVxufVxuXG5pbmhlcml0cyhTdHJlYW1DaXBoZXIsIFRyYW5zZm9ybSlcblxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gIGlmICghdGhpcy5fY2FsbGVkICYmIHRoaXMuX2FsZW4pIHtcbiAgICB2YXIgcnVtcCA9IDE2IC0gKHRoaXMuX2FsZW4gJSAxNilcbiAgICBpZiAocnVtcCA8IDE2KSB7XG4gICAgICBydW1wID0gQnVmZmVyLmFsbG9jKHJ1bXAsIDApXG4gICAgICB0aGlzLl9naGFzaC51cGRhdGUocnVtcClcbiAgICB9XG4gIH1cblxuICB0aGlzLl9jYWxsZWQgPSB0cnVlXG4gIHZhciBvdXQgPSB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmspXG4gIGlmICh0aGlzLl9kZWNyeXB0KSB7XG4gICAgdGhpcy5fZ2hhc2gudXBkYXRlKGNodW5rKVxuICB9IGVsc2Uge1xuICAgIHRoaXMuX2doYXNoLnVwZGF0ZShvdXQpXG4gIH1cbiAgdGhpcy5fbGVuICs9IGNodW5rLmxlbmd0aFxuICByZXR1cm4gb3V0XG59XG5cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5fZGVjcnlwdCAmJiAhdGhpcy5fYXV0aFRhZykgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBzdGF0ZSBvciB1bmFibGUgdG8gYXV0aGVudGljYXRlIGRhdGEnKVxuXG4gIHZhciB0YWcgPSB4b3IodGhpcy5fZ2hhc2guZmluYWwodGhpcy5fYWxlbiAqIDgsIHRoaXMuX2xlbiAqIDgpLCB0aGlzLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHRoaXMuX2ZpbklEKSlcbiAgaWYgKHRoaXMuX2RlY3J5cHQgJiYgeG9yVGVzdCh0YWcsIHRoaXMuX2F1dGhUYWcpKSB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIHN0YXRlIG9yIHVuYWJsZSB0byBhdXRoZW50aWNhdGUgZGF0YScpXG5cbiAgdGhpcy5fYXV0aFRhZyA9IHRhZ1xuICB0aGlzLl9jaXBoZXIuc2NydWIoKVxufVxuXG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiBnZXRBdXRoVGFnICgpIHtcbiAgaWYgKHRoaXMuX2RlY3J5cHQgfHwgIUJ1ZmZlci5pc0J1ZmZlcih0aGlzLl9hdXRoVGFnKSkgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG5cbiAgcmV0dXJuIHRoaXMuX2F1dGhUYWdcbn1cblxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5zZXRBdXRoVGFnID0gZnVuY3Rpb24gc2V0QXV0aFRhZyAodGFnKSB7XG4gIGlmICghdGhpcy5fZGVjcnlwdCkgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIHNldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG5cbiAgdGhpcy5fYXV0aFRhZyA9IHRhZ1xufVxuXG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLnNldEFBRCA9IGZ1bmN0aW9uIHNldEFBRCAoYnVmKSB7XG4gIGlmICh0aGlzLl9jYWxsZWQpIHRocm93IG5ldyBFcnJvcignQXR0ZW1wdGluZyB0byBzZXQgQUFEIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcblxuICB0aGlzLl9naGFzaC51cGRhdGUoYnVmKVxuICB0aGlzLl9hbGVuICs9IGJ1Zi5sZW5ndGhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW1DaXBoZXJcbiIsInZhciBjaXBoZXJzID0gcmVxdWlyZSgnLi9lbmNyeXB0ZXInKVxudmFyIGRlY2lwaGVycyA9IHJlcXVpcmUoJy4vZGVjcnlwdGVyJylcbnZhciBtb2RlcyA9IHJlcXVpcmUoJy4vbW9kZXMvbGlzdC5qc29uJylcblxuZnVuY3Rpb24gZ2V0Q2lwaGVycyAoKSB7XG4gIHJldHVybiBPYmplY3Qua2V5cyhtb2Rlcylcbn1cblxuZXhwb3J0cy5jcmVhdGVDaXBoZXIgPSBleHBvcnRzLkNpcGhlciA9IGNpcGhlcnMuY3JlYXRlQ2lwaGVyXG5leHBvcnRzLmNyZWF0ZUNpcGhlcml2ID0gZXhwb3J0cy5DaXBoZXJpdiA9IGNpcGhlcnMuY3JlYXRlQ2lwaGVyaXZcbmV4cG9ydHMuY3JlYXRlRGVjaXBoZXIgPSBleHBvcnRzLkRlY2lwaGVyID0gZGVjaXBoZXJzLmNyZWF0ZURlY2lwaGVyXG5leHBvcnRzLmNyZWF0ZURlY2lwaGVyaXYgPSBleHBvcnRzLkRlY2lwaGVyaXYgPSBkZWNpcGhlcnMuY3JlYXRlRGVjaXBoZXJpdlxuZXhwb3J0cy5saXN0Q2lwaGVycyA9IGV4cG9ydHMuZ2V0Q2lwaGVycyA9IGdldENpcGhlcnNcbiIsInZhciBBdXRoQ2lwaGVyID0gcmVxdWlyZSgnLi9hdXRoQ2lwaGVyJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxudmFyIE1PREVTID0gcmVxdWlyZSgnLi9tb2RlcycpXG52YXIgU3RyZWFtQ2lwaGVyID0gcmVxdWlyZSgnLi9zdHJlYW1DaXBoZXInKVxudmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ2NpcGhlci1iYXNlJylcbnZhciBhZXMgPSByZXF1aXJlKCcuL2FlcycpXG52YXIgZWJ0ayA9IHJlcXVpcmUoJ2V2cF9ieXRlc3Rva2V5JylcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcblxuZnVuY3Rpb24gRGVjaXBoZXIgKG1vZGUsIGtleSwgaXYpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcblxuICB0aGlzLl9jYWNoZSA9IG5ldyBTcGxpdHRlcigpXG4gIHRoaXMuX2xhc3QgPSB2b2lkIDBcbiAgdGhpcy5fY2lwaGVyID0gbmV3IGFlcy5BRVMoa2V5KVxuICB0aGlzLl9wcmV2ID0gQnVmZmVyLmZyb20oaXYpXG4gIHRoaXMuX21vZGUgPSBtb2RlXG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gdHJ1ZVxufVxuXG5pbmhlcml0cyhEZWNpcGhlciwgVHJhbnNmb3JtKVxuXG5EZWNpcGhlci5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuX2NhY2hlLmFkZChkYXRhKVxuICB2YXIgY2h1bmtcbiAgdmFyIHRoaW5nXG4gIHZhciBvdXQgPSBbXVxuICB3aGlsZSAoKGNodW5rID0gdGhpcy5fY2FjaGUuZ2V0KHRoaXMuX2F1dG9wYWRkaW5nKSkpIHtcbiAgICB0aGluZyA9IHRoaXMuX21vZGUuZGVjcnlwdCh0aGlzLCBjaHVuaylcbiAgICBvdXQucHVzaCh0aGluZylcbiAgfVxuICByZXR1cm4gQnVmZmVyLmNvbmNhdChvdXQpXG59XG5cbkRlY2lwaGVyLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBjaHVuayA9IHRoaXMuX2NhY2hlLmZsdXNoKClcbiAgaWYgKHRoaXMuX2F1dG9wYWRkaW5nKSB7XG4gICAgcmV0dXJuIHVucGFkKHRoaXMuX21vZGUuZGVjcnlwdCh0aGlzLCBjaHVuaykpXG4gIH0gZWxzZSBpZiAoY2h1bmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RhdGEgbm90IG11bHRpcGxlIG9mIGJsb2NrIGxlbmd0aCcpXG4gIH1cbn1cblxuRGVjaXBoZXIucHJvdG90eXBlLnNldEF1dG9QYWRkaW5nID0gZnVuY3Rpb24gKHNldFRvKSB7XG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gISFzZXRUb1xuICByZXR1cm4gdGhpc1xufVxuXG5mdW5jdGlvbiBTcGxpdHRlciAoKSB7XG4gIHRoaXMuY2FjaGUgPSBCdWZmZXIuYWxsb2NVbnNhZmUoMClcbn1cblxuU3BsaXR0ZXIucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuY2FjaGUgPSBCdWZmZXIuY29uY2F0KFt0aGlzLmNhY2hlLCBkYXRhXSlcbn1cblxuU3BsaXR0ZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChhdXRvUGFkZGluZykge1xuICB2YXIgb3V0XG4gIGlmIChhdXRvUGFkZGluZykge1xuICAgIGlmICh0aGlzLmNhY2hlLmxlbmd0aCA+IDE2KSB7XG4gICAgICBvdXQgPSB0aGlzLmNhY2hlLnNsaWNlKDAsIDE2KVxuICAgICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgICByZXR1cm4gb3V0XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmICh0aGlzLmNhY2hlLmxlbmd0aCA+PSAxNikge1xuICAgICAgb3V0ID0gdGhpcy5jYWNoZS5zbGljZSgwLCAxNilcbiAgICAgIHRoaXMuY2FjaGUgPSB0aGlzLmNhY2hlLnNsaWNlKDE2KVxuICAgICAgcmV0dXJuIG91dFxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsXG59XG5cblNwbGl0dGVyLnByb3RvdHlwZS5mbHVzaCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoKSByZXR1cm4gdGhpcy5jYWNoZVxufVxuXG5mdW5jdGlvbiB1bnBhZCAobGFzdCkge1xuICB2YXIgcGFkZGVkID0gbGFzdFsxNV1cbiAgaWYgKHBhZGRlZCA8IDEgfHwgcGFkZGVkID4gMTYpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3VuYWJsZSB0byBkZWNyeXB0IGRhdGEnKVxuICB9XG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IHBhZGRlZCkge1xuICAgIGlmIChsYXN0WyhpICsgKDE2IC0gcGFkZGVkKSldICE9PSBwYWRkZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5hYmxlIHRvIGRlY3J5cHQgZGF0YScpXG4gICAgfVxuICB9XG4gIGlmIChwYWRkZWQgPT09IDE2KSByZXR1cm5cblxuICByZXR1cm4gbGFzdC5zbGljZSgwLCAxNiAtIHBhZGRlZClcbn1cblxuZnVuY3Rpb24gY3JlYXRlRGVjaXBoZXJpdiAoc3VpdGUsIHBhc3N3b3JkLCBpdikge1xuICB2YXIgY29uZmlnID0gTU9ERVNbc3VpdGUudG9Mb3dlckNhc2UoKV1cbiAgaWYgKCFjb25maWcpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG5cbiAgaWYgKHR5cGVvZiBpdiA9PT0gJ3N0cmluZycpIGl2ID0gQnVmZmVyLmZyb20oaXYpXG4gIGlmIChjb25maWcubW9kZSAhPT0gJ0dDTScgJiYgaXYubGVuZ3RoICE9PSBjb25maWcuaXYpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgaXYgbGVuZ3RoICcgKyBpdi5sZW5ndGgpXG5cbiAgaWYgKHR5cGVvZiBwYXNzd29yZCA9PT0gJ3N0cmluZycpIHBhc3N3b3JkID0gQnVmZmVyLmZyb20ocGFzc3dvcmQpXG4gIGlmIChwYXNzd29yZC5sZW5ndGggIT09IGNvbmZpZy5rZXkgLyA4KSB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGtleSBsZW5ndGggJyArIHBhc3N3b3JkLmxlbmd0aClcblxuICBpZiAoY29uZmlnLnR5cGUgPT09ICdzdHJlYW0nKSB7XG4gICAgcmV0dXJuIG5ldyBTdHJlYW1DaXBoZXIoY29uZmlnLm1vZHVsZSwgcGFzc3dvcmQsIGl2LCB0cnVlKVxuICB9IGVsc2UgaWYgKGNvbmZpZy50eXBlID09PSAnYXV0aCcpIHtcbiAgICByZXR1cm4gbmV3IEF1dGhDaXBoZXIoY29uZmlnLm1vZHVsZSwgcGFzc3dvcmQsIGl2LCB0cnVlKVxuICB9XG5cbiAgcmV0dXJuIG5ldyBEZWNpcGhlcihjb25maWcubW9kdWxlLCBwYXNzd29yZCwgaXYpXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZURlY2lwaGVyIChzdWl0ZSwgcGFzc3dvcmQpIHtcbiAgdmFyIGNvbmZpZyA9IE1PREVTW3N1aXRlLnRvTG93ZXJDYXNlKCldXG4gIGlmICghY29uZmlnKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuXG4gIHZhciBrZXlzID0gZWJ0ayhwYXNzd29yZCwgZmFsc2UsIGNvbmZpZy5rZXksIGNvbmZpZy5pdilcbiAgcmV0dXJuIGNyZWF0ZURlY2lwaGVyaXYoc3VpdGUsIGtleXMua2V5LCBrZXlzLml2KVxufVxuXG5leHBvcnRzLmNyZWF0ZURlY2lwaGVyID0gY3JlYXRlRGVjaXBoZXJcbmV4cG9ydHMuY3JlYXRlRGVjaXBoZXJpdiA9IGNyZWF0ZURlY2lwaGVyaXZcbiIsInZhciBNT0RFUyA9IHJlcXVpcmUoJy4vbW9kZXMnKVxudmFyIEF1dGhDaXBoZXIgPSByZXF1aXJlKCcuL2F1dGhDaXBoZXInKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG52YXIgU3RyZWFtQ2lwaGVyID0gcmVxdWlyZSgnLi9zdHJlYW1DaXBoZXInKVxudmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ2NpcGhlci1iYXNlJylcbnZhciBhZXMgPSByZXF1aXJlKCcuL2FlcycpXG52YXIgZWJ0ayA9IHJlcXVpcmUoJ2V2cF9ieXRlc3Rva2V5JylcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcblxuZnVuY3Rpb24gQ2lwaGVyIChtb2RlLCBrZXksIGl2KSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG5cbiAgdGhpcy5fY2FjaGUgPSBuZXcgU3BsaXR0ZXIoKVxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHRoaXMuX3ByZXYgPSBCdWZmZXIuZnJvbShpdilcbiAgdGhpcy5fbW9kZSA9IG1vZGVcbiAgdGhpcy5fYXV0b3BhZGRpbmcgPSB0cnVlXG59XG5cbmluaGVyaXRzKENpcGhlciwgVHJhbnNmb3JtKVxuXG5DaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB0aGlzLl9jYWNoZS5hZGQoZGF0YSlcbiAgdmFyIGNodW5rXG4gIHZhciB0aGluZ1xuICB2YXIgb3V0ID0gW11cblxuICB3aGlsZSAoKGNodW5rID0gdGhpcy5fY2FjaGUuZ2V0KCkpKSB7XG4gICAgdGhpbmcgPSB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmspXG4gICAgb3V0LnB1c2godGhpbmcpXG4gIH1cblxuICByZXR1cm4gQnVmZmVyLmNvbmNhdChvdXQpXG59XG5cbnZhciBQQURESU5HID0gQnVmZmVyLmFsbG9jKDE2LCAweDEwKVxuXG5DaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNodW5rID0gdGhpcy5fY2FjaGUuZmx1c2goKVxuICBpZiAodGhpcy5fYXV0b3BhZGRpbmcpIHtcbiAgICBjaHVuayA9IHRoaXMuX21vZGUuZW5jcnlwdCh0aGlzLCBjaHVuaylcbiAgICB0aGlzLl9jaXBoZXIuc2NydWIoKVxuICAgIHJldHVybiBjaHVua1xuICB9XG5cbiAgaWYgKCFjaHVuay5lcXVhbHMoUEFERElORykpIHtcbiAgICB0aGlzLl9jaXBoZXIuc2NydWIoKVxuICAgIHRocm93IG5ldyBFcnJvcignZGF0YSBub3QgbXVsdGlwbGUgb2YgYmxvY2sgbGVuZ3RoJylcbiAgfVxufVxuXG5DaXBoZXIucHJvdG90eXBlLnNldEF1dG9QYWRkaW5nID0gZnVuY3Rpb24gKHNldFRvKSB7XG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gISFzZXRUb1xuICByZXR1cm4gdGhpc1xufVxuXG5mdW5jdGlvbiBTcGxpdHRlciAoKSB7XG4gIHRoaXMuY2FjaGUgPSBCdWZmZXIuYWxsb2NVbnNhZmUoMClcbn1cblxuU3BsaXR0ZXIucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuY2FjaGUgPSBCdWZmZXIuY29uY2F0KFt0aGlzLmNhY2hlLCBkYXRhXSlcbn1cblxuU3BsaXR0ZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoID4gMTUpIHtcbiAgICB2YXIgb3V0ID0gdGhpcy5jYWNoZS5zbGljZSgwLCAxNilcbiAgICB0aGlzLmNhY2hlID0gdGhpcy5jYWNoZS5zbGljZSgxNilcbiAgICByZXR1cm4gb3V0XG4gIH1cbiAgcmV0dXJuIG51bGxcbn1cblxuU3BsaXR0ZXIucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbGVuID0gMTYgLSB0aGlzLmNhY2hlLmxlbmd0aFxuICB2YXIgcGFkQnVmZiA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShsZW4pXG5cbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgcGFkQnVmZi53cml0ZVVJbnQ4KGxlbiwgaSlcbiAgfVxuXG4gIHJldHVybiBCdWZmZXIuY29uY2F0KFt0aGlzLmNhY2hlLCBwYWRCdWZmXSlcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2lwaGVyaXYgKHN1aXRlLCBwYXNzd29yZCwgaXYpIHtcbiAgdmFyIGNvbmZpZyA9IE1PREVTW3N1aXRlLnRvTG93ZXJDYXNlKCldXG4gIGlmICghY29uZmlnKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuXG4gIGlmICh0eXBlb2YgcGFzc3dvcmQgPT09ICdzdHJpbmcnKSBwYXNzd29yZCA9IEJ1ZmZlci5mcm9tKHBhc3N3b3JkKVxuICBpZiAocGFzc3dvcmQubGVuZ3RoICE9PSBjb25maWcua2V5IC8gOCkgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBrZXkgbGVuZ3RoICcgKyBwYXNzd29yZC5sZW5ndGgpXG5cbiAgaWYgKHR5cGVvZiBpdiA9PT0gJ3N0cmluZycpIGl2ID0gQnVmZmVyLmZyb20oaXYpXG4gIGlmIChjb25maWcubW9kZSAhPT0gJ0dDTScgJiYgaXYubGVuZ3RoICE9PSBjb25maWcuaXYpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgaXYgbGVuZ3RoICcgKyBpdi5sZW5ndGgpXG5cbiAgaWYgKGNvbmZpZy50eXBlID09PSAnc3RyZWFtJykge1xuICAgIHJldHVybiBuZXcgU3RyZWFtQ2lwaGVyKGNvbmZpZy5tb2R1bGUsIHBhc3N3b3JkLCBpdilcbiAgfSBlbHNlIGlmIChjb25maWcudHlwZSA9PT0gJ2F1dGgnKSB7XG4gICAgcmV0dXJuIG5ldyBBdXRoQ2lwaGVyKGNvbmZpZy5tb2R1bGUsIHBhc3N3b3JkLCBpdilcbiAgfVxuXG4gIHJldHVybiBuZXcgQ2lwaGVyKGNvbmZpZy5tb2R1bGUsIHBhc3N3b3JkLCBpdilcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2lwaGVyIChzdWl0ZSwgcGFzc3dvcmQpIHtcbiAgdmFyIGNvbmZpZyA9IE1PREVTW3N1aXRlLnRvTG93ZXJDYXNlKCldXG4gIGlmICghY29uZmlnKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuXG4gIHZhciBrZXlzID0gZWJ0ayhwYXNzd29yZCwgZmFsc2UsIGNvbmZpZy5rZXksIGNvbmZpZy5pdilcbiAgcmV0dXJuIGNyZWF0ZUNpcGhlcml2KHN1aXRlLCBrZXlzLmtleSwga2V5cy5pdilcbn1cblxuZXhwb3J0cy5jcmVhdGVDaXBoZXJpdiA9IGNyZWF0ZUNpcGhlcml2XG5leHBvcnRzLmNyZWF0ZUNpcGhlciA9IGNyZWF0ZUNpcGhlclxuIiwidmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG52YXIgWkVST0VTID0gQnVmZmVyLmFsbG9jKDE2LCAwKVxuXG5mdW5jdGlvbiB0b0FycmF5IChidWYpIHtcbiAgcmV0dXJuIFtcbiAgICBidWYucmVhZFVJbnQzMkJFKDApLFxuICAgIGJ1Zi5yZWFkVUludDMyQkUoNCksXG4gICAgYnVmLnJlYWRVSW50MzJCRSg4KSxcbiAgICBidWYucmVhZFVJbnQzMkJFKDEyKVxuICBdXG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheSAob3V0KSB7XG4gIHZhciBidWYgPSBCdWZmZXIuYWxsb2NVbnNhZmUoMTYpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFswXSA+Pj4gMCwgMClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzFdID4+PiAwLCA0KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMl0gPj4+IDAsIDgpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFszXSA+Pj4gMCwgMTIpXG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gR0hBU0ggKGtleSkge1xuICB0aGlzLmggPSBrZXlcbiAgdGhpcy5zdGF0ZSA9IEJ1ZmZlci5hbGxvYygxNiwgMClcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSgwKVxufVxuXG4vLyBmcm9tIGh0dHA6Ly9iaXR3aXNlc2hpZnRsZWZ0LmdpdGh1Yi5pby9zamNsL2RvYy9zeW1ib2xzL3NyYy9jb3JlX2djbS5qcy5odG1sXG4vLyBieSBKdWhvIFbDpGjDpC1IZXJ0dHVhXG5HSEFTSC5wcm90b3R5cGUuZ2hhc2ggPSBmdW5jdGlvbiAoYmxvY2spIHtcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgYmxvY2subGVuZ3RoKSB7XG4gICAgdGhpcy5zdGF0ZVtpXSBePSBibG9ja1tpXVxuICB9XG4gIHRoaXMuX211bHRpcGx5KClcbn1cblxuR0hBU0gucHJvdG90eXBlLl9tdWx0aXBseSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIFZpID0gdG9BcnJheSh0aGlzLmgpXG4gIHZhciBaaSA9IFswLCAwLCAwLCAwXVxuICB2YXIgaiwgeGksIGxzYlZpXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IDEyOCkge1xuICAgIHhpID0gKHRoaXMuc3RhdGVbfn4oaSAvIDgpXSAmICgxIDw8ICg3IC0gKGkgJSA4KSkpKSAhPT0gMFxuICAgIGlmICh4aSkge1xuICAgICAgLy8gWl9pKzEgPSBaX2kgXiBWX2lcbiAgICAgIFppWzBdIF49IFZpWzBdXG4gICAgICBaaVsxXSBePSBWaVsxXVxuICAgICAgWmlbMl0gXj0gVmlbMl1cbiAgICAgIFppWzNdIF49IFZpWzNdXG4gICAgfVxuXG4gICAgLy8gU3RvcmUgdGhlIHZhbHVlIG9mIExTQihWX2kpXG4gICAgbHNiVmkgPSAoVmlbM10gJiAxKSAhPT0gMFxuXG4gICAgLy8gVl9pKzEgPSBWX2kgPj4gMVxuICAgIGZvciAoaiA9IDM7IGogPiAwOyBqLS0pIHtcbiAgICAgIFZpW2pdID0gKFZpW2pdID4+PiAxKSB8ICgoVmlbaiAtIDFdICYgMSkgPDwgMzEpXG4gICAgfVxuICAgIFZpWzBdID0gVmlbMF0gPj4+IDFcblxuICAgIC8vIElmIExTQihWX2kpIGlzIDEsIFZfaSsxID0gKFZfaSA+PiAxKSBeIFJcbiAgICBpZiAobHNiVmkpIHtcbiAgICAgIFZpWzBdID0gVmlbMF0gXiAoMHhlMSA8PCAyNClcbiAgICB9XG4gIH1cbiAgdGhpcy5zdGF0ZSA9IGZyb21BcnJheShaaSlcbn1cblxuR0hBU0gucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChidWYpIHtcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIGJ1Zl0pXG4gIHZhciBjaHVua1xuICB3aGlsZSAodGhpcy5jYWNoZS5sZW5ndGggPj0gMTYpIHtcbiAgICBjaHVuayA9IHRoaXMuY2FjaGUuc2xpY2UoMCwgMTYpXG4gICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgdGhpcy5naGFzaChjaHVuaylcbiAgfVxufVxuXG5HSEFTSC5wcm90b3R5cGUuZmluYWwgPSBmdW5jdGlvbiAoYWJsLCBibCkge1xuICBpZiAodGhpcy5jYWNoZS5sZW5ndGgpIHtcbiAgICB0aGlzLmdoYXNoKEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIFpFUk9FU10sIDE2KSlcbiAgfVxuXG4gIHRoaXMuZ2hhc2goZnJvbUFycmF5KFswLCBhYmwsIDAsIGJsXSkpXG4gIHJldHVybiB0aGlzLnN0YXRlXG59XG5cbm1vZHVsZS5leHBvcnRzID0gR0hBU0hcbiIsImZ1bmN0aW9uIGluY3IzMiAoaXYpIHtcbiAgdmFyIGxlbiA9IGl2Lmxlbmd0aFxuICB2YXIgaXRlbVxuICB3aGlsZSAobGVuLS0pIHtcbiAgICBpdGVtID0gaXYucmVhZFVJbnQ4KGxlbilcbiAgICBpZiAoaXRlbSA9PT0gMjU1KSB7XG4gICAgICBpdi53cml0ZVVJbnQ4KDAsIGxlbilcbiAgICB9IGVsc2Uge1xuICAgICAgaXRlbSsrXG4gICAgICBpdi53cml0ZVVJbnQ4KGl0ZW0sIGxlbilcbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IGluY3IzMlxuIiwidmFyIHhvciA9IHJlcXVpcmUoJ2J1ZmZlci14b3InKVxuXG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgYmxvY2spIHtcbiAgdmFyIGRhdGEgPSB4b3IoYmxvY2ssIHNlbGYuX3ByZXYpXG5cbiAgc2VsZi5fcHJldiA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soZGF0YSlcbiAgcmV0dXJuIHNlbGYuX3ByZXZcbn1cblxuZXhwb3J0cy5kZWNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGJsb2NrKSB7XG4gIHZhciBwYWQgPSBzZWxmLl9wcmV2XG5cbiAgc2VsZi5fcHJldiA9IGJsb2NrXG4gIHZhciBvdXQgPSBzZWxmLl9jaXBoZXIuZGVjcnlwdEJsb2NrKGJsb2NrKVxuXG4gIHJldHVybiB4b3Iob3V0LCBwYWQpXG59XG4iLCJ2YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcbnZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcblxuZnVuY3Rpb24gZW5jcnlwdFN0YXJ0IChzZWxmLCBkYXRhLCBkZWNyeXB0KSB7XG4gIHZhciBsZW4gPSBkYXRhLmxlbmd0aFxuICB2YXIgb3V0ID0geG9yKGRhdGEsIHNlbGYuX2NhY2hlKVxuICBzZWxmLl9jYWNoZSA9IHNlbGYuX2NhY2hlLnNsaWNlKGxlbilcbiAgc2VsZi5fcHJldiA9IEJ1ZmZlci5jb25jYXQoW3NlbGYuX3ByZXYsIGRlY3J5cHQgPyBkYXRhIDogb3V0XSlcbiAgcmV0dXJuIG91dFxufVxuXG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgZGF0YSwgZGVjcnlwdCkge1xuICB2YXIgb3V0ID0gQnVmZmVyLmFsbG9jVW5zYWZlKDApXG4gIHZhciBsZW5cblxuICB3aGlsZSAoZGF0YS5sZW5ndGgpIHtcbiAgICBpZiAoc2VsZi5fY2FjaGUubGVuZ3RoID09PSAwKSB7XG4gICAgICBzZWxmLl9jYWNoZSA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soc2VsZi5fcHJldilcbiAgICAgIHNlbGYuX3ByZXYgPSBCdWZmZXIuYWxsb2NVbnNhZmUoMClcbiAgICB9XG5cbiAgICBpZiAoc2VsZi5fY2FjaGUubGVuZ3RoIDw9IGRhdGEubGVuZ3RoKSB7XG4gICAgICBsZW4gPSBzZWxmLl9jYWNoZS5sZW5ndGhcbiAgICAgIG91dCA9IEJ1ZmZlci5jb25jYXQoW291dCwgZW5jcnlwdFN0YXJ0KHNlbGYsIGRhdGEuc2xpY2UoMCwgbGVuKSwgZGVjcnlwdCldKVxuICAgICAgZGF0YSA9IGRhdGEuc2xpY2UobGVuKVxuICAgIH0gZWxzZSB7XG4gICAgICBvdXQgPSBCdWZmZXIuY29uY2F0KFtvdXQsIGVuY3J5cHRTdGFydChzZWxmLCBkYXRhLCBkZWNyeXB0KV0pXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvdXRcbn1cbiIsInZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxuXG5mdW5jdGlvbiBlbmNyeXB0Qnl0ZSAoc2VsZiwgYnl0ZVBhcmFtLCBkZWNyeXB0KSB7XG4gIHZhciBwYWRcbiAgdmFyIGkgPSAtMVxuICB2YXIgbGVuID0gOFxuICB2YXIgb3V0ID0gMFxuICB2YXIgYml0LCB2YWx1ZVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgcGFkID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhzZWxmLl9wcmV2KVxuICAgIGJpdCA9IChieXRlUGFyYW0gJiAoMSA8PCAoNyAtIGkpKSkgPyAweDgwIDogMFxuICAgIHZhbHVlID0gcGFkWzBdIF4gYml0XG4gICAgb3V0ICs9ICgodmFsdWUgJiAweDgwKSA+PiAoaSAlIDgpKVxuICAgIHNlbGYuX3ByZXYgPSBzaGlmdEluKHNlbGYuX3ByZXYsIGRlY3J5cHQgPyBiaXQgOiB2YWx1ZSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHNoaWZ0SW4gKGJ1ZmZlciwgdmFsdWUpIHtcbiAgdmFyIGxlbiA9IGJ1ZmZlci5sZW5ndGhcbiAgdmFyIGkgPSAtMVxuICB2YXIgb3V0ID0gQnVmZmVyLmFsbG9jVW5zYWZlKGJ1ZmZlci5sZW5ndGgpXG4gIGJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoW2J1ZmZlciwgQnVmZmVyLmZyb20oW3ZhbHVlXSldKVxuXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXRbaV0gPSBidWZmZXJbaV0gPDwgMSB8IGJ1ZmZlcltpICsgMV0gPj4gKDcpXG4gIH1cblxuICByZXR1cm4gb3V0XG59XG5cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBjaHVuaywgZGVjcnlwdCkge1xuICB2YXIgbGVuID0gY2h1bmsubGVuZ3RoXG4gIHZhciBvdXQgPSBCdWZmZXIuYWxsb2NVbnNhZmUobGVuKVxuICB2YXIgaSA9IC0xXG5cbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dFtpXSA9IGVuY3J5cHRCeXRlKHNlbGYsIGNodW5rW2ldLCBkZWNyeXB0KVxuICB9XG5cbiAgcmV0dXJuIG91dFxufVxuIiwidmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG5cbmZ1bmN0aW9uIGVuY3J5cHRCeXRlIChzZWxmLCBieXRlUGFyYW0sIGRlY3J5cHQpIHtcbiAgdmFyIHBhZCA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soc2VsZi5fcHJldilcbiAgdmFyIG91dCA9IHBhZFswXSBeIGJ5dGVQYXJhbVxuXG4gIHNlbGYuX3ByZXYgPSBCdWZmZXIuY29uY2F0KFtcbiAgICBzZWxmLl9wcmV2LnNsaWNlKDEpLFxuICAgIEJ1ZmZlci5mcm9tKFtkZWNyeXB0ID8gYnl0ZVBhcmFtIDogb3V0XSlcbiAgXSlcblxuICByZXR1cm4gb3V0XG59XG5cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBjaHVuaywgZGVjcnlwdCkge1xuICB2YXIgbGVuID0gY2h1bmsubGVuZ3RoXG4gIHZhciBvdXQgPSBCdWZmZXIuYWxsb2NVbnNhZmUobGVuKVxuICB2YXIgaSA9IC0xXG5cbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dFtpXSA9IGVuY3J5cHRCeXRlKHNlbGYsIGNodW5rW2ldLCBkZWNyeXB0KVxuICB9XG5cbiAgcmV0dXJuIG91dFxufVxuIiwidmFyIHhvciA9IHJlcXVpcmUoJ2J1ZmZlci14b3InKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG52YXIgaW5jcjMyID0gcmVxdWlyZSgnLi4vaW5jcjMyJylcblxuZnVuY3Rpb24gZ2V0QmxvY2sgKHNlbGYpIHtcbiAgdmFyIG91dCA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2tSYXcoc2VsZi5fcHJldilcbiAgaW5jcjMyKHNlbGYuX3ByZXYpXG4gIHJldHVybiBvdXRcbn1cblxudmFyIGJsb2NrU2l6ZSA9IDE2XG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgY2h1bmspIHtcbiAgdmFyIGNodW5rTnVtID0gTWF0aC5jZWlsKGNodW5rLmxlbmd0aCAvIGJsb2NrU2l6ZSlcbiAgdmFyIHN0YXJ0ID0gc2VsZi5fY2FjaGUubGVuZ3RoXG4gIHNlbGYuX2NhY2hlID0gQnVmZmVyLmNvbmNhdChbXG4gICAgc2VsZi5fY2FjaGUsXG4gICAgQnVmZmVyLmFsbG9jVW5zYWZlKGNodW5rTnVtICogYmxvY2tTaXplKVxuICBdKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGNodW5rTnVtOyBpKyspIHtcbiAgICB2YXIgb3V0ID0gZ2V0QmxvY2soc2VsZilcbiAgICB2YXIgb2Zmc2V0ID0gc3RhcnQgKyBpICogYmxvY2tTaXplXG4gICAgc2VsZi5fY2FjaGUud3JpdGVVSW50MzJCRShvdXRbMF0sIG9mZnNldCArIDApXG4gICAgc2VsZi5fY2FjaGUud3JpdGVVSW50MzJCRShvdXRbMV0sIG9mZnNldCArIDQpXG4gICAgc2VsZi5fY2FjaGUud3JpdGVVSW50MzJCRShvdXRbMl0sIG9mZnNldCArIDgpXG4gICAgc2VsZi5fY2FjaGUud3JpdGVVSW50MzJCRShvdXRbM10sIG9mZnNldCArIDEyKVxuICB9XG4gIHZhciBwYWQgPSBzZWxmLl9jYWNoZS5zbGljZSgwLCBjaHVuay5sZW5ndGgpXG4gIHNlbGYuX2NhY2hlID0gc2VsZi5fY2FjaGUuc2xpY2UoY2h1bmsubGVuZ3RoKVxuICByZXR1cm4geG9yKGNodW5rLCBwYWQpXG59XG4iLCJleHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgYmxvY2spIHtcbiAgcmV0dXJuIHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soYmxvY2spXG59XG5cbmV4cG9ydHMuZGVjcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBibG9jaykge1xuICByZXR1cm4gc2VsZi5fY2lwaGVyLmRlY3J5cHRCbG9jayhibG9jaylcbn1cbiIsInZhciBtb2RlTW9kdWxlcyA9IHtcbiAgRUNCOiByZXF1aXJlKCcuL2VjYicpLFxuICBDQkM6IHJlcXVpcmUoJy4vY2JjJyksXG4gIENGQjogcmVxdWlyZSgnLi9jZmInKSxcbiAgQ0ZCODogcmVxdWlyZSgnLi9jZmI4JyksXG4gIENGQjE6IHJlcXVpcmUoJy4vY2ZiMScpLFxuICBPRkI6IHJlcXVpcmUoJy4vb2ZiJyksXG4gIENUUjogcmVxdWlyZSgnLi9jdHInKSxcbiAgR0NNOiByZXF1aXJlKCcuL2N0cicpXG59XG5cbnZhciBtb2RlcyA9IHJlcXVpcmUoJy4vbGlzdC5qc29uJylcblxuZm9yICh2YXIga2V5IGluIG1vZGVzKSB7XG4gIG1vZGVzW2tleV0ubW9kdWxlID0gbW9kZU1vZHVsZXNbbW9kZXNba2V5XS5tb2RlXVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG1vZGVzXG4iLCJ2YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG5cbmZ1bmN0aW9uIGdldEJsb2NrIChzZWxmKSB7XG4gIHNlbGYuX3ByZXYgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gIHJldHVybiBzZWxmLl9wcmV2XG59XG5cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBjaHVuaykge1xuICB3aGlsZSAoc2VsZi5fY2FjaGUubGVuZ3RoIDwgY2h1bmsubGVuZ3RoKSB7XG4gICAgc2VsZi5fY2FjaGUgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9jYWNoZSwgZ2V0QmxvY2soc2VsZildKVxuICB9XG5cbiAgdmFyIHBhZCA9IHNlbGYuX2NhY2hlLnNsaWNlKDAsIGNodW5rLmxlbmd0aClcbiAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jYWNoZS5zbGljZShjaHVuay5sZW5ndGgpXG4gIHJldHVybiB4b3IoY2h1bmssIHBhZClcbn1cbiIsInZhciBhZXMgPSByZXF1aXJlKCcuL2FlcycpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG5cbmZ1bmN0aW9uIFN0cmVhbUNpcGhlciAobW9kZSwga2V5LCBpdiwgZGVjcnlwdCkge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuXG4gIHRoaXMuX2NpcGhlciA9IG5ldyBhZXMuQUVTKGtleSlcbiAgdGhpcy5fcHJldiA9IEJ1ZmZlci5mcm9tKGl2KVxuICB0aGlzLl9jYWNoZSA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSgwKVxuICB0aGlzLl9zZWNDYWNoZSA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSgwKVxuICB0aGlzLl9kZWNyeXB0ID0gZGVjcnlwdFxuICB0aGlzLl9tb2RlID0gbW9kZVxufVxuXG5pbmhlcml0cyhTdHJlYW1DaXBoZXIsIFRyYW5zZm9ybSlcblxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gIHJldHVybiB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmssIHRoaXMuX2RlY3J5cHQpXG59XG5cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9jaXBoZXIuc2NydWIoKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFN0cmVhbUNpcGhlclxuIiwidmFyIERFUyA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktZGVzJylcbnZhciBhZXMgPSByZXF1aXJlKCdicm93c2VyaWZ5LWFlcy9icm93c2VyJylcbnZhciBhZXNNb2RlcyA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktYWVzL21vZGVzJylcbnZhciBkZXNNb2RlcyA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktZGVzL21vZGVzJylcbnZhciBlYnRrID0gcmVxdWlyZSgnZXZwX2J5dGVzdG9rZXknKVxuXG5mdW5jdGlvbiBjcmVhdGVDaXBoZXIgKHN1aXRlLCBwYXNzd29yZCkge1xuICBzdWl0ZSA9IHN1aXRlLnRvTG93ZXJDYXNlKClcblxuICB2YXIga2V5TGVuLCBpdkxlblxuICBpZiAoYWVzTW9kZXNbc3VpdGVdKSB7XG4gICAga2V5TGVuID0gYWVzTW9kZXNbc3VpdGVdLmtleVxuICAgIGl2TGVuID0gYWVzTW9kZXNbc3VpdGVdLml2XG4gIH0gZWxzZSBpZiAoZGVzTW9kZXNbc3VpdGVdKSB7XG4gICAga2V5TGVuID0gZGVzTW9kZXNbc3VpdGVdLmtleSAqIDhcbiAgICBpdkxlbiA9IGRlc01vZGVzW3N1aXRlXS5pdlxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cblxuICB2YXIga2V5cyA9IGVidGsocGFzc3dvcmQsIGZhbHNlLCBrZXlMZW4sIGl2TGVuKVxuICByZXR1cm4gY3JlYXRlQ2lwaGVyaXYoc3VpdGUsIGtleXMua2V5LCBrZXlzLml2KVxufVxuXG5mdW5jdGlvbiBjcmVhdGVEZWNpcGhlciAoc3VpdGUsIHBhc3N3b3JkKSB7XG4gIHN1aXRlID0gc3VpdGUudG9Mb3dlckNhc2UoKVxuXG4gIHZhciBrZXlMZW4sIGl2TGVuXG4gIGlmIChhZXNNb2Rlc1tzdWl0ZV0pIHtcbiAgICBrZXlMZW4gPSBhZXNNb2Rlc1tzdWl0ZV0ua2V5XG4gICAgaXZMZW4gPSBhZXNNb2Rlc1tzdWl0ZV0uaXZcbiAgfSBlbHNlIGlmIChkZXNNb2Rlc1tzdWl0ZV0pIHtcbiAgICBrZXlMZW4gPSBkZXNNb2Rlc1tzdWl0ZV0ua2V5ICogOFxuICAgIGl2TGVuID0gZGVzTW9kZXNbc3VpdGVdLml2XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBzdWl0ZSB0eXBlJylcbiAgfVxuXG4gIHZhciBrZXlzID0gZWJ0ayhwYXNzd29yZCwgZmFsc2UsIGtleUxlbiwgaXZMZW4pXG4gIHJldHVybiBjcmVhdGVEZWNpcGhlcml2KHN1aXRlLCBrZXlzLmtleSwga2V5cy5pdilcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2lwaGVyaXYgKHN1aXRlLCBrZXksIGl2KSB7XG4gIHN1aXRlID0gc3VpdGUudG9Mb3dlckNhc2UoKVxuICBpZiAoYWVzTW9kZXNbc3VpdGVdKSByZXR1cm4gYWVzLmNyZWF0ZUNpcGhlcml2KHN1aXRlLCBrZXksIGl2KVxuICBpZiAoZGVzTW9kZXNbc3VpdGVdKSByZXR1cm4gbmV3IERFUyh7IGtleToga2V5LCBpdjogaXYsIG1vZGU6IHN1aXRlIH0pXG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBzdWl0ZSB0eXBlJylcbn1cblxuZnVuY3Rpb24gY3JlYXRlRGVjaXBoZXJpdiAoc3VpdGUsIGtleSwgaXYpIHtcbiAgc3VpdGUgPSBzdWl0ZS50b0xvd2VyQ2FzZSgpXG4gIGlmIChhZXNNb2Rlc1tzdWl0ZV0pIHJldHVybiBhZXMuY3JlYXRlRGVjaXBoZXJpdihzdWl0ZSwga2V5LCBpdilcbiAgaWYgKGRlc01vZGVzW3N1aXRlXSkgcmV0dXJuIG5ldyBERVMoeyBrZXk6IGtleSwgaXY6IGl2LCBtb2RlOiBzdWl0ZSwgZGVjcnlwdDogdHJ1ZSB9KVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG59XG5cbmZ1bmN0aW9uIGdldENpcGhlcnMgKCkge1xuICByZXR1cm4gT2JqZWN0LmtleXMoZGVzTW9kZXMpLmNvbmNhdChhZXMuZ2V0Q2lwaGVycygpKVxufVxuXG5leHBvcnRzLmNyZWF0ZUNpcGhlciA9IGV4cG9ydHMuQ2lwaGVyID0gY3JlYXRlQ2lwaGVyXG5leHBvcnRzLmNyZWF0ZUNpcGhlcml2ID0gZXhwb3J0cy5DaXBoZXJpdiA9IGNyZWF0ZUNpcGhlcml2XG5leHBvcnRzLmNyZWF0ZURlY2lwaGVyID0gZXhwb3J0cy5EZWNpcGhlciA9IGNyZWF0ZURlY2lwaGVyXG5leHBvcnRzLmNyZWF0ZURlY2lwaGVyaXYgPSBleHBvcnRzLkRlY2lwaGVyaXYgPSBjcmVhdGVEZWNpcGhlcml2XG5leHBvcnRzLmxpc3RDaXBoZXJzID0gZXhwb3J0cy5nZXRDaXBoZXJzID0gZ2V0Q2lwaGVyc1xuIiwidmFyIENpcGhlckJhc2UgPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgZGVzID0gcmVxdWlyZSgnZGVzLmpzJylcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxuXG52YXIgbW9kZXMgPSB7XG4gICdkZXMtZWRlMy1jYmMnOiBkZXMuQ0JDLmluc3RhbnRpYXRlKGRlcy5FREUpLFxuICAnZGVzLWVkZTMnOiBkZXMuRURFLFxuICAnZGVzLWVkZS1jYmMnOiBkZXMuQ0JDLmluc3RhbnRpYXRlKGRlcy5FREUpLFxuICAnZGVzLWVkZSc6IGRlcy5FREUsXG4gICdkZXMtY2JjJzogZGVzLkNCQy5pbnN0YW50aWF0ZShkZXMuREVTKSxcbiAgJ2Rlcy1lY2InOiBkZXMuREVTXG59XG5tb2Rlcy5kZXMgPSBtb2Rlc1snZGVzLWNiYyddXG5tb2Rlcy5kZXMzID0gbW9kZXNbJ2Rlcy1lZGUzLWNiYyddXG5tb2R1bGUuZXhwb3J0cyA9IERFU1xuaW5oZXJpdHMoREVTLCBDaXBoZXJCYXNlKVxuZnVuY3Rpb24gREVTIChvcHRzKSB7XG4gIENpcGhlckJhc2UuY2FsbCh0aGlzKVxuICB2YXIgbW9kZU5hbWUgPSBvcHRzLm1vZGUudG9Mb3dlckNhc2UoKVxuICB2YXIgbW9kZSA9IG1vZGVzW21vZGVOYW1lXVxuICB2YXIgdHlwZVxuICBpZiAob3B0cy5kZWNyeXB0KSB7XG4gICAgdHlwZSA9ICdkZWNyeXB0J1xuICB9IGVsc2Uge1xuICAgIHR5cGUgPSAnZW5jcnlwdCdcbiAgfVxuICB2YXIga2V5ID0gb3B0cy5rZXlcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoa2V5KSkge1xuICAgIGtleSA9IEJ1ZmZlci5mcm9tKGtleSlcbiAgfVxuICBpZiAobW9kZU5hbWUgPT09ICdkZXMtZWRlJyB8fCBtb2RlTmFtZSA9PT0gJ2Rlcy1lZGUtY2JjJykge1xuICAgIGtleSA9IEJ1ZmZlci5jb25jYXQoW2tleSwga2V5LnNsaWNlKDAsIDgpXSlcbiAgfVxuICB2YXIgaXYgPSBvcHRzLml2XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGl2KSkge1xuICAgIGl2ID0gQnVmZmVyLmZyb20oaXYpXG4gIH1cbiAgdGhpcy5fZGVzID0gbW9kZS5jcmVhdGUoe1xuICAgIGtleToga2V5LFxuICAgIGl2OiBpdixcbiAgICB0eXBlOiB0eXBlXG4gIH0pXG59XG5ERVMucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSkge1xuICByZXR1cm4gQnVmZmVyLmZyb20odGhpcy5fZGVzLnVwZGF0ZShkYXRhKSlcbn1cbkRFUy5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gQnVmZmVyLmZyb20odGhpcy5fZGVzLmZpbmFsKCkpXG59XG4iLCJleHBvcnRzWydkZXMtZWNiJ10gPSB7XG4gIGtleTogOCxcbiAgaXY6IDBcbn1cbmV4cG9ydHNbJ2Rlcy1jYmMnXSA9IGV4cG9ydHMuZGVzID0ge1xuICBrZXk6IDgsXG4gIGl2OiA4XG59XG5leHBvcnRzWydkZXMtZWRlMy1jYmMnXSA9IGV4cG9ydHMuZGVzMyA9IHtcbiAga2V5OiAyNCxcbiAgaXY6IDhcbn1cbmV4cG9ydHNbJ2Rlcy1lZGUzJ10gPSB7XG4gIGtleTogMjQsXG4gIGl2OiAwXG59XG5leHBvcnRzWydkZXMtZWRlLWNiYyddID0ge1xuICBrZXk6IDE2LFxuICBpdjogOFxufVxuZXhwb3J0c1snZGVzLWVkZSddID0ge1xuICBrZXk6IDE2LFxuICBpdjogMFxufVxuIiwidmFyIGJuID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciByYW5kb21CeXRlcyA9IHJlcXVpcmUoJ3JhbmRvbWJ5dGVzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGNydDtcbmZ1bmN0aW9uIGJsaW5kKHByaXYpIHtcbiAgdmFyIHIgPSBnZXRyKHByaXYpO1xuICB2YXIgYmxpbmRlciA9IHIudG9SZWQoYm4ubW9udChwcml2Lm1vZHVsdXMpKVxuICAucmVkUG93KG5ldyBibihwcml2LnB1YmxpY0V4cG9uZW50KSkuZnJvbVJlZCgpO1xuICByZXR1cm4ge1xuICAgIGJsaW5kZXI6IGJsaW5kZXIsXG4gICAgdW5ibGluZGVyOnIuaW52bShwcml2Lm1vZHVsdXMpXG4gIH07XG59XG5mdW5jdGlvbiBjcnQobXNnLCBwcml2KSB7XG4gIHZhciBibGluZHMgPSBibGluZChwcml2KTtcbiAgdmFyIGxlbiA9IHByaXYubW9kdWx1cy5ieXRlTGVuZ3RoKCk7XG4gIHZhciBtb2QgPSBibi5tb250KHByaXYubW9kdWx1cyk7XG4gIHZhciBibGluZGVkID0gbmV3IGJuKG1zZykubXVsKGJsaW5kcy5ibGluZGVyKS51bW9kKHByaXYubW9kdWx1cyk7XG4gIHZhciBjMSA9IGJsaW5kZWQudG9SZWQoYm4ubW9udChwcml2LnByaW1lMSkpO1xuICB2YXIgYzIgPSBibGluZGVkLnRvUmVkKGJuLm1vbnQocHJpdi5wcmltZTIpKTtcbiAgdmFyIHFpbnYgPSBwcml2LmNvZWZmaWNpZW50O1xuICB2YXIgcCA9IHByaXYucHJpbWUxO1xuICB2YXIgcSA9IHByaXYucHJpbWUyO1xuICB2YXIgbTEgPSBjMS5yZWRQb3cocHJpdi5leHBvbmVudDEpO1xuICB2YXIgbTIgPSBjMi5yZWRQb3cocHJpdi5leHBvbmVudDIpO1xuICBtMSA9IG0xLmZyb21SZWQoKTtcbiAgbTIgPSBtMi5mcm9tUmVkKCk7XG4gIHZhciBoID0gbTEuaXN1YihtMikuaW11bChxaW52KS51bW9kKHApO1xuICBoLmltdWwocSk7XG4gIG0yLmlhZGQoaCk7XG4gIHJldHVybiBuZXcgQnVmZmVyKG0yLmltdWwoYmxpbmRzLnVuYmxpbmRlcikudW1vZChwcml2Lm1vZHVsdXMpLnRvQXJyYXkoZmFsc2UsIGxlbikpO1xufVxuY3J0LmdldHIgPSBnZXRyO1xuZnVuY3Rpb24gZ2V0cihwcml2KSB7XG4gIHZhciBsZW4gPSBwcml2Lm1vZHVsdXMuYnl0ZUxlbmd0aCgpO1xuICB2YXIgciA9IG5ldyBibihyYW5kb21CeXRlcyhsZW4pKTtcbiAgd2hpbGUgKHIuY21wKHByaXYubW9kdWx1cykgPj0gIDAgfHwgIXIudW1vZChwcml2LnByaW1lMSkgfHwgIXIudW1vZChwcml2LnByaW1lMikpIHtcbiAgICByID0gbmV3IGJuKHJhbmRvbUJ5dGVzKGxlbikpO1xuICB9XG4gIHJldHVybiByO1xufVxuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Jyb3dzZXIvYWxnb3JpdGhtcy5qc29uJylcbiIsInZhciBjcmVhdGVIYXNoID0gcmVxdWlyZSgnY3JlYXRlLWhhc2gnKVxudmFyIHN0cmVhbSA9IHJlcXVpcmUoJ3N0cmVhbScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgc2lnbiA9IHJlcXVpcmUoJy4vc2lnbicpXG52YXIgdmVyaWZ5ID0gcmVxdWlyZSgnLi92ZXJpZnknKVxuXG52YXIgYWxnb3JpdGhtcyA9IHJlcXVpcmUoJy4vYWxnb3JpdGhtcy5qc29uJylcbk9iamVjdC5rZXlzKGFsZ29yaXRobXMpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICBhbGdvcml0aG1zW2tleV0uaWQgPSBuZXcgQnVmZmVyKGFsZ29yaXRobXNba2V5XS5pZCwgJ2hleCcpXG4gIGFsZ29yaXRobXNba2V5LnRvTG93ZXJDYXNlKCldID0gYWxnb3JpdGhtc1trZXldXG59KVxuXG5mdW5jdGlvbiBTaWduIChhbGdvcml0aG0pIHtcbiAgc3RyZWFtLldyaXRhYmxlLmNhbGwodGhpcylcblxuICB2YXIgZGF0YSA9IGFsZ29yaXRobXNbYWxnb3JpdGhtXVxuICBpZiAoIWRhdGEpIHRocm93IG5ldyBFcnJvcignVW5rbm93biBtZXNzYWdlIGRpZ2VzdCcpXG5cbiAgdGhpcy5faGFzaFR5cGUgPSBkYXRhLmhhc2hcbiAgdGhpcy5faGFzaCA9IGNyZWF0ZUhhc2goZGF0YS5oYXNoKVxuICB0aGlzLl90YWcgPSBkYXRhLmlkXG4gIHRoaXMuX3NpZ25UeXBlID0gZGF0YS5zaWduXG59XG5pbmhlcml0cyhTaWduLCBzdHJlYW0uV3JpdGFibGUpXG5cblNpZ24ucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uIF93cml0ZSAoZGF0YSwgXywgZG9uZSkge1xuICB0aGlzLl9oYXNoLnVwZGF0ZShkYXRhKVxuICBkb25lKClcbn1cblxuU2lnbi5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlIChkYXRhLCBlbmMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykgZGF0YSA9IG5ldyBCdWZmZXIoZGF0YSwgZW5jKVxuXG4gIHRoaXMuX2hhc2gudXBkYXRlKGRhdGEpXG4gIHJldHVybiB0aGlzXG59XG5cblNpZ24ucHJvdG90eXBlLnNpZ24gPSBmdW5jdGlvbiBzaWduTWV0aG9kIChrZXksIGVuYykge1xuICB0aGlzLmVuZCgpXG4gIHZhciBoYXNoID0gdGhpcy5faGFzaC5kaWdlc3QoKVxuICB2YXIgc2lnID0gc2lnbihoYXNoLCBrZXksIHRoaXMuX2hhc2hUeXBlLCB0aGlzLl9zaWduVHlwZSwgdGhpcy5fdGFnKVxuXG4gIHJldHVybiBlbmMgPyBzaWcudG9TdHJpbmcoZW5jKSA6IHNpZ1xufVxuXG5mdW5jdGlvbiBWZXJpZnkgKGFsZ29yaXRobSkge1xuICBzdHJlYW0uV3JpdGFibGUuY2FsbCh0aGlzKVxuXG4gIHZhciBkYXRhID0gYWxnb3JpdGhtc1thbGdvcml0aG1dXG4gIGlmICghZGF0YSkgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIG1lc3NhZ2UgZGlnZXN0JylcblxuICB0aGlzLl9oYXNoID0gY3JlYXRlSGFzaChkYXRhLmhhc2gpXG4gIHRoaXMuX3RhZyA9IGRhdGEuaWRcbiAgdGhpcy5fc2lnblR5cGUgPSBkYXRhLnNpZ25cbn1cbmluaGVyaXRzKFZlcmlmeSwgc3RyZWFtLldyaXRhYmxlKVxuXG5WZXJpZnkucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uIF93cml0ZSAoZGF0YSwgXywgZG9uZSkge1xuICB0aGlzLl9oYXNoLnVwZGF0ZShkYXRhKVxuICBkb25lKClcbn1cblxuVmVyaWZ5LnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUgKGRhdGEsIGVuYykge1xuICBpZiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSBkYXRhID0gbmV3IEJ1ZmZlcihkYXRhLCBlbmMpXG5cbiAgdGhpcy5faGFzaC51cGRhdGUoZGF0YSlcbiAgcmV0dXJuIHRoaXNcbn1cblxuVmVyaWZ5LnByb3RvdHlwZS52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnlNZXRob2QgKGtleSwgc2lnLCBlbmMpIHtcbiAgaWYgKHR5cGVvZiBzaWcgPT09ICdzdHJpbmcnKSBzaWcgPSBuZXcgQnVmZmVyKHNpZywgZW5jKVxuXG4gIHRoaXMuZW5kKClcbiAgdmFyIGhhc2ggPSB0aGlzLl9oYXNoLmRpZ2VzdCgpXG4gIHJldHVybiB2ZXJpZnkoc2lnLCBoYXNoLCBrZXksIHRoaXMuX3NpZ25UeXBlLCB0aGlzLl90YWcpXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVNpZ24gKGFsZ29yaXRobSkge1xuICByZXR1cm4gbmV3IFNpZ24oYWxnb3JpdGhtKVxufVxuXG5mdW5jdGlvbiBjcmVhdGVWZXJpZnkgKGFsZ29yaXRobSkge1xuICByZXR1cm4gbmV3IFZlcmlmeShhbGdvcml0aG0pXG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBTaWduOiBjcmVhdGVTaWduLFxuICBWZXJpZnk6IGNyZWF0ZVZlcmlmeSxcbiAgY3JlYXRlU2lnbjogY3JlYXRlU2lnbixcbiAgY3JlYXRlVmVyaWZ5OiBjcmVhdGVWZXJpZnlcbn1cbiIsIi8vIG11Y2ggb2YgdGhpcyBiYXNlZCBvbiBodHRwczovL2dpdGh1Yi5jb20vaW5kdXRueS9zZWxmLXNpZ25lZC9ibG9iL2doLXBhZ2VzL2xpYi9yc2EuanNcbnZhciBjcmVhdGVIbWFjID0gcmVxdWlyZSgnY3JlYXRlLWhtYWMnKVxudmFyIGNydCA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktcnNhJylcbnZhciBFQyA9IHJlcXVpcmUoJ2VsbGlwdGljJykuZWNcbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJylcbnZhciBwYXJzZUtleXMgPSByZXF1aXJlKCdwYXJzZS1hc24xJylcbnZhciBjdXJ2ZXMgPSByZXF1aXJlKCcuL2N1cnZlcy5qc29uJylcblxuZnVuY3Rpb24gc2lnbiAoaGFzaCwga2V5LCBoYXNoVHlwZSwgc2lnblR5cGUsIHRhZykge1xuICB2YXIgcHJpdiA9IHBhcnNlS2V5cyhrZXkpXG4gIGlmIChwcml2LmN1cnZlKSB7XG4gICAgLy8gcnNhIGtleXMgY2FuIGJlIGludGVycHJldGVkIGFzIGVjZHNhIG9uZXMgaW4gb3BlbnNzbFxuICAgIGlmIChzaWduVHlwZSAhPT0gJ2VjZHNhJyAmJiBzaWduVHlwZSAhPT0gJ2VjZHNhL3JzYScpIHRocm93IG5ldyBFcnJvcignd3JvbmcgcHJpdmF0ZSBrZXkgdHlwZScpXG4gICAgcmV0dXJuIGVjU2lnbihoYXNoLCBwcml2KVxuICB9IGVsc2UgaWYgKHByaXYudHlwZSA9PT0gJ2RzYScpIHtcbiAgICBpZiAoc2lnblR5cGUgIT09ICdkc2EnKSB0aHJvdyBuZXcgRXJyb3IoJ3dyb25nIHByaXZhdGUga2V5IHR5cGUnKVxuICAgIHJldHVybiBkc2FTaWduKGhhc2gsIHByaXYsIGhhc2hUeXBlKVxuICB9IGVsc2Uge1xuICAgIGlmIChzaWduVHlwZSAhPT0gJ3JzYScgJiYgc2lnblR5cGUgIT09ICdlY2RzYS9yc2EnKSB0aHJvdyBuZXcgRXJyb3IoJ3dyb25nIHByaXZhdGUga2V5IHR5cGUnKVxuICB9XG4gIGhhc2ggPSBCdWZmZXIuY29uY2F0KFt0YWcsIGhhc2hdKVxuICB2YXIgbGVuID0gcHJpdi5tb2R1bHVzLmJ5dGVMZW5ndGgoKVxuICB2YXIgcGFkID0gWyAwLCAxIF1cbiAgd2hpbGUgKGhhc2gubGVuZ3RoICsgcGFkLmxlbmd0aCArIDEgPCBsZW4pIHBhZC5wdXNoKDB4ZmYpXG4gIHBhZC5wdXNoKDB4MDApXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGhhc2gubGVuZ3RoKSBwYWQucHVzaChoYXNoW2ldKVxuXG4gIHZhciBvdXQgPSBjcnQocGFkLCBwcml2KVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIGVjU2lnbiAoaGFzaCwgcHJpdikge1xuICB2YXIgY3VydmVJZCA9IGN1cnZlc1twcml2LmN1cnZlLmpvaW4oJy4nKV1cbiAgaWYgKCFjdXJ2ZUlkKSB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gY3VydmUgJyArIHByaXYuY3VydmUuam9pbignLicpKVxuXG4gIHZhciBjdXJ2ZSA9IG5ldyBFQyhjdXJ2ZUlkKVxuICB2YXIga2V5ID0gY3VydmUua2V5RnJvbVByaXZhdGUocHJpdi5wcml2YXRlS2V5KVxuICB2YXIgb3V0ID0ga2V5LnNpZ24oaGFzaClcblxuICByZXR1cm4gbmV3IEJ1ZmZlcihvdXQudG9ERVIoKSlcbn1cblxuZnVuY3Rpb24gZHNhU2lnbiAoaGFzaCwgcHJpdiwgYWxnbykge1xuICB2YXIgeCA9IHByaXYucGFyYW1zLnByaXZfa2V5XG4gIHZhciBwID0gcHJpdi5wYXJhbXMucFxuICB2YXIgcSA9IHByaXYucGFyYW1zLnFcbiAgdmFyIGcgPSBwcml2LnBhcmFtcy5nXG4gIHZhciByID0gbmV3IEJOKDApXG4gIHZhciBrXG4gIHZhciBIID0gYml0czJpbnQoaGFzaCwgcSkubW9kKHEpXG4gIHZhciBzID0gZmFsc2VcbiAgdmFyIGt2ID0gZ2V0S2V5KHgsIHEsIGhhc2gsIGFsZ28pXG4gIHdoaWxlIChzID09PSBmYWxzZSkge1xuICAgIGsgPSBtYWtlS2V5KHEsIGt2LCBhbGdvKVxuICAgIHIgPSBtYWtlUihnLCBrLCBwLCBxKVxuICAgIHMgPSBrLmludm0ocSkuaW11bChILmFkZCh4Lm11bChyKSkpLm1vZChxKVxuICAgIGlmIChzLmNtcG4oMCkgPT09IDApIHtcbiAgICAgIHMgPSBmYWxzZVxuICAgICAgciA9IG5ldyBCTigwKVxuICAgIH1cbiAgfVxuICByZXR1cm4gdG9ERVIociwgcylcbn1cblxuZnVuY3Rpb24gdG9ERVIgKHIsIHMpIHtcbiAgciA9IHIudG9BcnJheSgpXG4gIHMgPSBzLnRvQXJyYXkoKVxuXG4gIC8vIFBhZCB2YWx1ZXNcbiAgaWYgKHJbMF0gJiAweDgwKSByID0gWyAwIF0uY29uY2F0KHIpXG4gIGlmIChzWzBdICYgMHg4MCkgcyA9IFsgMCBdLmNvbmNhdChzKVxuXG4gIHZhciB0b3RhbCA9IHIubGVuZ3RoICsgcy5sZW5ndGggKyA0XG4gIHZhciByZXMgPSBbIDB4MzAsIHRvdGFsLCAweDAyLCByLmxlbmd0aCBdXG4gIHJlcyA9IHJlcy5jb25jYXQociwgWyAweDAyLCBzLmxlbmd0aCBdLCBzKVxuICByZXR1cm4gbmV3IEJ1ZmZlcihyZXMpXG59XG5cbmZ1bmN0aW9uIGdldEtleSAoeCwgcSwgaGFzaCwgYWxnbykge1xuICB4ID0gbmV3IEJ1ZmZlcih4LnRvQXJyYXkoKSlcbiAgaWYgKHgubGVuZ3RoIDwgcS5ieXRlTGVuZ3RoKCkpIHtcbiAgICB2YXIgemVyb3MgPSBuZXcgQnVmZmVyKHEuYnl0ZUxlbmd0aCgpIC0geC5sZW5ndGgpXG4gICAgemVyb3MuZmlsbCgwKVxuICAgIHggPSBCdWZmZXIuY29uY2F0KFsgemVyb3MsIHggXSlcbiAgfVxuICB2YXIgaGxlbiA9IGhhc2gubGVuZ3RoXG4gIHZhciBoYml0cyA9IGJpdHMyb2N0ZXRzKGhhc2gsIHEpXG4gIHZhciB2ID0gbmV3IEJ1ZmZlcihobGVuKVxuICB2LmZpbGwoMSlcbiAgdmFyIGsgPSBuZXcgQnVmZmVyKGhsZW4pXG4gIGsuZmlsbCgwKVxuICBrID0gY3JlYXRlSG1hYyhhbGdvLCBrKS51cGRhdGUodikudXBkYXRlKG5ldyBCdWZmZXIoWyAwIF0pKS51cGRhdGUoeCkudXBkYXRlKGhiaXRzKS5kaWdlc3QoKVxuICB2ID0gY3JlYXRlSG1hYyhhbGdvLCBrKS51cGRhdGUodikuZGlnZXN0KClcbiAgayA9IGNyZWF0ZUhtYWMoYWxnbywgaykudXBkYXRlKHYpLnVwZGF0ZShuZXcgQnVmZmVyKFsgMSBdKSkudXBkYXRlKHgpLnVwZGF0ZShoYml0cykuZGlnZXN0KClcbiAgdiA9IGNyZWF0ZUhtYWMoYWxnbywgaykudXBkYXRlKHYpLmRpZ2VzdCgpXG4gIHJldHVybiB7IGs6IGssIHY6IHYgfVxufVxuXG5mdW5jdGlvbiBiaXRzMmludCAob2JpdHMsIHEpIHtcbiAgdmFyIGJpdHMgPSBuZXcgQk4ob2JpdHMpXG4gIHZhciBzaGlmdCA9IChvYml0cy5sZW5ndGggPDwgMykgLSBxLmJpdExlbmd0aCgpXG4gIGlmIChzaGlmdCA+IDApIGJpdHMuaXNocm4oc2hpZnQpXG4gIHJldHVybiBiaXRzXG59XG5cbmZ1bmN0aW9uIGJpdHMyb2N0ZXRzIChiaXRzLCBxKSB7XG4gIGJpdHMgPSBiaXRzMmludChiaXRzLCBxKVxuICBiaXRzID0gYml0cy5tb2QocSlcbiAgdmFyIG91dCA9IG5ldyBCdWZmZXIoYml0cy50b0FycmF5KCkpXG4gIGlmIChvdXQubGVuZ3RoIDwgcS5ieXRlTGVuZ3RoKCkpIHtcbiAgICB2YXIgemVyb3MgPSBuZXcgQnVmZmVyKHEuYnl0ZUxlbmd0aCgpIC0gb3V0Lmxlbmd0aClcbiAgICB6ZXJvcy5maWxsKDApXG4gICAgb3V0ID0gQnVmZmVyLmNvbmNhdChbIHplcm9zLCBvdXQgXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIG1ha2VLZXkgKHEsIGt2LCBhbGdvKSB7XG4gIHZhciB0XG4gIHZhciBrXG5cbiAgZG8ge1xuICAgIHQgPSBuZXcgQnVmZmVyKDApXG5cbiAgICB3aGlsZSAodC5sZW5ndGggKiA4IDwgcS5iaXRMZW5ndGgoKSkge1xuICAgICAga3YudiA9IGNyZWF0ZUhtYWMoYWxnbywga3YuaykudXBkYXRlKGt2LnYpLmRpZ2VzdCgpXG4gICAgICB0ID0gQnVmZmVyLmNvbmNhdChbIHQsIGt2LnYgXSlcbiAgICB9XG5cbiAgICBrID0gYml0czJpbnQodCwgcSlcbiAgICBrdi5rID0gY3JlYXRlSG1hYyhhbGdvLCBrdi5rKS51cGRhdGUoa3YudikudXBkYXRlKG5ldyBCdWZmZXIoWyAwIF0pKS5kaWdlc3QoKVxuICAgIGt2LnYgPSBjcmVhdGVIbWFjKGFsZ28sIGt2LmspLnVwZGF0ZShrdi52KS5kaWdlc3QoKVxuICB9IHdoaWxlIChrLmNtcChxKSAhPT0gLTEpXG5cbiAgcmV0dXJuIGtcbn1cblxuZnVuY3Rpb24gbWFrZVIgKGcsIGssIHAsIHEpIHtcbiAgcmV0dXJuIGcudG9SZWQoQk4ubW9udChwKSkucmVkUG93KGspLmZyb21SZWQoKS5tb2QocSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzaWduXG5tb2R1bGUuZXhwb3J0cy5nZXRLZXkgPSBnZXRLZXlcbm1vZHVsZS5leHBvcnRzLm1ha2VLZXkgPSBtYWtlS2V5XG4iLCIvLyBtdWNoIG9mIHRoaXMgYmFzZWQgb24gaHR0cHM6Ly9naXRodWIuY29tL2luZHV0bnkvc2VsZi1zaWduZWQvYmxvYi9naC1wYWdlcy9saWIvcnNhLmpzXG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpXG52YXIgRUMgPSByZXF1aXJlKCdlbGxpcHRpYycpLmVjXG52YXIgcGFyc2VLZXlzID0gcmVxdWlyZSgncGFyc2UtYXNuMScpXG52YXIgY3VydmVzID0gcmVxdWlyZSgnLi9jdXJ2ZXMuanNvbicpXG5cbmZ1bmN0aW9uIHZlcmlmeSAoc2lnLCBoYXNoLCBrZXksIHNpZ25UeXBlLCB0YWcpIHtcbiAgdmFyIHB1YiA9IHBhcnNlS2V5cyhrZXkpXG4gIGlmIChwdWIudHlwZSA9PT0gJ2VjJykge1xuICAgIC8vIHJzYSBrZXlzIGNhbiBiZSBpbnRlcnByZXRlZCBhcyBlY2RzYSBvbmVzIGluIG9wZW5zc2xcbiAgICBpZiAoc2lnblR5cGUgIT09ICdlY2RzYScgJiYgc2lnblR5cGUgIT09ICdlY2RzYS9yc2EnKSB0aHJvdyBuZXcgRXJyb3IoJ3dyb25nIHB1YmxpYyBrZXkgdHlwZScpXG4gICAgcmV0dXJuIGVjVmVyaWZ5KHNpZywgaGFzaCwgcHViKVxuICB9IGVsc2UgaWYgKHB1Yi50eXBlID09PSAnZHNhJykge1xuICAgIGlmIChzaWduVHlwZSAhPT0gJ2RzYScpIHRocm93IG5ldyBFcnJvcignd3JvbmcgcHVibGljIGtleSB0eXBlJylcbiAgICByZXR1cm4gZHNhVmVyaWZ5KHNpZywgaGFzaCwgcHViKVxuICB9IGVsc2Uge1xuICAgIGlmIChzaWduVHlwZSAhPT0gJ3JzYScgJiYgc2lnblR5cGUgIT09ICdlY2RzYS9yc2EnKSB0aHJvdyBuZXcgRXJyb3IoJ3dyb25nIHB1YmxpYyBrZXkgdHlwZScpXG4gIH1cbiAgaGFzaCA9IEJ1ZmZlci5jb25jYXQoW3RhZywgaGFzaF0pXG4gIHZhciBsZW4gPSBwdWIubW9kdWx1cy5ieXRlTGVuZ3RoKClcbiAgdmFyIHBhZCA9IFsgMSBdXG4gIHZhciBwYWROdW0gPSAwXG4gIHdoaWxlIChoYXNoLmxlbmd0aCArIHBhZC5sZW5ndGggKyAyIDwgbGVuKSB7XG4gICAgcGFkLnB1c2goMHhmZilcbiAgICBwYWROdW0rK1xuICB9XG4gIHBhZC5wdXNoKDB4MDApXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGhhc2gubGVuZ3RoKSB7XG4gICAgcGFkLnB1c2goaGFzaFtpXSlcbiAgfVxuICBwYWQgPSBuZXcgQnVmZmVyKHBhZClcbiAgdmFyIHJlZCA9IEJOLm1vbnQocHViLm1vZHVsdXMpXG4gIHNpZyA9IG5ldyBCTihzaWcpLnRvUmVkKHJlZClcblxuICBzaWcgPSBzaWcucmVkUG93KG5ldyBCTihwdWIucHVibGljRXhwb25lbnQpKVxuICBzaWcgPSBuZXcgQnVmZmVyKHNpZy5mcm9tUmVkKCkudG9BcnJheSgpKVxuICB2YXIgb3V0ID0gcGFkTnVtIDwgOCA/IDEgOiAwXG4gIGxlbiA9IE1hdGgubWluKHNpZy5sZW5ndGgsIHBhZC5sZW5ndGgpXG4gIGlmIChzaWcubGVuZ3RoICE9PSBwYWQubGVuZ3RoKSBvdXQgPSAxXG5cbiAgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIG91dCB8PSBzaWdbaV0gXiBwYWRbaV1cbiAgcmV0dXJuIG91dCA9PT0gMFxufVxuXG5mdW5jdGlvbiBlY1ZlcmlmeSAoc2lnLCBoYXNoLCBwdWIpIHtcbiAgdmFyIGN1cnZlSWQgPSBjdXJ2ZXNbcHViLmRhdGEuYWxnb3JpdGhtLmN1cnZlLmpvaW4oJy4nKV1cbiAgaWYgKCFjdXJ2ZUlkKSB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gY3VydmUgJyArIHB1Yi5kYXRhLmFsZ29yaXRobS5jdXJ2ZS5qb2luKCcuJykpXG5cbiAgdmFyIGN1cnZlID0gbmV3IEVDKGN1cnZlSWQpXG4gIHZhciBwdWJrZXkgPSBwdWIuZGF0YS5zdWJqZWN0UHJpdmF0ZUtleS5kYXRhXG5cbiAgcmV0dXJuIGN1cnZlLnZlcmlmeShoYXNoLCBzaWcsIHB1YmtleSlcbn1cblxuZnVuY3Rpb24gZHNhVmVyaWZ5IChzaWcsIGhhc2gsIHB1Yikge1xuICB2YXIgcCA9IHB1Yi5kYXRhLnBcbiAgdmFyIHEgPSBwdWIuZGF0YS5xXG4gIHZhciBnID0gcHViLmRhdGEuZ1xuICB2YXIgeSA9IHB1Yi5kYXRhLnB1Yl9rZXlcbiAgdmFyIHVucGFja2VkID0gcGFyc2VLZXlzLnNpZ25hdHVyZS5kZWNvZGUoc2lnLCAnZGVyJylcbiAgdmFyIHMgPSB1bnBhY2tlZC5zXG4gIHZhciByID0gdW5wYWNrZWQuclxuICBjaGVja1ZhbHVlKHMsIHEpXG4gIGNoZWNrVmFsdWUociwgcSlcbiAgdmFyIG1vbnRwID0gQk4ubW9udChwKVxuICB2YXIgdyA9IHMuaW52bShxKVxuICB2YXIgdiA9IGcudG9SZWQobW9udHApXG4gICAgLnJlZFBvdyhuZXcgQk4oaGFzaCkubXVsKHcpLm1vZChxKSlcbiAgICAuZnJvbVJlZCgpXG4gICAgLm11bCh5LnRvUmVkKG1vbnRwKS5yZWRQb3coci5tdWwodykubW9kKHEpKS5mcm9tUmVkKCkpXG4gICAgLm1vZChwKVxuICAgIC5tb2QocSlcbiAgcmV0dXJuIHYuY21wKHIpID09PSAwXG59XG5cbmZ1bmN0aW9uIGNoZWNrVmFsdWUgKGIsIHEpIHtcbiAgaWYgKGIuY21wbigwKSA8PSAwKSB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgc2lnJylcbiAgaWYgKGIuY21wKHEpID49IHEpIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBzaWcnKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHZlcmlmeVxuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB4b3IgKGEsIGIpIHtcbiAgdmFyIGxlbmd0aCA9IE1hdGgubWluKGEubGVuZ3RoLCBiLmxlbmd0aClcbiAgdmFyIGJ1ZmZlciA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBidWZmZXJbaV0gPSBhW2ldIF4gYltpXVxuICB9XG5cbiAgcmV0dXJuIGJ1ZmZlclxufVxuIiwiLyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8ZmVyb3NzQGZlcm9zcy5vcmc+IDxodHRwOi8vZmVyb3NzLm9yZz5cbiAqIEBsaWNlbnNlICBNSVRcbiAqL1xuLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi9cblxuJ3VzZSBzdHJpY3QnXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCdiYXNlNjQtanMnKVxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0JylcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXNhcnJheScpXG5cbmV4cG9ydHMuQnVmZmVyID0gQnVmZmVyXG5leHBvcnRzLlNsb3dCdWZmZXIgPSBTbG93QnVmZmVyXG5leHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTID0gNTBcblxuLyoqXG4gKiBJZiBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgOlxuICogICA9PT0gdHJ1ZSAgICBVc2UgVWludDhBcnJheSBpbXBsZW1lbnRhdGlvbiAoZmFzdGVzdClcbiAqICAgPT09IGZhbHNlICAgVXNlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiAobW9zdCBjb21wYXRpYmxlLCBldmVuIElFNilcbiAqXG4gKiBCcm93c2VycyB0aGF0IHN1cHBvcnQgdHlwZWQgYXJyYXlzIGFyZSBJRSAxMCssIEZpcmVmb3ggNCssIENocm9tZSA3KywgU2FmYXJpIDUuMSssXG4gKiBPcGVyYSAxMS42KywgaU9TIDQuMisuXG4gKlxuICogRHVlIHRvIHZhcmlvdXMgYnJvd3NlciBidWdzLCBzb21ldGltZXMgdGhlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiB3aWxsIGJlIHVzZWQgZXZlblxuICogd2hlbiB0aGUgYnJvd3NlciBzdXBwb3J0cyB0eXBlZCBhcnJheXMuXG4gKlxuICogTm90ZTpcbiAqXG4gKiAgIC0gRmlyZWZveCA0LTI5IGxhY2tzIHN1cHBvcnQgZm9yIGFkZGluZyBuZXcgcHJvcGVydGllcyB0byBgVWludDhBcnJheWAgaW5zdGFuY2VzLFxuICogICAgIFNlZTogaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9Njk1NDM4LlxuICpcbiAqICAgLSBDaHJvbWUgOS0xMCBpcyBtaXNzaW5nIHRoZSBgVHlwZWRBcnJheS5wcm90b3R5cGUuc3ViYXJyYXlgIGZ1bmN0aW9uLlxuICpcbiAqICAgLSBJRTEwIGhhcyBhIGJyb2tlbiBgVHlwZWRBcnJheS5wcm90b3R5cGUuc3ViYXJyYXlgIGZ1bmN0aW9uIHdoaWNoIHJldHVybnMgYXJyYXlzIG9mXG4gKiAgICAgaW5jb3JyZWN0IGxlbmd0aCBpbiBzb21lIHNpdHVhdGlvbnMuXG5cbiAqIFdlIGRldGVjdCB0aGVzZSBidWdneSBicm93c2VycyBhbmQgc2V0IGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGAgdG8gYGZhbHNlYCBzbyB0aGV5XG4gKiBnZXQgdGhlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiwgd2hpY2ggaXMgc2xvd2VyIGJ1dCBiZWhhdmVzIGNvcnJlY3RseS5cbiAqL1xuQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgPSBnbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVCAhPT0gdW5kZWZpbmVkXG4gID8gZ2xvYmFsLlRZUEVEX0FSUkFZX1NVUFBPUlRcbiAgOiB0eXBlZEFycmF5U3VwcG9ydCgpXG5cbi8qXG4gKiBFeHBvcnQga01heExlbmd0aCBhZnRlciB0eXBlZCBhcnJheSBzdXBwb3J0IGlzIGRldGVybWluZWQuXG4gKi9cbmV4cG9ydHMua01heExlbmd0aCA9IGtNYXhMZW5ndGgoKVxuXG5mdW5jdGlvbiB0eXBlZEFycmF5U3VwcG9ydCAoKSB7XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KDEpXG4gICAgYXJyLl9fcHJvdG9fXyA9IHtfX3Byb3RvX186IFVpbnQ4QXJyYXkucHJvdG90eXBlLCBmb286IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDQyIH19XG4gICAgcmV0dXJuIGFyci5mb28oKSA9PT0gNDIgJiYgLy8gdHlwZWQgYXJyYXkgaW5zdGFuY2VzIGNhbiBiZSBhdWdtZW50ZWRcbiAgICAgICAgdHlwZW9mIGFyci5zdWJhcnJheSA9PT0gJ2Z1bmN0aW9uJyAmJiAvLyBjaHJvbWUgOS0xMCBsYWNrIGBzdWJhcnJheWBcbiAgICAgICAgYXJyLnN1YmFycmF5KDEsIDEpLmJ5dGVMZW5ndGggPT09IDAgLy8gaWUxMCBoYXMgYnJva2VuIGBzdWJhcnJheWBcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbmZ1bmN0aW9uIGtNYXhMZW5ndGggKCkge1xuICByZXR1cm4gQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRcbiAgICA/IDB4N2ZmZmZmZmZcbiAgICA6IDB4M2ZmZmZmZmZcbn1cblxuZnVuY3Rpb24gY3JlYXRlQnVmZmVyICh0aGF0LCBsZW5ndGgpIHtcbiAgaWYgKGtNYXhMZW5ndGgoKSA8IGxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbnZhbGlkIHR5cGVkIGFycmF5IGxlbmd0aCcpXG4gIH1cbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgdGhhdCA9IG5ldyBVaW50OEFycmF5KGxlbmd0aClcbiAgICB0aGF0Ll9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIGFuIG9iamVjdCBpbnN0YW5jZSBvZiB0aGUgQnVmZmVyIGNsYXNzXG4gICAgaWYgKHRoYXQgPT09IG51bGwpIHtcbiAgICAgIHRoYXQgPSBuZXcgQnVmZmVyKGxlbmd0aClcbiAgICB9XG4gICAgdGhhdC5sZW5ndGggPSBsZW5ndGhcbiAgfVxuXG4gIHJldHVybiB0aGF0XG59XG5cbi8qKlxuICogVGhlIEJ1ZmZlciBjb25zdHJ1Y3RvciByZXR1cm5zIGluc3RhbmNlcyBvZiBgVWludDhBcnJheWAgdGhhdCBoYXZlIHRoZWlyXG4gKiBwcm90b3R5cGUgY2hhbmdlZCB0byBgQnVmZmVyLnByb3RvdHlwZWAuIEZ1cnRoZXJtb3JlLCBgQnVmZmVyYCBpcyBhIHN1YmNsYXNzIG9mXG4gKiBgVWludDhBcnJheWAsIHNvIHRoZSByZXR1cm5lZCBpbnN0YW5jZXMgd2lsbCBoYXZlIGFsbCB0aGUgbm9kZSBgQnVmZmVyYCBtZXRob2RzXG4gKiBhbmQgdGhlIGBVaW50OEFycmF5YCBtZXRob2RzLiBTcXVhcmUgYnJhY2tldCBub3RhdGlvbiB3b3JrcyBhcyBleHBlY3RlZCAtLSBpdFxuICogcmV0dXJucyBhIHNpbmdsZSBvY3RldC5cbiAqXG4gKiBUaGUgYFVpbnQ4QXJyYXlgIHByb3RvdHlwZSByZW1haW5zIHVubW9kaWZpZWQuXG4gKi9cblxuZnVuY3Rpb24gQnVmZmVyIChhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUICYmICEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcihhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIC8vIENvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICBpZiAodHlwZW9mIGVuY29kaW5nT3JPZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdJZiBlbmNvZGluZyBpcyBzcGVjaWZpZWQgdGhlbiB0aGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZydcbiAgICAgIClcbiAgICB9XG4gICAgcmV0dXJuIGFsbG9jVW5zYWZlKHRoaXMsIGFyZylcbiAgfVxuICByZXR1cm4gZnJvbSh0aGlzLCBhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuQnVmZmVyLnBvb2xTaXplID0gODE5MiAvLyBub3QgdXNlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uXG5cbi8vIFRPRE86IExlZ2FjeSwgbm90IG5lZWRlZCBhbnltb3JlLiBSZW1vdmUgaW4gbmV4dCBtYWpvciB2ZXJzaW9uLlxuQnVmZmVyLl9hdWdtZW50ID0gZnVuY3Rpb24gKGFycikge1xuICBhcnIuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICByZXR1cm4gYXJyXG59XG5cbmZ1bmN0aW9uIGZyb20gKHRoYXQsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgYSBudW1iZXInKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsdWUgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgIHJldHVybiBmcm9tQXJyYXlCdWZmZXIodGhhdCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGZyb21TdHJpbmcodGhhdCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQpXG4gIH1cblxuICByZXR1cm4gZnJvbU9iamVjdCh0aGF0LCB2YWx1ZSlcbn1cblxuLyoqXG4gKiBGdW5jdGlvbmFsbHkgZXF1aXZhbGVudCB0byBCdWZmZXIoYXJnLCBlbmNvZGluZykgYnV0IHRocm93cyBhIFR5cGVFcnJvclxuICogaWYgdmFsdWUgaXMgYSBudW1iZXIuXG4gKiBCdWZmZXIuZnJvbShzdHJbLCBlbmNvZGluZ10pXG4gKiBCdWZmZXIuZnJvbShhcnJheSlcbiAqIEJ1ZmZlci5mcm9tKGJ1ZmZlcilcbiAqIEJ1ZmZlci5mcm9tKGFycmF5QnVmZmVyWywgYnl0ZU9mZnNldFssIGxlbmd0aF1dKVxuICoqL1xuQnVmZmVyLmZyb20gPSBmdW5jdGlvbiAodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gZnJvbShudWxsLCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5pZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgQnVmZmVyLnByb3RvdHlwZS5fX3Byb3RvX18gPSBVaW50OEFycmF5LnByb3RvdHlwZVxuICBCdWZmZXIuX19wcm90b19fID0gVWludDhBcnJheVxuICBpZiAodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnNwZWNpZXMgJiZcbiAgICAgIEJ1ZmZlcltTeW1ib2wuc3BlY2llc10gPT09IEJ1ZmZlcikge1xuICAgIC8vIEZpeCBzdWJhcnJheSgpIGluIEVTMjAxNi4gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9wdWxsLzk3XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJ1ZmZlciwgU3ltYm9sLnNwZWNpZXMsIHtcbiAgICAgIHZhbHVlOiBudWxsLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSlcbiAgfVxufVxuXG5mdW5jdGlvbiBhc3NlcnRTaXplIChzaXplKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcInNpemVcIiBhcmd1bWVudCBtdXN0IGJlIGEgbnVtYmVyJylcbiAgfSBlbHNlIGlmIChzaXplIDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcInNpemVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBuZWdhdGl2ZScpXG4gIH1cbn1cblxuZnVuY3Rpb24gYWxsb2MgKHRoYXQsIHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIGFzc2VydFNpemUoc2l6ZSlcbiAgaWYgKHNpemUgPD0gMCkge1xuICAgIHJldHVybiBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSlcbiAgfVxuICBpZiAoZmlsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gT25seSBwYXkgYXR0ZW50aW9uIHRvIGVuY29kaW5nIGlmIGl0J3MgYSBzdHJpbmcuIFRoaXNcbiAgICAvLyBwcmV2ZW50cyBhY2NpZGVudGFsbHkgc2VuZGluZyBpbiBhIG51bWJlciB0aGF0IHdvdWxkXG4gICAgLy8gYmUgaW50ZXJwcmV0dGVkIGFzIGEgc3RhcnQgb2Zmc2V0LlxuICAgIHJldHVybiB0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnXG4gICAgICA/IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKS5maWxsKGZpbGwsIGVuY29kaW5nKVxuICAgICAgOiBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSkuZmlsbChmaWxsKVxuICB9XG4gIHJldHVybiBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSlcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKiBhbGxvYyhzaXplWywgZmlsbFssIGVuY29kaW5nXV0pXG4gKiovXG5CdWZmZXIuYWxsb2MgPSBmdW5jdGlvbiAoc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGFsbG9jKG51bGwsIHNpemUsIGZpbGwsIGVuY29kaW5nKVxufVxuXG5mdW5jdGlvbiBhbGxvY1Vuc2FmZSAodGhhdCwgc2l6ZSkge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSA8IDAgPyAwIDogY2hlY2tlZChzaXplKSB8IDApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpemU7ICsraSkge1xuICAgICAgdGhhdFtpXSA9IDBcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuLyoqXG4gKiBFcXVpdmFsZW50IHRvIEJ1ZmZlcihudW0pLCBieSBkZWZhdWx0IGNyZWF0ZXMgYSBub24temVyby1maWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogKi9cbkJ1ZmZlci5hbGxvY1Vuc2FmZSA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIHJldHVybiBhbGxvY1Vuc2FmZShudWxsLCBzaXplKVxufVxuLyoqXG4gKiBFcXVpdmFsZW50IHRvIFNsb3dCdWZmZXIobnVtKSwgYnkgZGVmYXVsdCBjcmVhdGVzIGEgbm9uLXplcm8tZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqL1xuQnVmZmVyLmFsbG9jVW5zYWZlU2xvdyA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIHJldHVybiBhbGxvY1Vuc2FmZShudWxsLCBzaXplKVxufVxuXG5mdW5jdGlvbiBmcm9tU3RyaW5nICh0aGF0LCBzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnIHx8IGVuY29kaW5nID09PSAnJykge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gIH1cblxuICBpZiAoIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZW5jb2RpbmdcIiBtdXN0IGJlIGEgdmFsaWQgc3RyaW5nIGVuY29kaW5nJylcbiAgfVxuXG4gIHZhciBsZW5ndGggPSBieXRlTGVuZ3RoKHN0cmluZywgZW5jb2RpbmcpIHwgMFxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIGxlbmd0aClcblxuICB2YXIgYWN0dWFsID0gdGhhdC53cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuXG4gIGlmIChhY3R1YWwgIT09IGxlbmd0aCkge1xuICAgIC8vIFdyaXRpbmcgYSBoZXggc3RyaW5nLCBmb3IgZXhhbXBsZSwgdGhhdCBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcnMgd2lsbFxuICAgIC8vIGNhdXNlIGV2ZXJ5dGhpbmcgYWZ0ZXIgdGhlIGZpcnN0IGludmFsaWQgY2hhcmFjdGVyIHRvIGJlIGlnbm9yZWQuIChlLmcuXG4gICAgLy8gJ2FieHhjZCcgd2lsbCBiZSB0cmVhdGVkIGFzICdhYicpXG4gICAgdGhhdCA9IHRoYXQuc2xpY2UoMCwgYWN0dWFsKVxuICB9XG5cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5TGlrZSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCA8IDAgPyAwIDogY2hlY2tlZChhcnJheS5sZW5ndGgpIHwgMFxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAodGhhdCwgYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICBhcnJheS5ieXRlTGVuZ3RoIC8vIHRoaXMgdGhyb3dzIGlmIGBhcnJheWAgaXMgbm90IGEgdmFsaWQgQXJyYXlCdWZmZXJcblxuICBpZiAoYnl0ZU9mZnNldCA8IDAgfHwgYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXFwnb2Zmc2V0XFwnIGlzIG91dCBvZiBib3VuZHMnKVxuICB9XG5cbiAgaWYgKGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0ICsgKGxlbmd0aCB8fCAwKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcXCdsZW5ndGhcXCcgaXMgb3V0IG9mIGJvdW5kcycpXG4gIH1cblxuICBpZiAoYnl0ZU9mZnNldCA9PT0gdW5kZWZpbmVkICYmIGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgYXJyYXkgPSBuZXcgVWludDhBcnJheShhcnJheSlcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQpXG4gIH0gZWxzZSB7XG4gICAgYXJyYXkgPSBuZXcgVWludDhBcnJheShhcnJheSwgYnl0ZU9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgdGhhdCA9IGFycmF5XG4gICAgdGhhdC5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIHRoYXQgPSBmcm9tQXJyYXlMaWtlKHRoYXQsIGFycmF5KVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21PYmplY3QgKHRoYXQsIG9iaikge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKG9iaikpIHtcbiAgICB2YXIgbGVuID0gY2hlY2tlZChvYmoubGVuZ3RoKSB8IDBcbiAgICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIGxlbilcblxuICAgIGlmICh0aGF0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoYXRcbiAgICB9XG5cbiAgICBvYmouY29weSh0aGF0LCAwLCAwLCBsZW4pXG4gICAgcmV0dXJuIHRoYXRcbiAgfVxuXG4gIGlmIChvYmopIHtcbiAgICBpZiAoKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgb2JqLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB8fCAnbGVuZ3RoJyBpbiBvYmopIHtcbiAgICAgIGlmICh0eXBlb2Ygb2JqLmxlbmd0aCAhPT0gJ251bWJlcicgfHwgaXNuYW4ob2JqLmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCAwKVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZyb21BcnJheUxpa2UodGhhdCwgb2JqKVxuICAgIH1cblxuICAgIGlmIChvYmoudHlwZSA9PT0gJ0J1ZmZlcicgJiYgaXNBcnJheShvYmouZGF0YSkpIHtcbiAgICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsIG9iai5kYXRhKVxuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcsIEJ1ZmZlciwgQXJyYXlCdWZmZXIsIEFycmF5LCBvciBhcnJheS1saWtlIG9iamVjdC4nKVxufVxuXG5mdW5jdGlvbiBjaGVja2VkIChsZW5ndGgpIHtcbiAgLy8gTm90ZTogY2Fubm90IHVzZSBgbGVuZ3RoIDwga01heExlbmd0aCgpYCBoZXJlIGJlY2F1c2UgdGhhdCBmYWlscyB3aGVuXG4gIC8vIGxlbmd0aCBpcyBOYU4gKHdoaWNoIGlzIG90aGVyd2lzZSBjb2VyY2VkIHRvIHplcm8uKVxuICBpZiAobGVuZ3RoID49IGtNYXhMZW5ndGgoKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIGFsbG9jYXRlIEJ1ZmZlciBsYXJnZXIgdGhhbiBtYXhpbXVtICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICdzaXplOiAweCcgKyBrTWF4TGVuZ3RoKCkudG9TdHJpbmcoMTYpICsgJyBieXRlcycpXG4gIH1cbiAgcmV0dXJuIGxlbmd0aCB8IDBcbn1cblxuZnVuY3Rpb24gU2xvd0J1ZmZlciAobGVuZ3RoKSB7XG4gIGlmICgrbGVuZ3RoICE9IGxlbmd0aCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVxZXFlcVxuICAgIGxlbmd0aCA9IDBcbiAgfVxuICByZXR1cm4gQnVmZmVyLmFsbG9jKCtsZW5ndGgpXG59XG5cbkJ1ZmZlci5pc0J1ZmZlciA9IGZ1bmN0aW9uIGlzQnVmZmVyIChiKSB7XG4gIHJldHVybiAhIShiICE9IG51bGwgJiYgYi5faXNCdWZmZXIpXG59XG5cbkJ1ZmZlci5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAoYSwgYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihhKSB8fCAhQnVmZmVyLmlzQnVmZmVyKGIpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnRzIG11c3QgYmUgQnVmZmVycycpXG4gIH1cblxuICBpZiAoYSA9PT0gYikgcmV0dXJuIDBcblxuICB2YXIgeCA9IGEubGVuZ3RoXG4gIHZhciB5ID0gYi5sZW5ndGhcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gTWF0aC5taW4oeCwgeSk7IGkgPCBsZW47ICsraSkge1xuICAgIGlmIChhW2ldICE9PSBiW2ldKSB7XG4gICAgICB4ID0gYVtpXVxuICAgICAgeSA9IGJbaV1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG5CdWZmZXIuaXNFbmNvZGluZyA9IGZ1bmN0aW9uIGlzRW5jb2RpbmcgKGVuY29kaW5nKSB7XG4gIHN3aXRjaCAoU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5CdWZmZXIuY29uY2F0ID0gZnVuY3Rpb24gY29uY2F0IChsaXN0LCBsZW5ndGgpIHtcbiAgaWYgKCFpc0FycmF5KGxpc3QpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBCdWZmZXIuYWxsb2MoMClcbiAgfVxuXG4gIHZhciBpXG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGxlbmd0aCA9IDBcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgICAgbGVuZ3RoICs9IGxpc3RbaV0ubGVuZ3RoXG4gICAgfVxuICB9XG5cbiAgdmFyIGJ1ZmZlciA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShsZW5ndGgpXG4gIHZhciBwb3MgPSAwXG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGJ1ZiA9IGxpc3RbaV1cbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICAgIH1cbiAgICBidWYuY29weShidWZmZXIsIHBvcylcbiAgICBwb3MgKz0gYnVmLmxlbmd0aFxuICB9XG4gIHJldHVybiBidWZmZXJcbn1cblxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHN0cmluZykpIHtcbiAgICByZXR1cm4gc3RyaW5nLmxlbmd0aFxuICB9XG4gIGlmICh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBBcnJheUJ1ZmZlci5pc1ZpZXcgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgIChBcnJheUJ1ZmZlci5pc1ZpZXcoc3RyaW5nKSB8fCBzdHJpbmcgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikpIHtcbiAgICByZXR1cm4gc3RyaW5nLmJ5dGVMZW5ndGhcbiAgfVxuICBpZiAodHlwZW9mIHN0cmluZyAhPT0gJ3N0cmluZycpIHtcbiAgICBzdHJpbmcgPSAnJyArIHN0cmluZ1xuICB9XG5cbiAgdmFyIGxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKGxlbiA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBVc2UgYSBmb3IgbG9vcCB0byBhdm9pZCByZWN1cnNpb25cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGVuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgIGNhc2UgdW5kZWZpbmVkOlxuICAgICAgICByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiBsZW4gKiAyXG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gbGVuID4+PiAxXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGggLy8gYXNzdW1lIHV0ZjhcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuXG5mdW5jdGlvbiBzbG93VG9TdHJpbmcgKGVuY29kaW5nLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG5cbiAgLy8gTm8gbmVlZCB0byB2ZXJpZnkgdGhhdCBcInRoaXMubGVuZ3RoIDw9IE1BWF9VSU5UMzJcIiBzaW5jZSBpdCdzIGEgcmVhZC1vbmx5XG4gIC8vIHByb3BlcnR5IG9mIGEgdHlwZWQgYXJyYXkuXG5cbiAgLy8gVGhpcyBiZWhhdmVzIG5laXRoZXIgbGlrZSBTdHJpbmcgbm9yIFVpbnQ4QXJyYXkgaW4gdGhhdCB3ZSBzZXQgc3RhcnQvZW5kXG4gIC8vIHRvIHRoZWlyIHVwcGVyL2xvd2VyIGJvdW5kcyBpZiB0aGUgdmFsdWUgcGFzc2VkIGlzIG91dCBvZiByYW5nZS5cbiAgLy8gdW5kZWZpbmVkIGlzIGhhbmRsZWQgc3BlY2lhbGx5IGFzIHBlciBFQ01BLTI2MiA2dGggRWRpdGlvbixcbiAgLy8gU2VjdGlvbiAxMy4zLjMuNyBSdW50aW1lIFNlbWFudGljczogS2V5ZWRCaW5kaW5nSW5pdGlhbGl6YXRpb24uXG4gIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkIHx8IHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ID0gMFxuICB9XG4gIC8vIFJldHVybiBlYXJseSBpZiBzdGFydCA+IHRoaXMubGVuZ3RoLiBEb25lIGhlcmUgdG8gcHJldmVudCBwb3RlbnRpYWwgdWludDMyXG4gIC8vIGNvZXJjaW9uIGZhaWwgYmVsb3cuXG4gIGlmIChzdGFydCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoZW5kID09PSB1bmRlZmluZWQgfHwgZW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICB9XG5cbiAgaWYgKGVuZCA8PSAwKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICAvLyBGb3JjZSBjb2Vyc2lvbiB0byB1aW50MzIuIFRoaXMgd2lsbCBhbHNvIGNvZXJjZSBmYWxzZXkvTmFOIHZhbHVlcyB0byAwLlxuICBlbmQgPj4+PSAwXG4gIHN0YXJ0ID4+Pj0gMFxuXG4gIGlmIChlbmQgPD0gc3RhcnQpIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxhdGluMVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdXRmMTZsZVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9IChlbmNvZGluZyArICcnKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG4vLyBUaGUgcHJvcGVydHkgaXMgdXNlZCBieSBgQnVmZmVyLmlzQnVmZmVyYCBhbmQgYGlzLWJ1ZmZlcmAgKGluIFNhZmFyaSA1LTcpIHRvIGRldGVjdFxuLy8gQnVmZmVyIGluc3RhbmNlcy5cbkJ1ZmZlci5wcm90b3R5cGUuX2lzQnVmZmVyID0gdHJ1ZVxuXG5mdW5jdGlvbiBzd2FwIChiLCBuLCBtKSB7XG4gIHZhciBpID0gYltuXVxuICBiW25dID0gYlttXVxuICBiW21dID0gaVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXAxNiA9IGZ1bmN0aW9uIHN3YXAxNiAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgMiAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMTYtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gMikge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDEpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMzIgPSBmdW5jdGlvbiBzd2FwMzIgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDQgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDMyLWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAzKVxuICAgIHN3YXAodGhpcywgaSArIDEsIGkgKyAyKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDY0ID0gZnVuY3Rpb24gc3dhcDY0ICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSA4ICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA2NC1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA4KSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgNylcbiAgICBzd2FwKHRoaXMsIGkgKyAxLCBpICsgNilcbiAgICBzd2FwKHRoaXMsIGkgKyAyLCBpICsgNSlcbiAgICBzd2FwKHRoaXMsIGkgKyAzLCBpICsgNClcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcgKCkge1xuICB2YXIgbGVuZ3RoID0gdGhpcy5sZW5ndGggfCAwXG4gIGlmIChsZW5ndGggPT09IDApIHJldHVybiAnJ1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCAwLCBsZW5ndGgpXG4gIHJldHVybiBzbG93VG9TdHJpbmcuYXBwbHkodGhpcywgYXJndW1lbnRzKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIGVxdWFscyAoYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihiKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlcicpXG4gIGlmICh0aGlzID09PSBiKSByZXR1cm4gdHJ1ZVxuICByZXR1cm4gQnVmZmVyLmNvbXBhcmUodGhpcywgYikgPT09IDBcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCAoKSB7XG4gIHZhciBzdHIgPSAnJ1xuICB2YXIgbWF4ID0gZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFU1xuICBpZiAodGhpcy5sZW5ndGggPiAwKSB7XG4gICAgc3RyID0gdGhpcy50b1N0cmluZygnaGV4JywgMCwgbWF4KS5tYXRjaCgvLnsyfS9nKS5qb2luKCcgJylcbiAgICBpZiAodGhpcy5sZW5ndGggPiBtYXgpIHN0ciArPSAnIC4uLiAnXG4gIH1cbiAgcmV0dXJuICc8QnVmZmVyICcgKyBzdHIgKyAnPidcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAodGFyZ2V0LCBzdGFydCwgZW5kLCB0aGlzU3RhcnQsIHRoaXNFbmQpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIodGFyZ2V0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICB9XG5cbiAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICBpZiAoZW5kID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmQgPSB0YXJnZXQgPyB0YXJnZXQubGVuZ3RoIDogMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNTdGFydCA9IDBcbiAgfVxuICBpZiAodGhpc0VuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc0VuZCA9IHRoaXMubGVuZ3RoXG4gIH1cblxuICBpZiAoc3RhcnQgPCAwIHx8IGVuZCA+IHRhcmdldC5sZW5ndGggfHwgdGhpc1N0YXJ0IDwgMCB8fCB0aGlzRW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCAmJiBzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCkge1xuICAgIHJldHVybiAtMVxuICB9XG4gIGlmIChzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMVxuICB9XG5cbiAgc3RhcnQgPj4+PSAwXG4gIGVuZCA+Pj49IDBcbiAgdGhpc1N0YXJ0ID4+Pj0gMFxuICB0aGlzRW5kID4+Pj0gMFxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQpIHJldHVybiAwXG5cbiAgdmFyIHggPSB0aGlzRW5kIC0gdGhpc1N0YXJ0XG4gIHZhciB5ID0gZW5kIC0gc3RhcnRcbiAgdmFyIGxlbiA9IE1hdGgubWluKHgsIHkpXG5cbiAgdmFyIHRoaXNDb3B5ID0gdGhpcy5zbGljZSh0aGlzU3RhcnQsIHRoaXNFbmQpXG4gIHZhciB0YXJnZXRDb3B5ID0gdGFyZ2V0LnNsaWNlKHN0YXJ0LCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgIGlmICh0aGlzQ29weVtpXSAhPT0gdGFyZ2V0Q29weVtpXSkge1xuICAgICAgeCA9IHRoaXNDb3B5W2ldXG4gICAgICB5ID0gdGFyZ2V0Q29weVtpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbi8vIEZpbmRzIGVpdGhlciB0aGUgZmlyc3QgaW5kZXggb2YgYHZhbGAgaW4gYGJ1ZmZlcmAgYXQgb2Zmc2V0ID49IGBieXRlT2Zmc2V0YCxcbi8vIE9SIHRoZSBsYXN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA8PSBgYnl0ZU9mZnNldGAuXG4vL1xuLy8gQXJndW1lbnRzOlxuLy8gLSBidWZmZXIgLSBhIEJ1ZmZlciB0byBzZWFyY2hcbi8vIC0gdmFsIC0gYSBzdHJpbmcsIEJ1ZmZlciwgb3IgbnVtYmVyXG4vLyAtIGJ5dGVPZmZzZXQgLSBhbiBpbmRleCBpbnRvIGBidWZmZXJgOyB3aWxsIGJlIGNsYW1wZWQgdG8gYW4gaW50MzJcbi8vIC0gZW5jb2RpbmcgLSBhbiBvcHRpb25hbCBlbmNvZGluZywgcmVsZXZhbnQgaXMgdmFsIGlzIGEgc3RyaW5nXG4vLyAtIGRpciAtIHRydWUgZm9yIGluZGV4T2YsIGZhbHNlIGZvciBsYXN0SW5kZXhPZlxuZnVuY3Rpb24gYmlkaXJlY3Rpb25hbEluZGV4T2YgKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIC8vIEVtcHR5IGJ1ZmZlciBtZWFucyBubyBtYXRjaFxuICBpZiAoYnVmZmVyLmxlbmd0aCA9PT0gMCkgcmV0dXJuIC0xXG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXRcbiAgaWYgKHR5cGVvZiBieXRlT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gYnl0ZU9mZnNldFxuICAgIGJ5dGVPZmZzZXQgPSAwXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA+IDB4N2ZmZmZmZmYpIHtcbiAgICBieXRlT2Zmc2V0ID0gMHg3ZmZmZmZmZlxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAtMHg4MDAwMDAwMCkge1xuICAgIGJ5dGVPZmZzZXQgPSAtMHg4MDAwMDAwMFxuICB9XG4gIGJ5dGVPZmZzZXQgPSArYnl0ZU9mZnNldCAgLy8gQ29lcmNlIHRvIE51bWJlci5cbiAgaWYgKGlzTmFOKGJ5dGVPZmZzZXQpKSB7XG4gICAgLy8gYnl0ZU9mZnNldDogaXQgaXQncyB1bmRlZmluZWQsIG51bGwsIE5hTiwgXCJmb29cIiwgZXRjLCBzZWFyY2ggd2hvbGUgYnVmZmVyXG4gICAgYnl0ZU9mZnNldCA9IGRpciA/IDAgOiAoYnVmZmVyLmxlbmd0aCAtIDEpXG4gIH1cblxuICAvLyBOb3JtYWxpemUgYnl0ZU9mZnNldDogbmVnYXRpdmUgb2Zmc2V0cyBzdGFydCBmcm9tIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlclxuICBpZiAoYnl0ZU9mZnNldCA8IDApIGJ5dGVPZmZzZXQgPSBidWZmZXIubGVuZ3RoICsgYnl0ZU9mZnNldFxuICBpZiAoYnl0ZU9mZnNldCA+PSBidWZmZXIubGVuZ3RoKSB7XG4gICAgaWYgKGRpcikgcmV0dXJuIC0xXG4gICAgZWxzZSBieXRlT2Zmc2V0ID0gYnVmZmVyLmxlbmd0aCAtIDFcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgMCkge1xuICAgIGlmIChkaXIpIGJ5dGVPZmZzZXQgPSAwXG4gICAgZWxzZSByZXR1cm4gLTFcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSB2YWxcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFsID0gQnVmZmVyLmZyb20odmFsLCBlbmNvZGluZylcbiAgfVxuXG4gIC8vIEZpbmFsbHksIHNlYXJjaCBlaXRoZXIgaW5kZXhPZiAoaWYgZGlyIGlzIHRydWUpIG9yIGxhc3RJbmRleE9mXG4gIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsKSkge1xuICAgIC8vIFNwZWNpYWwgY2FzZTogbG9va2luZyBmb3IgZW1wdHkgc3RyaW5nL2J1ZmZlciBhbHdheXMgZmFpbHNcbiAgICBpZiAodmFsLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIC0xXG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpXG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICB2YWwgPSB2YWwgJiAweEZGIC8vIFNlYXJjaCBmb3IgYSBieXRlIHZhbHVlIFswLTI1NV1cbiAgICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiZcbiAgICAgICAgdHlwZW9mIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlmIChkaXIpIHtcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5sYXN0SW5kZXhPZi5jYWxsKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0KVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlciwgWyB2YWwgXSwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcilcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ3ZhbCBtdXN0IGJlIHN0cmluZywgbnVtYmVyIG9yIEJ1ZmZlcicpXG59XG5cbmZ1bmN0aW9uIGFycmF5SW5kZXhPZiAoYXJyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpIHtcbiAgdmFyIGluZGV4U2l6ZSA9IDFcbiAgdmFyIGFyckxlbmd0aCA9IGFyci5sZW5ndGhcbiAgdmFyIHZhbExlbmd0aCA9IHZhbC5sZW5ndGhcblxuICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgaWYgKGVuY29kaW5nID09PSAndWNzMicgfHwgZW5jb2RpbmcgPT09ICd1Y3MtMicgfHxcbiAgICAgICAgZW5jb2RpbmcgPT09ICd1dGYxNmxlJyB8fCBlbmNvZGluZyA9PT0gJ3V0Zi0xNmxlJykge1xuICAgICAgaWYgKGFyci5sZW5ndGggPCAyIHx8IHZhbC5sZW5ndGggPCAyKSB7XG4gICAgICAgIHJldHVybiAtMVxuICAgICAgfVxuICAgICAgaW5kZXhTaXplID0gMlxuICAgICAgYXJyTGVuZ3RoIC89IDJcbiAgICAgIHZhbExlbmd0aCAvPSAyXG4gICAgICBieXRlT2Zmc2V0IC89IDJcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZWFkIChidWYsIGkpIHtcbiAgICBpZiAoaW5kZXhTaXplID09PSAxKSB7XG4gICAgICByZXR1cm4gYnVmW2ldXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBidWYucmVhZFVJbnQxNkJFKGkgKiBpbmRleFNpemUpXG4gICAgfVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGRpcikge1xuICAgIHZhciBmb3VuZEluZGV4ID0gLTFcbiAgICBmb3IgKGkgPSBieXRlT2Zmc2V0OyBpIDwgYXJyTGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChyZWFkKGFyciwgaSkgPT09IHJlYWQodmFsLCBmb3VuZEluZGV4ID09PSAtMSA/IDAgOiBpIC0gZm91bmRJbmRleCkpIHtcbiAgICAgICAgaWYgKGZvdW5kSW5kZXggPT09IC0xKSBmb3VuZEluZGV4ID0gaVxuICAgICAgICBpZiAoaSAtIGZvdW5kSW5kZXggKyAxID09PSB2YWxMZW5ndGgpIHJldHVybiBmb3VuZEluZGV4ICogaW5kZXhTaXplXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZm91bmRJbmRleCAhPT0gLTEpIGkgLT0gaSAtIGZvdW5kSW5kZXhcbiAgICAgICAgZm91bmRJbmRleCA9IC0xXG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChieXRlT2Zmc2V0ICsgdmFsTGVuZ3RoID4gYXJyTGVuZ3RoKSBieXRlT2Zmc2V0ID0gYXJyTGVuZ3RoIC0gdmFsTGVuZ3RoXG4gICAgZm9yIChpID0gYnl0ZU9mZnNldDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHZhciBmb3VuZCA9IHRydWVcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdmFsTGVuZ3RoOyBqKyspIHtcbiAgICAgICAgaWYgKHJlYWQoYXJyLCBpICsgaikgIT09IHJlYWQodmFsLCBqKSkge1xuICAgICAgICAgIGZvdW5kID0gZmFsc2VcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZm91bmQpIHJldHVybiBpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIC0xXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5jbHVkZXMgPSBmdW5jdGlvbiBpbmNsdWRlcyAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gdGhpcy5pbmRleE9mKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpICE9PSAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbiBpbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCB0cnVlKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmxhc3RJbmRleE9mID0gZnVuY3Rpb24gbGFzdEluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGZhbHNlKVxufVxuXG5mdW5jdGlvbiBoZXhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIG9mZnNldCA9IE51bWJlcihvZmZzZXQpIHx8IDBcbiAgdmFyIHJlbWFpbmluZyA9IGJ1Zi5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSBOdW1iZXIobGVuZ3RoKVxuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICAgIH1cbiAgfVxuXG4gIC8vIG11c3QgYmUgYW4gZXZlbiBudW1iZXIgb2YgZGlnaXRzXG4gIHZhciBzdHJMZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGlmIChzdHJMZW4gJSAyICE9PSAwKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKVxuXG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMlxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgcGFyc2VkID0gcGFyc2VJbnQoc3RyaW5nLnN1YnN0cihpICogMiwgMiksIDE2KVxuICAgIGlmIChpc05hTihwYXJzZWQpKSByZXR1cm4gaVxuICAgIGJ1ZltvZmZzZXQgKyBpXSA9IHBhcnNlZFxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIHV0ZjhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGFzY2lpV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gbGF0aW4xV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYXNjaWlXcml0ZShidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGJhc2U2NFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiB1Y3MyV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGYxNmxlVG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gd3JpdGUgKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcpXG4gIGlmIChvZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBvZmZzZXRcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgb2Zmc2V0WywgbGVuZ3RoXVssIGVuY29kaW5nXSlcbiAgfSBlbHNlIGlmIChpc0Zpbml0ZShvZmZzZXQpKSB7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICAgIGlmIChpc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICBsZW5ndGggPSBsZW5ndGggfCAwXG4gICAgICBpZiAoZW5jb2RpbmcgPT09IHVuZGVmaW5lZCkgZW5jb2RpbmcgPSAndXRmOCdcbiAgICB9IGVsc2Uge1xuICAgICAgZW5jb2RpbmcgPSBsZW5ndGhcbiAgICAgIGxlbmd0aCA9IHVuZGVmaW5lZFxuICAgIH1cbiAgLy8gbGVnYWN5IHdyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldCwgbGVuZ3RoKSAtIHJlbW92ZSBpbiB2MC4xM1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICdCdWZmZXIud3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0WywgbGVuZ3RoXSkgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZCdcbiAgICApXG4gIH1cblxuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkIHx8IGxlbmd0aCA+IHJlbWFpbmluZykgbGVuZ3RoID0gcmVtYWluaW5nXG5cbiAgaWYgKChzdHJpbmcubGVuZ3RoID4gMCAmJiAobGVuZ3RoIDwgMCB8fCBvZmZzZXQgPCAwKSkgfHwgb2Zmc2V0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byB3cml0ZSBvdXRzaWRlIGJ1ZmZlciBib3VuZHMnKVxuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsYXRpbjFXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICAvLyBXYXJuaW5nOiBtYXhMZW5ndGggbm90IHRha2VuIGludG8gYWNjb3VudCBpbiBiYXNlNjRXcml0ZVxuICAgICAgICByZXR1cm4gYmFzZTY0V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHVjczJXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04gKCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6ICdCdWZmZXInLFxuICAgIGRhdGE6IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHRoaXMuX2FyciB8fCB0aGlzLCAwKVxuICB9XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKHN0YXJ0ID09PSAwICYmIGVuZCA9PT0gYnVmLmxlbmd0aCkge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zi5zbGljZShzdGFydCwgZW5kKSlcbiAgfVxufVxuXG5mdW5jdGlvbiB1dGY4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG4gIHZhciByZXMgPSBbXVxuXG4gIHZhciBpID0gc3RhcnRcbiAgd2hpbGUgKGkgPCBlbmQpIHtcbiAgICB2YXIgZmlyc3RCeXRlID0gYnVmW2ldXG4gICAgdmFyIGNvZGVQb2ludCA9IG51bGxcbiAgICB2YXIgYnl0ZXNQZXJTZXF1ZW5jZSA9IChmaXJzdEJ5dGUgPiAweEVGKSA/IDRcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4REYpID8gM1xuICAgICAgOiAoZmlyc3RCeXRlID4gMHhCRikgPyAyXG4gICAgICA6IDFcblxuICAgIGlmIChpICsgYnl0ZXNQZXJTZXF1ZW5jZSA8PSBlbmQpIHtcbiAgICAgIHZhciBzZWNvbmRCeXRlLCB0aGlyZEJ5dGUsIGZvdXJ0aEJ5dGUsIHRlbXBDb2RlUG9pbnRcblxuICAgICAgc3dpdGNoIChieXRlc1BlclNlcXVlbmNlKSB7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBpZiAoZmlyc3RCeXRlIDwgMHg4MCkge1xuICAgICAgICAgICAgY29kZVBvaW50ID0gZmlyc3RCeXRlXG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4MUYpIDw8IDB4NiB8IChzZWNvbmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3Rikge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweEMgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4NiB8ICh0aGlyZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGRiAmJiAodGVtcENvZGVQb2ludCA8IDB4RDgwMCB8fCB0ZW1wQ29kZVBvaW50ID4gMHhERkZGKSkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBmb3VydGhCeXRlID0gYnVmW2kgKyAzXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAoZm91cnRoQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHgxMiB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHhDIHwgKHRoaXJkQnl0ZSAmIDB4M0YpIDw8IDB4NiB8IChmb3VydGhCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHhGRkZGICYmIHRlbXBDb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjb2RlUG9pbnQgPT09IG51bGwpIHtcbiAgICAgIC8vIHdlIGRpZCBub3QgZ2VuZXJhdGUgYSB2YWxpZCBjb2RlUG9pbnQgc28gaW5zZXJ0IGFcbiAgICAgIC8vIHJlcGxhY2VtZW50IGNoYXIgKFUrRkZGRCkgYW5kIGFkdmFuY2Ugb25seSAxIGJ5dGVcbiAgICAgIGNvZGVQb2ludCA9IDB4RkZGRFxuICAgICAgYnl0ZXNQZXJTZXF1ZW5jZSA9IDFcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA+IDB4RkZGRikge1xuICAgICAgLy8gZW5jb2RlIHRvIHV0ZjE2IChzdXJyb2dhdGUgcGFpciBkYW5jZSlcbiAgICAgIGNvZGVQb2ludCAtPSAweDEwMDAwXG4gICAgICByZXMucHVzaChjb2RlUG9pbnQgPj4+IDEwICYgMHgzRkYgfCAweEQ4MDApXG4gICAgICBjb2RlUG9pbnQgPSAweERDMDAgfCBjb2RlUG9pbnQgJiAweDNGRlxuICAgIH1cblxuICAgIHJlcy5wdXNoKGNvZGVQb2ludClcbiAgICBpICs9IGJ5dGVzUGVyU2VxdWVuY2VcbiAgfVxuXG4gIHJldHVybiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkocmVzKVxufVxuXG4vLyBCYXNlZCBvbiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMjc0NzI3Mi82ODA3NDIsIHRoZSBicm93c2VyIHdpdGhcbi8vIHRoZSBsb3dlc3QgbGltaXQgaXMgQ2hyb21lLCB3aXRoIDB4MTAwMDAgYXJncy5cbi8vIFdlIGdvIDEgbWFnbml0dWRlIGxlc3MsIGZvciBzYWZldHlcbnZhciBNQVhfQVJHVU1FTlRTX0xFTkdUSCA9IDB4MTAwMFxuXG5mdW5jdGlvbiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkgKGNvZGVQb2ludHMpIHtcbiAgdmFyIGxlbiA9IGNvZGVQb2ludHMubGVuZ3RoXG4gIGlmIChsZW4gPD0gTUFYX0FSR1VNRU5UU19MRU5HVEgpIHtcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNvZGVQb2ludHMpIC8vIGF2b2lkIGV4dHJhIHNsaWNlKClcbiAgfVxuXG4gIC8vIERlY29kZSBpbiBjaHVua3MgdG8gYXZvaWQgXCJjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWRcIi5cbiAgdmFyIHJlcyA9ICcnXG4gIHZhciBpID0gMFxuICB3aGlsZSAoaSA8IGxlbikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFxuICAgICAgU3RyaW5nLFxuICAgICAgY29kZVBvaW50cy5zbGljZShpLCBpICs9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKVxuICAgIClcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldICYgMHg3RilcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGxhdGluMVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGhleFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcblxuICBpZiAoIXN0YXJ0IHx8IHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmICghZW5kIHx8IGVuZCA8IDAgfHwgZW5kID4gbGVuKSBlbmQgPSBsZW5cblxuICB2YXIgb3V0ID0gJydcbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICBvdXQgKz0gdG9IZXgoYnVmW2ldKVxuICB9XG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGJ5dGVzID0gYnVmLnNsaWNlKHN0YXJ0LCBlbmQpXG4gIHZhciByZXMgPSAnJ1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0gKyBieXRlc1tpICsgMV0gKiAyNTYpXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24gc2xpY2UgKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIHN0YXJ0ID0gfn5zdGFydFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGxlbiA6IH5+ZW5kXG5cbiAgaWYgKHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ICs9IGxlblxuICAgIGlmIChzdGFydCA8IDApIHN0YXJ0ID0gMFxuICB9IGVsc2UgaWYgKHN0YXJ0ID4gbGVuKSB7XG4gICAgc3RhcnQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCAwKSB7XG4gICAgZW5kICs9IGxlblxuICAgIGlmIChlbmQgPCAwKSBlbmQgPSAwXG4gIH0gZWxzZSBpZiAoZW5kID4gbGVuKSB7XG4gICAgZW5kID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgdmFyIG5ld0J1ZlxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICBuZXdCdWYgPSB0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpXG4gICAgbmV3QnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICB2YXIgc2xpY2VMZW4gPSBlbmQgLSBzdGFydFxuICAgIG5ld0J1ZiA9IG5ldyBCdWZmZXIoc2xpY2VMZW4sIHVuZGVmaW5lZClcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNsaWNlTGVuOyArK2kpIHtcbiAgICAgIG5ld0J1ZltpXSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZXdCdWZcbn1cblxuLypcbiAqIE5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgYnVmZmVyIGlzbid0IHRyeWluZyB0byB3cml0ZSBvdXQgb2YgYm91bmRzLlxuICovXG5mdW5jdGlvbiBjaGVja09mZnNldCAob2Zmc2V0LCBleHQsIGxlbmd0aCkge1xuICBpZiAoKG9mZnNldCAlIDEpICE9PSAwIHx8IG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdvZmZzZXQgaXMgbm90IHVpbnQnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gbGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVHJ5aW5nIHRvIGFjY2VzcyBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRMRSA9IGZ1bmN0aW9uIHJlYWRVSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRCRSA9IGZ1bmN0aW9uIHJlYWRVSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG4gIH1cblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdXG4gIHZhciBtdWwgPSAxXG4gIHdoaWxlIChieXRlTGVuZ3RoID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbiByZWFkVUludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2QkUgPSBmdW5jdGlvbiByZWFkVUludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgOCkgfCB0aGlzW29mZnNldCArIDFdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkxFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICgodGhpc1tvZmZzZXRdKSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikpICtcbiAgICAgICh0aGlzW29mZnNldCArIDNdICogMHgxMDAwMDAwKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdICogMHgxMDAwMDAwKSArXG4gICAgKCh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgIHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludExFID0gZnVuY3Rpb24gcmVhZEludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludEJFID0gZnVuY3Rpb24gcmVhZEludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoXG4gIHZhciBtdWwgPSAxXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0taV1cbiAgd2hpbGUgKGkgPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1pXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbiByZWFkSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICBpZiAoISh0aGlzW29mZnNldF0gJiAweDgwKSkgcmV0dXJuICh0aGlzW29mZnNldF0pXG4gIHJldHVybiAoKDB4ZmYgLSB0aGlzW29mZnNldF0gKyAxKSAqIC0xKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkxFID0gZnVuY3Rpb24gcmVhZEludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIDFdIHwgKHRoaXNbb2Zmc2V0XSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyTEUgPSBmdW5jdGlvbiByZWFkSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdKSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10gPDwgMjQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyQkUgPSBmdW5jdGlvbiByZWFkSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDI0KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0TEUgPSBmdW5jdGlvbiByZWFkRmxvYXRMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0QkUgPSBmdW5jdGlvbiByZWFkRmxvYXRCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVMRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgNTIsIDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUJFID0gZnVuY3Rpb24gcmVhZERvdWJsZUJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgNTIsIDgpXG59XG5cbmZ1bmN0aW9uIGNoZWNrSW50IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJidWZmZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyIGluc3RhbmNlJylcbiAgaWYgKHZhbHVlID4gbWF4IHx8IHZhbHVlIDwgbWluKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uIHdyaXRlVUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHhmZiwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQxNiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCAyKTsgaSA8IGo7ICsraSkge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSAmICgweGZmIDw8ICg4ICogKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkpKSkgPj4+XG4gICAgICAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSAqIDhcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQzMiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgNCk7IGkgPCBqOyArK2kpIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgPj4+IChsaXR0bGVFbmRpYW4gPyBpIDogMyAtIGkpICogOCkgJiAweGZmXG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEUgPSBmdW5jdGlvbiB3cml0ZUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gMFxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgLSAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50QkUgPSBmdW5jdGlvbiB3cml0ZUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgKyAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uIHdyaXRlSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweDdmLCAtMHg4MClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmYgKyB2YWx1ZSArIDFcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmZmZmZiArIHZhbHVlICsgMVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuZnVuY3Rpb24gY2hlY2tJRUVFNzU0IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAob2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gd3JpdGVGbG9hdExFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbiAgcmV0dXJuIG9mZnNldCArIDhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5ICh0YXJnZXQsIHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXRTdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB0YXJnZXRTdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRTdGFydCkgdGFyZ2V0U3RhcnQgPSAwXG4gIGlmIChlbmQgPiAwICYmIGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDBcbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgdGhpcy5sZW5ndGggPT09IDApIHJldHVybiAwXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBpZiAodGFyZ2V0U3RhcnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICB9XG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgKyBzdGFydFxuICB9XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG4gIHZhciBpXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCAmJiBzdGFydCA8IHRhcmdldFN0YXJ0ICYmIHRhcmdldFN0YXJ0IDwgZW5kKSB7XG4gICAgLy8gZGVzY2VuZGluZyBjb3B5IGZyb20gZW5kXG4gICAgZm9yIChpID0gbGVuIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2UgaWYgKGxlbiA8IDEwMDAgfHwgIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gYXNjZW5kaW5nIGNvcHkgZnJvbSBzdGFydFxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgVWludDhBcnJheS5wcm90b3R5cGUuc2V0LmNhbGwoXG4gICAgICB0YXJnZXQsXG4gICAgICB0aGlzLnN1YmFycmF5KHN0YXJ0LCBzdGFydCArIGxlbiksXG4gICAgICB0YXJnZXRTdGFydFxuICAgIClcbiAgfVxuXG4gIHJldHVybiBsZW5cbn1cblxuLy8gVXNhZ2U6XG4vLyAgICBidWZmZXIuZmlsbChudW1iZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKGJ1ZmZlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoc3RyaW5nWywgb2Zmc2V0WywgZW5kXV1bLCBlbmNvZGluZ10pXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiBmaWxsICh2YWwsIHN0YXJ0LCBlbmQsIGVuY29kaW5nKSB7XG4gIC8vIEhhbmRsZSBzdHJpbmcgY2FzZXM6XG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIGlmICh0eXBlb2Ygc3RhcnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IHN0YXJ0XG4gICAgICBzdGFydCA9IDBcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZW5kID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBlbmRcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfVxuICAgIGlmICh2YWwubGVuZ3RoID09PSAxKSB7XG4gICAgICB2YXIgY29kZSA9IHZhbC5jaGFyQ29kZUF0KDApXG4gICAgICBpZiAoY29kZSA8IDI1Nikge1xuICAgICAgICB2YWwgPSBjb2RlXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2VuY29kaW5nIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJyAmJiAhQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMjU1XG4gIH1cblxuICAvLyBJbnZhbGlkIHJhbmdlcyBhcmUgbm90IHNldCB0byBhIGRlZmF1bHQsIHNvIGNhbiByYW5nZSBjaGVjayBlYXJseS5cbiAgaWYgKHN0YXJ0IDwgMCB8fCB0aGlzLmxlbmd0aCA8IHN0YXJ0IHx8IHRoaXMubGVuZ3RoIDwgZW5kKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ091dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHN0YXJ0ID0gc3RhcnQgPj4+IDBcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyB0aGlzLmxlbmd0aCA6IGVuZCA+Pj4gMFxuXG4gIGlmICghdmFsKSB2YWwgPSAwXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgICAgdGhpc1tpXSA9IHZhbFxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgYnl0ZXMgPSBCdWZmZXIuaXNCdWZmZXIodmFsKVxuICAgICAgPyB2YWxcbiAgICAgIDogdXRmOFRvQnl0ZXMobmV3IEJ1ZmZlcih2YWwsIGVuY29kaW5nKS50b1N0cmluZygpKVxuICAgIHZhciBsZW4gPSBieXRlcy5sZW5ndGhcbiAgICBmb3IgKGkgPSAwOyBpIDwgZW5kIC0gc3RhcnQ7ICsraSkge1xuICAgICAgdGhpc1tpICsgc3RhcnRdID0gYnl0ZXNbaSAlIGxlbl1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpc1xufVxuXG4vLyBIRUxQRVIgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09XG5cbnZhciBJTlZBTElEX0JBU0U2NF9SRSA9IC9bXitcXC8wLTlBLVphLXotX10vZ1xuXG5mdW5jdGlvbiBiYXNlNjRjbGVhbiAoc3RyKSB7XG4gIC8vIE5vZGUgc3RyaXBzIG91dCBpbnZhbGlkIGNoYXJhY3RlcnMgbGlrZSBcXG4gYW5kIFxcdCBmcm9tIHRoZSBzdHJpbmcsIGJhc2U2NC1qcyBkb2VzIG5vdFxuICBzdHIgPSBzdHJpbmd0cmltKHN0cikucmVwbGFjZShJTlZBTElEX0JBU0U2NF9SRSwgJycpXG4gIC8vIE5vZGUgY29udmVydHMgc3RyaW5ncyB3aXRoIGxlbmd0aCA8IDIgdG8gJydcbiAgaWYgKHN0ci5sZW5ndGggPCAyKSByZXR1cm4gJydcbiAgLy8gTm9kZSBhbGxvd3MgZm9yIG5vbi1wYWRkZWQgYmFzZTY0IHN0cmluZ3MgKG1pc3NpbmcgdHJhaWxpbmcgPT09KSwgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHdoaWxlIChzdHIubGVuZ3RoICUgNCAhPT0gMCkge1xuICAgIHN0ciA9IHN0ciArICc9J1xuICB9XG4gIHJldHVybiBzdHJcbn1cblxuZnVuY3Rpb24gc3RyaW5ndHJpbSAoc3RyKSB7XG4gIGlmIChzdHIudHJpbSkgcmV0dXJuIHN0ci50cmltKClcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJylcbn1cblxuZnVuY3Rpb24gdG9IZXggKG4pIHtcbiAgaWYgKG4gPCAxNikgcmV0dXJuICcwJyArIG4udG9TdHJpbmcoMTYpXG4gIHJldHVybiBuLnRvU3RyaW5nKDE2KVxufVxuXG5mdW5jdGlvbiB1dGY4VG9CeXRlcyAoc3RyaW5nLCB1bml0cykge1xuICB1bml0cyA9IHVuaXRzIHx8IEluZmluaXR5XG4gIHZhciBjb2RlUG9pbnRcbiAgdmFyIGxlbmd0aCA9IHN0cmluZy5sZW5ndGhcbiAgdmFyIGxlYWRTdXJyb2dhdGUgPSBudWxsXG4gIHZhciBieXRlcyA9IFtdXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGNvZGVQb2ludCA9IHN0cmluZy5jaGFyQ29kZUF0KGkpXG5cbiAgICAvLyBpcyBzdXJyb2dhdGUgY29tcG9uZW50XG4gICAgaWYgKGNvZGVQb2ludCA+IDB4RDdGRiAmJiBjb2RlUG9pbnQgPCAweEUwMDApIHtcbiAgICAgIC8vIGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoIWxlYWRTdXJyb2dhdGUpIHtcbiAgICAgICAgLy8gbm8gbGVhZCB5ZXRcbiAgICAgICAgaWYgKGNvZGVQb2ludCA+IDB4REJGRikge1xuICAgICAgICAgIC8vIHVuZXhwZWN0ZWQgdHJhaWxcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKGkgKyAxID09PSBsZW5ndGgpIHtcbiAgICAgICAgICAvLyB1bnBhaXJlZCBsZWFkXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHZhbGlkIGxlYWRcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIDIgbGVhZHMgaW4gYSByb3dcbiAgICAgIGlmIChjb2RlUG9pbnQgPCAweERDMDApIHtcbiAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gdmFsaWQgc3Vycm9nYXRlIHBhaXJcbiAgICAgIGNvZGVQb2ludCA9IChsZWFkU3Vycm9nYXRlIC0gMHhEODAwIDw8IDEwIHwgY29kZVBvaW50IC0gMHhEQzAwKSArIDB4MTAwMDBcbiAgICB9IGVsc2UgaWYgKGxlYWRTdXJyb2dhdGUpIHtcbiAgICAgIC8vIHZhbGlkIGJtcCBjaGFyLCBidXQgbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgIH1cblxuICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG5cbiAgICAvLyBlbmNvZGUgdXRmOFxuICAgIGlmIChjb2RlUG9pbnQgPCAweDgwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDEpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goY29kZVBvaW50KVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHg4MDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiB8IDB4QzAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgfCAweEUwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSA0KSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHgxMiB8IDB4RjAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29kZSBwb2ludCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIsIHVuaXRzKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG5cbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShiYXNlNjRjbGVhbihzdHIpKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGlmICgoaSArIG9mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSkgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiBpc25hbiAodmFsKSB7XG4gIHJldHVybiB2YWwgIT09IHZhbCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZVxufVxuIiwidmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnc3RyZWFtJykuVHJhbnNmb3JtXG52YXIgU3RyaW5nRGVjb2RlciA9IHJlcXVpcmUoJ3N0cmluZ19kZWNvZGVyJykuU3RyaW5nRGVjb2RlclxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxuXG5mdW5jdGlvbiBDaXBoZXJCYXNlIChoYXNoTW9kZSkge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuICB0aGlzLmhhc2hNb2RlID0gdHlwZW9mIGhhc2hNb2RlID09PSAnc3RyaW5nJ1xuICBpZiAodGhpcy5oYXNoTW9kZSkge1xuICAgIHRoaXNbaGFzaE1vZGVdID0gdGhpcy5fZmluYWxPckRpZ2VzdFxuICB9IGVsc2Uge1xuICAgIHRoaXMuZmluYWwgPSB0aGlzLl9maW5hbE9yRGlnZXN0XG4gIH1cbiAgaWYgKHRoaXMuX2ZpbmFsKSB7XG4gICAgdGhpcy5fX2ZpbmFsID0gdGhpcy5fZmluYWxcbiAgICB0aGlzLl9maW5hbCA9IG51bGxcbiAgfVxuICB0aGlzLl9kZWNvZGVyID0gbnVsbFxuICB0aGlzLl9lbmNvZGluZyA9IG51bGxcbn1cbmluaGVyaXRzKENpcGhlckJhc2UsIFRyYW5zZm9ybSlcblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGlucHV0RW5jLCBvdXRwdXRFbmMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIGRhdGEgPSBCdWZmZXIuZnJvbShkYXRhLCBpbnB1dEVuYylcbiAgfVxuXG4gIHZhciBvdXREYXRhID0gdGhpcy5fdXBkYXRlKGRhdGEpXG4gIGlmICh0aGlzLmhhc2hNb2RlKSByZXR1cm4gdGhpc1xuXG4gIGlmIChvdXRwdXRFbmMpIHtcbiAgICBvdXREYXRhID0gdGhpcy5fdG9TdHJpbmcob3V0RGF0YSwgb3V0cHV0RW5jKVxuICB9XG5cbiAgcmV0dXJuIG91dERhdGFcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuc2V0QXV0b1BhZGRpbmcgPSBmdW5jdGlvbiAoKSB7fVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuZ2V0QXV0aFRhZyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gZ2V0IGF1dGggdGFnIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuc2V0QXV0aFRhZyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gc2V0IGF1dGggdGFnIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuc2V0QUFEID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3RyeWluZyB0byBzZXQgYWFkIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChkYXRhLCBfLCBuZXh0KSB7XG4gIHZhciBlcnJcbiAgdHJ5IHtcbiAgICBpZiAodGhpcy5oYXNoTW9kZSkge1xuICAgICAgdGhpcy5fdXBkYXRlKGRhdGEpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHVzaCh0aGlzLl91cGRhdGUoZGF0YSkpXG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyID0gZVxuICB9IGZpbmFsbHkge1xuICAgIG5leHQoZXJyKVxuICB9XG59XG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fZmx1c2ggPSBmdW5jdGlvbiAoZG9uZSkge1xuICB2YXIgZXJyXG4gIHRyeSB7XG4gICAgdGhpcy5wdXNoKHRoaXMuX19maW5hbCgpKVxuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyID0gZVxuICB9XG5cbiAgZG9uZShlcnIpXG59XG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fZmluYWxPckRpZ2VzdCA9IGZ1bmN0aW9uIChvdXRwdXRFbmMpIHtcbiAgdmFyIG91dERhdGEgPSB0aGlzLl9fZmluYWwoKSB8fCBCdWZmZXIuYWxsb2MoMClcbiAgaWYgKG91dHB1dEVuYykge1xuICAgIG91dERhdGEgPSB0aGlzLl90b1N0cmluZyhvdXREYXRhLCBvdXRwdXRFbmMsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG91dERhdGFcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX3RvU3RyaW5nID0gZnVuY3Rpb24gKHZhbHVlLCBlbmMsIGZpbikge1xuICBpZiAoIXRoaXMuX2RlY29kZXIpIHtcbiAgICB0aGlzLl9kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKVxuICAgIHRoaXMuX2VuY29kaW5nID0gZW5jXG4gIH1cblxuICBpZiAodGhpcy5fZW5jb2RpbmcgIT09IGVuYykgdGhyb3cgbmV3IEVycm9yKCdjYW5cXCd0IHN3aXRjaCBlbmNvZGluZ3MnKVxuXG4gIHZhciBvdXQgPSB0aGlzLl9kZWNvZGVyLndyaXRlKHZhbHVlKVxuICBpZiAoZmluKSB7XG4gICAgb3V0ICs9IHRoaXMuX2RlY29kZXIuZW5kKClcbiAgfVxuXG4gIHJldHVybiBvdXRcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBDaXBoZXJCYXNlXG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cblxuZnVuY3Rpb24gaXNBcnJheShhcmcpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkpIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheShhcmcpO1xuICB9XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhhcmcpID09PSAnW29iamVjdCBBcnJheV0nO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gb2JqZWN0VG9TdHJpbmcocmUpID09PSAnW29iamVjdCBSZWdFeHBdJztcbn1cbmV4cG9ydHMuaXNSZWdFeHAgPSBpc1JlZ0V4cDtcblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuZXhwb3J0cy5pc0RhdGUgPSBpc0RhdGU7XG5cbmZ1bmN0aW9uIGlzRXJyb3IoZSkge1xuICByZXR1cm4gKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG59XG5leHBvcnRzLmlzRXJyb3IgPSBpc0Vycm9yO1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnYm9vbGVhbicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdudW1iZXInIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCcgfHwgIC8vIEVTNiBzeW1ib2xcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnO1xufVxuZXhwb3J0cy5pc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlO1xuXG5leHBvcnRzLmlzQnVmZmVyID0gQnVmZmVyLmlzQnVmZmVyO1xuXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7XG59XG4iLCJ2YXIgZWxsaXB0aWMgPSByZXF1aXJlKCdlbGxpcHRpYycpXG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY3JlYXRlRUNESCAoY3VydmUpIHtcbiAgcmV0dXJuIG5ldyBFQ0RIKGN1cnZlKVxufVxuXG52YXIgYWxpYXNlcyA9IHtcbiAgc2VjcDI1NmsxOiB7XG4gICAgbmFtZTogJ3NlY3AyNTZrMScsXG4gICAgYnl0ZUxlbmd0aDogMzJcbiAgfSxcbiAgc2VjcDIyNHIxOiB7XG4gICAgbmFtZTogJ3AyMjQnLFxuICAgIGJ5dGVMZW5ndGg6IDI4XG4gIH0sXG4gIHByaW1lMjU2djE6IHtcbiAgICBuYW1lOiAncDI1NicsXG4gICAgYnl0ZUxlbmd0aDogMzJcbiAgfSxcbiAgcHJpbWUxOTJ2MToge1xuICAgIG5hbWU6ICdwMTkyJyxcbiAgICBieXRlTGVuZ3RoOiAyNFxuICB9LFxuICBlZDI1NTE5OiB7XG4gICAgbmFtZTogJ2VkMjU1MTknLFxuICAgIGJ5dGVMZW5ndGg6IDMyXG4gIH0sXG4gIHNlY3AzODRyMToge1xuICAgIG5hbWU6ICdwMzg0JyxcbiAgICBieXRlTGVuZ3RoOiA0OFxuICB9LFxuICBzZWNwNTIxcjE6IHtcbiAgICBuYW1lOiAncDUyMScsXG4gICAgYnl0ZUxlbmd0aDogNjZcbiAgfVxufVxuXG5hbGlhc2VzLnAyMjQgPSBhbGlhc2VzLnNlY3AyMjRyMVxuYWxpYXNlcy5wMjU2ID0gYWxpYXNlcy5zZWNwMjU2cjEgPSBhbGlhc2VzLnByaW1lMjU2djFcbmFsaWFzZXMucDE5MiA9IGFsaWFzZXMuc2VjcDE5MnIxID0gYWxpYXNlcy5wcmltZTE5MnYxXG5hbGlhc2VzLnAzODQgPSBhbGlhc2VzLnNlY3AzODRyMVxuYWxpYXNlcy5wNTIxID0gYWxpYXNlcy5zZWNwNTIxcjFcblxuZnVuY3Rpb24gRUNESCAoY3VydmUpIHtcbiAgdGhpcy5jdXJ2ZVR5cGUgPSBhbGlhc2VzW2N1cnZlXVxuICBpZiAoIXRoaXMuY3VydmVUeXBlKSB7XG4gICAgdGhpcy5jdXJ2ZVR5cGUgPSB7XG4gICAgICBuYW1lOiBjdXJ2ZVxuICAgIH1cbiAgfVxuICB0aGlzLmN1cnZlID0gbmV3IGVsbGlwdGljLmVjKHRoaXMuY3VydmVUeXBlLm5hbWUpIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbmV3LWNhcFxuICB0aGlzLmtleXMgPSB2b2lkIDBcbn1cblxuRUNESC5wcm90b3R5cGUuZ2VuZXJhdGVLZXlzID0gZnVuY3Rpb24gKGVuYywgZm9ybWF0KSB7XG4gIHRoaXMua2V5cyA9IHRoaXMuY3VydmUuZ2VuS2V5UGFpcigpXG4gIHJldHVybiB0aGlzLmdldFB1YmxpY0tleShlbmMsIGZvcm1hdClcbn1cblxuRUNESC5wcm90b3R5cGUuY29tcHV0ZVNlY3JldCA9IGZ1bmN0aW9uIChvdGhlciwgaW5lbmMsIGVuYykge1xuICBpbmVuYyA9IGluZW5jIHx8ICd1dGY4J1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihvdGhlcikpIHtcbiAgICBvdGhlciA9IG5ldyBCdWZmZXIob3RoZXIsIGluZW5jKVxuICB9XG4gIHZhciBvdGhlclB1YiA9IHRoaXMuY3VydmUua2V5RnJvbVB1YmxpYyhvdGhlcikuZ2V0UHVibGljKClcbiAgdmFyIG91dCA9IG90aGVyUHViLm11bCh0aGlzLmtleXMuZ2V0UHJpdmF0ZSgpKS5nZXRYKClcbiAgcmV0dXJuIGZvcm1hdFJldHVyblZhbHVlKG91dCwgZW5jLCB0aGlzLmN1cnZlVHlwZS5ieXRlTGVuZ3RoKVxufVxuXG5FQ0RILnByb3RvdHlwZS5nZXRQdWJsaWNLZXkgPSBmdW5jdGlvbiAoZW5jLCBmb3JtYXQpIHtcbiAgdmFyIGtleSA9IHRoaXMua2V5cy5nZXRQdWJsaWMoZm9ybWF0ID09PSAnY29tcHJlc3NlZCcsIHRydWUpXG4gIGlmIChmb3JtYXQgPT09ICdoeWJyaWQnKSB7XG4gICAgaWYgKGtleVtrZXkubGVuZ3RoIC0gMV0gJSAyKSB7XG4gICAgICBrZXlbMF0gPSA3XG4gICAgfSBlbHNlIHtcbiAgICAgIGtleVswXSA9IDZcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZvcm1hdFJldHVyblZhbHVlKGtleSwgZW5jKVxufVxuXG5FQ0RILnByb3RvdHlwZS5nZXRQcml2YXRlS2V5ID0gZnVuY3Rpb24gKGVuYykge1xuICByZXR1cm4gZm9ybWF0UmV0dXJuVmFsdWUodGhpcy5rZXlzLmdldFByaXZhdGUoKSwgZW5jKVxufVxuXG5FQ0RILnByb3RvdHlwZS5zZXRQdWJsaWNLZXkgPSBmdW5jdGlvbiAocHViLCBlbmMpIHtcbiAgZW5jID0gZW5jIHx8ICd1dGY4J1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihwdWIpKSB7XG4gICAgcHViID0gbmV3IEJ1ZmZlcihwdWIsIGVuYylcbiAgfVxuICB0aGlzLmtleXMuX2ltcG9ydFB1YmxpYyhwdWIpXG4gIHJldHVybiB0aGlzXG59XG5cbkVDREgucHJvdG90eXBlLnNldFByaXZhdGVLZXkgPSBmdW5jdGlvbiAocHJpdiwgZW5jKSB7XG4gIGVuYyA9IGVuYyB8fCAndXRmOCdcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIocHJpdikpIHtcbiAgICBwcml2ID0gbmV3IEJ1ZmZlcihwcml2LCBlbmMpXG4gIH1cblxuICB2YXIgX3ByaXYgPSBuZXcgQk4ocHJpdilcbiAgX3ByaXYgPSBfcHJpdi50b1N0cmluZygxNilcbiAgdGhpcy5rZXlzID0gdGhpcy5jdXJ2ZS5nZW5LZXlQYWlyKClcbiAgdGhpcy5rZXlzLl9pbXBvcnRQcml2YXRlKF9wcml2KVxuICByZXR1cm4gdGhpc1xufVxuXG5mdW5jdGlvbiBmb3JtYXRSZXR1cm5WYWx1ZSAoYm4sIGVuYywgbGVuKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShibikpIHtcbiAgICBibiA9IGJuLnRvQXJyYXkoKVxuICB9XG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKGJuKVxuICBpZiAobGVuICYmIGJ1Zi5sZW5ndGggPCBsZW4pIHtcbiAgICB2YXIgemVyb3MgPSBuZXcgQnVmZmVyKGxlbiAtIGJ1Zi5sZW5ndGgpXG4gICAgemVyb3MuZmlsbCgwKVxuICAgIGJ1ZiA9IEJ1ZmZlci5jb25jYXQoW3plcm9zLCBidWZdKVxuICB9XG4gIGlmICghZW5jKSB7XG4gICAgcmV0dXJuIGJ1ZlxuICB9IGVsc2Uge1xuICAgIHJldHVybiBidWYudG9TdHJpbmcoZW5jKVxuICB9XG59XG4iLCIndXNlIHN0cmljdCdcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBNRDUgPSByZXF1aXJlKCdtZDUuanMnKVxudmFyIFJJUEVNRDE2MCA9IHJlcXVpcmUoJ3JpcGVtZDE2MCcpXG52YXIgc2hhID0gcmVxdWlyZSgnc2hhLmpzJylcbnZhciBCYXNlID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxuXG5mdW5jdGlvbiBIYXNoIChoYXNoKSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnZGlnZXN0JylcblxuICB0aGlzLl9oYXNoID0gaGFzaFxufVxuXG5pbmhlcml0cyhIYXNoLCBCYXNlKVxuXG5IYXNoLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5faGFzaC51cGRhdGUoZGF0YSlcbn1cblxuSGFzaC5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5faGFzaC5kaWdlc3QoKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNyZWF0ZUhhc2ggKGFsZykge1xuICBhbGcgPSBhbGcudG9Mb3dlckNhc2UoKVxuICBpZiAoYWxnID09PSAnbWQ1JykgcmV0dXJuIG5ldyBNRDUoKVxuICBpZiAoYWxnID09PSAncm1kMTYwJyB8fCBhbGcgPT09ICdyaXBlbWQxNjAnKSByZXR1cm4gbmV3IFJJUEVNRDE2MCgpXG5cbiAgcmV0dXJuIG5ldyBIYXNoKHNoYShhbGcpKVxufVxuIiwidmFyIE1ENSA9IHJlcXVpcmUoJ21kNS5qcycpXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGJ1ZmZlcikge1xuICByZXR1cm4gbmV3IE1ENSgpLnVwZGF0ZShidWZmZXIpLmRpZ2VzdCgpXG59XG4iLCIndXNlIHN0cmljdCdcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBMZWdhY3kgPSByZXF1aXJlKCcuL2xlZ2FjeScpXG52YXIgQmFzZSA9IHJlcXVpcmUoJ2NpcGhlci1iYXNlJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxudmFyIG1kNSA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoL21kNScpXG52YXIgUklQRU1EMTYwID0gcmVxdWlyZSgncmlwZW1kMTYwJylcblxudmFyIHNoYSA9IHJlcXVpcmUoJ3NoYS5qcycpXG5cbnZhciBaRVJPUyA9IEJ1ZmZlci5hbGxvYygxMjgpXG5cbmZ1bmN0aW9uIEhtYWMgKGFsZywga2V5KSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnZGlnZXN0JylcbiAgaWYgKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnKSB7XG4gICAga2V5ID0gQnVmZmVyLmZyb20oa2V5KVxuICB9XG5cbiAgdmFyIGJsb2Nrc2l6ZSA9IChhbGcgPT09ICdzaGE1MTInIHx8IGFsZyA9PT0gJ3NoYTM4NCcpID8gMTI4IDogNjRcblxuICB0aGlzLl9hbGcgPSBhbGdcbiAgdGhpcy5fa2V5ID0ga2V5XG4gIGlmIChrZXkubGVuZ3RoID4gYmxvY2tzaXplKSB7XG4gICAgdmFyIGhhc2ggPSBhbGcgPT09ICdybWQxNjAnID8gbmV3IFJJUEVNRDE2MCgpIDogc2hhKGFsZylcbiAgICBrZXkgPSBoYXNoLnVwZGF0ZShrZXkpLmRpZ2VzdCgpXG4gIH0gZWxzZSBpZiAoa2V5Lmxlbmd0aCA8IGJsb2Nrc2l6ZSkge1xuICAgIGtleSA9IEJ1ZmZlci5jb25jYXQoW2tleSwgWkVST1NdLCBibG9ja3NpemUpXG4gIH1cblxuICB2YXIgaXBhZCA9IHRoaXMuX2lwYWQgPSBCdWZmZXIuYWxsb2NVbnNhZmUoYmxvY2tzaXplKVxuICB2YXIgb3BhZCA9IHRoaXMuX29wYWQgPSBCdWZmZXIuYWxsb2NVbnNhZmUoYmxvY2tzaXplKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tzaXplOyBpKyspIHtcbiAgICBpcGFkW2ldID0ga2V5W2ldIF4gMHgzNlxuICAgIG9wYWRbaV0gPSBrZXlbaV0gXiAweDVDXG4gIH1cbiAgdGhpcy5faGFzaCA9IGFsZyA9PT0gJ3JtZDE2MCcgPyBuZXcgUklQRU1EMTYwKCkgOiBzaGEoYWxnKVxuICB0aGlzLl9oYXNoLnVwZGF0ZShpcGFkKVxufVxuXG5pbmhlcml0cyhIbWFjLCBCYXNlKVxuXG5IbWFjLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5faGFzaC51cGRhdGUoZGF0YSlcbn1cblxuSG1hYy5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaCA9IHRoaXMuX2hhc2guZGlnZXN0KClcbiAgdmFyIGhhc2ggPSB0aGlzLl9hbGcgPT09ICdybWQxNjAnID8gbmV3IFJJUEVNRDE2MCgpIDogc2hhKHRoaXMuX2FsZylcbiAgcmV0dXJuIGhhc2gudXBkYXRlKHRoaXMuX29wYWQpLnVwZGF0ZShoKS5kaWdlc3QoKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNyZWF0ZUhtYWMgKGFsZywga2V5KSB7XG4gIGFsZyA9IGFsZy50b0xvd2VyQ2FzZSgpXG4gIGlmIChhbGcgPT09ICdybWQxNjAnIHx8IGFsZyA9PT0gJ3JpcGVtZDE2MCcpIHtcbiAgICByZXR1cm4gbmV3IEhtYWMoJ3JtZDE2MCcsIGtleSlcbiAgfVxuICBpZiAoYWxnID09PSAnbWQ1Jykge1xuICAgIHJldHVybiBuZXcgTGVnYWN5KG1kNSwga2V5KVxuICB9XG4gIHJldHVybiBuZXcgSG1hYyhhbGcsIGtleSlcbn1cbiIsIid1c2Ugc3RyaWN0J1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG5cbnZhciBCYXNlID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxuXG52YXIgWkVST1MgPSBCdWZmZXIuYWxsb2MoMTI4KVxudmFyIGJsb2Nrc2l6ZSA9IDY0XG5cbmZ1bmN0aW9uIEhtYWMgKGFsZywga2V5KSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnZGlnZXN0JylcbiAgaWYgKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnKSB7XG4gICAga2V5ID0gQnVmZmVyLmZyb20oa2V5KVxuICB9XG5cbiAgdGhpcy5fYWxnID0gYWxnXG4gIHRoaXMuX2tleSA9IGtleVxuXG4gIGlmIChrZXkubGVuZ3RoID4gYmxvY2tzaXplKSB7XG4gICAga2V5ID0gYWxnKGtleSlcbiAgfSBlbHNlIGlmIChrZXkubGVuZ3RoIDwgYmxvY2tzaXplKSB7XG4gICAga2V5ID0gQnVmZmVyLmNvbmNhdChba2V5LCBaRVJPU10sIGJsb2Nrc2l6ZSlcbiAgfVxuXG4gIHZhciBpcGFkID0gdGhpcy5faXBhZCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShibG9ja3NpemUpXG4gIHZhciBvcGFkID0gdGhpcy5fb3BhZCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShibG9ja3NpemUpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja3NpemU7IGkrKykge1xuICAgIGlwYWRbaV0gPSBrZXlbaV0gXiAweDM2XG4gICAgb3BhZFtpXSA9IGtleVtpXSBeIDB4NUNcbiAgfVxuXG4gIHRoaXMuX2hhc2ggPSBbaXBhZF1cbn1cblxuaW5oZXJpdHMoSG1hYywgQmFzZSlcblxuSG1hYy5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuX2hhc2gucHVzaChkYXRhKVxufVxuXG5IbWFjLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBoID0gdGhpcy5fYWxnKEJ1ZmZlci5jb25jYXQodGhpcy5faGFzaCkpXG4gIHJldHVybiB0aGlzLl9hbGcoQnVmZmVyLmNvbmNhdChbdGhpcy5fb3BhZCwgaF0pKVxufVxubW9kdWxlLmV4cG9ydHMgPSBIbWFjXG4iLCIndXNlIHN0cmljdCdcblxuZXhwb3J0cy5yYW5kb21CeXRlcyA9IGV4cG9ydHMucm5nID0gZXhwb3J0cy5wc2V1ZG9SYW5kb21CeXRlcyA9IGV4cG9ydHMucHJuZyA9IHJlcXVpcmUoJ3JhbmRvbWJ5dGVzJylcbmV4cG9ydHMuY3JlYXRlSGFzaCA9IGV4cG9ydHMuSGFzaCA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoJylcbmV4cG9ydHMuY3JlYXRlSG1hYyA9IGV4cG9ydHMuSG1hYyA9IHJlcXVpcmUoJ2NyZWF0ZS1obWFjJylcblxudmFyIGFsZ29zID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1zaWduL2FsZ29zJylcbnZhciBhbGdvS2V5cyA9IE9iamVjdC5rZXlzKGFsZ29zKVxudmFyIGhhc2hlcyA9IFsnc2hhMScsICdzaGEyMjQnLCAnc2hhMjU2JywgJ3NoYTM4NCcsICdzaGE1MTInLCAnbWQ1JywgJ3JtZDE2MCddLmNvbmNhdChhbGdvS2V5cylcbmV4cG9ydHMuZ2V0SGFzaGVzID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gaGFzaGVzXG59XG5cbnZhciBwID0gcmVxdWlyZSgncGJrZGYyJylcbmV4cG9ydHMucGJrZGYyID0gcC5wYmtkZjJcbmV4cG9ydHMucGJrZGYyU3luYyA9IHAucGJrZGYyU3luY1xuXG52YXIgYWVzID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1jaXBoZXInKVxuXG5leHBvcnRzLkNpcGhlciA9IGFlcy5DaXBoZXJcbmV4cG9ydHMuY3JlYXRlQ2lwaGVyID0gYWVzLmNyZWF0ZUNpcGhlclxuZXhwb3J0cy5DaXBoZXJpdiA9IGFlcy5DaXBoZXJpdlxuZXhwb3J0cy5jcmVhdGVDaXBoZXJpdiA9IGFlcy5jcmVhdGVDaXBoZXJpdlxuZXhwb3J0cy5EZWNpcGhlciA9IGFlcy5EZWNpcGhlclxuZXhwb3J0cy5jcmVhdGVEZWNpcGhlciA9IGFlcy5jcmVhdGVEZWNpcGhlclxuZXhwb3J0cy5EZWNpcGhlcml2ID0gYWVzLkRlY2lwaGVyaXZcbmV4cG9ydHMuY3JlYXRlRGVjaXBoZXJpdiA9IGFlcy5jcmVhdGVEZWNpcGhlcml2XG5leHBvcnRzLmdldENpcGhlcnMgPSBhZXMuZ2V0Q2lwaGVyc1xuZXhwb3J0cy5saXN0Q2lwaGVycyA9IGFlcy5saXN0Q2lwaGVyc1xuXG52YXIgZGggPSByZXF1aXJlKCdkaWZmaWUtaGVsbG1hbicpXG5cbmV4cG9ydHMuRGlmZmllSGVsbG1hbkdyb3VwID0gZGguRGlmZmllSGVsbG1hbkdyb3VwXG5leHBvcnRzLmNyZWF0ZURpZmZpZUhlbGxtYW5Hcm91cCA9IGRoLmNyZWF0ZURpZmZpZUhlbGxtYW5Hcm91cFxuZXhwb3J0cy5nZXREaWZmaWVIZWxsbWFuID0gZGguZ2V0RGlmZmllSGVsbG1hblxuZXhwb3J0cy5jcmVhdGVEaWZmaWVIZWxsbWFuID0gZGguY3JlYXRlRGlmZmllSGVsbG1hblxuZXhwb3J0cy5EaWZmaWVIZWxsbWFuID0gZGguRGlmZmllSGVsbG1hblxuXG52YXIgc2lnbiA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktc2lnbicpXG5cbmV4cG9ydHMuY3JlYXRlU2lnbiA9IHNpZ24uY3JlYXRlU2lnblxuZXhwb3J0cy5TaWduID0gc2lnbi5TaWduXG5leHBvcnRzLmNyZWF0ZVZlcmlmeSA9IHNpZ24uY3JlYXRlVmVyaWZ5XG5leHBvcnRzLlZlcmlmeSA9IHNpZ24uVmVyaWZ5XG5cbmV4cG9ydHMuY3JlYXRlRUNESCA9IHJlcXVpcmUoJ2NyZWF0ZS1lY2RoJylcblxudmFyIHB1YmxpY0VuY3J5cHQgPSByZXF1aXJlKCdwdWJsaWMtZW5jcnlwdCcpXG5cbmV4cG9ydHMucHVibGljRW5jcnlwdCA9IHB1YmxpY0VuY3J5cHQucHVibGljRW5jcnlwdFxuZXhwb3J0cy5wcml2YXRlRW5jcnlwdCA9IHB1YmxpY0VuY3J5cHQucHJpdmF0ZUVuY3J5cHRcbmV4cG9ydHMucHVibGljRGVjcnlwdCA9IHB1YmxpY0VuY3J5cHQucHVibGljRGVjcnlwdFxuZXhwb3J0cy5wcml2YXRlRGVjcnlwdCA9IHB1YmxpY0VuY3J5cHQucHJpdmF0ZURlY3J5cHRcblxuLy8gdGhlIGxlYXN0IEkgY2FuIGRvIGlzIG1ha2UgZXJyb3IgbWVzc2FnZXMgZm9yIHRoZSByZXN0IG9mIHRoZSBub2RlLmpzL2NyeXB0byBhcGkuXG4vLyA7W1xuLy8gICAnY3JlYXRlQ3JlZGVudGlhbHMnXG4vLyBdLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbi8vICAgZXhwb3J0c1tuYW1lXSA9IGZ1bmN0aW9uICgpIHtcbi8vICAgICB0aHJvdyBuZXcgRXJyb3IoW1xuLy8gICAgICAgJ3NvcnJ5LCAnICsgbmFtZSArICcgaXMgbm90IGltcGxlbWVudGVkIHlldCcsXG4vLyAgICAgICAnd2UgYWNjZXB0IHB1bGwgcmVxdWVzdHMnLFxuLy8gICAgICAgJ2h0dHBzOi8vZ2l0aHViLmNvbS9jcnlwdG8tYnJvd3NlcmlmeS9jcnlwdG8tYnJvd3NlcmlmeSdcbi8vICAgICBdLmpvaW4oJ1xcbicpKVxuLy8gICB9XG4vLyB9KVxuXG52YXIgcmYgPSByZXF1aXJlKCdyYW5kb21maWxsJylcblxuZXhwb3J0cy5yYW5kb21GaWxsID0gcmYucmFuZG9tRmlsbFxuZXhwb3J0cy5yYW5kb21GaWxsU3luYyA9IHJmLnJhbmRvbUZpbGxTeW5jXG5cbmV4cG9ydHMuY3JlYXRlQ3JlZGVudGlhbHMgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcihbXG4gICAgJ3NvcnJ5LCBjcmVhdGVDcmVkZW50aWFscyBpcyBub3QgaW1wbGVtZW50ZWQgeWV0JyxcbiAgICAnd2UgYWNjZXB0IHB1bGwgcmVxdWVzdHMnLFxuICAgICdodHRwczovL2dpdGh1Yi5jb20vY3J5cHRvLWJyb3dzZXJpZnkvY3J5cHRvLWJyb3dzZXJpZnknXG4gIF0uam9pbignXFxuJykpXG59XG5cbmV4cG9ydHMuY29uc3RhbnRzID0ge1xuICAnREhfQ0hFQ0tfUF9OT1RfU0FGRV9QUklNRSc6IDIsXG4gICdESF9DSEVDS19QX05PVF9QUklNRSc6IDEsXG4gICdESF9VTkFCTEVfVE9fQ0hFQ0tfR0VORVJBVE9SJzogNCxcbiAgJ0RIX05PVF9TVUlUQUJMRV9HRU5FUkFUT1InOiA4LFxuICAnTlBOX0VOQUJMRUQnOiAxLFxuICAnQUxQTl9FTkFCTEVEJzogMSxcbiAgJ1JTQV9QS0NTMV9QQURESU5HJzogMSxcbiAgJ1JTQV9TU0xWMjNfUEFERElORyc6IDIsXG4gICdSU0FfTk9fUEFERElORyc6IDMsXG4gICdSU0FfUEtDUzFfT0FFUF9QQURESU5HJzogNCxcbiAgJ1JTQV9YOTMxX1BBRERJTkcnOiA1LFxuICAnUlNBX1BLQ1MxX1BTU19QQURESU5HJzogNixcbiAgJ1BPSU5UX0NPTlZFUlNJT05fQ09NUFJFU1NFRCc6IDIsXG4gICdQT0lOVF9DT05WRVJTSU9OX1VOQ09NUFJFU1NFRCc6IDQsXG4gICdQT0lOVF9DT05WRVJTSU9OX0hZQlJJRCc6IDZcbn1cbiIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7XG5cdGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xuXHRcdC8vIENvbW1vbkpTXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKFwiLi9jb3JlXCIpLCByZXF1aXJlKFwiLi9lbmMtYmFzZTY0XCIpLCByZXF1aXJlKFwiLi9tZDVcIiksIHJlcXVpcmUoXCIuL2V2cGtkZlwiKSwgcmVxdWlyZShcIi4vY2lwaGVyLWNvcmVcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiLCBcIi4vZW5jLWJhc2U2NFwiLCBcIi4vbWQ1XCIsIFwiLi9ldnBrZGZcIiwgXCIuL2NpcGhlci1jb3JlXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQoZnVuY3Rpb24gKCkge1xuXHQgICAgLy8gU2hvcnRjdXRzXG5cdCAgICB2YXIgQyA9IENyeXB0b0pTO1xuXHQgICAgdmFyIENfbGliID0gQy5saWI7XG5cdCAgICB2YXIgQmxvY2tDaXBoZXIgPSBDX2xpYi5CbG9ja0NpcGhlcjtcblx0ICAgIHZhciBDX2FsZ28gPSBDLmFsZ287XG5cblx0ICAgIC8vIExvb2t1cCB0YWJsZXNcblx0ICAgIHZhciBTQk9YID0gW107XG5cdCAgICB2YXIgSU5WX1NCT1ggPSBbXTtcblx0ICAgIHZhciBTVUJfTUlYXzAgPSBbXTtcblx0ICAgIHZhciBTVUJfTUlYXzEgPSBbXTtcblx0ICAgIHZhciBTVUJfTUlYXzIgPSBbXTtcblx0ICAgIHZhciBTVUJfTUlYXzMgPSBbXTtcblx0ICAgIHZhciBJTlZfU1VCX01JWF8wID0gW107XG5cdCAgICB2YXIgSU5WX1NVQl9NSVhfMSA9IFtdO1xuXHQgICAgdmFyIElOVl9TVUJfTUlYXzIgPSBbXTtcblx0ICAgIHZhciBJTlZfU1VCX01JWF8zID0gW107XG5cblx0ICAgIC8vIENvbXB1dGUgbG9va3VwIHRhYmxlc1xuXHQgICAgKGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAvLyBDb21wdXRlIGRvdWJsZSB0YWJsZVxuXHQgICAgICAgIHZhciBkID0gW107XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuXHQgICAgICAgICAgICBpZiAoaSA8IDEyOCkge1xuXHQgICAgICAgICAgICAgICAgZFtpXSA9IGkgPDwgMTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIGRbaV0gPSAoaSA8PCAxKSBeIDB4MTFiO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLy8gV2FsayBHRigyXjgpXG5cdCAgICAgICAgdmFyIHggPSAwO1xuXHQgICAgICAgIHZhciB4aSA9IDA7XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuXHQgICAgICAgICAgICAvLyBDb21wdXRlIHNib3hcblx0ICAgICAgICAgICAgdmFyIHN4ID0geGkgXiAoeGkgPDwgMSkgXiAoeGkgPDwgMikgXiAoeGkgPDwgMykgXiAoeGkgPDwgNCk7XG5cdCAgICAgICAgICAgIHN4ID0gKHN4ID4+PiA4KSBeIChzeCAmIDB4ZmYpIF4gMHg2Mztcblx0ICAgICAgICAgICAgU0JPWFt4XSA9IHN4O1xuXHQgICAgICAgICAgICBJTlZfU0JPWFtzeF0gPSB4O1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGUgbXVsdGlwbGljYXRpb25cblx0ICAgICAgICAgICAgdmFyIHgyID0gZFt4XTtcblx0ICAgICAgICAgICAgdmFyIHg0ID0gZFt4Ml07XG5cdCAgICAgICAgICAgIHZhciB4OCA9IGRbeDRdO1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGUgc3ViIGJ5dGVzLCBtaXggY29sdW1ucyB0YWJsZXNcblx0ICAgICAgICAgICAgdmFyIHQgPSAoZFtzeF0gKiAweDEwMSkgXiAoc3ggKiAweDEwMTAxMDApO1xuXHQgICAgICAgICAgICBTVUJfTUlYXzBbeF0gPSAodCA8PCAyNCkgfCAodCA+Pj4gOCk7XG5cdCAgICAgICAgICAgIFNVQl9NSVhfMVt4XSA9ICh0IDw8IDE2KSB8ICh0ID4+PiAxNik7XG5cdCAgICAgICAgICAgIFNVQl9NSVhfMlt4XSA9ICh0IDw8IDgpICB8ICh0ID4+PiAyNCk7XG5cdCAgICAgICAgICAgIFNVQl9NSVhfM1t4XSA9IHQ7XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0ZSBpbnYgc3ViIGJ5dGVzLCBpbnYgbWl4IGNvbHVtbnMgdGFibGVzXG5cdCAgICAgICAgICAgIHZhciB0ID0gKHg4ICogMHgxMDEwMTAxKSBeICh4NCAqIDB4MTAwMDEpIF4gKHgyICogMHgxMDEpIF4gKHggKiAweDEwMTAxMDApO1xuXHQgICAgICAgICAgICBJTlZfU1VCX01JWF8wW3N4XSA9ICh0IDw8IDI0KSB8ICh0ID4+PiA4KTtcblx0ICAgICAgICAgICAgSU5WX1NVQl9NSVhfMVtzeF0gPSAodCA8PCAxNikgfCAodCA+Pj4gMTYpO1xuXHQgICAgICAgICAgICBJTlZfU1VCX01JWF8yW3N4XSA9ICh0IDw8IDgpICB8ICh0ID4+PiAyNCk7XG5cdCAgICAgICAgICAgIElOVl9TVUJfTUlYXzNbc3hdID0gdDtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIG5leHQgY291bnRlclxuXHQgICAgICAgICAgICBpZiAoIXgpIHtcblx0ICAgICAgICAgICAgICAgIHggPSB4aSA9IDE7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICB4ID0geDIgXiBkW2RbZFt4OCBeIHgyXV1dO1xuXHQgICAgICAgICAgICAgICAgeGkgXj0gZFtkW3hpXV07XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9KCkpO1xuXG5cdCAgICAvLyBQcmVjb21wdXRlZCBSY29uIGxvb2t1cFxuXHQgICAgdmFyIFJDT04gPSBbMHgwMCwgMHgwMSwgMHgwMiwgMHgwNCwgMHgwOCwgMHgxMCwgMHgyMCwgMHg0MCwgMHg4MCwgMHgxYiwgMHgzNl07XG5cblx0ICAgIC8qKlxuXHQgICAgICogQUVTIGJsb2NrIGNpcGhlciBhbGdvcml0aG0uXG5cdCAgICAgKi9cblx0ICAgIHZhciBBRVMgPSBDX2FsZ28uQUVTID0gQmxvY2tDaXBoZXIuZXh0ZW5kKHtcblx0ICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgdDtcblxuXHQgICAgICAgICAgICAvLyBTa2lwIHJlc2V0IG9mIG5Sb3VuZHMgaGFzIGJlZW4gc2V0IGJlZm9yZSBhbmQga2V5IGRpZCBub3QgY2hhbmdlXG5cdCAgICAgICAgICAgIGlmICh0aGlzLl9uUm91bmRzICYmIHRoaXMuX2tleVByaW9yUmVzZXQgPT09IHRoaXMuX2tleSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBrZXkgPSB0aGlzLl9rZXlQcmlvclJlc2V0ID0gdGhpcy5fa2V5O1xuXHQgICAgICAgICAgICB2YXIga2V5V29yZHMgPSBrZXkud29yZHM7XG5cdCAgICAgICAgICAgIHZhciBrZXlTaXplID0ga2V5LnNpZ0J5dGVzIC8gNDtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIG51bWJlciBvZiByb3VuZHNcblx0ICAgICAgICAgICAgdmFyIG5Sb3VuZHMgPSB0aGlzLl9uUm91bmRzID0ga2V5U2l6ZSArIDY7XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0ZSBudW1iZXIgb2Yga2V5IHNjaGVkdWxlIHJvd3Ncblx0ICAgICAgICAgICAgdmFyIGtzUm93cyA9IChuUm91bmRzICsgMSkgKiA0O1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGUga2V5IHNjaGVkdWxlXG5cdCAgICAgICAgICAgIHZhciBrZXlTY2hlZHVsZSA9IHRoaXMuX2tleVNjaGVkdWxlID0gW107XG5cdCAgICAgICAgICAgIGZvciAodmFyIGtzUm93ID0gMDsga3NSb3cgPCBrc1Jvd3M7IGtzUm93KyspIHtcblx0ICAgICAgICAgICAgICAgIGlmIChrc1JvdyA8IGtleVNpemUpIHtcblx0ICAgICAgICAgICAgICAgICAgICBrZXlTY2hlZHVsZVtrc1Jvd10gPSBrZXlXb3Jkc1trc1Jvd107XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIHQgPSBrZXlTY2hlZHVsZVtrc1JvdyAtIDFdO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKCEoa3NSb3cgJSBrZXlTaXplKSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAvLyBSb3Qgd29yZFxuXHQgICAgICAgICAgICAgICAgICAgICAgICB0ID0gKHQgPDwgOCkgfCAodCA+Pj4gMjQpO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN1YiB3b3JkXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHQgPSAoU0JPWFt0ID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyh0ID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFt0ICYgMHhmZl07XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWl4IFJjb25cblx0ICAgICAgICAgICAgICAgICAgICAgICAgdCBePSBSQ09OWyhrc1JvdyAvIGtleVNpemUpIHwgMF0gPDwgMjQ7XG5cdCAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChrZXlTaXplID4gNiAmJiBrc1JvdyAlIGtleVNpemUgPT0gNCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWIgd29yZFxuXHQgICAgICAgICAgICAgICAgICAgICAgICB0ID0gKFNCT1hbdCA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyh0ID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsodCA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbdCAmIDB4ZmZdO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgIGtleVNjaGVkdWxlW2tzUm93XSA9IGtleVNjaGVkdWxlW2tzUm93IC0ga2V5U2l6ZV0gXiB0O1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0ZSBpbnYga2V5IHNjaGVkdWxlXG5cdCAgICAgICAgICAgIHZhciBpbnZLZXlTY2hlZHVsZSA9IHRoaXMuX2ludktleVNjaGVkdWxlID0gW107XG5cdCAgICAgICAgICAgIGZvciAodmFyIGludktzUm93ID0gMDsgaW52S3NSb3cgPCBrc1Jvd3M7IGludktzUm93KyspIHtcblx0ICAgICAgICAgICAgICAgIHZhciBrc1JvdyA9IGtzUm93cyAtIGludktzUm93O1xuXG5cdCAgICAgICAgICAgICAgICBpZiAoaW52S3NSb3cgJSA0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIHQgPSBrZXlTY2hlZHVsZVtrc1Jvd107XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciB0ID0ga2V5U2NoZWR1bGVba3NSb3cgLSA0XTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgaWYgKGludktzUm93IDwgNCB8fCBrc1JvdyA8PSA0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgaW52S2V5U2NoZWR1bGVbaW52S3NSb3ddID0gdDtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgaW52S2V5U2NoZWR1bGVbaW52S3NSb3ddID0gSU5WX1NVQl9NSVhfMFtTQk9YW3QgPj4+IDI0XV0gXiBJTlZfU1VCX01JWF8xW1NCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdXSBeXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5WX1NVQl9NSVhfMltTQk9YWyh0ID4+PiA4KSAmIDB4ZmZdXSBeIElOVl9TVUJfTUlYXzNbU0JPWFt0ICYgMHhmZl1dO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGVuY3J5cHRCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCkge1xuXHQgICAgICAgICAgICB0aGlzLl9kb0NyeXB0QmxvY2soTSwgb2Zmc2V0LCB0aGlzLl9rZXlTY2hlZHVsZSwgU1VCX01JWF8wLCBTVUJfTUlYXzEsIFNVQl9NSVhfMiwgU1VCX01JWF8zLCBTQk9YKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgZGVjcnlwdEJsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7XG5cdCAgICAgICAgICAgIC8vIFN3YXAgMm5kIGFuZCA0dGggcm93c1xuXHQgICAgICAgICAgICB2YXIgdCA9IE1bb2Zmc2V0ICsgMV07XG5cdCAgICAgICAgICAgIE1bb2Zmc2V0ICsgMV0gPSBNW29mZnNldCArIDNdO1xuXHQgICAgICAgICAgICBNW29mZnNldCArIDNdID0gdDtcblxuXHQgICAgICAgICAgICB0aGlzLl9kb0NyeXB0QmxvY2soTSwgb2Zmc2V0LCB0aGlzLl9pbnZLZXlTY2hlZHVsZSwgSU5WX1NVQl9NSVhfMCwgSU5WX1NVQl9NSVhfMSwgSU5WX1NVQl9NSVhfMiwgSU5WX1NVQl9NSVhfMywgSU5WX1NCT1gpO1xuXG5cdCAgICAgICAgICAgIC8vIEludiBzd2FwIDJuZCBhbmQgNHRoIHJvd3Ncblx0ICAgICAgICAgICAgdmFyIHQgPSBNW29mZnNldCArIDFdO1xuXHQgICAgICAgICAgICBNW29mZnNldCArIDFdID0gTVtvZmZzZXQgKyAzXTtcblx0ICAgICAgICAgICAgTVtvZmZzZXQgKyAzXSA9IHQ7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIF9kb0NyeXB0QmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQsIGtleVNjaGVkdWxlLCBTVUJfTUlYXzAsIFNVQl9NSVhfMSwgU1VCX01JWF8yLCBTVUJfTUlYXzMsIFNCT1gpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIG5Sb3VuZHMgPSB0aGlzLl9uUm91bmRzO1xuXG5cdCAgICAgICAgICAgIC8vIEdldCBpbnB1dCwgYWRkIHJvdW5kIGtleVxuXHQgICAgICAgICAgICB2YXIgczAgPSBNW29mZnNldF0gICAgIF4ga2V5U2NoZWR1bGVbMF07XG5cdCAgICAgICAgICAgIHZhciBzMSA9IE1bb2Zmc2V0ICsgMV0gXiBrZXlTY2hlZHVsZVsxXTtcblx0ICAgICAgICAgICAgdmFyIHMyID0gTVtvZmZzZXQgKyAyXSBeIGtleVNjaGVkdWxlWzJdO1xuXHQgICAgICAgICAgICB2YXIgczMgPSBNW29mZnNldCArIDNdIF4ga2V5U2NoZWR1bGVbM107XG5cblx0ICAgICAgICAgICAgLy8gS2V5IHNjaGVkdWxlIHJvdyBjb3VudGVyXG5cdCAgICAgICAgICAgIHZhciBrc1JvdyA9IDQ7XG5cblx0ICAgICAgICAgICAgLy8gUm91bmRzXG5cdCAgICAgICAgICAgIGZvciAodmFyIHJvdW5kID0gMTsgcm91bmQgPCBuUm91bmRzOyByb3VuZCsrKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBTaGlmdCByb3dzLCBzdWIgYnl0ZXMsIG1peCBjb2x1bW5zLCBhZGQgcm91bmQga2V5XG5cdCAgICAgICAgICAgICAgICB2YXIgdDAgPSBTVUJfTUlYXzBbczAgPj4+IDI0XSBeIFNVQl9NSVhfMVsoczEgPj4+IDE2KSAmIDB4ZmZdIF4gU1VCX01JWF8yWyhzMiA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhfM1tzMyAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK107XG5cdCAgICAgICAgICAgICAgICB2YXIgdDEgPSBTVUJfTUlYXzBbczEgPj4+IDI0XSBeIFNVQl9NSVhfMVsoczIgPj4+IDE2KSAmIDB4ZmZdIF4gU1VCX01JWF8yWyhzMyA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhfM1tzMCAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK107XG5cdCAgICAgICAgICAgICAgICB2YXIgdDIgPSBTVUJfTUlYXzBbczIgPj4+IDI0XSBeIFNVQl9NSVhfMVsoczMgPj4+IDE2KSAmIDB4ZmZdIF4gU1VCX01JWF8yWyhzMCA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhfM1tzMSAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK107XG5cdCAgICAgICAgICAgICAgICB2YXIgdDMgPSBTVUJfTUlYXzBbczMgPj4+IDI0XSBeIFNVQl9NSVhfMVsoczAgPj4+IDE2KSAmIDB4ZmZdIF4gU1VCX01JWF8yWyhzMSA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhfM1tzMiAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK107XG5cblx0ICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBzdGF0ZVxuXHQgICAgICAgICAgICAgICAgczAgPSB0MDtcblx0ICAgICAgICAgICAgICAgIHMxID0gdDE7XG5cdCAgICAgICAgICAgICAgICBzMiA9IHQyO1xuXHQgICAgICAgICAgICAgICAgczMgPSB0Mztcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIFNoaWZ0IHJvd3MsIHN1YiBieXRlcywgYWRkIHJvdW5kIGtleVxuXHQgICAgICAgICAgICB2YXIgdDAgPSAoKFNCT1hbczAgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczEgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMiA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczMgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblx0ICAgICAgICAgICAgdmFyIHQxID0gKChTQk9YW3MxID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMyID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczMgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MwICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK107XG5cdCAgICAgICAgICAgIHZhciB0MiA9ICgoU0JPWFtzMiA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMyA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMwID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMSAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdO1xuXHQgICAgICAgICAgICB2YXIgdDMgPSAoKFNCT1hbczMgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczAgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMSA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczIgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblxuXHQgICAgICAgICAgICAvLyBTZXQgb3V0cHV0XG5cdCAgICAgICAgICAgIE1bb2Zmc2V0XSAgICAgPSB0MDtcblx0ICAgICAgICAgICAgTVtvZmZzZXQgKyAxXSA9IHQxO1xuXHQgICAgICAgICAgICBNW29mZnNldCArIDJdID0gdDI7XG5cdCAgICAgICAgICAgIE1bb2Zmc2V0ICsgM10gPSB0Mztcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAga2V5U2l6ZTogMjU2LzMyXG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbnMgdG8gdGhlIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiAgICAgdmFyIGNpcGhlcnRleHQgPSBDcnlwdG9KUy5BRVMuZW5jcnlwdChtZXNzYWdlLCBrZXksIGNmZyk7XG5cdCAgICAgKiAgICAgdmFyIHBsYWludGV4dCAgPSBDcnlwdG9KUy5BRVMuZGVjcnlwdChjaXBoZXJ0ZXh0LCBrZXksIGNmZyk7XG5cdCAgICAgKi9cblx0ICAgIEMuQUVTID0gQmxvY2tDaXBoZXIuX2NyZWF0ZUhlbHBlcihBRVMpO1xuXHR9KCkpO1xuXG5cblx0cmV0dXJuIENyeXB0b0pTLkFFUztcblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7XG5cdGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xuXHRcdC8vIENvbW1vbkpTXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKFwiLi9jb3JlXCIpLCByZXF1aXJlKFwiLi9ldnBrZGZcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiLCBcIi4vZXZwa2RmXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQvKipcblx0ICogQ2lwaGVyIGNvcmUgY29tcG9uZW50cy5cblx0ICovXG5cdENyeXB0b0pTLmxpYi5DaXBoZXIgfHwgKGZ1bmN0aW9uICh1bmRlZmluZWQpIHtcblx0ICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgdmFyIEMgPSBDcnlwdG9KUztcblx0ICAgIHZhciBDX2xpYiA9IEMubGliO1xuXHQgICAgdmFyIEJhc2UgPSBDX2xpYi5CYXNlO1xuXHQgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTtcblx0ICAgIHZhciBCdWZmZXJlZEJsb2NrQWxnb3JpdGhtID0gQ19saWIuQnVmZmVyZWRCbG9ja0FsZ29yaXRobTtcblx0ICAgIHZhciBDX2VuYyA9IEMuZW5jO1xuXHQgICAgdmFyIFV0ZjggPSBDX2VuYy5VdGY4O1xuXHQgICAgdmFyIEJhc2U2NCA9IENfZW5jLkJhc2U2NDtcblx0ICAgIHZhciBDX2FsZ28gPSBDLmFsZ287XG5cdCAgICB2YXIgRXZwS0RGID0gQ19hbGdvLkV2cEtERjtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBYnN0cmFjdCBiYXNlIGNpcGhlciB0ZW1wbGF0ZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0ga2V5U2l6ZSBUaGlzIGNpcGhlcidzIGtleSBzaXplLiBEZWZhdWx0OiA0ICgxMjggYml0cylcblx0ICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBpdlNpemUgVGhpcyBjaXBoZXIncyBJViBzaXplLiBEZWZhdWx0OiA0ICgxMjggYml0cylcblx0ICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBfRU5DX1hGT1JNX01PREUgQSBjb25zdGFudCByZXByZXNlbnRpbmcgZW5jcnlwdGlvbiBtb2RlLlxuXHQgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IF9ERUNfWEZPUk1fTU9ERSBBIGNvbnN0YW50IHJlcHJlc2VudGluZyBkZWNyeXB0aW9uIG1vZGUuXG5cdCAgICAgKi9cblx0ICAgIHZhciBDaXBoZXIgPSBDX2xpYi5DaXBoZXIgPSBCdWZmZXJlZEJsb2NrQWxnb3JpdGhtLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29uZmlndXJhdGlvbiBvcHRpb25zLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHByb3BlcnR5IHtXb3JkQXJyYXl9IGl2IFRoZSBJViB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLlxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNmZzogQmFzZS5leHRlbmQoKSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENyZWF0ZXMgdGhpcyBjaXBoZXIgaW4gZW5jcnlwdGlvbiBtb2RlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IGtleSBUaGUga2V5LlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBvcGVyYXRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtDaXBoZXJ9IEEgY2lwaGVyIGluc3RhbmNlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVyID0gQ3J5cHRvSlMuYWxnby5BRVMuY3JlYXRlRW5jcnlwdG9yKGtleVdvcmRBcnJheSwgeyBpdjogaXZXb3JkQXJyYXkgfSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY3JlYXRlRW5jcnlwdG9yOiBmdW5jdGlvbiAoa2V5LCBjZmcpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlKHRoaXMuX0VOQ19YRk9STV9NT0RFLCBrZXksIGNmZyk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENyZWF0ZXMgdGhpcyBjaXBoZXIgaW4gZGVjcnlwdGlvbiBtb2RlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IGtleSBUaGUga2V5LlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBvcGVyYXRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtDaXBoZXJ9IEEgY2lwaGVyIGluc3RhbmNlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVyID0gQ3J5cHRvSlMuYWxnby5BRVMuY3JlYXRlRGVjcnlwdG9yKGtleVdvcmRBcnJheSwgeyBpdjogaXZXb3JkQXJyYXkgfSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY3JlYXRlRGVjcnlwdG9yOiBmdW5jdGlvbiAoa2V5LCBjZmcpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlKHRoaXMuX0RFQ19YRk9STV9NT0RFLCBrZXksIGNmZyk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBjaXBoZXIuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0geGZvcm1Nb2RlIEVpdGhlciB0aGUgZW5jcnlwdGlvbiBvciBkZWNyeXB0aW9uIHRyYW5zb3JtYXRpb24gbW9kZSBjb25zdGFudC5cblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkuXG5cdCAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNpcGhlciA9IENyeXB0b0pTLmFsZ28uQUVTLmNyZWF0ZShDcnlwdG9KUy5hbGdvLkFFUy5fRU5DX1hGT1JNX01PREUsIGtleVdvcmRBcnJheSwgeyBpdjogaXZXb3JkQXJyYXkgfSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgaW5pdDogZnVuY3Rpb24gKHhmb3JtTW9kZSwga2V5LCBjZmcpIHtcblx0ICAgICAgICAgICAgLy8gQXBwbHkgY29uZmlnIGRlZmF1bHRzXG5cdCAgICAgICAgICAgIHRoaXMuY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7XG5cblx0ICAgICAgICAgICAgLy8gU3RvcmUgdHJhbnNmb3JtIG1vZGUgYW5kIGtleVxuXHQgICAgICAgICAgICB0aGlzLl94Zm9ybU1vZGUgPSB4Zm9ybU1vZGU7XG5cdCAgICAgICAgICAgIHRoaXMuX2tleSA9IGtleTtcblxuXHQgICAgICAgICAgICAvLyBTZXQgaW5pdGlhbCB2YWx1ZXNcblx0ICAgICAgICAgICAgdGhpcy5yZXNldCgpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBSZXNldHMgdGhpcyBjaXBoZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGNpcGhlci5yZXNldCgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHJlc2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFJlc2V0IGRhdGEgYnVmZmVyXG5cdCAgICAgICAgICAgIEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0ucmVzZXQuY2FsbCh0aGlzKTtcblxuXHQgICAgICAgICAgICAvLyBQZXJmb3JtIGNvbmNyZXRlLWNpcGhlciBsb2dpY1xuXHQgICAgICAgICAgICB0aGlzLl9kb1Jlc2V0KCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEFkZHMgZGF0YSB0byBiZSBlbmNyeXB0ZWQgb3IgZGVjcnlwdGVkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBkYXRhVXBkYXRlIFRoZSBkYXRhIHRvIGVuY3J5cHQgb3IgZGVjcnlwdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRhdGEgYWZ0ZXIgcHJvY2Vzc2luZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGVuY3J5cHRlZCA9IGNpcGhlci5wcm9jZXNzKCdkYXRhJyk7XG5cdCAgICAgICAgICogICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIucHJvY2Vzcyh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHByb2Nlc3M6IGZ1bmN0aW9uIChkYXRhVXBkYXRlKSB7XG5cdCAgICAgICAgICAgIC8vIEFwcGVuZFxuXHQgICAgICAgICAgICB0aGlzLl9hcHBlbmQoZGF0YVVwZGF0ZSk7XG5cblx0ICAgICAgICAgICAgLy8gUHJvY2VzcyBhdmFpbGFibGUgYmxvY2tzXG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9wcm9jZXNzKCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEZpbmFsaXplcyB0aGUgZW5jcnlwdGlvbiBvciBkZWNyeXB0aW9uIHByb2Nlc3MuXG5cdCAgICAgICAgICogTm90ZSB0aGF0IHRoZSBmaW5hbGl6ZSBvcGVyYXRpb24gaXMgZWZmZWN0aXZlbHkgYSBkZXN0cnVjdGl2ZSwgcmVhZC1vbmNlIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gZGF0YVVwZGF0ZSBUaGUgZmluYWwgZGF0YSB0byBlbmNyeXB0IG9yIGRlY3J5cHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBkYXRhIGFmdGVyIGZpbmFsIHByb2Nlc3NpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIuZmluYWxpemUoKTtcblx0ICAgICAgICAgKiAgICAgdmFyIGVuY3J5cHRlZCA9IGNpcGhlci5maW5hbGl6ZSgnZGF0YScpO1xuXHQgICAgICAgICAqICAgICB2YXIgZW5jcnlwdGVkID0gY2lwaGVyLmZpbmFsaXplKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgZmluYWxpemU6IGZ1bmN0aW9uIChkYXRhVXBkYXRlKSB7XG5cdCAgICAgICAgICAgIC8vIEZpbmFsIGRhdGEgdXBkYXRlXG5cdCAgICAgICAgICAgIGlmIChkYXRhVXBkYXRlKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9hcHBlbmQoZGF0YVVwZGF0ZSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBQZXJmb3JtIGNvbmNyZXRlLWNpcGhlciBsb2dpY1xuXHQgICAgICAgICAgICB2YXIgZmluYWxQcm9jZXNzZWREYXRhID0gdGhpcy5fZG9GaW5hbGl6ZSgpO1xuXG5cdCAgICAgICAgICAgIHJldHVybiBmaW5hbFByb2Nlc3NlZERhdGE7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGtleVNpemU6IDEyOC8zMixcblxuXHQgICAgICAgIGl2U2l6ZTogMTI4LzMyLFxuXG5cdCAgICAgICAgX0VOQ19YRk9STV9NT0RFOiAxLFxuXG5cdCAgICAgICAgX0RFQ19YRk9STV9NT0RFOiAyLFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyBzaG9ydGN1dCBmdW5jdGlvbnMgdG8gYSBjaXBoZXIncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtDaXBoZXJ9IGNpcGhlciBUaGUgY2lwaGVyIHRvIGNyZWF0ZSBhIGhlbHBlciBmb3IuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEFuIG9iamVjdCB3aXRoIGVuY3J5cHQgYW5kIGRlY3J5cHQgc2hvcnRjdXQgZnVuY3Rpb25zLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgQUVTID0gQ3J5cHRvSlMubGliLkNpcGhlci5fY3JlYXRlSGVscGVyKENyeXB0b0pTLmFsZ28uQUVTKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBfY3JlYXRlSGVscGVyOiAoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICBmdW5jdGlvbiBzZWxlY3RDaXBoZXJTdHJhdGVneShrZXkpIHtcblx0ICAgICAgICAgICAgICAgIGlmICh0eXBlb2Yga2V5ID09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFBhc3N3b3JkQmFzZWRDaXBoZXI7XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBTZXJpYWxpemFibGVDaXBoZXI7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGNpcGhlcikge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgICAgICAgICBlbmNyeXB0OiBmdW5jdGlvbiAobWVzc2FnZSwga2V5LCBjZmcpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGVjdENpcGhlclN0cmF0ZWd5KGtleSkuZW5jcnlwdChjaXBoZXIsIG1lc3NhZ2UsIGtleSwgY2ZnKTtcblx0ICAgICAgICAgICAgICAgICAgICB9LFxuXG5cdCAgICAgICAgICAgICAgICAgICAgZGVjcnlwdDogZnVuY3Rpb24gKGNpcGhlcnRleHQsIGtleSwgY2ZnKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3RDaXBoZXJTdHJhdGVneShrZXkpLmRlY3J5cHQoY2lwaGVyLCBjaXBoZXJ0ZXh0LCBrZXksIGNmZyk7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICB9KCkpXG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBYnN0cmFjdCBiYXNlIHN0cmVhbSBjaXBoZXIgdGVtcGxhdGUuXG5cdCAgICAgKlxuXHQgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IGJsb2NrU2l6ZSBUaGUgbnVtYmVyIG9mIDMyLWJpdCB3b3JkcyB0aGlzIGNpcGhlciBvcGVyYXRlcyBvbi4gRGVmYXVsdDogMSAoMzIgYml0cylcblx0ICAgICAqL1xuXHQgICAgdmFyIFN0cmVhbUNpcGhlciA9IENfbGliLlN0cmVhbUNpcGhlciA9IENpcGhlci5leHRlbmQoe1xuXHQgICAgICAgIF9kb0ZpbmFsaXplOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFByb2Nlc3MgcGFydGlhbCBibG9ja3Ncblx0ICAgICAgICAgICAgdmFyIGZpbmFsUHJvY2Vzc2VkQmxvY2tzID0gdGhpcy5fcHJvY2VzcyghISdmbHVzaCcpO1xuXG5cdCAgICAgICAgICAgIHJldHVybiBmaW5hbFByb2Nlc3NlZEJsb2Nrcztcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgYmxvY2tTaXplOiAxXG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBNb2RlIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfbW9kZSA9IEMubW9kZSA9IHt9O1xuXG5cdCAgICAvKipcblx0ICAgICAqIEFic3RyYWN0IGJhc2UgYmxvY2sgY2lwaGVyIG1vZGUgdGVtcGxhdGUuXG5cdCAgICAgKi9cblx0ICAgIHZhciBCbG9ja0NpcGhlck1vZGUgPSBDX2xpYi5CbG9ja0NpcGhlck1vZGUgPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyB0aGlzIG1vZGUgZm9yIGVuY3J5cHRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIEEgYmxvY2sgY2lwaGVyIGluc3RhbmNlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IGl2IFRoZSBJViB3b3Jkcy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIG1vZGUgPSBDcnlwdG9KUy5tb2RlLkNCQy5jcmVhdGVFbmNyeXB0b3IoY2lwaGVyLCBpdi53b3Jkcyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY3JlYXRlRW5jcnlwdG9yOiBmdW5jdGlvbiAoY2lwaGVyLCBpdikge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5FbmNyeXB0b3IuY3JlYXRlKGNpcGhlciwgaXYpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIHRoaXMgbW9kZSBmb3IgZGVjcnlwdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyfSBjaXBoZXIgQSBibG9jayBjaXBoZXIgaW5zdGFuY2UuXG5cdCAgICAgICAgICogQHBhcmFtIHtBcnJheX0gaXYgVGhlIElWIHdvcmRzLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgbW9kZSA9IENyeXB0b0pTLm1vZGUuQ0JDLmNyZWF0ZURlY3J5cHRvcihjaXBoZXIsIGl2LndvcmRzKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjcmVhdGVEZWNyeXB0b3I6IGZ1bmN0aW9uIChjaXBoZXIsIGl2KSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLkRlY3J5cHRvci5jcmVhdGUoY2lwaGVyLCBpdik7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBtb2RlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtDaXBoZXJ9IGNpcGhlciBBIGJsb2NrIGNpcGhlciBpbnN0YW5jZS5cblx0ICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSBpdiBUaGUgSVYgd29yZHMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBtb2RlID0gQ3J5cHRvSlMubW9kZS5DQkMuRW5jcnlwdG9yLmNyZWF0ZShjaXBoZXIsIGl2LndvcmRzKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAoY2lwaGVyLCBpdikge1xuXHQgICAgICAgICAgICB0aGlzLl9jaXBoZXIgPSBjaXBoZXI7XG5cdCAgICAgICAgICAgIHRoaXMuX2l2ID0gaXY7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQ2lwaGVyIEJsb2NrIENoYWluaW5nIG1vZGUuXG5cdCAgICAgKi9cblx0ICAgIHZhciBDQkMgPSBDX21vZGUuQ0JDID0gKGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBBYnN0cmFjdCBiYXNlIENCQyBtb2RlLlxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHZhciBDQkMgPSBCbG9ja0NpcGhlck1vZGUuZXh0ZW5kKCk7XG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDQkMgZW5jcnlwdG9yLlxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIENCQy5FbmNyeXB0b3IgPSBDQkMuZXh0ZW5kKHtcblx0ICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAqIFByb2Nlc3NlcyB0aGUgZGF0YSBibG9jayBhdCBvZmZzZXQuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IHdvcmRzIFRoZSBkYXRhIHdvcmRzIHRvIG9wZXJhdGUgb24uXG5cdCAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgVGhlIG9mZnNldCB3aGVyZSB0aGUgYmxvY2sgc3RhcnRzLlxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiAgICAgbW9kZS5wcm9jZXNzQmxvY2soZGF0YS53b3Jkcywgb2Zmc2V0KTtcblx0ICAgICAgICAgICAgICovXG5cdCAgICAgICAgICAgIHByb2Nlc3NCbG9jazogZnVuY3Rpb24gKHdvcmRzLCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICAgICAgdmFyIGNpcGhlciA9IHRoaXMuX2NpcGhlcjtcblx0ICAgICAgICAgICAgICAgIHZhciBibG9ja1NpemUgPSBjaXBoZXIuYmxvY2tTaXplO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBYT1IgYW5kIGVuY3J5cHRcblx0ICAgICAgICAgICAgICAgIHhvckJsb2NrLmNhbGwodGhpcywgd29yZHMsIG9mZnNldCwgYmxvY2tTaXplKTtcblx0ICAgICAgICAgICAgICAgIGNpcGhlci5lbmNyeXB0QmxvY2sod29yZHMsIG9mZnNldCk7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFJlbWVtYmVyIHRoaXMgYmxvY2sgdG8gdXNlIHdpdGggbmV4dCBibG9ja1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fcHJldkJsb2NrID0gd29yZHMuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBibG9ja1NpemUpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSk7XG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDQkMgZGVjcnlwdG9yLlxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIENCQy5EZWNyeXB0b3IgPSBDQkMuZXh0ZW5kKHtcblx0ICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAqIFByb2Nlc3NlcyB0aGUgZGF0YSBibG9jayBhdCBvZmZzZXQuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IHdvcmRzIFRoZSBkYXRhIHdvcmRzIHRvIG9wZXJhdGUgb24uXG5cdCAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgVGhlIG9mZnNldCB3aGVyZSB0aGUgYmxvY2sgc3RhcnRzLlxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiAgICAgbW9kZS5wcm9jZXNzQmxvY2soZGF0YS53b3Jkcywgb2Zmc2V0KTtcblx0ICAgICAgICAgICAgICovXG5cdCAgICAgICAgICAgIHByb2Nlc3NCbG9jazogZnVuY3Rpb24gKHdvcmRzLCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICAgICAgdmFyIGNpcGhlciA9IHRoaXMuX2NpcGhlcjtcblx0ICAgICAgICAgICAgICAgIHZhciBibG9ja1NpemUgPSBjaXBoZXIuYmxvY2tTaXplO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBSZW1lbWJlciB0aGlzIGJsb2NrIHRvIHVzZSB3aXRoIG5leHQgYmxvY2tcblx0ICAgICAgICAgICAgICAgIHZhciB0aGlzQmxvY2sgPSB3b3Jkcy5zbGljZShvZmZzZXQsIG9mZnNldCArIGJsb2NrU2l6ZSk7XG5cblx0ICAgICAgICAgICAgICAgIC8vIERlY3J5cHQgYW5kIFhPUlxuXHQgICAgICAgICAgICAgICAgY2lwaGVyLmRlY3J5cHRCbG9jayh3b3Jkcywgb2Zmc2V0KTtcblx0ICAgICAgICAgICAgICAgIHhvckJsb2NrLmNhbGwodGhpcywgd29yZHMsIG9mZnNldCwgYmxvY2tTaXplKTtcblxuXHQgICAgICAgICAgICAgICAgLy8gVGhpcyBibG9jayBiZWNvbWVzIHRoZSBwcmV2aW91cyBibG9ja1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fcHJldkJsb2NrID0gdGhpc0Jsb2NrO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSk7XG5cblx0ICAgICAgICBmdW5jdGlvbiB4b3JCbG9jayh3b3Jkcywgb2Zmc2V0LCBibG9ja1NpemUpIHtcblx0ICAgICAgICAgICAgdmFyIGJsb2NrO1xuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgIHZhciBpdiA9IHRoaXMuX2l2O1xuXG5cdCAgICAgICAgICAgIC8vIENob29zZSBtaXhpbmcgYmxvY2tcblx0ICAgICAgICAgICAgaWYgKGl2KSB7XG5cdCAgICAgICAgICAgICAgICBibG9jayA9IGl2O1xuXG5cdCAgICAgICAgICAgICAgICAvLyBSZW1vdmUgSVYgZm9yIHN1YnNlcXVlbnQgYmxvY2tzXG5cdCAgICAgICAgICAgICAgICB0aGlzLl9pdiA9IHVuZGVmaW5lZDtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIGJsb2NrID0gdGhpcy5fcHJldkJsb2NrO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gWE9SIGJsb2Nrc1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrU2l6ZTsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB3b3Jkc1tvZmZzZXQgKyBpXSBePSBibG9ja1tpXTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIHJldHVybiBDQkM7XG5cdCAgICB9KCkpO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFBhZGRpbmcgbmFtZXNwYWNlLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ19wYWQgPSBDLnBhZCA9IHt9O1xuXG5cdCAgICAvKipcblx0ICAgICAqIFBLQ1MgIzUvNyBwYWRkaW5nIHN0cmF0ZWd5LlxuXHQgICAgICovXG5cdCAgICB2YXIgUGtjczcgPSBDX3BhZC5Qa2NzNyA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBQYWRzIGRhdGEgdXNpbmcgdGhlIGFsZ29yaXRobSBkZWZpbmVkIGluIFBLQ1MgIzUvNy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBkYXRhIFRoZSBkYXRhIHRvIHBhZC5cblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gYmxvY2tTaXplIFRoZSBtdWx0aXBsZSB0aGF0IHRoZSBkYXRhIHNob3VsZCBiZSBwYWRkZWQgdG8uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIENyeXB0b0pTLnBhZC5Qa2NzNy5wYWQod29yZEFycmF5LCA0KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwYWQ6IGZ1bmN0aW9uIChkYXRhLCBibG9ja1NpemUpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZUJ5dGVzID0gYmxvY2tTaXplICogNDtcblxuXHQgICAgICAgICAgICAvLyBDb3VudCBwYWRkaW5nIGJ5dGVzXG5cdCAgICAgICAgICAgIHZhciBuUGFkZGluZ0J5dGVzID0gYmxvY2tTaXplQnl0ZXMgLSBkYXRhLnNpZ0J5dGVzICUgYmxvY2tTaXplQnl0ZXM7XG5cblx0ICAgICAgICAgICAgLy8gQ3JlYXRlIHBhZGRpbmcgd29yZFxuXHQgICAgICAgICAgICB2YXIgcGFkZGluZ1dvcmQgPSAoblBhZGRpbmdCeXRlcyA8PCAyNCkgfCAoblBhZGRpbmdCeXRlcyA8PCAxNikgfCAoblBhZGRpbmdCeXRlcyA8PCA4KSB8IG5QYWRkaW5nQnl0ZXM7XG5cblx0ICAgICAgICAgICAgLy8gQ3JlYXRlIHBhZGRpbmdcblx0ICAgICAgICAgICAgdmFyIHBhZGRpbmdXb3JkcyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5QYWRkaW5nQnl0ZXM7IGkgKz0gNCkge1xuXHQgICAgICAgICAgICAgICAgcGFkZGluZ1dvcmRzLnB1c2gocGFkZGluZ1dvcmQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHZhciBwYWRkaW5nID0gV29yZEFycmF5LmNyZWF0ZShwYWRkaW5nV29yZHMsIG5QYWRkaW5nQnl0ZXMpO1xuXG5cdCAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nXG5cdCAgICAgICAgICAgIGRhdGEuY29uY2F0KHBhZGRpbmcpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBVbnBhZHMgZGF0YSB0aGF0IGhhZCBiZWVuIHBhZGRlZCB1c2luZyB0aGUgYWxnb3JpdGhtIGRlZmluZWQgaW4gUEtDUyAjNS83LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IGRhdGEgVGhlIGRhdGEgdG8gdW5wYWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIENyeXB0b0pTLnBhZC5Qa2NzNy51bnBhZCh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHVucGFkOiBmdW5jdGlvbiAoZGF0YSkge1xuXHQgICAgICAgICAgICAvLyBHZXQgbnVtYmVyIG9mIHBhZGRpbmcgYnl0ZXMgZnJvbSBsYXN0IGJ5dGVcblx0ICAgICAgICAgICAgdmFyIG5QYWRkaW5nQnl0ZXMgPSBkYXRhLndvcmRzWyhkYXRhLnNpZ0J5dGVzIC0gMSkgPj4+IDJdICYgMHhmZjtcblxuXHQgICAgICAgICAgICAvLyBSZW1vdmUgcGFkZGluZ1xuXHQgICAgICAgICAgICBkYXRhLnNpZ0J5dGVzIC09IG5QYWRkaW5nQnl0ZXM7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBYnN0cmFjdCBiYXNlIGJsb2NrIGNpcGhlciB0ZW1wbGF0ZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gYmxvY2tTaXplIFRoZSBudW1iZXIgb2YgMzItYml0IHdvcmRzIHRoaXMgY2lwaGVyIG9wZXJhdGVzIG9uLiBEZWZhdWx0OiA0ICgxMjggYml0cylcblx0ICAgICAqL1xuXHQgICAgdmFyIEJsb2NrQ2lwaGVyID0gQ19saWIuQmxvY2tDaXBoZXIgPSBDaXBoZXIuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge01vZGV9IG1vZGUgVGhlIGJsb2NrIG1vZGUgdG8gdXNlLiBEZWZhdWx0OiBDQkNcblx0ICAgICAgICAgKiBAcHJvcGVydHkge1BhZGRpbmd9IHBhZGRpbmcgVGhlIHBhZGRpbmcgc3RyYXRlZ3kgdG8gdXNlLiBEZWZhdWx0OiBQa2NzN1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNmZzogQ2lwaGVyLmNmZy5leHRlbmQoe1xuXHQgICAgICAgICAgICBtb2RlOiBDQkMsXG5cdCAgICAgICAgICAgIHBhZGRpbmc6IFBrY3M3XG5cdCAgICAgICAgfSksXG5cblx0ICAgICAgICByZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgbW9kZUNyZWF0b3I7XG5cblx0ICAgICAgICAgICAgLy8gUmVzZXQgY2lwaGVyXG5cdCAgICAgICAgICAgIENpcGhlci5yZXNldC5jYWxsKHRoaXMpO1xuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgY2ZnID0gdGhpcy5jZmc7XG5cdCAgICAgICAgICAgIHZhciBpdiA9IGNmZy5pdjtcblx0ICAgICAgICAgICAgdmFyIG1vZGUgPSBjZmcubW9kZTtcblxuXHQgICAgICAgICAgICAvLyBSZXNldCBibG9jayBtb2RlXG5cdCAgICAgICAgICAgIGlmICh0aGlzLl94Zm9ybU1vZGUgPT0gdGhpcy5fRU5DX1hGT1JNX01PREUpIHtcblx0ICAgICAgICAgICAgICAgIG1vZGVDcmVhdG9yID0gbW9kZS5jcmVhdGVFbmNyeXB0b3I7XG5cdCAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAodGhpcy5feGZvcm1Nb2RlID09IHRoaXMuX0RFQ19YRk9STV9NT0RFKSAqLyB7XG5cdCAgICAgICAgICAgICAgICBtb2RlQ3JlYXRvciA9IG1vZGUuY3JlYXRlRGVjcnlwdG9yO1xuXHQgICAgICAgICAgICAgICAgLy8gS2VlcCBhdCBsZWFzdCBvbmUgYmxvY2sgaW4gdGhlIGJ1ZmZlciBmb3IgdW5wYWRkaW5nXG5cdCAgICAgICAgICAgICAgICB0aGlzLl9taW5CdWZmZXJTaXplID0gMTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIGlmICh0aGlzLl9tb2RlICYmIHRoaXMuX21vZGUuX19jcmVhdG9yID09IG1vZGVDcmVhdG9yKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLl9tb2RlLmluaXQodGhpcywgaXYgJiYgaXYud29yZHMpO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fbW9kZSA9IG1vZGVDcmVhdG9yLmNhbGwobW9kZSwgdGhpcywgaXYgJiYgaXYud29yZHMpO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fbW9kZS5fX2NyZWF0b3IgPSBtb2RlQ3JlYXRvcjtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfZG9Qcm9jZXNzQmxvY2s6IGZ1bmN0aW9uICh3b3Jkcywgb2Zmc2V0KSB7XG5cdCAgICAgICAgICAgIHRoaXMuX21vZGUucHJvY2Vzc0Jsb2NrKHdvcmRzLCBvZmZzZXQpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgZmluYWxQcm9jZXNzZWRCbG9ja3M7XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIHBhZGRpbmcgPSB0aGlzLmNmZy5wYWRkaW5nO1xuXG5cdCAgICAgICAgICAgIC8vIEZpbmFsaXplXG5cdCAgICAgICAgICAgIGlmICh0aGlzLl94Zm9ybU1vZGUgPT0gdGhpcy5fRU5DX1hGT1JNX01PREUpIHtcblx0ICAgICAgICAgICAgICAgIC8vIFBhZCBkYXRhXG5cdCAgICAgICAgICAgICAgICBwYWRkaW5nLnBhZCh0aGlzLl9kYXRhLCB0aGlzLmJsb2NrU2l6ZSk7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFByb2Nlc3MgZmluYWwgYmxvY2tzXG5cdCAgICAgICAgICAgICAgICBmaW5hbFByb2Nlc3NlZEJsb2NrcyA9IHRoaXMuX3Byb2Nlc3MoISEnZmx1c2gnKTtcblx0ICAgICAgICAgICAgfSBlbHNlIC8qIGlmICh0aGlzLl94Zm9ybU1vZGUgPT0gdGhpcy5fREVDX1hGT1JNX01PREUpICovIHtcblx0ICAgICAgICAgICAgICAgIC8vIFByb2Nlc3MgZmluYWwgYmxvY2tzXG5cdCAgICAgICAgICAgICAgICBmaW5hbFByb2Nlc3NlZEJsb2NrcyA9IHRoaXMuX3Byb2Nlc3MoISEnZmx1c2gnKTtcblxuXHQgICAgICAgICAgICAgICAgLy8gVW5wYWQgZGF0YVxuXHQgICAgICAgICAgICAgICAgcGFkZGluZy51bnBhZChmaW5hbFByb2Nlc3NlZEJsb2Nrcyk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gZmluYWxQcm9jZXNzZWRCbG9ja3M7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGJsb2NrU2l6ZTogMTI4LzMyXG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBIGNvbGxlY3Rpb24gb2YgY2lwaGVyIHBhcmFtZXRlcnMuXG5cdCAgICAgKlxuXHQgICAgICogQHByb3BlcnR5IHtXb3JkQXJyYXl9IGNpcGhlcnRleHQgVGhlIHJhdyBjaXBoZXJ0ZXh0LlxuXHQgICAgICogQHByb3BlcnR5IHtXb3JkQXJyYXl9IGtleSBUaGUga2V5IHRvIHRoaXMgY2lwaGVydGV4dC5cblx0ICAgICAqIEBwcm9wZXJ0eSB7V29yZEFycmF5fSBpdiBUaGUgSVYgdXNlZCBpbiB0aGUgY2lwaGVyaW5nIG9wZXJhdGlvbi5cblx0ICAgICAqIEBwcm9wZXJ0eSB7V29yZEFycmF5fSBzYWx0IFRoZSBzYWx0IHVzZWQgd2l0aCBhIGtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uLlxuXHQgICAgICogQHByb3BlcnR5IHtDaXBoZXJ9IGFsZ29yaXRobSBUaGUgY2lwaGVyIGFsZ29yaXRobS5cblx0ICAgICAqIEBwcm9wZXJ0eSB7TW9kZX0gbW9kZSBUaGUgYmxvY2sgbW9kZSB1c2VkIGluIHRoZSBjaXBoZXJpbmcgb3BlcmF0aW9uLlxuXHQgICAgICogQHByb3BlcnR5IHtQYWRkaW5nfSBwYWRkaW5nIFRoZSBwYWRkaW5nIHNjaGVtZSB1c2VkIGluIHRoZSBjaXBoZXJpbmcgb3BlcmF0aW9uLlxuXHQgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IGJsb2NrU2l6ZSBUaGUgYmxvY2sgc2l6ZSBvZiB0aGUgY2lwaGVyLlxuXHQgICAgICogQHByb3BlcnR5IHtGb3JtYXR9IGZvcm1hdHRlciBUaGUgZGVmYXVsdCBmb3JtYXR0aW5nIHN0cmF0ZWd5IHRvIGNvbnZlcnQgdGhpcyBjaXBoZXIgcGFyYW1zIG9iamVjdCB0byBhIHN0cmluZy5cblx0ICAgICAqL1xuXHQgICAgdmFyIENpcGhlclBhcmFtcyA9IENfbGliLkNpcGhlclBhcmFtcyA9IEJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ld2x5IGNyZWF0ZWQgY2lwaGVyIHBhcmFtcyBvYmplY3QuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2lwaGVyUGFyYW1zIEFuIG9iamVjdCB3aXRoIGFueSBvZiB0aGUgcG9zc2libGUgY2lwaGVyIHBhcmFtZXRlcnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXJQYXJhbXMgPSBDcnlwdG9KUy5saWIuQ2lwaGVyUGFyYW1zLmNyZWF0ZSh7XG5cdCAgICAgICAgICogICAgICAgICBjaXBoZXJ0ZXh0OiBjaXBoZXJ0ZXh0V29yZEFycmF5LFxuXHQgICAgICAgICAqICAgICAgICAga2V5OiBrZXlXb3JkQXJyYXksXG5cdCAgICAgICAgICogICAgICAgICBpdjogaXZXb3JkQXJyYXksXG5cdCAgICAgICAgICogICAgICAgICBzYWx0OiBzYWx0V29yZEFycmF5LFxuXHQgICAgICAgICAqICAgICAgICAgYWxnb3JpdGhtOiBDcnlwdG9KUy5hbGdvLkFFUyxcblx0ICAgICAgICAgKiAgICAgICAgIG1vZGU6IENyeXB0b0pTLm1vZGUuQ0JDLFxuXHQgICAgICAgICAqICAgICAgICAgcGFkZGluZzogQ3J5cHRvSlMucGFkLlBLQ1M3LFxuXHQgICAgICAgICAqICAgICAgICAgYmxvY2tTaXplOiA0LFxuXHQgICAgICAgICAqICAgICAgICAgZm9ybWF0dGVyOiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTFxuXHQgICAgICAgICAqICAgICB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAoY2lwaGVyUGFyYW1zKSB7XG5cdCAgICAgICAgICAgIHRoaXMubWl4SW4oY2lwaGVyUGFyYW1zKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgdGhpcyBjaXBoZXIgcGFyYW1zIG9iamVjdCB0byBhIHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Rm9ybWF0fSBmb3JtYXR0ZXIgKE9wdGlvbmFsKSBUaGUgZm9ybWF0dGluZyBzdHJhdGVneSB0byB1c2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBzdHJpbmdpZmllZCBjaXBoZXIgcGFyYW1zLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHRocm93cyBFcnJvciBJZiBuZWl0aGVyIHRoZSBmb3JtYXR0ZXIgbm9yIHRoZSBkZWZhdWx0IGZvcm1hdHRlciBpcyBzZXQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBzdHJpbmcgPSBjaXBoZXJQYXJhbXMgKyAnJztcblx0ICAgICAgICAgKiAgICAgdmFyIHN0cmluZyA9IGNpcGhlclBhcmFtcy50b1N0cmluZygpO1xuXHQgICAgICAgICAqICAgICB2YXIgc3RyaW5nID0gY2lwaGVyUGFyYW1zLnRvU3RyaW5nKENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0b1N0cmluZzogZnVuY3Rpb24gKGZvcm1hdHRlcikge1xuXHQgICAgICAgICAgICByZXR1cm4gKGZvcm1hdHRlciB8fCB0aGlzLmZvcm1hdHRlcikuc3RyaW5naWZ5KHRoaXMpO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEZvcm1hdCBuYW1lc3BhY2UuXG5cdCAgICAgKi9cblx0ICAgIHZhciBDX2Zvcm1hdCA9IEMuZm9ybWF0ID0ge307XG5cblx0ICAgIC8qKlxuXHQgICAgICogT3BlblNTTCBmb3JtYXR0aW5nIHN0cmF0ZWd5LlxuXHQgICAgICovXG5cdCAgICB2YXIgT3BlblNTTEZvcm1hdHRlciA9IENfZm9ybWF0Lk9wZW5TU0wgPSB7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgYSBjaXBoZXIgcGFyYW1zIG9iamVjdCB0byBhbiBPcGVuU1NMLWNvbXBhdGlibGUgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtDaXBoZXJQYXJhbXN9IGNpcGhlclBhcmFtcyBUaGUgY2lwaGVyIHBhcmFtcyBvYmplY3QuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBPcGVuU1NMLWNvbXBhdGlibGUgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgb3BlblNTTFN0cmluZyA9IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMLnN0cmluZ2lmeShjaXBoZXJQYXJhbXMpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHN0cmluZ2lmeTogZnVuY3Rpb24gKGNpcGhlclBhcmFtcykge1xuXHQgICAgICAgICAgICB2YXIgd29yZEFycmF5O1xuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgY2lwaGVydGV4dCA9IGNpcGhlclBhcmFtcy5jaXBoZXJ0ZXh0O1xuXHQgICAgICAgICAgICB2YXIgc2FsdCA9IGNpcGhlclBhcmFtcy5zYWx0O1xuXG5cdCAgICAgICAgICAgIC8vIEZvcm1hdFxuXHQgICAgICAgICAgICBpZiAoc2FsdCkge1xuXHQgICAgICAgICAgICAgICAgd29yZEFycmF5ID0gV29yZEFycmF5LmNyZWF0ZShbMHg1MzYxNmM3NCwgMHg2NTY0NWY1Zl0pLmNvbmNhdChzYWx0KS5jb25jYXQoY2lwaGVydGV4dCk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICB3b3JkQXJyYXkgPSBjaXBoZXJ0ZXh0O1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIHdvcmRBcnJheS50b1N0cmluZyhCYXNlNjQpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhbiBPcGVuU1NMLWNvbXBhdGlibGUgc3RyaW5nIHRvIGEgY2lwaGVyIHBhcmFtcyBvYmplY3QuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gb3BlblNTTFN0ciBUaGUgT3BlblNTTC1jb21wYXRpYmxlIHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge0NpcGhlclBhcmFtc30gVGhlIGNpcGhlciBwYXJhbXMgb2JqZWN0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVyUGFyYW1zID0gQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wucGFyc2Uob3BlblNTTFN0cmluZyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcGFyc2U6IGZ1bmN0aW9uIChvcGVuU1NMU3RyKSB7XG5cdCAgICAgICAgICAgIHZhciBzYWx0O1xuXG5cdCAgICAgICAgICAgIC8vIFBhcnNlIGJhc2U2NFxuXHQgICAgICAgICAgICB2YXIgY2lwaGVydGV4dCA9IEJhc2U2NC5wYXJzZShvcGVuU1NMU3RyKTtcblxuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgY2lwaGVydGV4dFdvcmRzID0gY2lwaGVydGV4dC53b3JkcztcblxuXHQgICAgICAgICAgICAvLyBUZXN0IGZvciBzYWx0XG5cdCAgICAgICAgICAgIGlmIChjaXBoZXJ0ZXh0V29yZHNbMF0gPT0gMHg1MzYxNmM3NCAmJiBjaXBoZXJ0ZXh0V29yZHNbMV0gPT0gMHg2NTY0NWY1Zikge1xuXHQgICAgICAgICAgICAgICAgLy8gRXh0cmFjdCBzYWx0XG5cdCAgICAgICAgICAgICAgICBzYWx0ID0gV29yZEFycmF5LmNyZWF0ZShjaXBoZXJ0ZXh0V29yZHMuc2xpY2UoMiwgNCkpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBSZW1vdmUgc2FsdCBmcm9tIGNpcGhlcnRleHRcblx0ICAgICAgICAgICAgICAgIGNpcGhlcnRleHRXb3Jkcy5zcGxpY2UoMCwgNCk7XG5cdCAgICAgICAgICAgICAgICBjaXBoZXJ0ZXh0LnNpZ0J5dGVzIC09IDE2O1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIENpcGhlclBhcmFtcy5jcmVhdGUoeyBjaXBoZXJ0ZXh0OiBjaXBoZXJ0ZXh0LCBzYWx0OiBzYWx0IH0pO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogQSBjaXBoZXIgd3JhcHBlciB0aGF0IHJldHVybnMgY2lwaGVydGV4dCBhcyBhIHNlcmlhbGl6YWJsZSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAqL1xuXHQgICAgdmFyIFNlcmlhbGl6YWJsZUNpcGhlciA9IENfbGliLlNlcmlhbGl6YWJsZUNpcGhlciA9IEJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge0Zvcm1hdHRlcn0gZm9ybWF0IFRoZSBmb3JtYXR0aW5nIHN0cmF0ZWd5IHRvIGNvbnZlcnQgY2lwaGVyIHBhcmFtIG9iamVjdHMgdG8gYW5kIGZyb20gYSBzdHJpbmcuIERlZmF1bHQ6IE9wZW5TU0xcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjZmc6IEJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAgICAgZm9ybWF0OiBPcGVuU1NMRm9ybWF0dGVyXG5cdCAgICAgICAgfSksXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBFbmNyeXB0cyBhIG1lc3NhZ2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS5cblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gZW5jcnlwdC5cblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkuXG5cdCAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge0NpcGhlclBhcmFtc30gQSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHRQYXJhbXMgPSBDcnlwdG9KUy5saWIuU2VyaWFsaXphYmxlQ2lwaGVyLmVuY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIG1lc3NhZ2UsIGtleSk7XG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0UGFyYW1zID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5lbmNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBtZXNzYWdlLCBrZXksIHsgaXY6IGl2IH0pO1xuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dFBhcmFtcyA9IENyeXB0b0pTLmxpYi5TZXJpYWxpemFibGVDaXBoZXIuZW5jcnlwdChDcnlwdG9KUy5hbGdvLkFFUywgbWVzc2FnZSwga2V5LCB7IGl2OiBpdiwgZm9ybWF0OiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTCB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBlbmNyeXB0OiBmdW5jdGlvbiAoY2lwaGVyLCBtZXNzYWdlLCBrZXksIGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7XG5cblx0ICAgICAgICAgICAgLy8gRW5jcnlwdFxuXHQgICAgICAgICAgICB2YXIgZW5jcnlwdG9yID0gY2lwaGVyLmNyZWF0ZUVuY3J5cHRvcihrZXksIGNmZyk7XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJ0ZXh0ID0gZW5jcnlwdG9yLmZpbmFsaXplKG1lc3NhZ2UpO1xuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJDZmcgPSBlbmNyeXB0b3IuY2ZnO1xuXG5cdCAgICAgICAgICAgIC8vIENyZWF0ZSBhbmQgcmV0dXJuIHNlcmlhbGl6YWJsZSBjaXBoZXIgcGFyYW1zXG5cdCAgICAgICAgICAgIHJldHVybiBDaXBoZXJQYXJhbXMuY3JlYXRlKHtcblx0ICAgICAgICAgICAgICAgIGNpcGhlcnRleHQ6IGNpcGhlcnRleHQsXG5cdCAgICAgICAgICAgICAgICBrZXk6IGtleSxcblx0ICAgICAgICAgICAgICAgIGl2OiBjaXBoZXJDZmcuaXYsXG5cdCAgICAgICAgICAgICAgICBhbGdvcml0aG06IGNpcGhlcixcblx0ICAgICAgICAgICAgICAgIG1vZGU6IGNpcGhlckNmZy5tb2RlLFxuXHQgICAgICAgICAgICAgICAgcGFkZGluZzogY2lwaGVyQ2ZnLnBhZGRpbmcsXG5cdCAgICAgICAgICAgICAgICBibG9ja1NpemU6IGNpcGhlci5ibG9ja1NpemUsXG5cdCAgICAgICAgICAgICAgICBmb3JtYXR0ZXI6IGNmZy5mb3JtYXRcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIERlY3J5cHRzIHNlcmlhbGl6ZWQgY2lwaGVydGV4dC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyfSBjaXBoZXIgVGhlIGNpcGhlciBhbGdvcml0aG0gdG8gdXNlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyUGFyYW1zfHN0cmluZ30gY2lwaGVydGV4dCBUaGUgY2lwaGVydGV4dCB0byBkZWNyeXB0LlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBrZXkgVGhlIGtleS5cblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgcGxhaW50ZXh0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgcGxhaW50ZXh0ID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBmb3JtYXR0ZWRDaXBoZXJ0ZXh0LCBrZXksIHsgaXY6IGl2LCBmb3JtYXQ6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMIH0pO1xuXHQgICAgICAgICAqICAgICB2YXIgcGxhaW50ZXh0ID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBjaXBoZXJ0ZXh0UGFyYW1zLCBrZXksIHsgaXY6IGl2LCBmb3JtYXQ6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMIH0pO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGRlY3J5cHQ6IGZ1bmN0aW9uIChjaXBoZXIsIGNpcGhlcnRleHQsIGtleSwgY2ZnKSB7XG5cdCAgICAgICAgICAgIC8vIEFwcGx5IGNvbmZpZyBkZWZhdWx0c1xuXHQgICAgICAgICAgICBjZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0IHN0cmluZyB0byBDaXBoZXJQYXJhbXNcblx0ICAgICAgICAgICAgY2lwaGVydGV4dCA9IHRoaXMuX3BhcnNlKGNpcGhlcnRleHQsIGNmZy5mb3JtYXQpO1xuXG5cdCAgICAgICAgICAgIC8vIERlY3J5cHRcblx0ICAgICAgICAgICAgdmFyIHBsYWludGV4dCA9IGNpcGhlci5jcmVhdGVEZWNyeXB0b3Ioa2V5LCBjZmcpLmZpbmFsaXplKGNpcGhlcnRleHQuY2lwaGVydGV4dCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIHBsYWludGV4dDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgc2VyaWFsaXplZCBjaXBoZXJ0ZXh0IHRvIENpcGhlclBhcmFtcyxcblx0ICAgICAgICAgKiBlbHNlIGFzc3VtZWQgQ2lwaGVyUGFyYW1zIGFscmVhZHkgYW5kIHJldHVybnMgY2lwaGVydGV4dCB1bmNoYW5nZWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlclBhcmFtc3xzdHJpbmd9IGNpcGhlcnRleHQgVGhlIGNpcGhlcnRleHQuXG5cdCAgICAgICAgICogQHBhcmFtIHtGb3JtYXR0ZXJ9IGZvcm1hdCBUaGUgZm9ybWF0dGluZyBzdHJhdGVneSB0byB1c2UgdG8gcGFyc2Ugc2VyaWFsaXplZCBjaXBoZXJ0ZXh0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7Q2lwaGVyUGFyYW1zfSBUaGUgdW5zZXJpYWxpemVkIGNpcGhlcnRleHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0UGFyYW1zID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5fcGFyc2UoY2lwaGVydGV4dFN0cmluZ09yUGFyYW1zLCBmb3JtYXQpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIF9wYXJzZTogZnVuY3Rpb24gKGNpcGhlcnRleHQsIGZvcm1hdCkge1xuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGNpcGhlcnRleHQgPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXQucGFyc2UoY2lwaGVydGV4dCwgdGhpcyk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gY2lwaGVydGV4dDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfa2RmID0gQy5rZGYgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBPcGVuU1NMIGtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uLlxuXHQgICAgICovXG5cdCAgICB2YXIgT3BlblNTTEtkZiA9IENfa2RmLk9wZW5TU0wgPSB7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRGVyaXZlcyBhIGtleSBhbmQgSVYgZnJvbSBhIHBhc3N3b3JkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZCB0byBkZXJpdmUgZnJvbS5cblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0ga2V5U2l6ZSBUaGUgc2l6ZSBpbiB3b3JkcyBvZiB0aGUga2V5IHRvIGdlbmVyYXRlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpdlNpemUgVGhlIHNpemUgaW4gd29yZHMgb2YgdGhlIElWIHRvIGdlbmVyYXRlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gc2FsdCAoT3B0aW9uYWwpIEEgNjQtYml0IHNhbHQgdG8gdXNlLiBJZiBvbWl0dGVkLCBhIHNhbHQgd2lsbCBiZSBnZW5lcmF0ZWQgcmFuZG9tbHkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtDaXBoZXJQYXJhbXN9IEEgY2lwaGVyIHBhcmFtcyBvYmplY3Qgd2l0aCB0aGUga2V5LCBJViwgYW5kIHNhbHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBkZXJpdmVkUGFyYW1zID0gQ3J5cHRvSlMua2RmLk9wZW5TU0wuZXhlY3V0ZSgnUGFzc3dvcmQnLCAyNTYvMzIsIDEyOC8zMik7XG5cdCAgICAgICAgICogICAgIHZhciBkZXJpdmVkUGFyYW1zID0gQ3J5cHRvSlMua2RmLk9wZW5TU0wuZXhlY3V0ZSgnUGFzc3dvcmQnLCAyNTYvMzIsIDEyOC8zMiwgJ3NhbHRzYWx0Jyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgZXhlY3V0ZTogZnVuY3Rpb24gKHBhc3N3b3JkLCBrZXlTaXplLCBpdlNpemUsIHNhbHQpIHtcblx0ICAgICAgICAgICAgLy8gR2VuZXJhdGUgcmFuZG9tIHNhbHRcblx0ICAgICAgICAgICAgaWYgKCFzYWx0KSB7XG5cdCAgICAgICAgICAgICAgICBzYWx0ID0gV29yZEFycmF5LnJhbmRvbSg2NC84KTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIERlcml2ZSBrZXkgYW5kIElWXG5cdCAgICAgICAgICAgIHZhciBrZXkgPSBFdnBLREYuY3JlYXRlKHsga2V5U2l6ZToga2V5U2l6ZSArIGl2U2l6ZSB9KS5jb21wdXRlKHBhc3N3b3JkLCBzYWx0KTtcblxuXHQgICAgICAgICAgICAvLyBTZXBhcmF0ZSBrZXkgYW5kIElWXG5cdCAgICAgICAgICAgIHZhciBpdiA9IFdvcmRBcnJheS5jcmVhdGUoa2V5LndvcmRzLnNsaWNlKGtleVNpemUpLCBpdlNpemUgKiA0KTtcblx0ICAgICAgICAgICAga2V5LnNpZ0J5dGVzID0ga2V5U2l6ZSAqIDQ7XG5cblx0ICAgICAgICAgICAgLy8gUmV0dXJuIHBhcmFtc1xuXHQgICAgICAgICAgICByZXR1cm4gQ2lwaGVyUGFyYW1zLmNyZWF0ZSh7IGtleToga2V5LCBpdjogaXYsIHNhbHQ6IHNhbHQgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBIHNlcmlhbGl6YWJsZSBjaXBoZXIgd3JhcHBlciB0aGF0IGRlcml2ZXMgdGhlIGtleSBmcm9tIGEgcGFzc3dvcmQsXG5cdCAgICAgKiBhbmQgcmV0dXJucyBjaXBoZXJ0ZXh0IGFzIGEgc2VyaWFsaXphYmxlIGNpcGhlciBwYXJhbXMgb2JqZWN0LlxuXHQgICAgICovXG5cdCAgICB2YXIgUGFzc3dvcmRCYXNlZENpcGhlciA9IENfbGliLlBhc3N3b3JkQmFzZWRDaXBoZXIgPSBTZXJpYWxpemFibGVDaXBoZXIuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge0tERn0ga2RmIFRoZSBrZXkgZGVyaXZhdGlvbiBmdW5jdGlvbiB0byB1c2UgdG8gZ2VuZXJhdGUgYSBrZXkgYW5kIElWIGZyb20gYSBwYXNzd29yZC4gRGVmYXVsdDogT3BlblNTTFxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNmZzogU2VyaWFsaXphYmxlQ2lwaGVyLmNmZy5leHRlbmQoe1xuXHQgICAgICAgICAgICBrZGY6IE9wZW5TU0xLZGZcblx0ICAgICAgICB9KSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEVuY3J5cHRzIGEgbWVzc2FnZSB1c2luZyBhIHBhc3N3b3JkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtDaXBoZXJ9IGNpcGhlciBUaGUgY2lwaGVyIGFsZ29yaXRobSB0byB1c2UuXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGVuY3J5cHQuXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZC5cblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7Q2lwaGVyUGFyYW1zfSBBIGNpcGhlciBwYXJhbXMgb2JqZWN0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dFBhcmFtcyA9IENyeXB0b0pTLmxpYi5QYXNzd29yZEJhc2VkQ2lwaGVyLmVuY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIG1lc3NhZ2UsICdwYXNzd29yZCcpO1xuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dFBhcmFtcyA9IENyeXB0b0pTLmxpYi5QYXNzd29yZEJhc2VkQ2lwaGVyLmVuY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIG1lc3NhZ2UsICdwYXNzd29yZCcsIHsgZm9ybWF0OiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTCB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBlbmNyeXB0OiBmdW5jdGlvbiAoY2lwaGVyLCBtZXNzYWdlLCBwYXNzd29yZCwgY2ZnKSB7XG5cdCAgICAgICAgICAgIC8vIEFwcGx5IGNvbmZpZyBkZWZhdWx0c1xuXHQgICAgICAgICAgICBjZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBEZXJpdmUga2V5IGFuZCBvdGhlciBwYXJhbXNcblx0ICAgICAgICAgICAgdmFyIGRlcml2ZWRQYXJhbXMgPSBjZmcua2RmLmV4ZWN1dGUocGFzc3dvcmQsIGNpcGhlci5rZXlTaXplLCBjaXBoZXIuaXZTaXplKTtcblxuXHQgICAgICAgICAgICAvLyBBZGQgSVYgdG8gY29uZmlnXG5cdCAgICAgICAgICAgIGNmZy5pdiA9IGRlcml2ZWRQYXJhbXMuaXY7XG5cblx0ICAgICAgICAgICAgLy8gRW5jcnlwdFxuXHQgICAgICAgICAgICB2YXIgY2lwaGVydGV4dCA9IFNlcmlhbGl6YWJsZUNpcGhlci5lbmNyeXB0LmNhbGwodGhpcywgY2lwaGVyLCBtZXNzYWdlLCBkZXJpdmVkUGFyYW1zLmtleSwgY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBNaXggaW4gZGVyaXZlZCBwYXJhbXNcblx0ICAgICAgICAgICAgY2lwaGVydGV4dC5taXhJbihkZXJpdmVkUGFyYW1zKTtcblxuXHQgICAgICAgICAgICByZXR1cm4gY2lwaGVydGV4dDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRGVjcnlwdHMgc2VyaWFsaXplZCBjaXBoZXJ0ZXh0IHVzaW5nIGEgcGFzc3dvcmQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS5cblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlclBhcmFtc3xzdHJpbmd9IGNpcGhlcnRleHQgVGhlIGNpcGhlcnRleHQgdG8gZGVjcnlwdC5cblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGFzc3dvcmQgVGhlIHBhc3N3b3JkLlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBvcGVyYXRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBwbGFpbnRleHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBwbGFpbnRleHQgPSBDcnlwdG9KUy5saWIuUGFzc3dvcmRCYXNlZENpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBmb3JtYXR0ZWRDaXBoZXJ0ZXh0LCAncGFzc3dvcmQnLCB7IGZvcm1hdDogQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wgfSk7XG5cdCAgICAgICAgICogICAgIHZhciBwbGFpbnRleHQgPSBDcnlwdG9KUy5saWIuUGFzc3dvcmRCYXNlZENpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBjaXBoZXJ0ZXh0UGFyYW1zLCAncGFzc3dvcmQnLCB7IGZvcm1hdDogQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wgfSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgZGVjcnlwdDogZnVuY3Rpb24gKGNpcGhlciwgY2lwaGVydGV4dCwgcGFzc3dvcmQsIGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gQ2lwaGVyUGFyYW1zXG5cdCAgICAgICAgICAgIGNpcGhlcnRleHQgPSB0aGlzLl9wYXJzZShjaXBoZXJ0ZXh0LCBjZmcuZm9ybWF0KTtcblxuXHQgICAgICAgICAgICAvLyBEZXJpdmUga2V5IGFuZCBvdGhlciBwYXJhbXNcblx0ICAgICAgICAgICAgdmFyIGRlcml2ZWRQYXJhbXMgPSBjZmcua2RmLmV4ZWN1dGUocGFzc3dvcmQsIGNpcGhlci5rZXlTaXplLCBjaXBoZXIuaXZTaXplLCBjaXBoZXJ0ZXh0LnNhbHQpO1xuXG5cdCAgICAgICAgICAgIC8vIEFkZCBJViB0byBjb25maWdcblx0ICAgICAgICAgICAgY2ZnLml2ID0gZGVyaXZlZFBhcmFtcy5pdjtcblxuXHQgICAgICAgICAgICAvLyBEZWNyeXB0XG5cdCAgICAgICAgICAgIHZhciBwbGFpbnRleHQgPSBTZXJpYWxpemFibGVDaXBoZXIuZGVjcnlwdC5jYWxsKHRoaXMsIGNpcGhlciwgY2lwaGVydGV4dCwgZGVyaXZlZFBhcmFtcy5rZXksIGNmZyk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIHBsYWludGV4dDtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0fSgpKTtcblxuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdHJvb3QuQ3J5cHRvSlMgPSBmYWN0b3J5KCk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKCkge1xuXG5cdC8qZ2xvYmFscyB3aW5kb3csIGdsb2JhbCwgcmVxdWlyZSovXG5cblx0LyoqXG5cdCAqIENyeXB0b0pTIGNvcmUgY29tcG9uZW50cy5cblx0ICovXG5cdHZhciBDcnlwdG9KUyA9IENyeXB0b0pTIHx8IChmdW5jdGlvbiAoTWF0aCwgdW5kZWZpbmVkKSB7XG5cblx0ICAgIHZhciBjcnlwdG87XG5cblx0ICAgIC8vIE5hdGl2ZSBjcnlwdG8gZnJvbSB3aW5kb3cgKEJyb3dzZXIpXG5cdCAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93LmNyeXB0bykge1xuXHQgICAgICAgIGNyeXB0byA9IHdpbmRvdy5jcnlwdG87XG5cdCAgICB9XG5cblx0ICAgIC8vIE5hdGl2ZSAoZXhwZXJpbWVudGFsIElFIDExKSBjcnlwdG8gZnJvbSB3aW5kb3cgKEJyb3dzZXIpXG5cdCAgICBpZiAoIWNyeXB0byAmJiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cubXNDcnlwdG8pIHtcblx0ICAgICAgICBjcnlwdG8gPSB3aW5kb3cubXNDcnlwdG87XG5cdCAgICB9XG5cblx0ICAgIC8vIE5hdGl2ZSBjcnlwdG8gZnJvbSBnbG9iYWwgKE5vZGVKUylcblx0ICAgIGlmICghY3J5cHRvICYmIHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnICYmIGdsb2JhbC5jcnlwdG8pIHtcblx0ICAgICAgICBjcnlwdG8gPSBnbG9iYWwuY3J5cHRvO1xuXHQgICAgfVxuXG5cdCAgICAvLyBOYXRpdmUgY3J5cHRvIGltcG9ydCB2aWEgcmVxdWlyZSAoTm9kZUpTKVxuXHQgICAgaWYgKCFjcnlwdG8gJiYgdHlwZW9mIHJlcXVpcmUgPT09ICdmdW5jdGlvbicpIHtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcblx0ICAgICAgICB9IGNhdGNoIChlcnIpIHt9XG5cdCAgICB9XG5cblx0ICAgIC8qXG5cdCAgICAgKiBDcnlwdG9ncmFwaGljYWxseSBzZWN1cmUgcHNldWRvcmFuZG9tIG51bWJlciBnZW5lcmF0b3Jcblx0ICAgICAqXG5cdCAgICAgKiBBcyBNYXRoLnJhbmRvbSgpIGlzIGNyeXB0b2dyYXBoaWNhbGx5IG5vdCBzYWZlIHRvIHVzZVxuXHQgICAgICovXG5cdCAgICB2YXIgY3J5cHRvU2VjdXJlUmFuZG9tSW50ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGlmIChjcnlwdG8pIHtcblx0ICAgICAgICAgICAgLy8gVXNlIGdldFJhbmRvbVZhbHVlcyBtZXRob2QgKEJyb3dzZXIpXG5cdCAgICAgICAgICAgIGlmICh0eXBlb2YgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PT0gJ2Z1bmN0aW9uJykge1xuXHQgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhuZXcgVWludDMyQXJyYXkoMSkpWzBdO1xuXHQgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7fVxuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gVXNlIHJhbmRvbUJ5dGVzIG1ldGhvZCAoTm9kZUpTKVxuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGNyeXB0by5yYW5kb21CeXRlcyA9PT0gJ2Z1bmN0aW9uJykge1xuXHQgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3J5cHRvLnJhbmRvbUJ5dGVzKDQpLnJlYWRJbnQzMkxFKCk7XG5cdCAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHt9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cblx0ICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05hdGl2ZSBjcnlwdG8gbW9kdWxlIGNvdWxkIG5vdCBiZSB1c2VkIHRvIGdldCBzZWN1cmUgcmFuZG9tIG51bWJlci4nKTtcblx0ICAgIH07XG5cblx0ICAgIC8qXG5cdCAgICAgKiBMb2NhbCBwb2x5ZmlsbCBvZiBPYmplY3QuY3JlYXRlXG5cblx0ICAgICAqL1xuXHQgICAgdmFyIGNyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgKGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBmdW5jdGlvbiBGKCkge31cblxuXHQgICAgICAgIHJldHVybiBmdW5jdGlvbiAob2JqKSB7XG5cdCAgICAgICAgICAgIHZhciBzdWJ0eXBlO1xuXG5cdCAgICAgICAgICAgIEYucHJvdG90eXBlID0gb2JqO1xuXG5cdCAgICAgICAgICAgIHN1YnR5cGUgPSBuZXcgRigpO1xuXG5cdCAgICAgICAgICAgIEYucHJvdG90eXBlID0gbnVsbDtcblxuXHQgICAgICAgICAgICByZXR1cm4gc3VidHlwZTtcblx0ICAgICAgICB9O1xuXHQgICAgfSgpKVxuXG5cdCAgICAvKipcblx0ICAgICAqIENyeXB0b0pTIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEMgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBMaWJyYXJ5IG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfbGliID0gQy5saWIgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBCYXNlIG9iamVjdCBmb3IgcHJvdG90eXBhbCBpbmhlcml0YW5jZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEJhc2UgPSBDX2xpYi5CYXNlID0gKGZ1bmN0aW9uICgpIHtcblxuXG5cdCAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAqIENyZWF0ZXMgYSBuZXcgb2JqZWN0IHRoYXQgaW5oZXJpdHMgZnJvbSB0aGlzIG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IG92ZXJyaWRlcyBQcm9wZXJ0aWVzIHRvIGNvcHkgaW50byB0aGUgbmV3IG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSBUaGUgbmV3IG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiAgICAgdmFyIE15VHlwZSA9IENyeXB0b0pTLmxpYi5CYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgZmllbGQ6ICd2YWx1ZScsXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICAgICAgbWV0aG9kOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgfVxuXHQgICAgICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICBleHRlbmQ6IGZ1bmN0aW9uIChvdmVycmlkZXMpIHtcblx0ICAgICAgICAgICAgICAgIC8vIFNwYXduXG5cdCAgICAgICAgICAgICAgICB2YXIgc3VidHlwZSA9IGNyZWF0ZSh0aGlzKTtcblxuXHQgICAgICAgICAgICAgICAgLy8gQXVnbWVudFxuXHQgICAgICAgICAgICAgICAgaWYgKG92ZXJyaWRlcykge1xuXHQgICAgICAgICAgICAgICAgICAgIHN1YnR5cGUubWl4SW4ob3ZlcnJpZGVzKTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGRlZmF1bHQgaW5pdGlhbGl6ZXJcblx0ICAgICAgICAgICAgICAgIGlmICghc3VidHlwZS5oYXNPd25Qcm9wZXJ0eSgnaW5pdCcpIHx8IHRoaXMuaW5pdCA9PT0gc3VidHlwZS5pbml0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgc3VidHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlLiRzdXBlci5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdCAgICAgICAgICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZXIncyBwcm90b3R5cGUgaXMgdGhlIHN1YnR5cGUgb2JqZWN0XG5cdCAgICAgICAgICAgICAgICBzdWJ0eXBlLmluaXQucHJvdG90eXBlID0gc3VidHlwZTtcblxuXHQgICAgICAgICAgICAgICAgLy8gUmVmZXJlbmNlIHN1cGVydHlwZVxuXHQgICAgICAgICAgICAgICAgc3VidHlwZS4kc3VwZXIgPSB0aGlzO1xuXG5cdCAgICAgICAgICAgICAgICByZXR1cm4gc3VidHlwZTtcblx0ICAgICAgICAgICAgfSxcblxuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogRXh0ZW5kcyB0aGlzIG9iamVjdCBhbmQgcnVucyB0aGUgaW5pdCBtZXRob2QuXG5cdCAgICAgICAgICAgICAqIEFyZ3VtZW50cyB0byBjcmVhdGUoKSB3aWxsIGJlIHBhc3NlZCB0byBpbml0KCkuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEByZXR1cm4ge09iamVjdH0gVGhlIG5ldyBvYmplY3QuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogICAgIHZhciBpbnN0YW5jZSA9IE15VHlwZS5jcmVhdGUoKTtcblx0ICAgICAgICAgICAgICovXG5cdCAgICAgICAgICAgIGNyZWF0ZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlID0gdGhpcy5leHRlbmQoKTtcblx0ICAgICAgICAgICAgICAgIGluc3RhbmNlLmluaXQuYXBwbHkoaW5zdGFuY2UsIGFyZ3VtZW50cyk7XG5cblx0ICAgICAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZTtcblx0ICAgICAgICAgICAgfSxcblxuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIG9iamVjdC5cblx0ICAgICAgICAgICAgICogT3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gYWRkIHNvbWUgbG9naWMgd2hlbiB5b3VyIG9iamVjdHMgYXJlIGNyZWF0ZWQuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICB2YXIgTXlUeXBlID0gQ3J5cHRvSlMubGliLkJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAgICAgICogICAgICAgICBpbml0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgICAgIC8vIC4uLlxuXHQgICAgICAgICAgICAgKiAgICAgICAgIH1cblx0ICAgICAgICAgICAgICogICAgIH0pO1xuXHQgICAgICAgICAgICAgKi9cblx0ICAgICAgICAgICAgaW5pdDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB9LFxuXG5cdCAgICAgICAgICAgIC8qKlxuXHQgICAgICAgICAgICAgKiBDb3BpZXMgcHJvcGVydGllcyBpbnRvIHRoaXMgb2JqZWN0LlxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcGVydGllcyBUaGUgcHJvcGVydGllcyB0byBtaXggaW4uXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICBNeVR5cGUubWl4SW4oe1xuXHQgICAgICAgICAgICAgKiAgICAgICAgIGZpZWxkOiAndmFsdWUnXG5cdCAgICAgICAgICAgICAqICAgICB9KTtcblx0ICAgICAgICAgICAgICovXG5cdCAgICAgICAgICAgIG1peEluOiBmdW5jdGlvbiAocHJvcGVydGllcykge1xuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgcHJvcGVydHlOYW1lIGluIHByb3BlcnRpZXMpIHtcblx0ICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShwcm9wZXJ0eU5hbWUpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNbcHJvcGVydHlOYW1lXSA9IHByb3BlcnRpZXNbcHJvcGVydHlOYW1lXTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIC8vIElFIHdvbid0IGNvcHkgdG9TdHJpbmcgdXNpbmcgdGhlIGxvb3AgYWJvdmVcblx0ICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzLmhhc093blByb3BlcnR5KCd0b1N0cmluZycpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy50b1N0cmluZyA9IHByb3BlcnRpZXMudG9TdHJpbmc7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0sXG5cblx0ICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAqIENyZWF0ZXMgYSBjb3B5IG9mIHRoaXMgb2JqZWN0LlxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogICAgIHZhciBjbG9uZSA9IGluc3RhbmNlLmNsb25lKCk7XG5cdCAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5pdC5wcm90b3R5cGUuZXh0ZW5kKHRoaXMpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH0oKSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQW4gYXJyYXkgb2YgMzItYml0IHdvcmRzLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7QXJyYXl9IHdvcmRzIFRoZSBhcnJheSBvZiAzMi1iaXQgd29yZHMuXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gc2lnQnl0ZXMgVGhlIG51bWJlciBvZiBzaWduaWZpY2FudCBieXRlcyBpbiB0aGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgKi9cblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXkgPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSB3b3JkcyAoT3B0aW9uYWwpIEFuIGFycmF5IG9mIDMyLWJpdCB3b3Jkcy5cblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gc2lnQnl0ZXMgKE9wdGlvbmFsKSBUaGUgbnVtYmVyIG9mIHNpZ25pZmljYW50IGJ5dGVzIGluIHRoZSB3b3Jkcy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmxpYi5Xb3JkQXJyYXkuY3JlYXRlKCk7XG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5saWIuV29yZEFycmF5LmNyZWF0ZShbMHgwMDAxMDIwMywgMHgwNDA1MDYwN10pO1xuXHQgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMubGliLldvcmRBcnJheS5jcmVhdGUoWzB4MDAwMTAyMDMsIDB4MDQwNTA2MDddLCA2KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAod29yZHMsIHNpZ0J5dGVzKSB7XG5cdCAgICAgICAgICAgIHdvcmRzID0gdGhpcy53b3JkcyA9IHdvcmRzIHx8IFtdO1xuXG5cdCAgICAgICAgICAgIGlmIChzaWdCeXRlcyAhPSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgPSBzaWdCeXRlcztcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgPSB3b3Jkcy5sZW5ndGggKiA0O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIHRoaXMgd29yZCBhcnJheSB0byBhIHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7RW5jb2Rlcn0gZW5jb2RlciAoT3B0aW9uYWwpIFRoZSBlbmNvZGluZyBzdHJhdGVneSB0byB1c2UuIERlZmF1bHQ6IENyeXB0b0pTLmVuYy5IZXhcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHN0cmluZ2lmaWVkIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBzdHJpbmcgPSB3b3JkQXJyYXkgKyAnJztcblx0ICAgICAgICAgKiAgICAgdmFyIHN0cmluZyA9IHdvcmRBcnJheS50b1N0cmluZygpO1xuXHQgICAgICAgICAqICAgICB2YXIgc3RyaW5nID0gd29yZEFycmF5LnRvU3RyaW5nKENyeXB0b0pTLmVuYy5VdGY4KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0b1N0cmluZzogZnVuY3Rpb24gKGVuY29kZXIpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIChlbmNvZGVyIHx8IEhleCkuc3RyaW5naWZ5KHRoaXMpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25jYXRlbmF0ZXMgYSB3b3JkIGFycmF5IHRvIHRoaXMgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkgdG8gYXBwZW5kLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHdvcmRBcnJheTEuY29uY2F0KHdvcmRBcnJheTIpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNvbmNhdDogZnVuY3Rpb24gKHdvcmRBcnJheSkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIHRoaXNXb3JkcyA9IHRoaXMud29yZHM7XG5cdCAgICAgICAgICAgIHZhciB0aGF0V29yZHMgPSB3b3JkQXJyYXkud29yZHM7XG5cdCAgICAgICAgICAgIHZhciB0aGlzU2lnQnl0ZXMgPSB0aGlzLnNpZ0J5dGVzO1xuXHQgICAgICAgICAgICB2YXIgdGhhdFNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENsYW1wIGV4Y2VzcyBiaXRzXG5cdCAgICAgICAgICAgIHRoaXMuY2xhbXAoKTtcblxuXHQgICAgICAgICAgICAvLyBDb25jYXRcblx0ICAgICAgICAgICAgaWYgKHRoaXNTaWdCeXRlcyAlIDQpIHtcblx0ICAgICAgICAgICAgICAgIC8vIENvcHkgb25lIGJ5dGUgYXQgYSB0aW1lXG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoYXRTaWdCeXRlczsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIHRoYXRCeXRlID0gKHRoYXRXb3Jkc1tpID4+PiAyXSA+Pj4gKDI0IC0gKGkgJSA0KSAqIDgpKSAmIDB4ZmY7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpc1dvcmRzWyh0aGlzU2lnQnl0ZXMgKyBpKSA+Pj4gMl0gfD0gdGhhdEJ5dGUgPDwgKDI0IC0gKCh0aGlzU2lnQnl0ZXMgKyBpKSAlIDQpICogOCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAvLyBDb3B5IG9uZSB3b3JkIGF0IGEgdGltZVxuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGF0U2lnQnl0ZXM7IGkgKz0gNCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXNXb3Jkc1sodGhpc1NpZ0J5dGVzICsgaSkgPj4+IDJdID0gdGhhdFdvcmRzW2kgPj4+IDJdO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgKz0gdGhhdFNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENoYWluYWJsZVxuXHQgICAgICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmVtb3ZlcyBpbnNpZ25pZmljYW50IGJpdHMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHdvcmRBcnJheS5jbGFtcCgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNsYW1wOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSB0aGlzLndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgc2lnQnl0ZXMgPSB0aGlzLnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENsYW1wXG5cdCAgICAgICAgICAgIHdvcmRzW3NpZ0J5dGVzID4+PiAyXSAmPSAweGZmZmZmZmZmIDw8ICgzMiAtIChzaWdCeXRlcyAlIDQpICogOCk7XG5cdCAgICAgICAgICAgIHdvcmRzLmxlbmd0aCA9IE1hdGguY2VpbChzaWdCeXRlcyAvIDQpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgY29weSBvZiB0aGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNsb25lID0gd29yZEFycmF5LmNsb25lKCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdmFyIGNsb25lID0gQmFzZS5jbG9uZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgICAgICBjbG9uZS53b3JkcyA9IHRoaXMud29yZHMuc2xpY2UoMCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgd29yZCBhcnJheSBmaWxsZWQgd2l0aCByYW5kb20gYnl0ZXMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gbkJ5dGVzIFRoZSBudW1iZXIgb2YgcmFuZG9tIGJ5dGVzIHRvIGdlbmVyYXRlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgcmFuZG9tIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5saWIuV29yZEFycmF5LnJhbmRvbSgxNik7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcmFuZG9tOiBmdW5jdGlvbiAobkJ5dGVzKSB7XG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IFtdO1xuXG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbkJ5dGVzOyBpICs9IDQpIHtcblx0ICAgICAgICAgICAgICAgIHdvcmRzLnB1c2goY3J5cHRvU2VjdXJlUmFuZG9tSW50KCkpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIG5ldyBXb3JkQXJyYXkuaW5pdCh3b3JkcywgbkJ5dGVzKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBFbmNvZGVyIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfZW5jID0gQy5lbmMgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBIZXggZW5jb2Rpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBIZXggPSBDX2VuYy5IZXggPSB7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgYSB3b3JkIGFycmF5IHRvIGEgaGV4IHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBoZXggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGV4U3RyaW5nID0gQ3J5cHRvSlMuZW5jLkhleC5zdHJpbmdpZnkod29yZEFycmF5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBzdHJpbmdpZnk6IGZ1bmN0aW9uICh3b3JkQXJyYXkpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IHdvcmRBcnJheS53b3Jkcztcblx0ICAgICAgICAgICAgdmFyIHNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENvbnZlcnRcblx0ICAgICAgICAgICAgdmFyIGhleENoYXJzID0gW107XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnQnl0ZXM7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgdmFyIGJpdGUgPSAod29yZHNbaSA+Pj4gMl0gPj4+ICgyNCAtIChpICUgNCkgKiA4KSkgJiAweGZmO1xuXHQgICAgICAgICAgICAgICAgaGV4Q2hhcnMucHVzaCgoYml0ZSA+Pj4gNCkudG9TdHJpbmcoMTYpKTtcblx0ICAgICAgICAgICAgICAgIGhleENoYXJzLnB1c2goKGJpdGUgJiAweDBmKS50b1N0cmluZygxNikpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGhleENoYXJzLmpvaW4oJycpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIGhleCBzdHJpbmcgdG8gYSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGhleFN0ciBUaGUgaGV4IHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5lbmMuSGV4LnBhcnNlKGhleFN0cmluZyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcGFyc2U6IGZ1bmN0aW9uIChoZXhTdHIpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIGhleFN0ckxlbmd0aCA9IGhleFN0ci5sZW5ndGg7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydFxuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSBbXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZXhTdHJMZW5ndGg7IGkgKz0gMikge1xuXHQgICAgICAgICAgICAgICAgd29yZHNbaSA+Pj4gM10gfD0gcGFyc2VJbnQoaGV4U3RyLnN1YnN0cihpLCAyKSwgMTYpIDw8ICgyNCAtIChpICUgOCkgKiA0KTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgV29yZEFycmF5LmluaXQod29yZHMsIGhleFN0ckxlbmd0aCAvIDIpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogTGF0aW4xIGVuY29kaW5nIHN0cmF0ZWd5LlxuXHQgICAgICovXG5cdCAgICB2YXIgTGF0aW4xID0gQ19lbmMuTGF0aW4xID0ge1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGEgd29yZCBhcnJheSB0byBhIExhdGluMSBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0gd29yZEFycmF5IFRoZSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgTGF0aW4xIHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGxhdGluMVN0cmluZyA9IENyeXB0b0pTLmVuYy5MYXRpbjEuc3RyaW5naWZ5KHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAod29yZEFycmF5KSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSB3b3JkQXJyYXkud29yZHM7XG5cdCAgICAgICAgICAgIHZhciBzaWdCeXRlcyA9IHdvcmRBcnJheS5zaWdCeXRlcztcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0XG5cdCAgICAgICAgICAgIHZhciBsYXRpbjFDaGFycyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZ0J5dGVzOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIHZhciBiaXRlID0gKHdvcmRzW2kgPj4+IDJdID4+PiAoMjQgLSAoaSAlIDQpICogOCkpICYgMHhmZjtcblx0ICAgICAgICAgICAgICAgIGxhdGluMUNoYXJzLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShiaXRlKSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gbGF0aW4xQ2hhcnMuam9pbignJyk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGEgTGF0aW4xIHN0cmluZyB0byBhIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gbGF0aW4xU3RyIFRoZSBMYXRpbjEgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5MYXRpbjEucGFyc2UobGF0aW4xU3RyaW5nKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwYXJzZTogZnVuY3Rpb24gKGxhdGluMVN0cikge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgbGF0aW4xU3RyTGVuZ3RoID0gbGF0aW4xU3RyLmxlbmd0aDtcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0XG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxhdGluMVN0ckxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB3b3Jkc1tpID4+PiAyXSB8PSAobGF0aW4xU3RyLmNoYXJDb2RlQXQoaSkgJiAweGZmKSA8PCAoMjQgLSAoaSAlIDQpICogOCk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gbmV3IFdvcmRBcnJheS5pbml0KHdvcmRzLCBsYXRpbjFTdHJMZW5ndGgpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogVVRGLTggZW5jb2Rpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBVdGY4ID0gQ19lbmMuVXRmOCA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIHdvcmQgYXJyYXkgdG8gYSBVVEYtOCBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0gd29yZEFycmF5IFRoZSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgVVRGLTggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgdXRmOFN0cmluZyA9IENyeXB0b0pTLmVuYy5VdGY4LnN0cmluZ2lmeSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHN0cmluZ2lmeTogZnVuY3Rpb24gKHdvcmRBcnJheSkge1xuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChlc2NhcGUoTGF0aW4xLnN0cmluZ2lmeSh3b3JkQXJyYXkpKSk7XG5cdCAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWFsZm9ybWVkIFVURi04IGRhdGEnKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIFVURi04IHN0cmluZyB0byBhIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXRmOFN0ciBUaGUgVVRGLTggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5VdGY4LnBhcnNlKHV0ZjhTdHJpbmcpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAodXRmOFN0cikge1xuXHQgICAgICAgICAgICByZXR1cm4gTGF0aW4xLnBhcnNlKHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudCh1dGY4U3RyKSkpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogQWJzdHJhY3QgYnVmZmVyZWQgYmxvY2sgYWxnb3JpdGhtIHRlbXBsYXRlLlxuXHQgICAgICpcblx0ICAgICAqIFRoZSBwcm9wZXJ0eSBibG9ja1NpemUgbXVzdCBiZSBpbXBsZW1lbnRlZCBpbiBhIGNvbmNyZXRlIHN1YnR5cGUuXG5cdCAgICAgKlxuXHQgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IF9taW5CdWZmZXJTaXplIFRoZSBudW1iZXIgb2YgYmxvY2tzIHRoYXQgc2hvdWxkIGJlIGtlcHQgdW5wcm9jZXNzZWQgaW4gdGhlIGJ1ZmZlci4gRGVmYXVsdDogMFxuXHQgICAgICovXG5cdCAgICB2YXIgQnVmZmVyZWRCbG9ja0FsZ29yaXRobSA9IENfbGliLkJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0gPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmVzZXRzIHRoaXMgYmxvY2sgYWxnb3JpdGhtJ3MgZGF0YSBidWZmZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0ucmVzZXQoKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICByZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBJbml0aWFsIHZhbHVlc1xuXHQgICAgICAgICAgICB0aGlzLl9kYXRhID0gbmV3IFdvcmRBcnJheS5pbml0KCk7XG5cdCAgICAgICAgICAgIHRoaXMuX25EYXRhQnl0ZXMgPSAwO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBBZGRzIG5ldyBkYXRhIHRvIHRoaXMgYmxvY2sgYWxnb3JpdGhtJ3MgYnVmZmVyLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBkYXRhIFRoZSBkYXRhIHRvIGFwcGVuZC4gU3RyaW5ncyBhcmUgY29udmVydGVkIHRvIGEgV29yZEFycmF5IHVzaW5nIFVURi04LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBidWZmZXJlZEJsb2NrQWxnb3JpdGhtLl9hcHBlbmQoJ2RhdGEnKTtcblx0ICAgICAgICAgKiAgICAgYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5fYXBwZW5kKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgX2FwcGVuZDogZnVuY3Rpb24gKGRhdGEpIHtcblx0ICAgICAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gV29yZEFycmF5LCBlbHNlIGFzc3VtZSBXb3JkQXJyYXkgYWxyZWFkeVxuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgICAgIGRhdGEgPSBVdGY4LnBhcnNlKGRhdGEpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gQXBwZW5kXG5cdCAgICAgICAgICAgIHRoaXMuX2RhdGEuY29uY2F0KGRhdGEpO1xuXHQgICAgICAgICAgICB0aGlzLl9uRGF0YUJ5dGVzICs9IGRhdGEuc2lnQnl0ZXM7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFByb2Nlc3NlcyBhdmFpbGFibGUgZGF0YSBibG9ja3MuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBUaGlzIG1ldGhvZCBpbnZva2VzIF9kb1Byb2Nlc3NCbG9jayhvZmZzZXQpLCB3aGljaCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGEgY29uY3JldGUgc3VidHlwZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZG9GbHVzaCBXaGV0aGVyIGFsbCBibG9ja3MgYW5kIHBhcnRpYWwgYmxvY2tzIHNob3VsZCBiZSBwcm9jZXNzZWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBwcm9jZXNzZWQgZGF0YS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHByb2Nlc3NlZERhdGEgPSBidWZmZXJlZEJsb2NrQWxnb3JpdGhtLl9wcm9jZXNzKCk7XG5cdCAgICAgICAgICogICAgIHZhciBwcm9jZXNzZWREYXRhID0gYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5fcHJvY2VzcyghISdmbHVzaCcpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIF9wcm9jZXNzOiBmdW5jdGlvbiAoZG9GbHVzaCkge1xuXHQgICAgICAgICAgICB2YXIgcHJvY2Vzc2VkV29yZHM7XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBkYXRhID0gdGhpcy5fZGF0YTtcblx0ICAgICAgICAgICAgdmFyIGRhdGFXb3JkcyA9IGRhdGEud29yZHM7XG5cdCAgICAgICAgICAgIHZhciBkYXRhU2lnQnl0ZXMgPSBkYXRhLnNpZ0J5dGVzO1xuXHQgICAgICAgICAgICB2YXIgYmxvY2tTaXplID0gdGhpcy5ibG9ja1NpemU7XG5cdCAgICAgICAgICAgIHZhciBibG9ja1NpemVCeXRlcyA9IGJsb2NrU2l6ZSAqIDQ7XG5cblx0ICAgICAgICAgICAgLy8gQ291bnQgYmxvY2tzIHJlYWR5XG5cdCAgICAgICAgICAgIHZhciBuQmxvY2tzUmVhZHkgPSBkYXRhU2lnQnl0ZXMgLyBibG9ja1NpemVCeXRlcztcblx0ICAgICAgICAgICAgaWYgKGRvRmx1c2gpIHtcblx0ICAgICAgICAgICAgICAgIC8vIFJvdW5kIHVwIHRvIGluY2x1ZGUgcGFydGlhbCBibG9ja3Ncblx0ICAgICAgICAgICAgICAgIG5CbG9ja3NSZWFkeSA9IE1hdGguY2VpbChuQmxvY2tzUmVhZHkpO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgLy8gUm91bmQgZG93biB0byBpbmNsdWRlIG9ubHkgZnVsbCBibG9ja3MsXG5cdCAgICAgICAgICAgICAgICAvLyBsZXNzIHRoZSBudW1iZXIgb2YgYmxvY2tzIHRoYXQgbXVzdCByZW1haW4gaW4gdGhlIGJ1ZmZlclxuXHQgICAgICAgICAgICAgICAgbkJsb2Nrc1JlYWR5ID0gTWF0aC5tYXgoKG5CbG9ja3NSZWFkeSB8IDApIC0gdGhpcy5fbWluQnVmZmVyU2l6ZSwgMCk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBDb3VudCB3b3JkcyByZWFkeVxuXHQgICAgICAgICAgICB2YXIgbldvcmRzUmVhZHkgPSBuQmxvY2tzUmVhZHkgKiBibG9ja1NpemU7XG5cblx0ICAgICAgICAgICAgLy8gQ291bnQgYnl0ZXMgcmVhZHlcblx0ICAgICAgICAgICAgdmFyIG5CeXRlc1JlYWR5ID0gTWF0aC5taW4obldvcmRzUmVhZHkgKiA0LCBkYXRhU2lnQnl0ZXMpO1xuXG5cdCAgICAgICAgICAgIC8vIFByb2Nlc3MgYmxvY2tzXG5cdCAgICAgICAgICAgIGlmIChuV29yZHNSZWFkeSkge1xuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgbldvcmRzUmVhZHk7IG9mZnNldCArPSBibG9ja1NpemUpIHtcblx0ICAgICAgICAgICAgICAgICAgICAvLyBQZXJmb3JtIGNvbmNyZXRlLWFsZ29yaXRobSBsb2dpY1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuX2RvUHJvY2Vzc0Jsb2NrKGRhdGFXb3Jkcywgb2Zmc2V0KTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgLy8gUmVtb3ZlIHByb2Nlc3NlZCB3b3Jkc1xuXHQgICAgICAgICAgICAgICAgcHJvY2Vzc2VkV29yZHMgPSBkYXRhV29yZHMuc3BsaWNlKDAsIG5Xb3Jkc1JlYWR5KTtcblx0ICAgICAgICAgICAgICAgIGRhdGEuc2lnQnl0ZXMgLT0gbkJ5dGVzUmVhZHk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBSZXR1cm4gcHJvY2Vzc2VkIHdvcmRzXG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgV29yZEFycmF5LmluaXQocHJvY2Vzc2VkV29yZHMsIG5CeXRlc1JlYWR5KTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhpcyBvYmplY3QuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNsb25lID0gYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5jbG9uZSgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHZhciBjbG9uZSA9IEJhc2UuY2xvbmUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAgICAgY2xvbmUuX2RhdGEgPSB0aGlzLl9kYXRhLmNsb25lKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfbWluQnVmZmVyU2l6ZTogMFxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQWJzdHJhY3QgaGFzaGVyIHRlbXBsYXRlLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBibG9ja1NpemUgVGhlIG51bWJlciBvZiAzMi1iaXQgd29yZHMgdGhpcyBoYXNoZXIgb3BlcmF0ZXMgb24uIERlZmF1bHQ6IDE2ICg1MTIgYml0cylcblx0ICAgICAqL1xuXHQgICAgdmFyIEhhc2hlciA9IENfbGliLkhhc2hlciA9IEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0uZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2ZnOiBCYXNlLmV4dGVuZCgpLFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIGhhc2hlci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBoYXNoIGNvbXB1dGF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGFzaGVyID0gQ3J5cHRvSlMuYWxnby5TSEEyNTYuY3JlYXRlKCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgaW5pdDogZnVuY3Rpb24gKGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgdGhpcy5jZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBTZXQgaW5pdGlhbCB2YWx1ZXNcblx0ICAgICAgICAgICAgdGhpcy5yZXNldCgpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBSZXNldHMgdGhpcyBoYXNoZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGhhc2hlci5yZXNldCgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHJlc2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFJlc2V0IGRhdGEgYnVmZmVyXG5cdCAgICAgICAgICAgIEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0ucmVzZXQuY2FsbCh0aGlzKTtcblxuXHQgICAgICAgICAgICAvLyBQZXJmb3JtIGNvbmNyZXRlLWhhc2hlciBsb2dpY1xuXHQgICAgICAgICAgICB0aGlzLl9kb1Jlc2V0KCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFVwZGF0ZXMgdGhpcyBoYXNoZXIgd2l0aCBhIG1lc3NhZ2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2VVcGRhdGUgVGhlIG1lc3NhZ2UgdG8gYXBwZW5kLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7SGFzaGVyfSBUaGlzIGhhc2hlci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgaGFzaGVyLnVwZGF0ZSgnbWVzc2FnZScpO1xuXHQgICAgICAgICAqICAgICBoYXNoZXIudXBkYXRlKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdXBkYXRlOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBBcHBlbmRcblx0ICAgICAgICAgICAgdGhpcy5fYXBwZW5kKG1lc3NhZ2VVcGRhdGUpO1xuXG5cdCAgICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgaGFzaFxuXHQgICAgICAgICAgICB0aGlzLl9wcm9jZXNzKCk7XG5cblx0ICAgICAgICAgICAgLy8gQ2hhaW5hYmxlXG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBGaW5hbGl6ZXMgdGhlIGhhc2ggY29tcHV0YXRpb24uXG5cdCAgICAgICAgICogTm90ZSB0aGF0IHRoZSBmaW5hbGl6ZSBvcGVyYXRpb24gaXMgZWZmZWN0aXZlbHkgYSBkZXN0cnVjdGl2ZSwgcmVhZC1vbmNlIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZVVwZGF0ZSAoT3B0aW9uYWwpIEEgZmluYWwgbWVzc2FnZSB1cGRhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSgpO1xuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSgnbWVzc2FnZScpO1xuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGZpbmFsaXplOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBGaW5hbCBtZXNzYWdlIHVwZGF0ZVxuXHQgICAgICAgICAgICBpZiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fYXBwZW5kKG1lc3NhZ2VVcGRhdGUpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gUGVyZm9ybSBjb25jcmV0ZS1oYXNoZXIgbG9naWNcblx0ICAgICAgICAgICAgdmFyIGhhc2ggPSB0aGlzLl9kb0ZpbmFsaXplKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGhhc2g7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGJsb2NrU2l6ZTogNTEyLzMyLFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyBhIHNob3J0Y3V0IGZ1bmN0aW9uIHRvIGEgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7SGFzaGVyfSBoYXNoZXIgVGhlIGhhc2hlciB0byBjcmVhdGUgYSBoZWxwZXIgZm9yLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBzaG9ydGN1dCBmdW5jdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIFNIQTI1NiA9IENyeXB0b0pTLmxpYi5IYXNoZXIuX2NyZWF0ZUhlbHBlcihDcnlwdG9KUy5hbGdvLlNIQTI1Nik7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgX2NyZWF0ZUhlbHBlcjogZnVuY3Rpb24gKGhhc2hlcikge1xuXHQgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1lc3NhZ2UsIGNmZykge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBoYXNoZXIuaW5pdChjZmcpLmZpbmFsaXplKG1lc3NhZ2UpO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgc2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIEhNQUMncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtIYXNoZXJ9IGhhc2hlciBUaGUgaGFzaGVyIHRvIHVzZSBpbiB0aGlzIEhNQUMgaGVscGVyLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBzaG9ydGN1dCBmdW5jdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIEhtYWNTSEEyNTYgPSBDcnlwdG9KUy5saWIuSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKENyeXB0b0pTLmFsZ28uU0hBMjU2KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBfY3JlYXRlSG1hY0hlbHBlcjogZnVuY3Rpb24gKGhhc2hlcikge1xuXHQgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1lc3NhZ2UsIGtleSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDX2FsZ28uSE1BQy5pbml0KGhhc2hlciwga2V5KS5maW5hbGl6ZShtZXNzYWdlKTtcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBbGdvcml0aG0gbmFtZXNwYWNlLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvID0ge307XG5cblx0ICAgIHJldHVybiBDO1xuXHR9KE1hdGgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUztcblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0KGZ1bmN0aW9uICgpIHtcblx0ICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgdmFyIEMgPSBDcnlwdG9KUztcblx0ICAgIHZhciBDX2xpYiA9IEMubGliO1xuXHQgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTtcblx0ICAgIHZhciBDX2VuYyA9IEMuZW5jO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEJhc2U2NCBlbmNvZGluZyBzdHJhdGVneS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEJhc2U2NCA9IENfZW5jLkJhc2U2NCA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIHdvcmQgYXJyYXkgdG8gYSBCYXNlNjQgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IHdvcmRBcnJheSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIEJhc2U2NCBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBiYXNlNjRTdHJpbmcgPSBDcnlwdG9KUy5lbmMuQmFzZTY0LnN0cmluZ2lmeSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHN0cmluZ2lmeTogZnVuY3Rpb24gKHdvcmRBcnJheSkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIHdvcmRzID0gd29yZEFycmF5LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgc2lnQnl0ZXMgPSB3b3JkQXJyYXkuc2lnQnl0ZXM7XG5cdCAgICAgICAgICAgIHZhciBtYXAgPSB0aGlzLl9tYXA7XG5cblx0ICAgICAgICAgICAgLy8gQ2xhbXAgZXhjZXNzIGJpdHNcblx0ICAgICAgICAgICAgd29yZEFycmF5LmNsYW1wKCk7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydFxuXHQgICAgICAgICAgICB2YXIgYmFzZTY0Q2hhcnMgPSBbXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaWdCeXRlczsgaSArPSAzKSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgYnl0ZTEgPSAod29yZHNbaSA+Pj4gMl0gICAgICAgPj4+ICgyNCAtIChpICUgNCkgKiA4KSkgICAgICAgJiAweGZmO1xuXHQgICAgICAgICAgICAgICAgdmFyIGJ5dGUyID0gKHdvcmRzWyhpICsgMSkgPj4+IDJdID4+PiAoMjQgLSAoKGkgKyAxKSAlIDQpICogOCkpICYgMHhmZjtcblx0ICAgICAgICAgICAgICAgIHZhciBieXRlMyA9ICh3b3Jkc1soaSArIDIpID4+PiAyXSA+Pj4gKDI0IC0gKChpICsgMikgJSA0KSAqIDgpKSAmIDB4ZmY7XG5cblx0ICAgICAgICAgICAgICAgIHZhciB0cmlwbGV0ID0gKGJ5dGUxIDw8IDE2KSB8IChieXRlMiA8PCA4KSB8IGJ5dGUzO1xuXG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgKGogPCA0KSAmJiAoaSArIGogKiAwLjc1IDwgc2lnQnl0ZXMpOyBqKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICBiYXNlNjRDaGFycy5wdXNoKG1hcC5jaGFyQXQoKHRyaXBsZXQgPj4+ICg2ICogKDMgLSBqKSkpICYgMHgzZikpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmdcblx0ICAgICAgICAgICAgdmFyIHBhZGRpbmdDaGFyID0gbWFwLmNoYXJBdCg2NCk7XG5cdCAgICAgICAgICAgIGlmIChwYWRkaW5nQ2hhcikge1xuXHQgICAgICAgICAgICAgICAgd2hpbGUgKGJhc2U2NENoYXJzLmxlbmd0aCAlIDQpIHtcblx0ICAgICAgICAgICAgICAgICAgICBiYXNlNjRDaGFycy5wdXNoKHBhZGRpbmdDaGFyKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBiYXNlNjRDaGFycy5qb2luKCcnKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgYSBCYXNlNjQgc3RyaW5nIHRvIGEgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlNjRTdHIgVGhlIEJhc2U2NCBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMuZW5jLkJhc2U2NC5wYXJzZShiYXNlNjRTdHJpbmcpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAoYmFzZTY0U3RyKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgYmFzZTY0U3RyTGVuZ3RoID0gYmFzZTY0U3RyLmxlbmd0aDtcblx0ICAgICAgICAgICAgdmFyIG1hcCA9IHRoaXMuX21hcDtcblx0ICAgICAgICAgICAgdmFyIHJldmVyc2VNYXAgPSB0aGlzLl9yZXZlcnNlTWFwO1xuXG5cdCAgICAgICAgICAgIGlmICghcmV2ZXJzZU1hcCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldmVyc2VNYXAgPSB0aGlzLl9yZXZlcnNlTWFwID0gW107XG5cdCAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtYXAubGVuZ3RoOyBqKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcmV2ZXJzZU1hcFttYXAuY2hhckNvZGVBdChqKV0gPSBqO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIElnbm9yZSBwYWRkaW5nXG5cdCAgICAgICAgICAgIHZhciBwYWRkaW5nQ2hhciA9IG1hcC5jaGFyQXQoNjQpO1xuXHQgICAgICAgICAgICBpZiAocGFkZGluZ0NoYXIpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nSW5kZXggPSBiYXNlNjRTdHIuaW5kZXhPZihwYWRkaW5nQ2hhcik7XG5cdCAgICAgICAgICAgICAgICBpZiAocGFkZGluZ0luZGV4ICE9PSAtMSkge1xuXHQgICAgICAgICAgICAgICAgICAgIGJhc2U2NFN0ckxlbmd0aCA9IHBhZGRpbmdJbmRleDtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIENvbnZlcnRcblx0ICAgICAgICAgICAgcmV0dXJuIHBhcnNlTG9vcChiYXNlNjRTdHIsIGJhc2U2NFN0ckxlbmd0aCwgcmV2ZXJzZU1hcCk7XG5cblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX21hcDogJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89J1xuXHQgICAgfTtcblxuXHQgICAgZnVuY3Rpb24gcGFyc2VMb29wKGJhc2U2NFN0ciwgYmFzZTY0U3RyTGVuZ3RoLCByZXZlcnNlTWFwKSB7XG5cdCAgICAgIHZhciB3b3JkcyA9IFtdO1xuXHQgICAgICB2YXIgbkJ5dGVzID0gMDtcblx0ICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBiYXNlNjRTdHJMZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgaWYgKGkgJSA0KSB7XG5cdCAgICAgICAgICAgICAgdmFyIGJpdHMxID0gcmV2ZXJzZU1hcFtiYXNlNjRTdHIuY2hhckNvZGVBdChpIC0gMSldIDw8ICgoaSAlIDQpICogMik7XG5cdCAgICAgICAgICAgICAgdmFyIGJpdHMyID0gcmV2ZXJzZU1hcFtiYXNlNjRTdHIuY2hhckNvZGVBdChpKV0gPj4+ICg2IC0gKGkgJSA0KSAqIDIpO1xuXHQgICAgICAgICAgICAgIHZhciBiaXRzQ29tYmluZWQgPSBiaXRzMSB8IGJpdHMyO1xuXHQgICAgICAgICAgICAgIHdvcmRzW25CeXRlcyA+Pj4gMl0gfD0gYml0c0NvbWJpbmVkIDw8ICgyNCAtIChuQnl0ZXMgJSA0KSAqIDgpO1xuXHQgICAgICAgICAgICAgIG5CeXRlcysrO1xuXHQgICAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICAgIHJldHVybiBXb3JkQXJyYXkuY3JlYXRlKHdvcmRzLCBuQnl0ZXMpO1xuXHQgICAgfVxuXHR9KCkpO1xuXG5cblx0cmV0dXJuIENyeXB0b0pTLmVuYy5CYXNlNjQ7XG5cbn0pKTsiLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XG5cdGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xuXHRcdC8vIENvbW1vbkpTXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKFwiLi9jb3JlXCIpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7XG5cdCAgICB2YXIgQ19lbmMgPSBDLmVuYztcblxuXHQgICAgLyoqXG5cdCAgICAgKiBVVEYtMTYgQkUgZW5jb2Rpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBVdGYxNkJFID0gQ19lbmMuVXRmMTYgPSBDX2VuYy5VdGYxNkJFID0ge1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGEgd29yZCBhcnJheSB0byBhIFVURi0xNiBCRSBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0gd29yZEFycmF5IFRoZSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgVVRGLTE2IEJFIHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHV0ZjE2U3RyaW5nID0gQ3J5cHRvSlMuZW5jLlV0ZjE2LnN0cmluZ2lmeSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHN0cmluZ2lmeTogZnVuY3Rpb24gKHdvcmRBcnJheSkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIHdvcmRzID0gd29yZEFycmF5LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgc2lnQnl0ZXMgPSB3b3JkQXJyYXkuc2lnQnl0ZXM7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydFxuXHQgICAgICAgICAgICB2YXIgdXRmMTZDaGFycyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZ0J5dGVzOyBpICs9IDIpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBjb2RlUG9pbnQgPSAod29yZHNbaSA+Pj4gMl0gPj4+ICgxNiAtIChpICUgNCkgKiA4KSkgJiAweGZmZmY7XG5cdCAgICAgICAgICAgICAgICB1dGYxNkNoYXJzLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlUG9pbnQpKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiB1dGYxNkNoYXJzLmpvaW4oJycpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIFVURi0xNiBCRSBzdHJpbmcgdG8gYSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHV0ZjE2U3RyIFRoZSBVVEYtMTYgQkUgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5VdGYxNi5wYXJzZSh1dGYxNlN0cmluZyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcGFyc2U6IGZ1bmN0aW9uICh1dGYxNlN0cikge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgdXRmMTZTdHJMZW5ndGggPSB1dGYxNlN0ci5sZW5ndGg7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydFxuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSBbXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB1dGYxNlN0ckxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB3b3Jkc1tpID4+PiAxXSB8PSB1dGYxNlN0ci5jaGFyQ29kZUF0KGkpIDw8ICgxNiAtIChpICUgMikgKiAxNik7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gV29yZEFycmF5LmNyZWF0ZSh3b3JkcywgdXRmMTZTdHJMZW5ndGggKiAyKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXG5cdCAgICAvKipcblx0ICAgICAqIFVURi0xNiBMRSBlbmNvZGluZyBzdHJhdGVneS5cblx0ICAgICAqL1xuXHQgICAgQ19lbmMuVXRmMTZMRSA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIHdvcmQgYXJyYXkgdG8gYSBVVEYtMTYgTEUgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IHdvcmRBcnJheSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIFVURi0xNiBMRSBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciB1dGYxNlN0ciA9IENyeXB0b0pTLmVuYy5VdGYxNkxFLnN0cmluZ2lmeSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHN0cmluZ2lmeTogZnVuY3Rpb24gKHdvcmRBcnJheSkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIHdvcmRzID0gd29yZEFycmF5LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgc2lnQnl0ZXMgPSB3b3JkQXJyYXkuc2lnQnl0ZXM7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydFxuXHQgICAgICAgICAgICB2YXIgdXRmMTZDaGFycyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZ0J5dGVzOyBpICs9IDIpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBjb2RlUG9pbnQgPSBzd2FwRW5kaWFuKCh3b3Jkc1tpID4+PiAyXSA+Pj4gKDE2IC0gKGkgJSA0KSAqIDgpKSAmIDB4ZmZmZik7XG5cdCAgICAgICAgICAgICAgICB1dGYxNkNoYXJzLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlUG9pbnQpKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiB1dGYxNkNoYXJzLmpvaW4oJycpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIFVURi0xNiBMRSBzdHJpbmcgdG8gYSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHV0ZjE2U3RyIFRoZSBVVEYtMTYgTEUgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5VdGYxNkxFLnBhcnNlKHV0ZjE2U3RyKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwYXJzZTogZnVuY3Rpb24gKHV0ZjE2U3RyKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgIHZhciB1dGYxNlN0ckxlbmd0aCA9IHV0ZjE2U3RyLmxlbmd0aDtcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0XG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHV0ZjE2U3RyTGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIHdvcmRzW2kgPj4+IDFdIHw9IHN3YXBFbmRpYW4odXRmMTZTdHIuY2hhckNvZGVBdChpKSA8PCAoMTYgLSAoaSAlIDIpICogMTYpKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBXb3JkQXJyYXkuY3JlYXRlKHdvcmRzLCB1dGYxNlN0ckxlbmd0aCAqIDIpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIGZ1bmN0aW9uIHN3YXBFbmRpYW4od29yZCkge1xuXHQgICAgICAgIHJldHVybiAoKHdvcmQgPDwgOCkgJiAweGZmMDBmZjAwKSB8ICgod29yZCA+Pj4gOCkgJiAweDAwZmYwMGZmKTtcblx0ICAgIH1cblx0fSgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUy5lbmMuVXRmMTY7XG5cbn0pKTsiLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZShcIi4vY29yZVwiKSwgcmVxdWlyZShcIi4vc2hhMVwiKSwgcmVxdWlyZShcIi4vaG1hY1wiKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCIsIFwiLi9zaGExXCIsIFwiLi9obWFjXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQoZnVuY3Rpb24gKCkge1xuXHQgICAgLy8gU2hvcnRjdXRzXG5cdCAgICB2YXIgQyA9IENyeXB0b0pTO1xuXHQgICAgdmFyIENfbGliID0gQy5saWI7XG5cdCAgICB2YXIgQmFzZSA9IENfbGliLkJhc2U7XG5cdCAgICB2YXIgV29yZEFycmF5ID0gQ19saWIuV29yZEFycmF5O1xuXHQgICAgdmFyIENfYWxnbyA9IEMuYWxnbztcblx0ICAgIHZhciBNRDUgPSBDX2FsZ28uTUQ1O1xuXG5cdCAgICAvKipcblx0ICAgICAqIFRoaXMga2V5IGRlcml2YXRpb24gZnVuY3Rpb24gaXMgbWVhbnQgdG8gY29uZm9ybSB3aXRoIEVWUF9CeXRlc1RvS2V5LlxuXHQgICAgICogd3d3Lm9wZW5zc2wub3JnL2RvY3MvY3J5cHRvL0VWUF9CeXRlc1RvS2V5Lmh0bWxcblx0ICAgICAqL1xuXHQgICAgdmFyIEV2cEtERiA9IENfYWxnby5FdnBLREYgPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29uZmlndXJhdGlvbiBvcHRpb25zLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IGtleVNpemUgVGhlIGtleSBzaXplIGluIHdvcmRzIHRvIGdlbmVyYXRlLiBEZWZhdWx0OiA0ICgxMjggYml0cylcblx0ICAgICAgICAgKiBAcHJvcGVydHkge0hhc2hlcn0gaGFzaGVyIFRoZSBoYXNoIGFsZ29yaXRobSB0byB1c2UuIERlZmF1bHQ6IE1ENVxuXHQgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBpdGVyYXRpb25zIFRoZSBudW1iZXIgb2YgaXRlcmF0aW9ucyB0byBwZXJmb3JtLiBEZWZhdWx0OiAxXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2ZnOiBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgICAgIGtleVNpemU6IDEyOC8zMixcblx0ICAgICAgICAgICAgaGFzaGVyOiBNRDUsXG5cdCAgICAgICAgICAgIGl0ZXJhdGlvbnM6IDFcblx0ICAgICAgICB9KSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBrZXkgZGVyaXZhdGlvbiBmdW5jdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhlIGRlcml2YXRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBrZGYgPSBDcnlwdG9KUy5hbGdvLkV2cEtERi5jcmVhdGUoKTtcblx0ICAgICAgICAgKiAgICAgdmFyIGtkZiA9IENyeXB0b0pTLmFsZ28uRXZwS0RGLmNyZWF0ZSh7IGtleVNpemU6IDggfSk7XG5cdCAgICAgICAgICogICAgIHZhciBrZGYgPSBDcnlwdG9KUy5hbGdvLkV2cEtERi5jcmVhdGUoeyBrZXlTaXplOiA4LCBpdGVyYXRpb25zOiAxMDAwIH0pO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGluaXQ6IGZ1bmN0aW9uIChjZmcpIHtcblx0ICAgICAgICAgICAgdGhpcy5jZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRGVyaXZlcyBhIGtleSBmcm9tIGEgcGFzc3dvcmQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZC5cblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHNhbHQgQSBzYWx0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgZGVyaXZlZCBrZXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBrZXkgPSBrZGYuY29tcHV0ZShwYXNzd29yZCwgc2FsdCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY29tcHV0ZTogZnVuY3Rpb24gKHBhc3N3b3JkLCBzYWx0KSB7XG5cdCAgICAgICAgICAgIHZhciBibG9jaztcblxuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgY2ZnID0gdGhpcy5jZmc7XG5cblx0ICAgICAgICAgICAgLy8gSW5pdCBoYXNoZXJcblx0ICAgICAgICAgICAgdmFyIGhhc2hlciA9IGNmZy5oYXNoZXIuY3JlYXRlKCk7XG5cblx0ICAgICAgICAgICAgLy8gSW5pdGlhbCB2YWx1ZXNcblx0ICAgICAgICAgICAgdmFyIGRlcml2ZWRLZXkgPSBXb3JkQXJyYXkuY3JlYXRlKCk7XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBkZXJpdmVkS2V5V29yZHMgPSBkZXJpdmVkS2V5LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIga2V5U2l6ZSA9IGNmZy5rZXlTaXplO1xuXHQgICAgICAgICAgICB2YXIgaXRlcmF0aW9ucyA9IGNmZy5pdGVyYXRpb25zO1xuXG5cdCAgICAgICAgICAgIC8vIEdlbmVyYXRlIGtleVxuXHQgICAgICAgICAgICB3aGlsZSAoZGVyaXZlZEtleVdvcmRzLmxlbmd0aCA8IGtleVNpemUpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChibG9jaykge1xuXHQgICAgICAgICAgICAgICAgICAgIGhhc2hlci51cGRhdGUoYmxvY2spO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgYmxvY2sgPSBoYXNoZXIudXBkYXRlKHBhc3N3b3JkKS5maW5hbGl6ZShzYWx0KTtcblx0ICAgICAgICAgICAgICAgIGhhc2hlci5yZXNldCgpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBJdGVyYXRpb25zXG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGl0ZXJhdGlvbnM7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgICAgIGJsb2NrID0gaGFzaGVyLmZpbmFsaXplKGJsb2NrKTtcblx0ICAgICAgICAgICAgICAgICAgICBoYXNoZXIucmVzZXQoKTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgZGVyaXZlZEtleS5jb25jYXQoYmxvY2spO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGRlcml2ZWRLZXkuc2lnQnl0ZXMgPSBrZXlTaXplICogNDtcblxuXHQgICAgICAgICAgICByZXR1cm4gZGVyaXZlZEtleTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBEZXJpdmVzIGEga2V5IGZyb20gYSBwYXNzd29yZC5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZC5cblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gc2FsdCBBIHNhbHQuXG5cdCAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgY29tcHV0YXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgZGVyaXZlZCBrZXkuXG5cdCAgICAgKlxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogICAgIHZhciBrZXkgPSBDcnlwdG9KUy5FdnBLREYocGFzc3dvcmQsIHNhbHQpO1xuXHQgICAgICogICAgIHZhciBrZXkgPSBDcnlwdG9KUy5FdnBLREYocGFzc3dvcmQsIHNhbHQsIHsga2V5U2l6ZTogOCB9KTtcblx0ICAgICAqICAgICB2YXIga2V5ID0gQ3J5cHRvSlMuRXZwS0RGKHBhc3N3b3JkLCBzYWx0LCB7IGtleVNpemU6IDgsIGl0ZXJhdGlvbnM6IDEwMDAgfSk7XG5cdCAgICAgKi9cblx0ICAgIEMuRXZwS0RGID0gZnVuY3Rpb24gKHBhc3N3b3JkLCBzYWx0LCBjZmcpIHtcblx0ICAgICAgICByZXR1cm4gRXZwS0RGLmNyZWF0ZShjZmcpLmNvbXB1dGUocGFzc3dvcmQsIHNhbHQpO1xuXHQgICAgfTtcblx0fSgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUy5FdnBLREY7XG5cbn0pKTsiLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZShcIi4vY29yZVwiKSwgcmVxdWlyZShcIi4vY2lwaGVyLWNvcmVcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiLCBcIi4vY2lwaGVyLWNvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAodW5kZWZpbmVkKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBDaXBoZXJQYXJhbXMgPSBDX2xpYi5DaXBoZXJQYXJhbXM7XG5cdCAgICB2YXIgQ19lbmMgPSBDLmVuYztcblx0ICAgIHZhciBIZXggPSBDX2VuYy5IZXg7XG5cdCAgICB2YXIgQ19mb3JtYXQgPSBDLmZvcm1hdDtcblxuXHQgICAgdmFyIEhleEZvcm1hdHRlciA9IENfZm9ybWF0LkhleCA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyB0aGUgY2lwaGVydGV4dCBvZiBhIGNpcGhlciBwYXJhbXMgb2JqZWN0IHRvIGEgaGV4YWRlY2ltYWxseSBlbmNvZGVkIHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyUGFyYW1zfSBjaXBoZXJQYXJhbXMgVGhlIGNpcGhlciBwYXJhbXMgb2JqZWN0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgaGV4YWRlY2ltYWxseSBlbmNvZGVkIHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGhleFN0cmluZyA9IENyeXB0b0pTLmZvcm1hdC5IZXguc3RyaW5naWZ5KGNpcGhlclBhcmFtcyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAoY2lwaGVyUGFyYW1zKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBjaXBoZXJQYXJhbXMuY2lwaGVydGV4dC50b1N0cmluZyhIZXgpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIGhleGFkZWNpbWFsbHkgZW5jb2RlZCBjaXBoZXJ0ZXh0IHN0cmluZyB0byBhIGNpcGhlciBwYXJhbXMgb2JqZWN0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGlucHV0IFRoZSBoZXhhZGVjaW1hbGx5IGVuY29kZWQgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7Q2lwaGVyUGFyYW1zfSBUaGUgY2lwaGVyIHBhcmFtcyBvYmplY3QuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXJQYXJhbXMgPSBDcnlwdG9KUy5mb3JtYXQuSGV4LnBhcnNlKGhleFN0cmluZyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcGFyc2U6IGZ1bmN0aW9uIChpbnB1dCkge1xuXHQgICAgICAgICAgICB2YXIgY2lwaGVydGV4dCA9IEhleC5wYXJzZShpbnB1dCk7XG5cdCAgICAgICAgICAgIHJldHVybiBDaXBoZXJQYXJhbXMuY3JlYXRlKHsgY2lwaGVydGV4dDogY2lwaGVydGV4dCB9KTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHR9KCkpO1xuXG5cblx0cmV0dXJuIENyeXB0b0pTLmZvcm1hdC5IZXg7XG5cbn0pKTsiLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XG5cdGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xuXHRcdC8vIENvbW1vbkpTXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKFwiLi9jb3JlXCIpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBCYXNlID0gQ19saWIuQmFzZTtcblx0ICAgIHZhciBDX2VuYyA9IEMuZW5jO1xuXHQgICAgdmFyIFV0ZjggPSBDX2VuYy5VdGY4O1xuXHQgICAgdmFyIENfYWxnbyA9IEMuYWxnbztcblxuXHQgICAgLyoqXG5cdCAgICAgKiBITUFDIGFsZ29yaXRobS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEhNQUMgPSBDX2FsZ28uSE1BQyA9IEJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ld2x5IGNyZWF0ZWQgSE1BQy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7SGFzaGVyfSBoYXNoZXIgVGhlIGhhc2ggYWxnb3JpdGhtIHRvIHVzZS5cblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGtleSBUaGUgc2VjcmV0IGtleS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGhtYWNIYXNoZXIgPSBDcnlwdG9KUy5hbGdvLkhNQUMuY3JlYXRlKENyeXB0b0pTLmFsZ28uU0hBMjU2LCBrZXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGluaXQ6IGZ1bmN0aW9uIChoYXNoZXIsIGtleSkge1xuXHQgICAgICAgICAgICAvLyBJbml0IGhhc2hlclxuXHQgICAgICAgICAgICBoYXNoZXIgPSB0aGlzLl9oYXNoZXIgPSBuZXcgaGFzaGVyLmluaXQoKTtcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0IHN0cmluZyB0byBXb3JkQXJyYXksIGVsc2UgYXNzdW1lIFdvcmRBcnJheSBhbHJlYWR5XG5cdCAgICAgICAgICAgIGlmICh0eXBlb2Yga2V5ID09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgICAgICBrZXkgPSBVdGY4LnBhcnNlKGtleSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGhhc2hlckJsb2NrU2l6ZSA9IGhhc2hlci5ibG9ja1NpemU7XG5cdCAgICAgICAgICAgIHZhciBoYXNoZXJCbG9ja1NpemVCeXRlcyA9IGhhc2hlckJsb2NrU2l6ZSAqIDQ7XG5cblx0ICAgICAgICAgICAgLy8gQWxsb3cgYXJiaXRyYXJ5IGxlbmd0aCBrZXlzXG5cdCAgICAgICAgICAgIGlmIChrZXkuc2lnQnl0ZXMgPiBoYXNoZXJCbG9ja1NpemVCeXRlcykge1xuXHQgICAgICAgICAgICAgICAga2V5ID0gaGFzaGVyLmZpbmFsaXplKGtleSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBDbGFtcCBleGNlc3MgYml0c1xuXHQgICAgICAgICAgICBrZXkuY2xhbXAoKTtcblxuXHQgICAgICAgICAgICAvLyBDbG9uZSBrZXkgZm9yIGlubmVyIGFuZCBvdXRlciBwYWRzXG5cdCAgICAgICAgICAgIHZhciBvS2V5ID0gdGhpcy5fb0tleSA9IGtleS5jbG9uZSgpO1xuXHQgICAgICAgICAgICB2YXIgaUtleSA9IHRoaXMuX2lLZXkgPSBrZXkuY2xvbmUoKTtcblxuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIG9LZXlXb3JkcyA9IG9LZXkud29yZHM7XG5cdCAgICAgICAgICAgIHZhciBpS2V5V29yZHMgPSBpS2V5LndvcmRzO1xuXG5cdCAgICAgICAgICAgIC8vIFhPUiBrZXlzIHdpdGggcGFkIGNvbnN0YW50c1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhhc2hlckJsb2NrU2l6ZTsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICBvS2V5V29yZHNbaV0gXj0gMHg1YzVjNWM1Yztcblx0ICAgICAgICAgICAgICAgIGlLZXlXb3Jkc1tpXSBePSAweDM2MzYzNjM2O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIG9LZXkuc2lnQnl0ZXMgPSBpS2V5LnNpZ0J5dGVzID0gaGFzaGVyQmxvY2tTaXplQnl0ZXM7XG5cblx0ICAgICAgICAgICAgLy8gU2V0IGluaXRpYWwgdmFsdWVzXG5cdCAgICAgICAgICAgIHRoaXMucmVzZXQoKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmVzZXRzIHRoaXMgSE1BQyB0byBpdHMgaW5pdGlhbCBzdGF0ZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgaG1hY0hhc2hlci5yZXNldCgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHJlc2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgIHZhciBoYXNoZXIgPSB0aGlzLl9oYXNoZXI7XG5cblx0ICAgICAgICAgICAgLy8gUmVzZXRcblx0ICAgICAgICAgICAgaGFzaGVyLnJlc2V0KCk7XG5cdCAgICAgICAgICAgIGhhc2hlci51cGRhdGUodGhpcy5faUtleSk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFVwZGF0ZXMgdGhpcyBITUFDIHdpdGggYSBtZXNzYWdlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlVXBkYXRlIFRoZSBtZXNzYWdlIHRvIGFwcGVuZC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge0hNQUN9IFRoaXMgSE1BQyBpbnN0YW5jZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgaG1hY0hhc2hlci51cGRhdGUoJ21lc3NhZ2UnKTtcblx0ICAgICAgICAgKiAgICAgaG1hY0hhc2hlci51cGRhdGUod29yZEFycmF5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB1cGRhdGU6IGZ1bmN0aW9uIChtZXNzYWdlVXBkYXRlKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2hhc2hlci51cGRhdGUobWVzc2FnZVVwZGF0ZSk7XG5cblx0ICAgICAgICAgICAgLy8gQ2hhaW5hYmxlXG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBGaW5hbGl6ZXMgdGhlIEhNQUMgY29tcHV0YXRpb24uXG5cdCAgICAgICAgICogTm90ZSB0aGF0IHRoZSBmaW5hbGl6ZSBvcGVyYXRpb24gaXMgZWZmZWN0aXZlbHkgYSBkZXN0cnVjdGl2ZSwgcmVhZC1vbmNlIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZVVwZGF0ZSAoT3B0aW9uYWwpIEEgZmluYWwgbWVzc2FnZSB1cGRhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBITUFDLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaG1hYyA9IGhtYWNIYXNoZXIuZmluYWxpemUoKTtcblx0ICAgICAgICAgKiAgICAgdmFyIGhtYWMgPSBobWFjSGFzaGVyLmZpbmFsaXplKCdtZXNzYWdlJyk7XG5cdCAgICAgICAgICogICAgIHZhciBobWFjID0gaG1hY0hhc2hlci5maW5hbGl6ZSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGZpbmFsaXplOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgaGFzaGVyID0gdGhpcy5faGFzaGVyO1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGUgSE1BQ1xuXHQgICAgICAgICAgICB2YXIgaW5uZXJIYXNoID0gaGFzaGVyLmZpbmFsaXplKG1lc3NhZ2VVcGRhdGUpO1xuXHQgICAgICAgICAgICBoYXNoZXIucmVzZXQoKTtcblx0ICAgICAgICAgICAgdmFyIGhtYWMgPSBoYXNoZXIuZmluYWxpemUodGhpcy5fb0tleS5jbG9uZSgpLmNvbmNhdChpbm5lckhhc2gpKTtcblxuXHQgICAgICAgICAgICByZXR1cm4gaG1hYztcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0fSgpKTtcblxuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIiksIHJlcXVpcmUoXCIuL3g2NC1jb3JlXCIpLCByZXF1aXJlKFwiLi9saWItdHlwZWRhcnJheXNcIiksIHJlcXVpcmUoXCIuL2VuYy11dGYxNlwiKSwgcmVxdWlyZShcIi4vZW5jLWJhc2U2NFwiKSwgcmVxdWlyZShcIi4vbWQ1XCIpLCByZXF1aXJlKFwiLi9zaGExXCIpLCByZXF1aXJlKFwiLi9zaGEyNTZcIiksIHJlcXVpcmUoXCIuL3NoYTIyNFwiKSwgcmVxdWlyZShcIi4vc2hhNTEyXCIpLCByZXF1aXJlKFwiLi9zaGEzODRcIiksIHJlcXVpcmUoXCIuL3NoYTNcIiksIHJlcXVpcmUoXCIuL3JpcGVtZDE2MFwiKSwgcmVxdWlyZShcIi4vaG1hY1wiKSwgcmVxdWlyZShcIi4vcGJrZGYyXCIpLCByZXF1aXJlKFwiLi9ldnBrZGZcIiksIHJlcXVpcmUoXCIuL2NpcGhlci1jb3JlXCIpLCByZXF1aXJlKFwiLi9tb2RlLWNmYlwiKSwgcmVxdWlyZShcIi4vbW9kZS1jdHJcIiksIHJlcXVpcmUoXCIuL21vZGUtY3RyLWdsYWRtYW5cIiksIHJlcXVpcmUoXCIuL21vZGUtb2ZiXCIpLCByZXF1aXJlKFwiLi9tb2RlLWVjYlwiKSwgcmVxdWlyZShcIi4vcGFkLWFuc2l4OTIzXCIpLCByZXF1aXJlKFwiLi9wYWQtaXNvMTAxMjZcIiksIHJlcXVpcmUoXCIuL3BhZC1pc285Nzk3MVwiKSwgcmVxdWlyZShcIi4vcGFkLXplcm9wYWRkaW5nXCIpLCByZXF1aXJlKFwiLi9wYWQtbm9wYWRkaW5nXCIpLCByZXF1aXJlKFwiLi9mb3JtYXQtaGV4XCIpLCByZXF1aXJlKFwiLi9hZXNcIiksIHJlcXVpcmUoXCIuL3RyaXBsZWRlc1wiKSwgcmVxdWlyZShcIi4vcmM0XCIpLCByZXF1aXJlKFwiLi9yYWJiaXRcIiksIHJlcXVpcmUoXCIuL3JhYmJpdC1sZWdhY3lcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiLCBcIi4veDY0LWNvcmVcIiwgXCIuL2xpYi10eXBlZGFycmF5c1wiLCBcIi4vZW5jLXV0ZjE2XCIsIFwiLi9lbmMtYmFzZTY0XCIsIFwiLi9tZDVcIiwgXCIuL3NoYTFcIiwgXCIuL3NoYTI1NlwiLCBcIi4vc2hhMjI0XCIsIFwiLi9zaGE1MTJcIiwgXCIuL3NoYTM4NFwiLCBcIi4vc2hhM1wiLCBcIi4vcmlwZW1kMTYwXCIsIFwiLi9obWFjXCIsIFwiLi9wYmtkZjJcIiwgXCIuL2V2cGtkZlwiLCBcIi4vY2lwaGVyLWNvcmVcIiwgXCIuL21vZGUtY2ZiXCIsIFwiLi9tb2RlLWN0clwiLCBcIi4vbW9kZS1jdHItZ2xhZG1hblwiLCBcIi4vbW9kZS1vZmJcIiwgXCIuL21vZGUtZWNiXCIsIFwiLi9wYWQtYW5zaXg5MjNcIiwgXCIuL3BhZC1pc28xMDEyNlwiLCBcIi4vcGFkLWlzbzk3OTcxXCIsIFwiLi9wYWQtemVyb3BhZGRpbmdcIiwgXCIuL3BhZC1ub3BhZGRpbmdcIiwgXCIuL2Zvcm1hdC1oZXhcIiwgXCIuL2Flc1wiLCBcIi4vdHJpcGxlZGVzXCIsIFwiLi9yYzRcIiwgXCIuL3JhYmJpdFwiLCBcIi4vcmFiYml0LWxlZ2FjeVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdHJvb3QuQ3J5cHRvSlMgPSBmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdHJldHVybiBDcnlwdG9KUztcblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0KGZ1bmN0aW9uICgpIHtcblx0ICAgIC8vIENoZWNrIGlmIHR5cGVkIGFycmF5cyBhcmUgc3VwcG9ydGVkXG5cdCAgICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9ICdmdW5jdGlvbicpIHtcblx0ICAgICAgICByZXR1cm47XG5cdCAgICB9XG5cblx0ICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgdmFyIEMgPSBDcnlwdG9KUztcblx0ICAgIHZhciBDX2xpYiA9IEMubGliO1xuXHQgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTtcblxuXHQgICAgLy8gUmVmZXJlbmNlIG9yaWdpbmFsIGluaXRcblx0ICAgIHZhciBzdXBlckluaXQgPSBXb3JkQXJyYXkuaW5pdDtcblxuXHQgICAgLy8gQXVnbWVudCBXb3JkQXJyYXkuaW5pdCB0byBoYW5kbGUgdHlwZWQgYXJyYXlzXG5cdCAgICB2YXIgc3ViSW5pdCA9IFdvcmRBcnJheS5pbml0ID0gZnVuY3Rpb24gKHR5cGVkQXJyYXkpIHtcblx0ICAgICAgICAvLyBDb252ZXJ0IGJ1ZmZlcnMgdG8gdWludDhcblx0ICAgICAgICBpZiAodHlwZWRBcnJheSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG5cdCAgICAgICAgICAgIHR5cGVkQXJyYXkgPSBuZXcgVWludDhBcnJheSh0eXBlZEFycmF5KTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvLyBDb252ZXJ0IG90aGVyIGFycmF5IHZpZXdzIHRvIHVpbnQ4XG5cdCAgICAgICAgaWYgKFxuXHQgICAgICAgICAgICB0eXBlZEFycmF5IGluc3RhbmNlb2YgSW50OEFycmF5IHx8XG5cdCAgICAgICAgICAgICh0eXBlb2YgVWludDhDbGFtcGVkQXJyYXkgIT09IFwidW5kZWZpbmVkXCIgJiYgdHlwZWRBcnJheSBpbnN0YW5jZW9mIFVpbnQ4Q2xhbXBlZEFycmF5KSB8fFxuXHQgICAgICAgICAgICB0eXBlZEFycmF5IGluc3RhbmNlb2YgSW50MTZBcnJheSB8fFxuXHQgICAgICAgICAgICB0eXBlZEFycmF5IGluc3RhbmNlb2YgVWludDE2QXJyYXkgfHxcblx0ICAgICAgICAgICAgdHlwZWRBcnJheSBpbnN0YW5jZW9mIEludDMyQXJyYXkgfHxcblx0ICAgICAgICAgICAgdHlwZWRBcnJheSBpbnN0YW5jZW9mIFVpbnQzMkFycmF5IHx8XG5cdCAgICAgICAgICAgIHR5cGVkQXJyYXkgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgfHxcblx0ICAgICAgICAgICAgdHlwZWRBcnJheSBpbnN0YW5jZW9mIEZsb2F0NjRBcnJheVxuXHQgICAgICAgICkge1xuXHQgICAgICAgICAgICB0eXBlZEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkodHlwZWRBcnJheS5idWZmZXIsIHR5cGVkQXJyYXkuYnl0ZU9mZnNldCwgdHlwZWRBcnJheS5ieXRlTGVuZ3RoKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvLyBIYW5kbGUgVWludDhBcnJheVxuXHQgICAgICAgIGlmICh0eXBlZEFycmF5IGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgdHlwZWRBcnJheUJ5dGVMZW5ndGggPSB0eXBlZEFycmF5LmJ5dGVMZW5ndGg7XG5cblx0ICAgICAgICAgICAgLy8gRXh0cmFjdCBieXRlc1xuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSBbXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0eXBlZEFycmF5Qnl0ZUxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB3b3Jkc1tpID4+PiAyXSB8PSB0eXBlZEFycmF5W2ldIDw8ICgyNCAtIChpICUgNCkgKiA4KTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIEluaXRpYWxpemUgdGhpcyB3b3JkIGFycmF5XG5cdCAgICAgICAgICAgIHN1cGVySW5pdC5jYWxsKHRoaXMsIHdvcmRzLCB0eXBlZEFycmF5Qnl0ZUxlbmd0aCk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgLy8gRWxzZSBjYWxsIG5vcm1hbCBpbml0XG5cdCAgICAgICAgICAgIHN1cGVySW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIHN1YkluaXQucHJvdG90eXBlID0gV29yZEFycmF5O1xuXHR9KCkpO1xuXG5cblx0cmV0dXJuIENyeXB0b0pTLmxpYi5Xb3JkQXJyYXk7XG5cbn0pKTsiLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XG5cdGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xuXHRcdC8vIENvbW1vbkpTXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKFwiLi9jb3JlXCIpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAoTWF0aCkge1xuXHQgICAgLy8gU2hvcnRjdXRzXG5cdCAgICB2YXIgQyA9IENyeXB0b0pTO1xuXHQgICAgdmFyIENfbGliID0gQy5saWI7XG5cdCAgICB2YXIgV29yZEFycmF5ID0gQ19saWIuV29yZEFycmF5O1xuXHQgICAgdmFyIEhhc2hlciA9IENfbGliLkhhc2hlcjtcblx0ICAgIHZhciBDX2FsZ28gPSBDLmFsZ287XG5cblx0ICAgIC8vIENvbnN0YW50cyB0YWJsZVxuXHQgICAgdmFyIFQgPSBbXTtcblxuXHQgICAgLy8gQ29tcHV0ZSBjb25zdGFudHNcblx0ICAgIChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA2NDsgaSsrKSB7XG5cdCAgICAgICAgICAgIFRbaV0gPSAoTWF0aC5hYnMoTWF0aC5zaW4oaSArIDEpKSAqIDB4MTAwMDAwMDAwKSB8IDA7XG5cdCAgICAgICAgfVxuXHQgICAgfSgpKTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBNRDUgaGFzaCBhbGdvcml0aG0uXG5cdCAgICAgKi9cblx0ICAgIHZhciBNRDUgPSBDX2FsZ28uTUQ1ID0gSGFzaGVyLmV4dGVuZCh7XG5cdCAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdGhpcy5faGFzaCA9IG5ldyBXb3JkQXJyYXkuaW5pdChbXG5cdCAgICAgICAgICAgICAgICAweDY3NDUyMzAxLCAweGVmY2RhYjg5LFxuXHQgICAgICAgICAgICAgICAgMHg5OGJhZGNmZSwgMHgxMDMyNTQ3NlxuXHQgICAgICAgICAgICBdKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7XG5cdCAgICAgICAgICAgIC8vIFN3YXAgZW5kaWFuXG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgICAgICB2YXIgb2Zmc2V0X2kgPSBvZmZzZXQgKyBpO1xuXHQgICAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0X2kgPSBNW29mZnNldF9pXTtcblxuXHQgICAgICAgICAgICAgICAgTVtvZmZzZXRfaV0gPSAoXG5cdCAgICAgICAgICAgICAgICAgICAgKCgoTV9vZmZzZXRfaSA8PCA4KSAgfCAoTV9vZmZzZXRfaSA+Pj4gMjQpKSAmIDB4MDBmZjAwZmYpIHxcblx0ICAgICAgICAgICAgICAgICAgICAoKChNX29mZnNldF9pIDw8IDI0KSB8IChNX29mZnNldF9pID4+PiA4KSkgICYgMHhmZjAwZmYwMClcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIEggPSB0aGlzLl9oYXNoLndvcmRzO1xuXG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8wICA9IE1bb2Zmc2V0ICsgMF07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8xICA9IE1bb2Zmc2V0ICsgMV07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8yICA9IE1bb2Zmc2V0ICsgMl07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8zICA9IE1bb2Zmc2V0ICsgM107XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF80ICA9IE1bb2Zmc2V0ICsgNF07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF81ICA9IE1bb2Zmc2V0ICsgNV07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF82ICA9IE1bb2Zmc2V0ICsgNl07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF83ICA9IE1bb2Zmc2V0ICsgN107XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF84ICA9IE1bb2Zmc2V0ICsgOF07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF85ICA9IE1bb2Zmc2V0ICsgOV07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8xMCA9IE1bb2Zmc2V0ICsgMTBdO1xuXHQgICAgICAgICAgICB2YXIgTV9vZmZzZXRfMTEgPSBNW29mZnNldCArIDExXTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzEyID0gTVtvZmZzZXQgKyAxMl07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8xMyA9IE1bb2Zmc2V0ICsgMTNdO1xuXHQgICAgICAgICAgICB2YXIgTV9vZmZzZXRfMTQgPSBNW29mZnNldCArIDE0XTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzE1ID0gTVtvZmZzZXQgKyAxNV07XG5cblx0ICAgICAgICAgICAgLy8gV29ya2luZyB2YXJpYWxiZXNcblx0ICAgICAgICAgICAgdmFyIGEgPSBIWzBdO1xuXHQgICAgICAgICAgICB2YXIgYiA9IEhbMV07XG5cdCAgICAgICAgICAgIHZhciBjID0gSFsyXTtcblx0ICAgICAgICAgICAgdmFyIGQgPSBIWzNdO1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGF0aW9uXG5cdCAgICAgICAgICAgIGEgPSBGRihhLCBiLCBjLCBkLCBNX29mZnNldF8wLCAgNywgIFRbMF0pO1xuXHQgICAgICAgICAgICBkID0gRkYoZCwgYSwgYiwgYywgTV9vZmZzZXRfMSwgIDEyLCBUWzFdKTtcblx0ICAgICAgICAgICAgYyA9IEZGKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzIsICAxNywgVFsyXSk7XG5cdCAgICAgICAgICAgIGIgPSBGRihiLCBjLCBkLCBhLCBNX29mZnNldF8zLCAgMjIsIFRbM10pO1xuXHQgICAgICAgICAgICBhID0gRkYoYSwgYiwgYywgZCwgTV9vZmZzZXRfNCwgIDcsICBUWzRdKTtcblx0ICAgICAgICAgICAgZCA9IEZGKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzUsICAxMiwgVFs1XSk7XG5cdCAgICAgICAgICAgIGMgPSBGRihjLCBkLCBhLCBiLCBNX29mZnNldF82LCAgMTcsIFRbNl0pO1xuXHQgICAgICAgICAgICBiID0gRkYoYiwgYywgZCwgYSwgTV9vZmZzZXRfNywgIDIyLCBUWzddKTtcblx0ICAgICAgICAgICAgYSA9IEZGKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzgsICA3LCAgVFs4XSk7XG5cdCAgICAgICAgICAgIGQgPSBGRihkLCBhLCBiLCBjLCBNX29mZnNldF85LCAgMTIsIFRbOV0pO1xuXHQgICAgICAgICAgICBjID0gRkYoYywgZCwgYSwgYiwgTV9vZmZzZXRfMTAsIDE3LCBUWzEwXSk7XG5cdCAgICAgICAgICAgIGIgPSBGRihiLCBjLCBkLCBhLCBNX29mZnNldF8xMSwgMjIsIFRbMTFdKTtcblx0ICAgICAgICAgICAgYSA9IEZGKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzEyLCA3LCAgVFsxMl0pO1xuXHQgICAgICAgICAgICBkID0gRkYoZCwgYSwgYiwgYywgTV9vZmZzZXRfMTMsIDEyLCBUWzEzXSk7XG5cdCAgICAgICAgICAgIGMgPSBGRihjLCBkLCBhLCBiLCBNX29mZnNldF8xNCwgMTcsIFRbMTRdKTtcblx0ICAgICAgICAgICAgYiA9IEZGKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzE1LCAyMiwgVFsxNV0pO1xuXG5cdCAgICAgICAgICAgIGEgPSBHRyhhLCBiLCBjLCBkLCBNX29mZnNldF8xLCAgNSwgIFRbMTZdKTtcblx0ICAgICAgICAgICAgZCA9IEdHKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzYsICA5LCAgVFsxN10pO1xuXHQgICAgICAgICAgICBjID0gR0coYywgZCwgYSwgYiwgTV9vZmZzZXRfMTEsIDE0LCBUWzE4XSk7XG5cdCAgICAgICAgICAgIGIgPSBHRyhiLCBjLCBkLCBhLCBNX29mZnNldF8wLCAgMjAsIFRbMTldKTtcblx0ICAgICAgICAgICAgYSA9IEdHKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzUsICA1LCAgVFsyMF0pO1xuXHQgICAgICAgICAgICBkID0gR0coZCwgYSwgYiwgYywgTV9vZmZzZXRfMTAsIDksICBUWzIxXSk7XG5cdCAgICAgICAgICAgIGMgPSBHRyhjLCBkLCBhLCBiLCBNX29mZnNldF8xNSwgMTQsIFRbMjJdKTtcblx0ICAgICAgICAgICAgYiA9IEdHKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzQsICAyMCwgVFsyM10pO1xuXHQgICAgICAgICAgICBhID0gR0coYSwgYiwgYywgZCwgTV9vZmZzZXRfOSwgIDUsICBUWzI0XSk7XG5cdCAgICAgICAgICAgIGQgPSBHRyhkLCBhLCBiLCBjLCBNX29mZnNldF8xNCwgOSwgIFRbMjVdKTtcblx0ICAgICAgICAgICAgYyA9IEdHKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzMsICAxNCwgVFsyNl0pO1xuXHQgICAgICAgICAgICBiID0gR0coYiwgYywgZCwgYSwgTV9vZmZzZXRfOCwgIDIwLCBUWzI3XSk7XG5cdCAgICAgICAgICAgIGEgPSBHRyhhLCBiLCBjLCBkLCBNX29mZnNldF8xMywgNSwgIFRbMjhdKTtcblx0ICAgICAgICAgICAgZCA9IEdHKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzIsICA5LCAgVFsyOV0pO1xuXHQgICAgICAgICAgICBjID0gR0coYywgZCwgYSwgYiwgTV9vZmZzZXRfNywgIDE0LCBUWzMwXSk7XG5cdCAgICAgICAgICAgIGIgPSBHRyhiLCBjLCBkLCBhLCBNX29mZnNldF8xMiwgMjAsIFRbMzFdKTtcblxuXHQgICAgICAgICAgICBhID0gSEgoYSwgYiwgYywgZCwgTV9vZmZzZXRfNSwgIDQsICBUWzMyXSk7XG5cdCAgICAgICAgICAgIGQgPSBISChkLCBhLCBiLCBjLCBNX29mZnNldF84LCAgMTEsIFRbMzNdKTtcblx0ICAgICAgICAgICAgYyA9IEhIKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzExLCAxNiwgVFszNF0pO1xuXHQgICAgICAgICAgICBiID0gSEgoYiwgYywgZCwgYSwgTV9vZmZzZXRfMTQsIDIzLCBUWzM1XSk7XG5cdCAgICAgICAgICAgIGEgPSBISChhLCBiLCBjLCBkLCBNX29mZnNldF8xLCAgNCwgIFRbMzZdKTtcblx0ICAgICAgICAgICAgZCA9IEhIKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzQsICAxMSwgVFszN10pO1xuXHQgICAgICAgICAgICBjID0gSEgoYywgZCwgYSwgYiwgTV9vZmZzZXRfNywgIDE2LCBUWzM4XSk7XG5cdCAgICAgICAgICAgIGIgPSBISChiLCBjLCBkLCBhLCBNX29mZnNldF8xMCwgMjMsIFRbMzldKTtcblx0ICAgICAgICAgICAgYSA9IEhIKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzEzLCA0LCAgVFs0MF0pO1xuXHQgICAgICAgICAgICBkID0gSEgoZCwgYSwgYiwgYywgTV9vZmZzZXRfMCwgIDExLCBUWzQxXSk7XG5cdCAgICAgICAgICAgIGMgPSBISChjLCBkLCBhLCBiLCBNX29mZnNldF8zLCAgMTYsIFRbNDJdKTtcblx0ICAgICAgICAgICAgYiA9IEhIKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzYsICAyMywgVFs0M10pO1xuXHQgICAgICAgICAgICBhID0gSEgoYSwgYiwgYywgZCwgTV9vZmZzZXRfOSwgIDQsICBUWzQ0XSk7XG5cdCAgICAgICAgICAgIGQgPSBISChkLCBhLCBiLCBjLCBNX29mZnNldF8xMiwgMTEsIFRbNDVdKTtcblx0ICAgICAgICAgICAgYyA9IEhIKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzE1LCAxNiwgVFs0Nl0pO1xuXHQgICAgICAgICAgICBiID0gSEgoYiwgYywgZCwgYSwgTV9vZmZzZXRfMiwgIDIzLCBUWzQ3XSk7XG5cblx0ICAgICAgICAgICAgYSA9IElJKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzAsICA2LCAgVFs0OF0pO1xuXHQgICAgICAgICAgICBkID0gSUkoZCwgYSwgYiwgYywgTV9vZmZzZXRfNywgIDEwLCBUWzQ5XSk7XG5cdCAgICAgICAgICAgIGMgPSBJSShjLCBkLCBhLCBiLCBNX29mZnNldF8xNCwgMTUsIFRbNTBdKTtcblx0ICAgICAgICAgICAgYiA9IElJKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzUsICAyMSwgVFs1MV0pO1xuXHQgICAgICAgICAgICBhID0gSUkoYSwgYiwgYywgZCwgTV9vZmZzZXRfMTIsIDYsICBUWzUyXSk7XG5cdCAgICAgICAgICAgIGQgPSBJSShkLCBhLCBiLCBjLCBNX29mZnNldF8zLCAgMTAsIFRbNTNdKTtcblx0ICAgICAgICAgICAgYyA9IElJKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzEwLCAxNSwgVFs1NF0pO1xuXHQgICAgICAgICAgICBiID0gSUkoYiwgYywgZCwgYSwgTV9vZmZzZXRfMSwgIDIxLCBUWzU1XSk7XG5cdCAgICAgICAgICAgIGEgPSBJSShhLCBiLCBjLCBkLCBNX29mZnNldF84LCAgNiwgIFRbNTZdKTtcblx0ICAgICAgICAgICAgZCA9IElJKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzE1LCAxMCwgVFs1N10pO1xuXHQgICAgICAgICAgICBjID0gSUkoYywgZCwgYSwgYiwgTV9vZmZzZXRfNiwgIDE1LCBUWzU4XSk7XG5cdCAgICAgICAgICAgIGIgPSBJSShiLCBjLCBkLCBhLCBNX29mZnNldF8xMywgMjEsIFRbNTldKTtcblx0ICAgICAgICAgICAgYSA9IElJKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzQsICA2LCAgVFs2MF0pO1xuXHQgICAgICAgICAgICBkID0gSUkoZCwgYSwgYiwgYywgTV9vZmZzZXRfMTEsIDEwLCBUWzYxXSk7XG5cdCAgICAgICAgICAgIGMgPSBJSShjLCBkLCBhLCBiLCBNX29mZnNldF8yLCAgMTUsIFRbNjJdKTtcblx0ICAgICAgICAgICAgYiA9IElJKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzksICAyMSwgVFs2M10pO1xuXG5cdCAgICAgICAgICAgIC8vIEludGVybWVkaWF0ZSBoYXNoIHZhbHVlXG5cdCAgICAgICAgICAgIEhbMF0gPSAoSFswXSArIGEpIHwgMDtcblx0ICAgICAgICAgICAgSFsxXSA9IChIWzFdICsgYikgfCAwO1xuXHQgICAgICAgICAgICBIWzJdID0gKEhbMl0gKyBjKSB8IDA7XG5cdCAgICAgICAgICAgIEhbM10gPSAoSFszXSArIGQpIHwgMDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBkYXRhID0gdGhpcy5fZGF0YTtcblx0ICAgICAgICAgICAgdmFyIGRhdGFXb3JkcyA9IGRhdGEud29yZHM7XG5cblx0ICAgICAgICAgICAgdmFyIG5CaXRzVG90YWwgPSB0aGlzLl9uRGF0YUJ5dGVzICogODtcblx0ICAgICAgICAgICAgdmFyIG5CaXRzTGVmdCA9IGRhdGEuc2lnQnl0ZXMgKiA4O1xuXG5cdCAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nXG5cdCAgICAgICAgICAgIGRhdGFXb3Jkc1tuQml0c0xlZnQgPj4+IDVdIHw9IDB4ODAgPDwgKDI0IC0gbkJpdHNMZWZ0ICUgMzIpO1xuXG5cdCAgICAgICAgICAgIHZhciBuQml0c1RvdGFsSCA9IE1hdGguZmxvb3IobkJpdHNUb3RhbCAvIDB4MTAwMDAwMDAwKTtcblx0ICAgICAgICAgICAgdmFyIG5CaXRzVG90YWxMID0gbkJpdHNUb3RhbDtcblx0ICAgICAgICAgICAgZGF0YVdvcmRzWygoKG5CaXRzTGVmdCArIDY0KSA+Pj4gOSkgPDwgNCkgKyAxNV0gPSAoXG5cdCAgICAgICAgICAgICAgICAoKChuQml0c1RvdGFsSCA8PCA4KSAgfCAobkJpdHNUb3RhbEggPj4+IDI0KSkgJiAweDAwZmYwMGZmKSB8XG5cdCAgICAgICAgICAgICAgICAoKChuQml0c1RvdGFsSCA8PCAyNCkgfCAobkJpdHNUb3RhbEggPj4+IDgpKSAgJiAweGZmMDBmZjAwKVxuXHQgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICBkYXRhV29yZHNbKCgobkJpdHNMZWZ0ICsgNjQpID4+PiA5KSA8PCA0KSArIDE0XSA9IChcblx0ICAgICAgICAgICAgICAgICgoKG5CaXRzVG90YWxMIDw8IDgpICB8IChuQml0c1RvdGFsTCA+Pj4gMjQpKSAmIDB4MDBmZjAwZmYpIHxcblx0ICAgICAgICAgICAgICAgICgoKG5CaXRzVG90YWxMIDw8IDI0KSB8IChuQml0c1RvdGFsTCA+Pj4gOCkpICAmIDB4ZmYwMGZmMDApXG5cdCAgICAgICAgICAgICk7XG5cblx0ICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyA9IChkYXRhV29yZHMubGVuZ3RoICsgMSkgKiA0O1xuXG5cdCAgICAgICAgICAgIC8vIEhhc2ggZmluYWwgYmxvY2tzXG5cdCAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3MoKTtcblxuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGhhc2ggPSB0aGlzLl9oYXNoO1xuXHQgICAgICAgICAgICB2YXIgSCA9IGhhc2gud29yZHM7XG5cblx0ICAgICAgICAgICAgLy8gU3dhcCBlbmRpYW5cblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgICAgICB2YXIgSF9pID0gSFtpXTtcblxuXHQgICAgICAgICAgICAgICAgSFtpXSA9ICgoKEhfaSA8PCA4KSAgfCAoSF9pID4+PiAyNCkpICYgMHgwMGZmMDBmZikgfFxuXHQgICAgICAgICAgICAgICAgICAgICAgICgoKEhfaSA8PCAyNCkgfCAoSF9pID4+PiA4KSkgICYgMHhmZjAwZmYwMCk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBSZXR1cm4gZmluYWwgY29tcHV0ZWQgaGFzaFxuXHQgICAgICAgICAgICByZXR1cm4gaGFzaDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdmFyIGNsb25lID0gSGFzaGVyLmNsb25lLmNhbGwodGhpcyk7XG5cdCAgICAgICAgICAgIGNsb25lLl9oYXNoID0gdGhpcy5faGFzaC5jbG9uZSgpO1xuXG5cdCAgICAgICAgICAgIHJldHVybiBjbG9uZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgZnVuY3Rpb24gRkYoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuXHQgICAgICAgIHZhciBuID0gYSArICgoYiAmIGMpIHwgKH5iICYgZCkpICsgeCArIHQ7XG5cdCAgICAgICAgcmV0dXJuICgobiA8PCBzKSB8IChuID4+PiAoMzIgLSBzKSkpICsgYjtcblx0ICAgIH1cblxuXHQgICAgZnVuY3Rpb24gR0coYSwgYiwgYywgZCwgeCwgcywgdCkge1xuXHQgICAgICAgIHZhciBuID0gYSArICgoYiAmIGQpIHwgKGMgJiB+ZCkpICsgeCArIHQ7XG5cdCAgICAgICAgcmV0dXJuICgobiA8PCBzKSB8IChuID4+PiAoMzIgLSBzKSkpICsgYjtcblx0ICAgIH1cblxuXHQgICAgZnVuY3Rpb24gSEgoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuXHQgICAgICAgIHZhciBuID0gYSArIChiIF4gYyBeIGQpICsgeCArIHQ7XG5cdCAgICAgICAgcmV0dXJuICgobiA8PCBzKSB8IChuID4+PiAoMzIgLSBzKSkpICsgYjtcblx0ICAgIH1cblxuXHQgICAgZnVuY3Rpb24gSUkoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuXHQgICAgICAgIHZhciBuID0gYSArIChjIF4gKGIgfCB+ZCkpICsgeCArIHQ7XG5cdCAgICAgICAgcmV0dXJuICgobiA8PCBzKSB8IChuID4+PiAoMzIgLSBzKSkpICsgYjtcblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLk1ENSgnbWVzc2FnZScpO1xuXHQgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuTUQ1KHdvcmRBcnJheSk7XG5cdCAgICAgKi9cblx0ICAgIEMuTUQ1ID0gSGFzaGVyLl9jcmVhdGVIZWxwZXIoTUQ1KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgSE1BQydzIG9iamVjdCBpbnRlcmZhY2UuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGtleSBUaGUgc2VjcmV0IGtleS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBITUFDLlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgaG1hYyA9IENyeXB0b0pTLkhtYWNNRDUobWVzc2FnZSwga2V5KTtcblx0ICAgICAqL1xuXHQgICAgQy5IbWFjTUQ1ID0gSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKE1ENSk7XG5cdH0oTWF0aCkpO1xuXG5cblx0cmV0dXJuIENyeXB0b0pTLk1ENTtcblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7XG5cdGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xuXHRcdC8vIENvbW1vbkpTXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKFwiLi9jb3JlXCIpLCByZXF1aXJlKFwiLi9jaXBoZXItY29yZVwiKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCIsIFwiLi9jaXBoZXItY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0LyoqXG5cdCAqIENpcGhlciBGZWVkYmFjayBibG9jayBtb2RlLlxuXHQgKi9cblx0Q3J5cHRvSlMubW9kZS5DRkIgPSAoZnVuY3Rpb24gKCkge1xuXHQgICAgdmFyIENGQiA9IENyeXB0b0pTLmxpYi5CbG9ja0NpcGhlck1vZGUuZXh0ZW5kKCk7XG5cblx0ICAgIENGQi5FbmNyeXB0b3IgPSBDRkIuZXh0ZW5kKHtcblx0ICAgICAgICBwcm9jZXNzQmxvY2s6IGZ1bmN0aW9uICh3b3Jkcywgb2Zmc2V0KSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgY2lwaGVyID0gdGhpcy5fY2lwaGVyO1xuXHQgICAgICAgICAgICB2YXIgYmxvY2tTaXplID0gY2lwaGVyLmJsb2NrU2l6ZTtcblxuXHQgICAgICAgICAgICBnZW5lcmF0ZUtleXN0cmVhbUFuZEVuY3J5cHQuY2FsbCh0aGlzLCB3b3Jkcywgb2Zmc2V0LCBibG9ja1NpemUsIGNpcGhlcik7XG5cblx0ICAgICAgICAgICAgLy8gUmVtZW1iZXIgdGhpcyBibG9jayB0byB1c2Ugd2l0aCBuZXh0IGJsb2NrXG5cdCAgICAgICAgICAgIHRoaXMuX3ByZXZCbG9jayA9IHdvcmRzLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgYmxvY2tTaXplKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgQ0ZCLkRlY3J5cHRvciA9IENGQi5leHRlbmQoe1xuXHQgICAgICAgIHByb2Nlc3NCbG9jazogZnVuY3Rpb24gKHdvcmRzLCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBjaXBoZXIgPSB0aGlzLl9jaXBoZXI7XG5cdCAgICAgICAgICAgIHZhciBibG9ja1NpemUgPSBjaXBoZXIuYmxvY2tTaXplO1xuXG5cdCAgICAgICAgICAgIC8vIFJlbWVtYmVyIHRoaXMgYmxvY2sgdG8gdXNlIHdpdGggbmV4dCBibG9ja1xuXHQgICAgICAgICAgICB2YXIgdGhpc0Jsb2NrID0gd29yZHMuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBibG9ja1NpemUpO1xuXG5cdCAgICAgICAgICAgIGdlbmVyYXRlS2V5c3RyZWFtQW5kRW5jcnlwdC5jYWxsKHRoaXMsIHdvcmRzLCBvZmZzZXQsIGJsb2NrU2l6ZSwgY2lwaGVyKTtcblxuXHQgICAgICAgICAgICAvLyBUaGlzIGJsb2NrIGJlY29tZXMgdGhlIHByZXZpb3VzIGJsb2NrXG5cdCAgICAgICAgICAgIHRoaXMuX3ByZXZCbG9jayA9IHRoaXNCbG9jaztcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgZnVuY3Rpb24gZ2VuZXJhdGVLZXlzdHJlYW1BbmRFbmNyeXB0KHdvcmRzLCBvZmZzZXQsIGJsb2NrU2l6ZSwgY2lwaGVyKSB7XG5cdCAgICAgICAgdmFyIGtleXN0cmVhbTtcblxuXHQgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgdmFyIGl2ID0gdGhpcy5faXY7XG5cblx0ICAgICAgICAvLyBHZW5lcmF0ZSBrZXlzdHJlYW1cblx0ICAgICAgICBpZiAoaXYpIHtcblx0ICAgICAgICAgICAga2V5c3RyZWFtID0gaXYuc2xpY2UoMCk7XG5cblx0ICAgICAgICAgICAgLy8gUmVtb3ZlIElWIGZvciBzdWJzZXF1ZW50IGJsb2Nrc1xuXHQgICAgICAgICAgICB0aGlzLl9pdiA9IHVuZGVmaW5lZDtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICBrZXlzdHJlYW0gPSB0aGlzLl9wcmV2QmxvY2s7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNpcGhlci5lbmNyeXB0QmxvY2soa2V5c3RyZWFtLCAwKTtcblxuXHQgICAgICAgIC8vIEVuY3J5cHRcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrU2l6ZTsgaSsrKSB7XG5cdCAgICAgICAgICAgIHdvcmRzW29mZnNldCArIGldIF49IGtleXN0cmVhbVtpXTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cblx0ICAgIHJldHVybiBDRkI7XG5cdH0oKSk7XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMubW9kZS5DRkI7XG5cbn0pKTsiLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZShcIi4vY29yZVwiKSwgcmVxdWlyZShcIi4vY2lwaGVyLWNvcmVcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiLCBcIi4vY2lwaGVyLWNvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdC8qKiBAcHJlc2VydmVcblx0ICogQ291bnRlciBibG9jayBtb2RlIGNvbXBhdGlibGUgd2l0aCAgRHIgQnJpYW4gR2xhZG1hbiBmaWxlZW5jLmNcblx0ICogZGVyaXZlZCBmcm9tIENyeXB0b0pTLm1vZGUuQ1RSXG5cdCAqIEphbiBIcnVieSBqaHJ1Ynkud2ViQGdtYWlsLmNvbVxuXHQgKi9cblx0Q3J5cHRvSlMubW9kZS5DVFJHbGFkbWFuID0gKGZ1bmN0aW9uICgpIHtcblx0ICAgIHZhciBDVFJHbGFkbWFuID0gQ3J5cHRvSlMubGliLkJsb2NrQ2lwaGVyTW9kZS5leHRlbmQoKTtcblxuXHRcdGZ1bmN0aW9uIGluY1dvcmQod29yZClcblx0XHR7XG5cdFx0XHRpZiAoKCh3b3JkID4+IDI0KSAmIDB4ZmYpID09PSAweGZmKSB7IC8vb3ZlcmZsb3dcblx0XHRcdHZhciBiMSA9ICh3b3JkID4+IDE2KSYweGZmO1xuXHRcdFx0dmFyIGIyID0gKHdvcmQgPj4gOCkmMHhmZjtcblx0XHRcdHZhciBiMyA9IHdvcmQgJiAweGZmO1xuXG5cdFx0XHRpZiAoYjEgPT09IDB4ZmYpIC8vIG92ZXJmbG93IGIxXG5cdFx0XHR7XG5cdFx0XHRiMSA9IDA7XG5cdFx0XHRpZiAoYjIgPT09IDB4ZmYpXG5cdFx0XHR7XG5cdFx0XHRcdGIyID0gMDtcblx0XHRcdFx0aWYgKGIzID09PSAweGZmKVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0YjMgPSAwO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGVsc2Vcblx0XHRcdFx0e1xuXHRcdFx0XHRcdCsrYjM7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGVsc2Vcblx0XHRcdHtcblx0XHRcdFx0KytiMjtcblx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGVsc2Vcblx0XHRcdHtcblx0XHRcdCsrYjE7XG5cdFx0XHR9XG5cblx0XHRcdHdvcmQgPSAwO1xuXHRcdFx0d29yZCArPSAoYjEgPDwgMTYpO1xuXHRcdFx0d29yZCArPSAoYjIgPDwgOCk7XG5cdFx0XHR3b3JkICs9IGIzO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZVxuXHRcdFx0e1xuXHRcdFx0d29yZCArPSAoMHgwMSA8PCAyNCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gd29yZDtcblx0XHR9XG5cblx0XHRmdW5jdGlvbiBpbmNDb3VudGVyKGNvdW50ZXIpXG5cdFx0e1xuXHRcdFx0aWYgKChjb3VudGVyWzBdID0gaW5jV29yZChjb3VudGVyWzBdKSkgPT09IDApXG5cdFx0XHR7XG5cdFx0XHRcdC8vIGVuY3JfZGF0YSBpbiBmaWxlZW5jLmMgZnJvbSAgRHIgQnJpYW4gR2xhZG1hbidzIGNvdW50cyBvbmx5IHdpdGggRFdPUkQgaiA8IDhcblx0XHRcdFx0Y291bnRlclsxXSA9IGluY1dvcmQoY291bnRlclsxXSk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gY291bnRlcjtcblx0XHR9XG5cblx0ICAgIHZhciBFbmNyeXB0b3IgPSBDVFJHbGFkbWFuLkVuY3J5cHRvciA9IENUUkdsYWRtYW4uZXh0ZW5kKHtcblx0ICAgICAgICBwcm9jZXNzQmxvY2s6IGZ1bmN0aW9uICh3b3Jkcywgb2Zmc2V0KSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgY2lwaGVyID0gdGhpcy5fY2lwaGVyXG5cdCAgICAgICAgICAgIHZhciBibG9ja1NpemUgPSBjaXBoZXIuYmxvY2tTaXplO1xuXHQgICAgICAgICAgICB2YXIgaXYgPSB0aGlzLl9pdjtcblx0ICAgICAgICAgICAgdmFyIGNvdW50ZXIgPSB0aGlzLl9jb3VudGVyO1xuXG5cdCAgICAgICAgICAgIC8vIEdlbmVyYXRlIGtleXN0cmVhbVxuXHQgICAgICAgICAgICBpZiAoaXYpIHtcblx0ICAgICAgICAgICAgICAgIGNvdW50ZXIgPSB0aGlzLl9jb3VudGVyID0gaXYuc2xpY2UoMCk7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBJViBmb3Igc3Vic2VxdWVudCBibG9ja3Ncblx0ICAgICAgICAgICAgICAgIHRoaXMuX2l2ID0gdW5kZWZpbmVkO1xuXHQgICAgICAgICAgICB9XG5cblx0XHRcdFx0aW5jQ291bnRlcihjb3VudGVyKTtcblxuXHRcdFx0XHR2YXIga2V5c3RyZWFtID0gY291bnRlci5zbGljZSgwKTtcblx0ICAgICAgICAgICAgY2lwaGVyLmVuY3J5cHRCbG9jayhrZXlzdHJlYW0sIDApO1xuXG5cdCAgICAgICAgICAgIC8vIEVuY3J5cHRcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja1NpemU7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgd29yZHNbb2Zmc2V0ICsgaV0gXj0ga2V5c3RyZWFtW2ldO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cblx0ICAgIENUUkdsYWRtYW4uRGVjcnlwdG9yID0gRW5jcnlwdG9yO1xuXG5cdCAgICByZXR1cm4gQ1RSR2xhZG1hbjtcblx0fSgpKTtcblxuXG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMubW9kZS5DVFJHbGFkbWFuO1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIiksIHJlcXVpcmUoXCIuL2NpcGhlci1jb3JlXCIpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIiwgXCIuL2NpcGhlci1jb3JlXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQvKipcblx0ICogQ291bnRlciBibG9jayBtb2RlLlxuXHQgKi9cblx0Q3J5cHRvSlMubW9kZS5DVFIgPSAoZnVuY3Rpb24gKCkge1xuXHQgICAgdmFyIENUUiA9IENyeXB0b0pTLmxpYi5CbG9ja0NpcGhlck1vZGUuZXh0ZW5kKCk7XG5cblx0ICAgIHZhciBFbmNyeXB0b3IgPSBDVFIuRW5jcnlwdG9yID0gQ1RSLmV4dGVuZCh7XG5cdCAgICAgICAgcHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAod29yZHMsIG9mZnNldCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGNpcGhlciA9IHRoaXMuX2NpcGhlclxuXHQgICAgICAgICAgICB2YXIgYmxvY2tTaXplID0gY2lwaGVyLmJsb2NrU2l6ZTtcblx0ICAgICAgICAgICAgdmFyIGl2ID0gdGhpcy5faXY7XG5cdCAgICAgICAgICAgIHZhciBjb3VudGVyID0gdGhpcy5fY291bnRlcjtcblxuXHQgICAgICAgICAgICAvLyBHZW5lcmF0ZSBrZXlzdHJlYW1cblx0ICAgICAgICAgICAgaWYgKGl2KSB7XG5cdCAgICAgICAgICAgICAgICBjb3VudGVyID0gdGhpcy5fY291bnRlciA9IGl2LnNsaWNlKDApO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBSZW1vdmUgSVYgZm9yIHN1YnNlcXVlbnQgYmxvY2tzXG5cdCAgICAgICAgICAgICAgICB0aGlzLl9pdiA9IHVuZGVmaW5lZDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB2YXIga2V5c3RyZWFtID0gY291bnRlci5zbGljZSgwKTtcblx0ICAgICAgICAgICAgY2lwaGVyLmVuY3J5cHRCbG9jayhrZXlzdHJlYW0sIDApO1xuXG5cdCAgICAgICAgICAgIC8vIEluY3JlbWVudCBjb3VudGVyXG5cdCAgICAgICAgICAgIGNvdW50ZXJbYmxvY2tTaXplIC0gMV0gPSAoY291bnRlcltibG9ja1NpemUgLSAxXSArIDEpIHwgMFxuXG5cdCAgICAgICAgICAgIC8vIEVuY3J5cHRcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja1NpemU7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgd29yZHNbb2Zmc2V0ICsgaV0gXj0ga2V5c3RyZWFtW2ldO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cblx0ICAgIENUUi5EZWNyeXB0b3IgPSBFbmNyeXB0b3I7XG5cblx0ICAgIHJldHVybiBDVFI7XG5cdH0oKSk7XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMubW9kZS5DVFI7XG5cbn0pKTsiLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZShcIi4vY29yZVwiKSwgcmVxdWlyZShcIi4vY2lwaGVyLWNvcmVcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiLCBcIi4vY2lwaGVyLWNvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdC8qKlxuXHQgKiBFbGVjdHJvbmljIENvZGVib29rIGJsb2NrIG1vZGUuXG5cdCAqL1xuXHRDcnlwdG9KUy5tb2RlLkVDQiA9IChmdW5jdGlvbiAoKSB7XG5cdCAgICB2YXIgRUNCID0gQ3J5cHRvSlMubGliLkJsb2NrQ2lwaGVyTW9kZS5leHRlbmQoKTtcblxuXHQgICAgRUNCLkVuY3J5cHRvciA9IEVDQi5leHRlbmQoe1xuXHQgICAgICAgIHByb2Nlc3NCbG9jazogZnVuY3Rpb24gKHdvcmRzLCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgdGhpcy5fY2lwaGVyLmVuY3J5cHRCbG9jayh3b3Jkcywgb2Zmc2V0KTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgRUNCLkRlY3J5cHRvciA9IEVDQi5leHRlbmQoe1xuXHQgICAgICAgIHByb2Nlc3NCbG9jazogZnVuY3Rpb24gKHdvcmRzLCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgdGhpcy5fY2lwaGVyLmRlY3J5cHRCbG9jayh3b3Jkcywgb2Zmc2V0KTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgcmV0dXJuIEVDQjtcblx0fSgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUy5tb2RlLkVDQjtcblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7XG5cdGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xuXHRcdC8vIENvbW1vbkpTXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKFwiLi9jb3JlXCIpLCByZXF1aXJlKFwiLi9jaXBoZXItY29yZVwiKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCIsIFwiLi9jaXBoZXItY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0LyoqXG5cdCAqIE91dHB1dCBGZWVkYmFjayBibG9jayBtb2RlLlxuXHQgKi9cblx0Q3J5cHRvSlMubW9kZS5PRkIgPSAoZnVuY3Rpb24gKCkge1xuXHQgICAgdmFyIE9GQiA9IENyeXB0b0pTLmxpYi5CbG9ja0NpcGhlck1vZGUuZXh0ZW5kKCk7XG5cblx0ICAgIHZhciBFbmNyeXB0b3IgPSBPRkIuRW5jcnlwdG9yID0gT0ZCLmV4dGVuZCh7XG5cdCAgICAgICAgcHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAod29yZHMsIG9mZnNldCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGNpcGhlciA9IHRoaXMuX2NpcGhlclxuXHQgICAgICAgICAgICB2YXIgYmxvY2tTaXplID0gY2lwaGVyLmJsb2NrU2l6ZTtcblx0ICAgICAgICAgICAgdmFyIGl2ID0gdGhpcy5faXY7XG5cdCAgICAgICAgICAgIHZhciBrZXlzdHJlYW0gPSB0aGlzLl9rZXlzdHJlYW07XG5cblx0ICAgICAgICAgICAgLy8gR2VuZXJhdGUga2V5c3RyZWFtXG5cdCAgICAgICAgICAgIGlmIChpdikge1xuXHQgICAgICAgICAgICAgICAga2V5c3RyZWFtID0gdGhpcy5fa2V5c3RyZWFtID0gaXYuc2xpY2UoMCk7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBJViBmb3Igc3Vic2VxdWVudCBibG9ja3Ncblx0ICAgICAgICAgICAgICAgIHRoaXMuX2l2ID0gdW5kZWZpbmVkO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNpcGhlci5lbmNyeXB0QmxvY2soa2V5c3RyZWFtLCAwKTtcblxuXHQgICAgICAgICAgICAvLyBFbmNyeXB0XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tTaXplOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIHdvcmRzW29mZnNldCArIGldIF49IGtleXN0cmVhbVtpXTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXG5cdCAgICBPRkIuRGVjcnlwdG9yID0gRW5jcnlwdG9yO1xuXG5cdCAgICByZXR1cm4gT0ZCO1xuXHR9KCkpO1xuXG5cblx0cmV0dXJuIENyeXB0b0pTLm1vZGUuT0ZCO1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIiksIHJlcXVpcmUoXCIuL2NpcGhlci1jb3JlXCIpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIiwgXCIuL2NpcGhlci1jb3JlXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQvKipcblx0ICogQU5TSSBYLjkyMyBwYWRkaW5nIHN0cmF0ZWd5LlxuXHQgKi9cblx0Q3J5cHRvSlMucGFkLkFuc2lYOTIzID0ge1xuXHQgICAgcGFkOiBmdW5jdGlvbiAoZGF0YSwgYmxvY2tTaXplKSB7XG5cdCAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgdmFyIGRhdGFTaWdCeXRlcyA9IGRhdGEuc2lnQnl0ZXM7XG5cdCAgICAgICAgdmFyIGJsb2NrU2l6ZUJ5dGVzID0gYmxvY2tTaXplICogNDtcblxuXHQgICAgICAgIC8vIENvdW50IHBhZGRpbmcgYnl0ZXNcblx0ICAgICAgICB2YXIgblBhZGRpbmdCeXRlcyA9IGJsb2NrU2l6ZUJ5dGVzIC0gZGF0YVNpZ0J5dGVzICUgYmxvY2tTaXplQnl0ZXM7XG5cblx0ICAgICAgICAvLyBDb21wdXRlIGxhc3QgYnl0ZSBwb3NpdGlvblxuXHQgICAgICAgIHZhciBsYXN0Qnl0ZVBvcyA9IGRhdGFTaWdCeXRlcyArIG5QYWRkaW5nQnl0ZXMgLSAxO1xuXG5cdCAgICAgICAgLy8gUGFkXG5cdCAgICAgICAgZGF0YS5jbGFtcCgpO1xuXHQgICAgICAgIGRhdGEud29yZHNbbGFzdEJ5dGVQb3MgPj4+IDJdIHw9IG5QYWRkaW5nQnl0ZXMgPDwgKDI0IC0gKGxhc3RCeXRlUG9zICUgNCkgKiA4KTtcblx0ICAgICAgICBkYXRhLnNpZ0J5dGVzICs9IG5QYWRkaW5nQnl0ZXM7XG5cdCAgICB9LFxuXG5cdCAgICB1bnBhZDogZnVuY3Rpb24gKGRhdGEpIHtcblx0ICAgICAgICAvLyBHZXQgbnVtYmVyIG9mIHBhZGRpbmcgYnl0ZXMgZnJvbSBsYXN0IGJ5dGVcblx0ICAgICAgICB2YXIgblBhZGRpbmdCeXRlcyA9IGRhdGEud29yZHNbKGRhdGEuc2lnQnl0ZXMgLSAxKSA+Pj4gMl0gJiAweGZmO1xuXG5cdCAgICAgICAgLy8gUmVtb3ZlIHBhZGRpbmdcblx0ICAgICAgICBkYXRhLnNpZ0J5dGVzIC09IG5QYWRkaW5nQnl0ZXM7XG5cdCAgICB9XG5cdH07XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMucGFkLkFuc2l4OTIzO1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIiksIHJlcXVpcmUoXCIuL2NpcGhlci1jb3JlXCIpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIiwgXCIuL2NpcGhlci1jb3JlXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQvKipcblx0ICogSVNPIDEwMTI2IHBhZGRpbmcgc3RyYXRlZ3kuXG5cdCAqL1xuXHRDcnlwdG9KUy5wYWQuSXNvMTAxMjYgPSB7XG5cdCAgICBwYWQ6IGZ1bmN0aW9uIChkYXRhLCBibG9ja1NpemUpIHtcblx0ICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgIHZhciBibG9ja1NpemVCeXRlcyA9IGJsb2NrU2l6ZSAqIDQ7XG5cblx0ICAgICAgICAvLyBDb3VudCBwYWRkaW5nIGJ5dGVzXG5cdCAgICAgICAgdmFyIG5QYWRkaW5nQnl0ZXMgPSBibG9ja1NpemVCeXRlcyAtIGRhdGEuc2lnQnl0ZXMgJSBibG9ja1NpemVCeXRlcztcblxuXHQgICAgICAgIC8vIFBhZFxuXHQgICAgICAgIGRhdGEuY29uY2F0KENyeXB0b0pTLmxpYi5Xb3JkQXJyYXkucmFuZG9tKG5QYWRkaW5nQnl0ZXMgLSAxKSkuXG5cdCAgICAgICAgICAgICBjb25jYXQoQ3J5cHRvSlMubGliLldvcmRBcnJheS5jcmVhdGUoW25QYWRkaW5nQnl0ZXMgPDwgMjRdLCAxKSk7XG5cdCAgICB9LFxuXG5cdCAgICB1bnBhZDogZnVuY3Rpb24gKGRhdGEpIHtcblx0ICAgICAgICAvLyBHZXQgbnVtYmVyIG9mIHBhZGRpbmcgYnl0ZXMgZnJvbSBsYXN0IGJ5dGVcblx0ICAgICAgICB2YXIgblBhZGRpbmdCeXRlcyA9IGRhdGEud29yZHNbKGRhdGEuc2lnQnl0ZXMgLSAxKSA+Pj4gMl0gJiAweGZmO1xuXG5cdCAgICAgICAgLy8gUmVtb3ZlIHBhZGRpbmdcblx0ICAgICAgICBkYXRhLnNpZ0J5dGVzIC09IG5QYWRkaW5nQnl0ZXM7XG5cdCAgICB9XG5cdH07XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMucGFkLklzbzEwMTI2O1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIiksIHJlcXVpcmUoXCIuL2NpcGhlci1jb3JlXCIpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIiwgXCIuL2NpcGhlci1jb3JlXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQvKipcblx0ICogSVNPL0lFQyA5Nzk3LTEgUGFkZGluZyBNZXRob2QgMi5cblx0ICovXG5cdENyeXB0b0pTLnBhZC5Jc285Nzk3MSA9IHtcblx0ICAgIHBhZDogZnVuY3Rpb24gKGRhdGEsIGJsb2NrU2l6ZSkge1xuXHQgICAgICAgIC8vIEFkZCAweDgwIGJ5dGVcblx0ICAgICAgICBkYXRhLmNvbmNhdChDcnlwdG9KUy5saWIuV29yZEFycmF5LmNyZWF0ZShbMHg4MDAwMDAwMF0sIDEpKTtcblxuXHQgICAgICAgIC8vIFplcm8gcGFkIHRoZSByZXN0XG5cdCAgICAgICAgQ3J5cHRvSlMucGFkLlplcm9QYWRkaW5nLnBhZChkYXRhLCBibG9ja1NpemUpO1xuXHQgICAgfSxcblxuXHQgICAgdW5wYWQ6IGZ1bmN0aW9uIChkYXRhKSB7XG5cdCAgICAgICAgLy8gUmVtb3ZlIHplcm8gcGFkZGluZ1xuXHQgICAgICAgIENyeXB0b0pTLnBhZC5aZXJvUGFkZGluZy51bnBhZChkYXRhKTtcblxuXHQgICAgICAgIC8vIFJlbW92ZSBvbmUgbW9yZSBieXRlIC0tIHRoZSAweDgwIGJ5dGVcblx0ICAgICAgICBkYXRhLnNpZ0J5dGVzLS07XG5cdCAgICB9XG5cdH07XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMucGFkLklzbzk3OTcxO1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIiksIHJlcXVpcmUoXCIuL2NpcGhlci1jb3JlXCIpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIiwgXCIuL2NpcGhlci1jb3JlXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQvKipcblx0ICogQSBub29wIHBhZGRpbmcgc3RyYXRlZ3kuXG5cdCAqL1xuXHRDcnlwdG9KUy5wYWQuTm9QYWRkaW5nID0ge1xuXHQgICAgcGFkOiBmdW5jdGlvbiAoKSB7XG5cdCAgICB9LFxuXG5cdCAgICB1bnBhZDogZnVuY3Rpb24gKCkge1xuXHQgICAgfVxuXHR9O1xuXG5cblx0cmV0dXJuIENyeXB0b0pTLnBhZC5Ob1BhZGRpbmc7XG5cbn0pKTsiLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZShcIi4vY29yZVwiKSwgcmVxdWlyZShcIi4vY2lwaGVyLWNvcmVcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiLCBcIi4vY2lwaGVyLWNvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdC8qKlxuXHQgKiBaZXJvIHBhZGRpbmcgc3RyYXRlZ3kuXG5cdCAqL1xuXHRDcnlwdG9KUy5wYWQuWmVyb1BhZGRpbmcgPSB7XG5cdCAgICBwYWQ6IGZ1bmN0aW9uIChkYXRhLCBibG9ja1NpemUpIHtcblx0ICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgIHZhciBibG9ja1NpemVCeXRlcyA9IGJsb2NrU2l6ZSAqIDQ7XG5cblx0ICAgICAgICAvLyBQYWRcblx0ICAgICAgICBkYXRhLmNsYW1wKCk7XG5cdCAgICAgICAgZGF0YS5zaWdCeXRlcyArPSBibG9ja1NpemVCeXRlcyAtICgoZGF0YS5zaWdCeXRlcyAlIGJsb2NrU2l6ZUJ5dGVzKSB8fCBibG9ja1NpemVCeXRlcyk7XG5cdCAgICB9LFxuXG5cdCAgICB1bnBhZDogZnVuY3Rpb24gKGRhdGEpIHtcblx0ICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgIHZhciBkYXRhV29yZHMgPSBkYXRhLndvcmRzO1xuXG5cdCAgICAgICAgLy8gVW5wYWRcblx0ICAgICAgICB2YXIgaSA9IGRhdGEuc2lnQnl0ZXMgLSAxO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSBkYXRhLnNpZ0J5dGVzIC0gMTsgaSA+PSAwOyBpLS0pIHtcblx0ICAgICAgICAgICAgaWYgKCgoZGF0YVdvcmRzW2kgPj4+IDJdID4+PiAoMjQgLSAoaSAlIDQpICogOCkpICYgMHhmZikpIHtcblx0ICAgICAgICAgICAgICAgIGRhdGEuc2lnQnl0ZXMgPSBpICsgMTtcblx0ICAgICAgICAgICAgICAgIGJyZWFrO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHR9O1xuXG5cblx0cmV0dXJuIENyeXB0b0pTLnBhZC5aZXJvUGFkZGluZztcblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7XG5cdGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xuXHRcdC8vIENvbW1vbkpTXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKFwiLi9jb3JlXCIpLCByZXF1aXJlKFwiLi9zaGExXCIpLCByZXF1aXJlKFwiLi9obWFjXCIpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIiwgXCIuL3NoYTFcIiwgXCIuL2htYWNcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBCYXNlID0gQ19saWIuQmFzZTtcblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7XG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvO1xuXHQgICAgdmFyIFNIQTEgPSBDX2FsZ28uU0hBMTtcblx0ICAgIHZhciBITUFDID0gQ19hbGdvLkhNQUM7XG5cblx0ICAgIC8qKlxuXHQgICAgICogUGFzc3dvcmQtQmFzZWQgS2V5IERlcml2YXRpb24gRnVuY3Rpb24gMiBhbGdvcml0aG0uXG5cdCAgICAgKi9cblx0ICAgIHZhciBQQktERjIgPSBDX2FsZ28uUEJLREYyID0gQmFzZS5leHRlbmQoe1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBrZXlTaXplIFRoZSBrZXkgc2l6ZSBpbiB3b3JkcyB0byBnZW5lcmF0ZS4gRGVmYXVsdDogNCAoMTI4IGJpdHMpXG5cdCAgICAgICAgICogQHByb3BlcnR5IHtIYXNoZXJ9IGhhc2hlciBUaGUgaGFzaGVyIHRvIHVzZS4gRGVmYXVsdDogU0hBMVxuXHQgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBpdGVyYXRpb25zIFRoZSBudW1iZXIgb2YgaXRlcmF0aW9ucyB0byBwZXJmb3JtLiBEZWZhdWx0OiAxXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2ZnOiBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgICAgIGtleVNpemU6IDEyOC8zMixcblx0ICAgICAgICAgICAgaGFzaGVyOiBTSEExLFxuXHQgICAgICAgICAgICBpdGVyYXRpb25zOiAxXG5cdCAgICAgICAgfSksXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ld2x5IGNyZWF0ZWQga2V5IGRlcml2YXRpb24gZnVuY3Rpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoZSBkZXJpdmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIga2RmID0gQ3J5cHRvSlMuYWxnby5QQktERjIuY3JlYXRlKCk7XG5cdCAgICAgICAgICogICAgIHZhciBrZGYgPSBDcnlwdG9KUy5hbGdvLlBCS0RGMi5jcmVhdGUoeyBrZXlTaXplOiA4IH0pO1xuXHQgICAgICAgICAqICAgICB2YXIga2RmID0gQ3J5cHRvSlMuYWxnby5QQktERjIuY3JlYXRlKHsga2V5U2l6ZTogOCwgaXRlcmF0aW9uczogMTAwMCB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAoY2ZnKSB7XG5cdCAgICAgICAgICAgIHRoaXMuY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbXB1dGVzIHRoZSBQYXNzd29yZC1CYXNlZCBLZXkgRGVyaXZhdGlvbiBGdW5jdGlvbiAyLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBwYXNzd29yZCBUaGUgcGFzc3dvcmQuXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBzYWx0IEEgc2FsdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRlcml2ZWQga2V5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIga2V5ID0ga2RmLmNvbXB1dGUocGFzc3dvcmQsIHNhbHQpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNvbXB1dGU6IGZ1bmN0aW9uIChwYXNzd29yZCwgc2FsdCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgY2ZnID0gdGhpcy5jZmc7XG5cblx0ICAgICAgICAgICAgLy8gSW5pdCBITUFDXG5cdCAgICAgICAgICAgIHZhciBobWFjID0gSE1BQy5jcmVhdGUoY2ZnLmhhc2hlciwgcGFzc3dvcmQpO1xuXG5cdCAgICAgICAgICAgIC8vIEluaXRpYWwgdmFsdWVzXG5cdCAgICAgICAgICAgIHZhciBkZXJpdmVkS2V5ID0gV29yZEFycmF5LmNyZWF0ZSgpO1xuXHQgICAgICAgICAgICB2YXIgYmxvY2tJbmRleCA9IFdvcmRBcnJheS5jcmVhdGUoWzB4MDAwMDAwMDFdKTtcblxuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGRlcml2ZWRLZXlXb3JkcyA9IGRlcml2ZWRLZXkud29yZHM7XG5cdCAgICAgICAgICAgIHZhciBibG9ja0luZGV4V29yZHMgPSBibG9ja0luZGV4LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIga2V5U2l6ZSA9IGNmZy5rZXlTaXplO1xuXHQgICAgICAgICAgICB2YXIgaXRlcmF0aW9ucyA9IGNmZy5pdGVyYXRpb25zO1xuXG5cdCAgICAgICAgICAgIC8vIEdlbmVyYXRlIGtleVxuXHQgICAgICAgICAgICB3aGlsZSAoZGVyaXZlZEtleVdvcmRzLmxlbmd0aCA8IGtleVNpemUpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBibG9jayA9IGhtYWMudXBkYXRlKHNhbHQpLmZpbmFsaXplKGJsb2NrSW5kZXgpO1xuXHQgICAgICAgICAgICAgICAgaG1hYy5yZXNldCgpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgICAgIHZhciBibG9ja1dvcmRzID0gYmxvY2sud29yZHM7XG5cdCAgICAgICAgICAgICAgICB2YXIgYmxvY2tXb3Jkc0xlbmd0aCA9IGJsb2NrV29yZHMubGVuZ3RoO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBJdGVyYXRpb25zXG5cdCAgICAgICAgICAgICAgICB2YXIgaW50ZXJtZWRpYXRlID0gYmxvY2s7XG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGl0ZXJhdGlvbnM7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgICAgIGludGVybWVkaWF0ZSA9IGhtYWMuZmluYWxpemUoaW50ZXJtZWRpYXRlKTtcblx0ICAgICAgICAgICAgICAgICAgICBobWFjLnJlc2V0KCk7XG5cblx0ICAgICAgICAgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICAgICAgICAgIHZhciBpbnRlcm1lZGlhdGVXb3JkcyA9IGludGVybWVkaWF0ZS53b3JkcztcblxuXHQgICAgICAgICAgICAgICAgICAgIC8vIFhPUiBpbnRlcm1lZGlhdGUgd2l0aCBibG9ja1xuXHQgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgYmxvY2tXb3Jkc0xlbmd0aDsgaisrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrV29yZHNbal0gXj0gaW50ZXJtZWRpYXRlV29yZHNbal07XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICBkZXJpdmVkS2V5LmNvbmNhdChibG9jayk7XG5cdCAgICAgICAgICAgICAgICBibG9ja0luZGV4V29yZHNbMF0rKztcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBkZXJpdmVkS2V5LnNpZ0J5dGVzID0ga2V5U2l6ZSAqIDQ7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGRlcml2ZWRLZXk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQ29tcHV0ZXMgdGhlIFBhc3N3b3JkLUJhc2VkIEtleSBEZXJpdmF0aW9uIEZ1bmN0aW9uIDIuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBwYXNzd29yZCBUaGUgcGFzc3dvcmQuXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHNhbHQgQSBzYWx0LlxuXHQgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIGNvbXB1dGF0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRlcml2ZWQga2V5LlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIga2V5ID0gQ3J5cHRvSlMuUEJLREYyKHBhc3N3b3JkLCBzYWx0KTtcblx0ICAgICAqICAgICB2YXIga2V5ID0gQ3J5cHRvSlMuUEJLREYyKHBhc3N3b3JkLCBzYWx0LCB7IGtleVNpemU6IDggfSk7XG5cdCAgICAgKiAgICAgdmFyIGtleSA9IENyeXB0b0pTLlBCS0RGMihwYXNzd29yZCwgc2FsdCwgeyBrZXlTaXplOiA4LCBpdGVyYXRpb25zOiAxMDAwIH0pO1xuXHQgICAgICovXG5cdCAgICBDLlBCS0RGMiA9IGZ1bmN0aW9uIChwYXNzd29yZCwgc2FsdCwgY2ZnKSB7XG5cdCAgICAgICAgcmV0dXJuIFBCS0RGMi5jcmVhdGUoY2ZnKS5jb21wdXRlKHBhc3N3b3JkLCBzYWx0KTtcblx0ICAgIH07XG5cdH0oKSk7XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMuUEJLREYyO1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIiksIHJlcXVpcmUoXCIuL2VuYy1iYXNlNjRcIiksIHJlcXVpcmUoXCIuL21kNVwiKSwgcmVxdWlyZShcIi4vZXZwa2RmXCIpLCByZXF1aXJlKFwiLi9jaXBoZXItY29yZVwiKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCIsIFwiLi9lbmMtYmFzZTY0XCIsIFwiLi9tZDVcIiwgXCIuL2V2cGtkZlwiLCBcIi4vY2lwaGVyLWNvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBTdHJlYW1DaXBoZXIgPSBDX2xpYi5TdHJlYW1DaXBoZXI7XG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvO1xuXG5cdCAgICAvLyBSZXVzYWJsZSBvYmplY3RzXG5cdCAgICB2YXIgUyAgPSBbXTtcblx0ICAgIHZhciBDXyA9IFtdO1xuXHQgICAgdmFyIEcgID0gW107XG5cblx0ICAgIC8qKlxuXHQgICAgICogUmFiYml0IHN0cmVhbSBjaXBoZXIgYWxnb3JpdGhtLlxuXHQgICAgICpcblx0ICAgICAqIFRoaXMgaXMgYSBsZWdhY3kgdmVyc2lvbiB0aGF0IG5lZ2xlY3RlZCB0byBjb252ZXJ0IHRoZSBrZXkgdG8gbGl0dGxlLWVuZGlhbi5cblx0ICAgICAqIFRoaXMgZXJyb3IgZG9lc24ndCBhZmZlY3QgdGhlIGNpcGhlcidzIHNlY3VyaXR5LFxuXHQgICAgICogYnV0IGl0IGRvZXMgYWZmZWN0IGl0cyBjb21wYXRpYmlsaXR5IHdpdGggb3RoZXIgaW1wbGVtZW50YXRpb25zLlxuXHQgICAgICovXG5cdCAgICB2YXIgUmFiYml0TGVnYWN5ID0gQ19hbGdvLlJhYmJpdExlZ2FjeSA9IFN0cmVhbUNpcGhlci5leHRlbmQoe1xuXHQgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgSyA9IHRoaXMuX2tleS53b3Jkcztcblx0ICAgICAgICAgICAgdmFyIGl2ID0gdGhpcy5jZmcuaXY7XG5cblx0ICAgICAgICAgICAgLy8gR2VuZXJhdGUgaW5pdGlhbCBzdGF0ZSB2YWx1ZXNcblx0ICAgICAgICAgICAgdmFyIFggPSB0aGlzLl9YID0gW1xuXHQgICAgICAgICAgICAgICAgS1swXSwgKEtbM10gPDwgMTYpIHwgKEtbMl0gPj4+IDE2KSxcblx0ICAgICAgICAgICAgICAgIEtbMV0sIChLWzBdIDw8IDE2KSB8IChLWzNdID4+PiAxNiksXG5cdCAgICAgICAgICAgICAgICBLWzJdLCAoS1sxXSA8PCAxNikgfCAoS1swXSA+Pj4gMTYpLFxuXHQgICAgICAgICAgICAgICAgS1szXSwgKEtbMl0gPDwgMTYpIHwgKEtbMV0gPj4+IDE2KVxuXHQgICAgICAgICAgICBdO1xuXG5cdCAgICAgICAgICAgIC8vIEdlbmVyYXRlIGluaXRpYWwgY291bnRlciB2YWx1ZXNcblx0ICAgICAgICAgICAgdmFyIEMgPSB0aGlzLl9DID0gW1xuXHQgICAgICAgICAgICAgICAgKEtbMl0gPDwgMTYpIHwgKEtbMl0gPj4+IDE2KSwgKEtbMF0gJiAweGZmZmYwMDAwKSB8IChLWzFdICYgMHgwMDAwZmZmZiksXG5cdCAgICAgICAgICAgICAgICAoS1szXSA8PCAxNikgfCAoS1szXSA+Pj4gMTYpLCAoS1sxXSAmIDB4ZmZmZjAwMDApIHwgKEtbMl0gJiAweDAwMDBmZmZmKSxcblx0ICAgICAgICAgICAgICAgIChLWzBdIDw8IDE2KSB8IChLWzBdID4+PiAxNiksIChLWzJdICYgMHhmZmZmMDAwMCkgfCAoS1szXSAmIDB4MDAwMGZmZmYpLFxuXHQgICAgICAgICAgICAgICAgKEtbMV0gPDwgMTYpIHwgKEtbMV0gPj4+IDE2KSwgKEtbM10gJiAweGZmZmYwMDAwKSB8IChLWzBdICYgMHgwMDAwZmZmZilcblx0ICAgICAgICAgICAgXTtcblxuXHQgICAgICAgICAgICAvLyBDYXJyeSBiaXRcblx0ICAgICAgICAgICAgdGhpcy5fYiA9IDA7XG5cblx0ICAgICAgICAgICAgLy8gSXRlcmF0ZSB0aGUgc3lzdGVtIGZvdXIgdGltZXNcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIG5leHRTdGF0ZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gTW9kaWZ5IHRoZSBjb3VudGVyc1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDg7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgQ1tpXSBePSBYWyhpICsgNCkgJiA3XTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIElWIHNldHVwXG5cdCAgICAgICAgICAgIGlmIChpdikge1xuXHQgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgICAgICB2YXIgSVYgPSBpdi53b3Jkcztcblx0ICAgICAgICAgICAgICAgIHZhciBJVl8wID0gSVZbMF07XG5cdCAgICAgICAgICAgICAgICB2YXIgSVZfMSA9IElWWzFdO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBmb3VyIHN1YnZlY3RvcnNcblx0ICAgICAgICAgICAgICAgIHZhciBpMCA9ICgoKElWXzAgPDwgOCkgfCAoSVZfMCA+Pj4gMjQpKSAmIDB4MDBmZjAwZmYpIHwgKCgoSVZfMCA8PCAyNCkgfCAoSVZfMCA+Pj4gOCkpICYgMHhmZjAwZmYwMCk7XG5cdCAgICAgICAgICAgICAgICB2YXIgaTIgPSAoKChJVl8xIDw8IDgpIHwgKElWXzEgPj4+IDI0KSkgJiAweDAwZmYwMGZmKSB8ICgoKElWXzEgPDwgMjQpIHwgKElWXzEgPj4+IDgpKSAmIDB4ZmYwMGZmMDApO1xuXHQgICAgICAgICAgICAgICAgdmFyIGkxID0gKGkwID4+PiAxNikgfCAoaTIgJiAweGZmZmYwMDAwKTtcblx0ICAgICAgICAgICAgICAgIHZhciBpMyA9IChpMiA8PCAxNikgIHwgKGkwICYgMHgwMDAwZmZmZik7XG5cblx0ICAgICAgICAgICAgICAgIC8vIE1vZGlmeSBjb3VudGVyIHZhbHVlc1xuXHQgICAgICAgICAgICAgICAgQ1swXSBePSBpMDtcblx0ICAgICAgICAgICAgICAgIENbMV0gXj0gaTE7XG5cdCAgICAgICAgICAgICAgICBDWzJdIF49IGkyO1xuXHQgICAgICAgICAgICAgICAgQ1szXSBePSBpMztcblx0ICAgICAgICAgICAgICAgIENbNF0gXj0gaTA7XG5cdCAgICAgICAgICAgICAgICBDWzVdIF49IGkxO1xuXHQgICAgICAgICAgICAgICAgQ1s2XSBePSBpMjtcblx0ICAgICAgICAgICAgICAgIENbN10gXj0gaTM7XG5cblx0ICAgICAgICAgICAgICAgIC8vIEl0ZXJhdGUgdGhlIHN5c3RlbSBmb3VyIHRpbWVzXG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgICAgIG5leHRTdGF0ZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIF9kb1Byb2Nlc3NCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgWCA9IHRoaXMuX1g7XG5cblx0ICAgICAgICAgICAgLy8gSXRlcmF0ZSB0aGUgc3lzdGVtXG5cdCAgICAgICAgICAgIG5leHRTdGF0ZS5jYWxsKHRoaXMpO1xuXG5cdCAgICAgICAgICAgIC8vIEdlbmVyYXRlIGZvdXIga2V5c3RyZWFtIHdvcmRzXG5cdCAgICAgICAgICAgIFNbMF0gPSBYWzBdIF4gKFhbNV0gPj4+IDE2KSBeIChYWzNdIDw8IDE2KTtcblx0ICAgICAgICAgICAgU1sxXSA9IFhbMl0gXiAoWFs3XSA+Pj4gMTYpIF4gKFhbNV0gPDwgMTYpO1xuXHQgICAgICAgICAgICBTWzJdID0gWFs0XSBeIChYWzFdID4+PiAxNikgXiAoWFs3XSA8PCAxNik7XG5cdCAgICAgICAgICAgIFNbM10gPSBYWzZdIF4gKFhbM10gPj4+IDE2KSBeIChYWzFdIDw8IDE2KTtcblxuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgLy8gU3dhcCBlbmRpYW5cblx0ICAgICAgICAgICAgICAgIFNbaV0gPSAoKChTW2ldIDw8IDgpICB8IChTW2ldID4+PiAyNCkpICYgMHgwMGZmMDBmZikgfFxuXHQgICAgICAgICAgICAgICAgICAgICAgICgoKFNbaV0gPDwgMjQpIHwgKFNbaV0gPj4+IDgpKSAgJiAweGZmMDBmZjAwKTtcblxuXHQgICAgICAgICAgICAgICAgLy8gRW5jcnlwdFxuXHQgICAgICAgICAgICAgICAgTVtvZmZzZXQgKyBpXSBePSBTW2ldO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGJsb2NrU2l6ZTogMTI4LzMyLFxuXG5cdCAgICAgICAgaXZTaXplOiA2NC8zMlxuXHQgICAgfSk7XG5cblx0ICAgIGZ1bmN0aW9uIG5leHRTdGF0ZSgpIHtcblx0ICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICB2YXIgWCA9IHRoaXMuX1g7XG5cdCAgICAgICAgdmFyIEMgPSB0aGlzLl9DO1xuXG5cdCAgICAgICAgLy8gU2F2ZSBvbGQgY291bnRlciB2YWx1ZXNcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDg7IGkrKykge1xuXHQgICAgICAgICAgICBDX1tpXSA9IENbaV07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLy8gQ2FsY3VsYXRlIG5ldyBjb3VudGVyIHZhbHVlc1xuXHQgICAgICAgIENbMF0gPSAoQ1swXSArIDB4NGQzNGQzNGQgKyB0aGlzLl9iKSB8IDA7XG5cdCAgICAgICAgQ1sxXSA9IChDWzFdICsgMHhkMzRkMzRkMyArICgoQ1swXSA+Pj4gMCkgPCAoQ19bMF0gPj4+IDApID8gMSA6IDApKSB8IDA7XG5cdCAgICAgICAgQ1syXSA9IChDWzJdICsgMHgzNGQzNGQzNCArICgoQ1sxXSA+Pj4gMCkgPCAoQ19bMV0gPj4+IDApID8gMSA6IDApKSB8IDA7XG5cdCAgICAgICAgQ1szXSA9IChDWzNdICsgMHg0ZDM0ZDM0ZCArICgoQ1syXSA+Pj4gMCkgPCAoQ19bMl0gPj4+IDApID8gMSA6IDApKSB8IDA7XG5cdCAgICAgICAgQ1s0XSA9IChDWzRdICsgMHhkMzRkMzRkMyArICgoQ1szXSA+Pj4gMCkgPCAoQ19bM10gPj4+IDApID8gMSA6IDApKSB8IDA7XG5cdCAgICAgICAgQ1s1XSA9IChDWzVdICsgMHgzNGQzNGQzNCArICgoQ1s0XSA+Pj4gMCkgPCAoQ19bNF0gPj4+IDApID8gMSA6IDApKSB8IDA7XG5cdCAgICAgICAgQ1s2XSA9IChDWzZdICsgMHg0ZDM0ZDM0ZCArICgoQ1s1XSA+Pj4gMCkgPCAoQ19bNV0gPj4+IDApID8gMSA6IDApKSB8IDA7XG5cdCAgICAgICAgQ1s3XSA9IChDWzddICsgMHhkMzRkMzRkMyArICgoQ1s2XSA+Pj4gMCkgPCAoQ19bNl0gPj4+IDApID8gMSA6IDApKSB8IDA7XG5cdCAgICAgICAgdGhpcy5fYiA9IChDWzddID4+PiAwKSA8IChDX1s3XSA+Pj4gMCkgPyAxIDogMDtcblxuXHQgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgZy12YWx1ZXNcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDg7IGkrKykge1xuXHQgICAgICAgICAgICB2YXIgZ3ggPSBYW2ldICsgQ1tpXTtcblxuXHQgICAgICAgICAgICAvLyBDb25zdHJ1Y3QgaGlnaCBhbmQgbG93IGFyZ3VtZW50IGZvciBzcXVhcmluZ1xuXHQgICAgICAgICAgICB2YXIgZ2EgPSBneCAmIDB4ZmZmZjtcblx0ICAgICAgICAgICAgdmFyIGdiID0gZ3ggPj4+IDE2O1xuXG5cdCAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBoaWdoIGFuZCBsb3cgcmVzdWx0IG9mIHNxdWFyaW5nXG5cdCAgICAgICAgICAgIHZhciBnaCA9ICgoKChnYSAqIGdhKSA+Pj4gMTcpICsgZ2EgKiBnYikgPj4+IDE1KSArIGdiICogZ2I7XG5cdCAgICAgICAgICAgIHZhciBnbCA9ICgoKGd4ICYgMHhmZmZmMDAwMCkgKiBneCkgfCAwKSArICgoKGd4ICYgMHgwMDAwZmZmZikgKiBneCkgfCAwKTtcblxuXHQgICAgICAgICAgICAvLyBIaWdoIFhPUiBsb3dcblx0ICAgICAgICAgICAgR1tpXSA9IGdoIF4gZ2w7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLy8gQ2FsY3VsYXRlIG5ldyBzdGF0ZSB2YWx1ZXNcblx0ICAgICAgICBYWzBdID0gKEdbMF0gKyAoKEdbN10gPDwgMTYpIHwgKEdbN10gPj4+IDE2KSkgKyAoKEdbNl0gPDwgMTYpIHwgKEdbNl0gPj4+IDE2KSkpIHwgMDtcblx0ICAgICAgICBYWzFdID0gKEdbMV0gKyAoKEdbMF0gPDwgOCkgIHwgKEdbMF0gPj4+IDI0KSkgKyBHWzddKSB8IDA7XG5cdCAgICAgICAgWFsyXSA9IChHWzJdICsgKChHWzFdIDw8IDE2KSB8IChHWzFdID4+PiAxNikpICsgKChHWzBdIDw8IDE2KSB8IChHWzBdID4+PiAxNikpKSB8IDA7XG5cdCAgICAgICAgWFszXSA9IChHWzNdICsgKChHWzJdIDw8IDgpICB8IChHWzJdID4+PiAyNCkpICsgR1sxXSkgfCAwO1xuXHQgICAgICAgIFhbNF0gPSAoR1s0XSArICgoR1szXSA8PCAxNikgfCAoR1szXSA+Pj4gMTYpKSArICgoR1syXSA8PCAxNikgfCAoR1syXSA+Pj4gMTYpKSkgfCAwO1xuXHQgICAgICAgIFhbNV0gPSAoR1s1XSArICgoR1s0XSA8PCA4KSAgfCAoR1s0XSA+Pj4gMjQpKSArIEdbM10pIHwgMDtcblx0ICAgICAgICBYWzZdID0gKEdbNl0gKyAoKEdbNV0gPDwgMTYpIHwgKEdbNV0gPj4+IDE2KSkgKyAoKEdbNF0gPDwgMTYpIHwgKEdbNF0gPj4+IDE2KSkpIHwgMDtcblx0ICAgICAgICBYWzddID0gKEdbN10gKyAoKEdbNl0gPDwgOCkgIHwgKEdbNl0gPj4+IDI0KSkgKyBHWzVdKSB8IDA7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogU2hvcnRjdXQgZnVuY3Rpb25zIHRvIHRoZSBjaXBoZXIncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0ID0gQ3J5cHRvSlMuUmFiYml0TGVnYWN5LmVuY3J5cHQobWVzc2FnZSwga2V5LCBjZmcpO1xuXHQgICAgICogICAgIHZhciBwbGFpbnRleHQgID0gQ3J5cHRvSlMuUmFiYml0TGVnYWN5LmRlY3J5cHQoY2lwaGVydGV4dCwga2V5LCBjZmcpO1xuXHQgICAgICovXG5cdCAgICBDLlJhYmJpdExlZ2FjeSA9IFN0cmVhbUNpcGhlci5fY3JlYXRlSGVscGVyKFJhYmJpdExlZ2FjeSk7XG5cdH0oKSk7XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMuUmFiYml0TGVnYWN5O1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIiksIHJlcXVpcmUoXCIuL2VuYy1iYXNlNjRcIiksIHJlcXVpcmUoXCIuL21kNVwiKSwgcmVxdWlyZShcIi4vZXZwa2RmXCIpLCByZXF1aXJlKFwiLi9jaXBoZXItY29yZVwiKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCIsIFwiLi9lbmMtYmFzZTY0XCIsIFwiLi9tZDVcIiwgXCIuL2V2cGtkZlwiLCBcIi4vY2lwaGVyLWNvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBTdHJlYW1DaXBoZXIgPSBDX2xpYi5TdHJlYW1DaXBoZXI7XG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvO1xuXG5cdCAgICAvLyBSZXVzYWJsZSBvYmplY3RzXG5cdCAgICB2YXIgUyAgPSBbXTtcblx0ICAgIHZhciBDXyA9IFtdO1xuXHQgICAgdmFyIEcgID0gW107XG5cblx0ICAgIC8qKlxuXHQgICAgICogUmFiYml0IHN0cmVhbSBjaXBoZXIgYWxnb3JpdGhtXG5cdCAgICAgKi9cblx0ICAgIHZhciBSYWJiaXQgPSBDX2FsZ28uUmFiYml0ID0gU3RyZWFtQ2lwaGVyLmV4dGVuZCh7XG5cdCAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBLID0gdGhpcy5fa2V5LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgaXYgPSB0aGlzLmNmZy5pdjtcblxuXHQgICAgICAgICAgICAvLyBTd2FwIGVuZGlhblxuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgS1tpXSA9ICgoKEtbaV0gPDwgOCkgIHwgKEtbaV0gPj4+IDI0KSkgJiAweDAwZmYwMGZmKSB8XG5cdCAgICAgICAgICAgICAgICAgICAgICAgKCgoS1tpXSA8PCAyNCkgfCAoS1tpXSA+Pj4gOCkpICAmIDB4ZmYwMGZmMDApO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gR2VuZXJhdGUgaW5pdGlhbCBzdGF0ZSB2YWx1ZXNcblx0ICAgICAgICAgICAgdmFyIFggPSB0aGlzLl9YID0gW1xuXHQgICAgICAgICAgICAgICAgS1swXSwgKEtbM10gPDwgMTYpIHwgKEtbMl0gPj4+IDE2KSxcblx0ICAgICAgICAgICAgICAgIEtbMV0sIChLWzBdIDw8IDE2KSB8IChLWzNdID4+PiAxNiksXG5cdCAgICAgICAgICAgICAgICBLWzJdLCAoS1sxXSA8PCAxNikgfCAoS1swXSA+Pj4gMTYpLFxuXHQgICAgICAgICAgICAgICAgS1szXSwgKEtbMl0gPDwgMTYpIHwgKEtbMV0gPj4+IDE2KVxuXHQgICAgICAgICAgICBdO1xuXG5cdCAgICAgICAgICAgIC8vIEdlbmVyYXRlIGluaXRpYWwgY291bnRlciB2YWx1ZXNcblx0ICAgICAgICAgICAgdmFyIEMgPSB0aGlzLl9DID0gW1xuXHQgICAgICAgICAgICAgICAgKEtbMl0gPDwgMTYpIHwgKEtbMl0gPj4+IDE2KSwgKEtbMF0gJiAweGZmZmYwMDAwKSB8IChLWzFdICYgMHgwMDAwZmZmZiksXG5cdCAgICAgICAgICAgICAgICAoS1szXSA8PCAxNikgfCAoS1szXSA+Pj4gMTYpLCAoS1sxXSAmIDB4ZmZmZjAwMDApIHwgKEtbMl0gJiAweDAwMDBmZmZmKSxcblx0ICAgICAgICAgICAgICAgIChLWzBdIDw8IDE2KSB8IChLWzBdID4+PiAxNiksIChLWzJdICYgMHhmZmZmMDAwMCkgfCAoS1szXSAmIDB4MDAwMGZmZmYpLFxuXHQgICAgICAgICAgICAgICAgKEtbMV0gPDwgMTYpIHwgKEtbMV0gPj4+IDE2KSwgKEtbM10gJiAweGZmZmYwMDAwKSB8IChLWzBdICYgMHgwMDAwZmZmZilcblx0ICAgICAgICAgICAgXTtcblxuXHQgICAgICAgICAgICAvLyBDYXJyeSBiaXRcblx0ICAgICAgICAgICAgdGhpcy5fYiA9IDA7XG5cblx0ICAgICAgICAgICAgLy8gSXRlcmF0ZSB0aGUgc3lzdGVtIGZvdXIgdGltZXNcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIG5leHRTdGF0ZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gTW9kaWZ5IHRoZSBjb3VudGVyc1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDg7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgQ1tpXSBePSBYWyhpICsgNCkgJiA3XTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIElWIHNldHVwXG5cdCAgICAgICAgICAgIGlmIChpdikge1xuXHQgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgICAgICB2YXIgSVYgPSBpdi53b3Jkcztcblx0ICAgICAgICAgICAgICAgIHZhciBJVl8wID0gSVZbMF07XG5cdCAgICAgICAgICAgICAgICB2YXIgSVZfMSA9IElWWzFdO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBmb3VyIHN1YnZlY3RvcnNcblx0ICAgICAgICAgICAgICAgIHZhciBpMCA9ICgoKElWXzAgPDwgOCkgfCAoSVZfMCA+Pj4gMjQpKSAmIDB4MDBmZjAwZmYpIHwgKCgoSVZfMCA8PCAyNCkgfCAoSVZfMCA+Pj4gOCkpICYgMHhmZjAwZmYwMCk7XG5cdCAgICAgICAgICAgICAgICB2YXIgaTIgPSAoKChJVl8xIDw8IDgpIHwgKElWXzEgPj4+IDI0KSkgJiAweDAwZmYwMGZmKSB8ICgoKElWXzEgPDwgMjQpIHwgKElWXzEgPj4+IDgpKSAmIDB4ZmYwMGZmMDApO1xuXHQgICAgICAgICAgICAgICAgdmFyIGkxID0gKGkwID4+PiAxNikgfCAoaTIgJiAweGZmZmYwMDAwKTtcblx0ICAgICAgICAgICAgICAgIHZhciBpMyA9IChpMiA8PCAxNikgIHwgKGkwICYgMHgwMDAwZmZmZik7XG5cblx0ICAgICAgICAgICAgICAgIC8vIE1vZGlmeSBjb3VudGVyIHZhbHVlc1xuXHQgICAgICAgICAgICAgICAgQ1swXSBePSBpMDtcblx0ICAgICAgICAgICAgICAgIENbMV0gXj0gaTE7XG5cdCAgICAgICAgICAgICAgICBDWzJdIF49IGkyO1xuXHQgICAgICAgICAgICAgICAgQ1szXSBePSBpMztcblx0ICAgICAgICAgICAgICAgIENbNF0gXj0gaTA7XG5cdCAgICAgICAgICAgICAgICBDWzVdIF49IGkxO1xuXHQgICAgICAgICAgICAgICAgQ1s2XSBePSBpMjtcblx0ICAgICAgICAgICAgICAgIENbN10gXj0gaTM7XG5cblx0ICAgICAgICAgICAgICAgIC8vIEl0ZXJhdGUgdGhlIHN5c3RlbSBmb3VyIHRpbWVzXG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgICAgIG5leHRTdGF0ZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIF9kb1Byb2Nlc3NCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgWCA9IHRoaXMuX1g7XG5cblx0ICAgICAgICAgICAgLy8gSXRlcmF0ZSB0aGUgc3lzdGVtXG5cdCAgICAgICAgICAgIG5leHRTdGF0ZS5jYWxsKHRoaXMpO1xuXG5cdCAgICAgICAgICAgIC8vIEdlbmVyYXRlIGZvdXIga2V5c3RyZWFtIHdvcmRzXG5cdCAgICAgICAgICAgIFNbMF0gPSBYWzBdIF4gKFhbNV0gPj4+IDE2KSBeIChYWzNdIDw8IDE2KTtcblx0ICAgICAgICAgICAgU1sxXSA9IFhbMl0gXiAoWFs3XSA+Pj4gMTYpIF4gKFhbNV0gPDwgMTYpO1xuXHQgICAgICAgICAgICBTWzJdID0gWFs0XSBeIChYWzFdID4+PiAxNikgXiAoWFs3XSA8PCAxNik7XG5cdCAgICAgICAgICAgIFNbM10gPSBYWzZdIF4gKFhbM10gPj4+IDE2KSBeIChYWzFdIDw8IDE2KTtcblxuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgLy8gU3dhcCBlbmRpYW5cblx0ICAgICAgICAgICAgICAgIFNbaV0gPSAoKChTW2ldIDw8IDgpICB8IChTW2ldID4+PiAyNCkpICYgMHgwMGZmMDBmZikgfFxuXHQgICAgICAgICAgICAgICAgICAgICAgICgoKFNbaV0gPDwgMjQpIHwgKFNbaV0gPj4+IDgpKSAgJiAweGZmMDBmZjAwKTtcblxuXHQgICAgICAgICAgICAgICAgLy8gRW5jcnlwdFxuXHQgICAgICAgICAgICAgICAgTVtvZmZzZXQgKyBpXSBePSBTW2ldO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGJsb2NrU2l6ZTogMTI4LzMyLFxuXG5cdCAgICAgICAgaXZTaXplOiA2NC8zMlxuXHQgICAgfSk7XG5cblx0ICAgIGZ1bmN0aW9uIG5leHRTdGF0ZSgpIHtcblx0ICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICB2YXIgWCA9IHRoaXMuX1g7XG5cdCAgICAgICAgdmFyIEMgPSB0aGlzLl9DO1xuXG5cdCAgICAgICAgLy8gU2F2ZSBvbGQgY291bnRlciB2YWx1ZXNcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDg7IGkrKykge1xuXHQgICAgICAgICAgICBDX1tpXSA9IENbaV07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLy8gQ2FsY3VsYXRlIG5ldyBjb3VudGVyIHZhbHVlc1xuXHQgICAgICAgIENbMF0gPSAoQ1swXSArIDB4NGQzNGQzNGQgKyB0aGlzLl9iKSB8IDA7XG5cdCAgICAgICAgQ1sxXSA9IChDWzFdICsgMHhkMzRkMzRkMyArICgoQ1swXSA+Pj4gMCkgPCAoQ19bMF0gPj4+IDApID8gMSA6IDApKSB8IDA7XG5cdCAgICAgICAgQ1syXSA9IChDWzJdICsgMHgzNGQzNGQzNCArICgoQ1sxXSA+Pj4gMCkgPCAoQ19bMV0gPj4+IDApID8gMSA6IDApKSB8IDA7XG5cdCAgICAgICAgQ1szXSA9IChDWzNdICsgMHg0ZDM0ZDM0ZCArICgoQ1syXSA+Pj4gMCkgPCAoQ19bMl0gPj4+IDApID8gMSA6IDApKSB8IDA7XG5cdCAgICAgICAgQ1s0XSA9IChDWzRdICsgMHhkMzRkMzRkMyArICgoQ1szXSA+Pj4gMCkgPCAoQ19bM10gPj4+IDApID8gMSA6IDApKSB8IDA7XG5cdCAgICAgICAgQ1s1XSA9IChDWzVdICsgMHgzNGQzNGQzNCArICgoQ1s0XSA+Pj4gMCkgPCAoQ19bNF0gPj4+IDApID8gMSA6IDApKSB8IDA7XG5cdCAgICAgICAgQ1s2XSA9IChDWzZdICsgMHg0ZDM0ZDM0ZCArICgoQ1s1XSA+Pj4gMCkgPCAoQ19bNV0gPj4+IDApID8gMSA6IDApKSB8IDA7XG5cdCAgICAgICAgQ1s3XSA9IChDWzddICsgMHhkMzRkMzRkMyArICgoQ1s2XSA+Pj4gMCkgPCAoQ19bNl0gPj4+IDApID8gMSA6IDApKSB8IDA7XG5cdCAgICAgICAgdGhpcy5fYiA9IChDWzddID4+PiAwKSA8IChDX1s3XSA+Pj4gMCkgPyAxIDogMDtcblxuXHQgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgZy12YWx1ZXNcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDg7IGkrKykge1xuXHQgICAgICAgICAgICB2YXIgZ3ggPSBYW2ldICsgQ1tpXTtcblxuXHQgICAgICAgICAgICAvLyBDb25zdHJ1Y3QgaGlnaCBhbmQgbG93IGFyZ3VtZW50IGZvciBzcXVhcmluZ1xuXHQgICAgICAgICAgICB2YXIgZ2EgPSBneCAmIDB4ZmZmZjtcblx0ICAgICAgICAgICAgdmFyIGdiID0gZ3ggPj4+IDE2O1xuXG5cdCAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBoaWdoIGFuZCBsb3cgcmVzdWx0IG9mIHNxdWFyaW5nXG5cdCAgICAgICAgICAgIHZhciBnaCA9ICgoKChnYSAqIGdhKSA+Pj4gMTcpICsgZ2EgKiBnYikgPj4+IDE1KSArIGdiICogZ2I7XG5cdCAgICAgICAgICAgIHZhciBnbCA9ICgoKGd4ICYgMHhmZmZmMDAwMCkgKiBneCkgfCAwKSArICgoKGd4ICYgMHgwMDAwZmZmZikgKiBneCkgfCAwKTtcblxuXHQgICAgICAgICAgICAvLyBIaWdoIFhPUiBsb3dcblx0ICAgICAgICAgICAgR1tpXSA9IGdoIF4gZ2w7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLy8gQ2FsY3VsYXRlIG5ldyBzdGF0ZSB2YWx1ZXNcblx0ICAgICAgICBYWzBdID0gKEdbMF0gKyAoKEdbN10gPDwgMTYpIHwgKEdbN10gPj4+IDE2KSkgKyAoKEdbNl0gPDwgMTYpIHwgKEdbNl0gPj4+IDE2KSkpIHwgMDtcblx0ICAgICAgICBYWzFdID0gKEdbMV0gKyAoKEdbMF0gPDwgOCkgIHwgKEdbMF0gPj4+IDI0KSkgKyBHWzddKSB8IDA7XG5cdCAgICAgICAgWFsyXSA9IChHWzJdICsgKChHWzFdIDw8IDE2KSB8IChHWzFdID4+PiAxNikpICsgKChHWzBdIDw8IDE2KSB8IChHWzBdID4+PiAxNikpKSB8IDA7XG5cdCAgICAgICAgWFszXSA9IChHWzNdICsgKChHWzJdIDw8IDgpICB8IChHWzJdID4+PiAyNCkpICsgR1sxXSkgfCAwO1xuXHQgICAgICAgIFhbNF0gPSAoR1s0XSArICgoR1szXSA8PCAxNikgfCAoR1szXSA+Pj4gMTYpKSArICgoR1syXSA8PCAxNikgfCAoR1syXSA+Pj4gMTYpKSkgfCAwO1xuXHQgICAgICAgIFhbNV0gPSAoR1s1XSArICgoR1s0XSA8PCA4KSAgfCAoR1s0XSA+Pj4gMjQpKSArIEdbM10pIHwgMDtcblx0ICAgICAgICBYWzZdID0gKEdbNl0gKyAoKEdbNV0gPDwgMTYpIHwgKEdbNV0gPj4+IDE2KSkgKyAoKEdbNF0gPDwgMTYpIHwgKEdbNF0gPj4+IDE2KSkpIHwgMDtcblx0ICAgICAgICBYWzddID0gKEdbN10gKyAoKEdbNl0gPDwgOCkgIHwgKEdbNl0gPj4+IDI0KSkgKyBHWzVdKSB8IDA7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogU2hvcnRjdXQgZnVuY3Rpb25zIHRvIHRoZSBjaXBoZXIncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0ID0gQ3J5cHRvSlMuUmFiYml0LmVuY3J5cHQobWVzc2FnZSwga2V5LCBjZmcpO1xuXHQgICAgICogICAgIHZhciBwbGFpbnRleHQgID0gQ3J5cHRvSlMuUmFiYml0LmRlY3J5cHQoY2lwaGVydGV4dCwga2V5LCBjZmcpO1xuXHQgICAgICovXG5cdCAgICBDLlJhYmJpdCA9IFN0cmVhbUNpcGhlci5fY3JlYXRlSGVscGVyKFJhYmJpdCk7XG5cdH0oKSk7XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMuUmFiYml0O1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIiksIHJlcXVpcmUoXCIuL2VuYy1iYXNlNjRcIiksIHJlcXVpcmUoXCIuL21kNVwiKSwgcmVxdWlyZShcIi4vZXZwa2RmXCIpLCByZXF1aXJlKFwiLi9jaXBoZXItY29yZVwiKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCIsIFwiLi9lbmMtYmFzZTY0XCIsIFwiLi9tZDVcIiwgXCIuL2V2cGtkZlwiLCBcIi4vY2lwaGVyLWNvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBTdHJlYW1DaXBoZXIgPSBDX2xpYi5TdHJlYW1DaXBoZXI7XG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFJDNCBzdHJlYW0gY2lwaGVyIGFsZ29yaXRobS5cblx0ICAgICAqL1xuXHQgICAgdmFyIFJDNCA9IENfYWxnby5SQzQgPSBTdHJlYW1DaXBoZXIuZXh0ZW5kKHtcblx0ICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGtleSA9IHRoaXMuX2tleTtcblx0ICAgICAgICAgICAgdmFyIGtleVdvcmRzID0ga2V5LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIga2V5U2lnQnl0ZXMgPSBrZXkuc2lnQnl0ZXM7XG5cblx0ICAgICAgICAgICAgLy8gSW5pdCBzYm94XG5cdCAgICAgICAgICAgIHZhciBTID0gdGhpcy5fUyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICBTW2ldID0gaTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIEtleSBzZXR1cFxuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgaiA9IDA7IGkgPCAyNTY7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgdmFyIGtleUJ5dGVJbmRleCA9IGkgJSBrZXlTaWdCeXRlcztcblx0ICAgICAgICAgICAgICAgIHZhciBrZXlCeXRlID0gKGtleVdvcmRzW2tleUJ5dGVJbmRleCA+Pj4gMl0gPj4+ICgyNCAtIChrZXlCeXRlSW5kZXggJSA0KSAqIDgpKSAmIDB4ZmY7XG5cblx0ICAgICAgICAgICAgICAgIGogPSAoaiArIFNbaV0gKyBrZXlCeXRlKSAlIDI1NjtcblxuXHQgICAgICAgICAgICAgICAgLy8gU3dhcFxuXHQgICAgICAgICAgICAgICAgdmFyIHQgPSBTW2ldO1xuXHQgICAgICAgICAgICAgICAgU1tpXSA9IFNbal07XG5cdCAgICAgICAgICAgICAgICBTW2pdID0gdDtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIENvdW50ZXJzXG5cdCAgICAgICAgICAgIHRoaXMuX2kgPSB0aGlzLl9qID0gMDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7XG5cdCAgICAgICAgICAgIE1bb2Zmc2V0XSBePSBnZW5lcmF0ZUtleXN0cmVhbVdvcmQuY2FsbCh0aGlzKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAga2V5U2l6ZTogMjU2LzMyLFxuXG5cdCAgICAgICAgaXZTaXplOiAwXG5cdCAgICB9KTtcblxuXHQgICAgZnVuY3Rpb24gZ2VuZXJhdGVLZXlzdHJlYW1Xb3JkKCkge1xuXHQgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgIHZhciBTID0gdGhpcy5fUztcblx0ICAgICAgICB2YXIgaSA9IHRoaXMuX2k7XG5cdCAgICAgICAgdmFyIGogPSB0aGlzLl9qO1xuXG5cdCAgICAgICAgLy8gR2VuZXJhdGUga2V5c3RyZWFtIHdvcmRcblx0ICAgICAgICB2YXIga2V5c3RyZWFtV29yZCA9IDA7XG5cdCAgICAgICAgZm9yICh2YXIgbiA9IDA7IG4gPCA0OyBuKyspIHtcblx0ICAgICAgICAgICAgaSA9IChpICsgMSkgJSAyNTY7XG5cdCAgICAgICAgICAgIGogPSAoaiArIFNbaV0pICUgMjU2O1xuXG5cdCAgICAgICAgICAgIC8vIFN3YXBcblx0ICAgICAgICAgICAgdmFyIHQgPSBTW2ldO1xuXHQgICAgICAgICAgICBTW2ldID0gU1tqXTtcblx0ICAgICAgICAgICAgU1tqXSA9IHQ7XG5cblx0ICAgICAgICAgICAga2V5c3RyZWFtV29yZCB8PSBTWyhTW2ldICsgU1tqXSkgJSAyNTZdIDw8ICgyNCAtIG4gKiA4KTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvLyBVcGRhdGUgY291bnRlcnNcblx0ICAgICAgICB0aGlzLl9pID0gaTtcblx0ICAgICAgICB0aGlzLl9qID0gajtcblxuXHQgICAgICAgIHJldHVybiBrZXlzdHJlYW1Xb3JkO1xuXHQgICAgfVxuXG5cdCAgICAvKipcblx0ICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9ucyB0byB0aGUgY2lwaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgY2lwaGVydGV4dCA9IENyeXB0b0pTLlJDNC5lbmNyeXB0KG1lc3NhZ2UsIGtleSwgY2ZnKTtcblx0ICAgICAqICAgICB2YXIgcGxhaW50ZXh0ICA9IENyeXB0b0pTLlJDNC5kZWNyeXB0KGNpcGhlcnRleHQsIGtleSwgY2ZnKTtcblx0ICAgICAqL1xuXHQgICAgQy5SQzQgPSBTdHJlYW1DaXBoZXIuX2NyZWF0ZUhlbHBlcihSQzQpO1xuXG5cdCAgICAvKipcblx0ICAgICAqIE1vZGlmaWVkIFJDNCBzdHJlYW0gY2lwaGVyIGFsZ29yaXRobS5cblx0ICAgICAqL1xuXHQgICAgdmFyIFJDNERyb3AgPSBDX2FsZ28uUkM0RHJvcCA9IFJDNC5leHRlbmQoe1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBkcm9wIFRoZSBudW1iZXIgb2Yga2V5c3RyZWFtIHdvcmRzIHRvIGRyb3AuIERlZmF1bHQgMTkyXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2ZnOiBSQzQuY2ZnLmV4dGVuZCh7XG5cdCAgICAgICAgICAgIGRyb3A6IDE5MlxuXHQgICAgICAgIH0pLFxuXG5cdCAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgUkM0Ll9kb1Jlc2V0LmNhbGwodGhpcyk7XG5cblx0ICAgICAgICAgICAgLy8gRHJvcFxuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gdGhpcy5jZmcuZHJvcDsgaSA+IDA7IGktLSkge1xuXHQgICAgICAgICAgICAgICAgZ2VuZXJhdGVLZXlzdHJlYW1Xb3JkLmNhbGwodGhpcyk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbnMgdG8gdGhlIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiAgICAgdmFyIGNpcGhlcnRleHQgPSBDcnlwdG9KUy5SQzREcm9wLmVuY3J5cHQobWVzc2FnZSwga2V5LCBjZmcpO1xuXHQgICAgICogICAgIHZhciBwbGFpbnRleHQgID0gQ3J5cHRvSlMuUkM0RHJvcC5kZWNyeXB0KGNpcGhlcnRleHQsIGtleSwgY2ZnKTtcblx0ICAgICAqL1xuXHQgICAgQy5SQzREcm9wID0gU3RyZWFtQ2lwaGVyLl9jcmVhdGVIZWxwZXIoUkM0RHJvcCk7XG5cdH0oKSk7XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMuUkM0O1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZShcIi4vY29yZVwiKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQvKiogQHByZXNlcnZlXG5cdChjKSAyMDEyIGJ5IEPDqWRyaWMgTWVzbmlsLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuXG5cdFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dCBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcblxuXHQgICAgLSBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG5cdCAgICAtIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cblxuXHRUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG5cdCovXG5cblx0KGZ1bmN0aW9uIChNYXRoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7XG5cdCAgICB2YXIgSGFzaGVyID0gQ19saWIuSGFzaGVyO1xuXHQgICAgdmFyIENfYWxnbyA9IEMuYWxnbztcblxuXHQgICAgLy8gQ29uc3RhbnRzIHRhYmxlXG5cdCAgICB2YXIgX3psID0gV29yZEFycmF5LmNyZWF0ZShbXG5cdCAgICAgICAgMCwgIDEsICAyLCAgMywgIDQsICA1LCAgNiwgIDcsICA4LCAgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSxcblx0ICAgICAgICA3LCAgNCwgMTMsICAxLCAxMCwgIDYsIDE1LCAgMywgMTIsICAwLCAgOSwgIDUsICAyLCAxNCwgMTEsICA4LFxuXHQgICAgICAgIDMsIDEwLCAxNCwgIDQsICA5LCAxNSwgIDgsICAxLCAgMiwgIDcsICAwLCAgNiwgMTMsIDExLCAgNSwgMTIsXG5cdCAgICAgICAgMSwgIDksIDExLCAxMCwgIDAsICA4LCAxMiwgIDQsIDEzLCAgMywgIDcsIDE1LCAxNCwgIDUsICA2LCAgMixcblx0ICAgICAgICA0LCAgMCwgIDUsICA5LCAgNywgMTIsICAyLCAxMCwgMTQsICAxLCAgMywgIDgsIDExLCAgNiwgMTUsIDEzXSk7XG5cdCAgICB2YXIgX3pyID0gV29yZEFycmF5LmNyZWF0ZShbXG5cdCAgICAgICAgNSwgMTQsICA3LCAgMCwgIDksICAyLCAxMSwgIDQsIDEzLCAgNiwgMTUsICA4LCAgMSwgMTAsICAzLCAxMixcblx0ICAgICAgICA2LCAxMSwgIDMsICA3LCAgMCwgMTMsICA1LCAxMCwgMTQsIDE1LCAgOCwgMTIsICA0LCAgOSwgIDEsICAyLFxuXHQgICAgICAgIDE1LCAgNSwgIDEsICAzLCAgNywgMTQsICA2LCAgOSwgMTEsICA4LCAxMiwgIDIsIDEwLCAgMCwgIDQsIDEzLFxuXHQgICAgICAgIDgsICA2LCAgNCwgIDEsICAzLCAxMSwgMTUsICAwLCAgNSwgMTIsICAyLCAxMywgIDksICA3LCAxMCwgMTQsXG5cdCAgICAgICAgMTIsIDE1LCAxMCwgIDQsICAxLCAgNSwgIDgsICA3LCAgNiwgIDIsIDEzLCAxNCwgIDAsICAzLCAgOSwgMTFdKTtcblx0ICAgIHZhciBfc2wgPSBXb3JkQXJyYXkuY3JlYXRlKFtcblx0ICAgICAgICAgMTEsIDE0LCAxNSwgMTIsICA1LCAgOCwgIDcsICA5LCAxMSwgMTMsIDE0LCAxNSwgIDYsICA3LCAgOSwgIDgsXG5cdCAgICAgICAgNywgNiwgICA4LCAxMywgMTEsICA5LCAgNywgMTUsICA3LCAxMiwgMTUsICA5LCAxMSwgIDcsIDEzLCAxMixcblx0ICAgICAgICAxMSwgMTMsICA2LCAgNywgMTQsICA5LCAxMywgMTUsIDE0LCAgOCwgMTMsICA2LCAgNSwgMTIsICA3LCAgNSxcblx0ICAgICAgICAgIDExLCAxMiwgMTQsIDE1LCAxNCwgMTUsICA5LCAgOCwgIDksIDE0LCAgNSwgIDYsICA4LCAgNiwgIDUsIDEyLFxuXHQgICAgICAgIDksIDE1LCAgNSwgMTEsICA2LCAgOCwgMTMsIDEyLCAgNSwgMTIsIDEzLCAxNCwgMTEsICA4LCAgNSwgIDYgXSk7XG5cdCAgICB2YXIgX3NyID0gV29yZEFycmF5LmNyZWF0ZShbXG5cdCAgICAgICAgOCwgIDksICA5LCAxMSwgMTMsIDE1LCAxNSwgIDUsICA3LCAgNywgIDgsIDExLCAxNCwgMTQsIDEyLCAgNixcblx0ICAgICAgICA5LCAxMywgMTUsICA3LCAxMiwgIDgsICA5LCAxMSwgIDcsICA3LCAxMiwgIDcsICA2LCAxNSwgMTMsIDExLFxuXHQgICAgICAgIDksICA3LCAxNSwgMTEsICA4LCAgNiwgIDYsIDE0LCAxMiwgMTMsICA1LCAxNCwgMTMsIDEzLCAgNywgIDUsXG5cdCAgICAgICAgMTUsICA1LCAgOCwgMTEsIDE0LCAxNCwgIDYsIDE0LCAgNiwgIDksIDEyLCAgOSwgMTIsICA1LCAxNSwgIDgsXG5cdCAgICAgICAgOCwgIDUsIDEyLCAgOSwgMTIsICA1LCAxNCwgIDYsICA4LCAxMywgIDYsICA1LCAxNSwgMTMsIDExLCAxMSBdKTtcblxuXHQgICAgdmFyIF9obCA9ICBXb3JkQXJyYXkuY3JlYXRlKFsgMHgwMDAwMDAwMCwgMHg1QTgyNzk5OSwgMHg2RUQ5RUJBMSwgMHg4RjFCQkNEQywgMHhBOTUzRkQ0RV0pO1xuXHQgICAgdmFyIF9ociA9ICBXb3JkQXJyYXkuY3JlYXRlKFsgMHg1MEEyOEJFNiwgMHg1QzRERDEyNCwgMHg2RDcwM0VGMywgMHg3QTZENzZFOSwgMHgwMDAwMDAwMF0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFJJUEVNRDE2MCBoYXNoIGFsZ29yaXRobS5cblx0ICAgICAqL1xuXHQgICAgdmFyIFJJUEVNRDE2MCA9IENfYWxnby5SSVBFTUQxNjAgPSBIYXNoZXIuZXh0ZW5kKHtcblx0ICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB0aGlzLl9oYXNoICA9IFdvcmRBcnJheS5jcmVhdGUoWzB4Njc0NTIzMDEsIDB4RUZDREFCODksIDB4OThCQURDRkUsIDB4MTAzMjU0NzYsIDB4QzNEMkUxRjBdKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7XG5cblx0ICAgICAgICAgICAgLy8gU3dhcCBlbmRpYW5cblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgICAgIHZhciBvZmZzZXRfaSA9IG9mZnNldCArIGk7XG5cdCAgICAgICAgICAgICAgICB2YXIgTV9vZmZzZXRfaSA9IE1bb2Zmc2V0X2ldO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBTd2FwXG5cdCAgICAgICAgICAgICAgICBNW29mZnNldF9pXSA9IChcblx0ICAgICAgICAgICAgICAgICAgICAoKChNX29mZnNldF9pIDw8IDgpICB8IChNX29mZnNldF9pID4+PiAyNCkpICYgMHgwMGZmMDBmZikgfFxuXHQgICAgICAgICAgICAgICAgICAgICgoKE1fb2Zmc2V0X2kgPDwgMjQpIHwgKE1fb2Zmc2V0X2kgPj4+IDgpKSAgJiAweGZmMDBmZjAwKVxuXHQgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgSCAgPSB0aGlzLl9oYXNoLndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgaGwgPSBfaGwud29yZHM7XG5cdCAgICAgICAgICAgIHZhciBociA9IF9oci53b3Jkcztcblx0ICAgICAgICAgICAgdmFyIHpsID0gX3psLndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgenIgPSBfenIud29yZHM7XG5cdCAgICAgICAgICAgIHZhciBzbCA9IF9zbC53b3Jkcztcblx0ICAgICAgICAgICAgdmFyIHNyID0gX3NyLndvcmRzO1xuXG5cdCAgICAgICAgICAgIC8vIFdvcmtpbmcgdmFyaWFibGVzXG5cdCAgICAgICAgICAgIHZhciBhbCwgYmwsIGNsLCBkbCwgZWw7XG5cdCAgICAgICAgICAgIHZhciBhciwgYnIsIGNyLCBkciwgZXI7XG5cblx0ICAgICAgICAgICAgYXIgPSBhbCA9IEhbMF07XG5cdCAgICAgICAgICAgIGJyID0gYmwgPSBIWzFdO1xuXHQgICAgICAgICAgICBjciA9IGNsID0gSFsyXTtcblx0ICAgICAgICAgICAgZHIgPSBkbCA9IEhbM107XG5cdCAgICAgICAgICAgIGVyID0gZWwgPSBIWzRdO1xuXHQgICAgICAgICAgICAvLyBDb21wdXRhdGlvblxuXHQgICAgICAgICAgICB2YXIgdDtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA4MDsgaSArPSAxKSB7XG5cdCAgICAgICAgICAgICAgICB0ID0gKGFsICsgIE1bb2Zmc2V0K3psW2ldXSl8MDtcblx0ICAgICAgICAgICAgICAgIGlmIChpPDE2KXtcblx0XHQgICAgICAgICAgICB0ICs9ICBmMShibCxjbCxkbCkgKyBobFswXTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaTwzMikge1xuXHRcdCAgICAgICAgICAgIHQgKz0gIGYyKGJsLGNsLGRsKSArIGhsWzFdO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpPDQ4KSB7XG5cdFx0ICAgICAgICAgICAgdCArPSAgZjMoYmwsY2wsZGwpICsgaGxbMl07XG5cdCAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGk8NjQpIHtcblx0XHQgICAgICAgICAgICB0ICs9ICBmNChibCxjbCxkbCkgKyBobFszXTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7Ly8gaWYgKGk8ODApIHtcblx0XHQgICAgICAgICAgICB0ICs9ICBmNShibCxjbCxkbCkgKyBobFs0XTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIHQgPSB0fDA7XG5cdCAgICAgICAgICAgICAgICB0ID0gIHJvdGwodCxzbFtpXSk7XG5cdCAgICAgICAgICAgICAgICB0ID0gKHQrZWwpfDA7XG5cdCAgICAgICAgICAgICAgICBhbCA9IGVsO1xuXHQgICAgICAgICAgICAgICAgZWwgPSBkbDtcblx0ICAgICAgICAgICAgICAgIGRsID0gcm90bChjbCwgMTApO1xuXHQgICAgICAgICAgICAgICAgY2wgPSBibDtcblx0ICAgICAgICAgICAgICAgIGJsID0gdDtcblxuXHQgICAgICAgICAgICAgICAgdCA9IChhciArIE1bb2Zmc2V0K3pyW2ldXSl8MDtcblx0ICAgICAgICAgICAgICAgIGlmIChpPDE2KXtcblx0XHQgICAgICAgICAgICB0ICs9ICBmNShicixjcixkcikgKyBoclswXTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaTwzMikge1xuXHRcdCAgICAgICAgICAgIHQgKz0gIGY0KGJyLGNyLGRyKSArIGhyWzFdO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpPDQ4KSB7XG5cdFx0ICAgICAgICAgICAgdCArPSAgZjMoYnIsY3IsZHIpICsgaHJbMl07XG5cdCAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGk8NjQpIHtcblx0XHQgICAgICAgICAgICB0ICs9ICBmMihicixjcixkcikgKyBoclszXTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7Ly8gaWYgKGk8ODApIHtcblx0XHQgICAgICAgICAgICB0ICs9ICBmMShicixjcixkcikgKyBocls0XTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIHQgPSB0fDA7XG5cdCAgICAgICAgICAgICAgICB0ID0gIHJvdGwodCxzcltpXSkgO1xuXHQgICAgICAgICAgICAgICAgdCA9ICh0K2VyKXwwO1xuXHQgICAgICAgICAgICAgICAgYXIgPSBlcjtcblx0ICAgICAgICAgICAgICAgIGVyID0gZHI7XG5cdCAgICAgICAgICAgICAgICBkciA9IHJvdGwoY3IsIDEwKTtcblx0ICAgICAgICAgICAgICAgIGNyID0gYnI7XG5cdCAgICAgICAgICAgICAgICBiciA9IHQ7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgLy8gSW50ZXJtZWRpYXRlIGhhc2ggdmFsdWVcblx0ICAgICAgICAgICAgdCAgICA9IChIWzFdICsgY2wgKyBkcil8MDtcblx0ICAgICAgICAgICAgSFsxXSA9IChIWzJdICsgZGwgKyBlcil8MDtcblx0ICAgICAgICAgICAgSFsyXSA9IChIWzNdICsgZWwgKyBhcil8MDtcblx0ICAgICAgICAgICAgSFszXSA9IChIWzRdICsgYWwgKyBicil8MDtcblx0ICAgICAgICAgICAgSFs0XSA9IChIWzBdICsgYmwgKyBjcil8MDtcblx0ICAgICAgICAgICAgSFswXSA9ICB0O1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGRhdGEgPSB0aGlzLl9kYXRhO1xuXHQgICAgICAgICAgICB2YXIgZGF0YVdvcmRzID0gZGF0YS53b3JkcztcblxuXHQgICAgICAgICAgICB2YXIgbkJpdHNUb3RhbCA9IHRoaXMuX25EYXRhQnl0ZXMgKiA4O1xuXHQgICAgICAgICAgICB2YXIgbkJpdHNMZWZ0ID0gZGF0YS5zaWdCeXRlcyAqIDg7XG5cblx0ICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmdcblx0ICAgICAgICAgICAgZGF0YVdvcmRzW25CaXRzTGVmdCA+Pj4gNV0gfD0gMHg4MCA8PCAoMjQgLSBuQml0c0xlZnQgJSAzMik7XG5cdCAgICAgICAgICAgIGRhdGFXb3Jkc1soKChuQml0c0xlZnQgKyA2NCkgPj4+IDkpIDw8IDQpICsgMTRdID0gKFxuXHQgICAgICAgICAgICAgICAgKCgobkJpdHNUb3RhbCA8PCA4KSAgfCAobkJpdHNUb3RhbCA+Pj4gMjQpKSAmIDB4MDBmZjAwZmYpIHxcblx0ICAgICAgICAgICAgICAgICgoKG5CaXRzVG90YWwgPDwgMjQpIHwgKG5CaXRzVG90YWwgPj4+IDgpKSAgJiAweGZmMDBmZjAwKVxuXHQgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICBkYXRhLnNpZ0J5dGVzID0gKGRhdGFXb3Jkcy5sZW5ndGggKyAxKSAqIDQ7XG5cblx0ICAgICAgICAgICAgLy8gSGFzaCBmaW5hbCBibG9ja3Ncblx0ICAgICAgICAgICAgdGhpcy5fcHJvY2VzcygpO1xuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgaGFzaCA9IHRoaXMuX2hhc2g7XG5cdCAgICAgICAgICAgIHZhciBIID0gaGFzaC53b3JkcztcblxuXHQgICAgICAgICAgICAvLyBTd2FwIGVuZGlhblxuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDU7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgICAgIHZhciBIX2kgPSBIW2ldO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBTd2FwXG5cdCAgICAgICAgICAgICAgICBIW2ldID0gKCgoSF9pIDw8IDgpICB8IChIX2kgPj4+IDI0KSkgJiAweDAwZmYwMGZmKSB8XG5cdCAgICAgICAgICAgICAgICAgICAgICAgKCgoSF9pIDw8IDI0KSB8IChIX2kgPj4+IDgpKSAgJiAweGZmMDBmZjAwKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIFJldHVybiBmaW5hbCBjb21wdXRlZCBoYXNoXG5cdCAgICAgICAgICAgIHJldHVybiBoYXNoO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgY2xvbmUgPSBIYXNoZXIuY2xvbmUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAgICAgY2xvbmUuX2hhc2ggPSB0aGlzLl9oYXNoLmNsb25lKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXG5cblx0ICAgIGZ1bmN0aW9uIGYxKHgsIHksIHopIHtcblx0ICAgICAgICByZXR1cm4gKCh4KSBeICh5KSBeICh6KSk7XG5cblx0ICAgIH1cblxuXHQgICAgZnVuY3Rpb24gZjIoeCwgeSwgeikge1xuXHQgICAgICAgIHJldHVybiAoKCh4KSYoeSkpIHwgKCh+eCkmKHopKSk7XG5cdCAgICB9XG5cblx0ICAgIGZ1bmN0aW9uIGYzKHgsIHksIHopIHtcblx0ICAgICAgICByZXR1cm4gKCgoeCkgfCAofih5KSkpIF4gKHopKTtcblx0ICAgIH1cblxuXHQgICAgZnVuY3Rpb24gZjQoeCwgeSwgeikge1xuXHQgICAgICAgIHJldHVybiAoKCh4KSAmICh6KSkgfCAoKHkpJih+KHopKSkpO1xuXHQgICAgfVxuXG5cdCAgICBmdW5jdGlvbiBmNSh4LCB5LCB6KSB7XG5cdCAgICAgICAgcmV0dXJuICgoeCkgXiAoKHkpIHwofih6KSkpKTtcblxuXHQgICAgfVxuXG5cdCAgICBmdW5jdGlvbiByb3RsKHgsbikge1xuXHQgICAgICAgIHJldHVybiAoeDw8bikgfCAoeD4+PigzMi1uKSk7XG5cdCAgICB9XG5cblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlJJUEVNRDE2MCgnbWVzc2FnZScpO1xuXHQgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuUklQRU1EMTYwKHdvcmRBcnJheSk7XG5cdCAgICAgKi9cblx0ICAgIEMuUklQRU1EMTYwID0gSGFzaGVyLl9jcmVhdGVIZWxwZXIoUklQRU1EMTYwKTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgSE1BQydzIG9iamVjdCBpbnRlcmZhY2UuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGtleSBUaGUgc2VjcmV0IGtleS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBITUFDLlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgaG1hYyA9IENyeXB0b0pTLkhtYWNSSVBFTUQxNjAobWVzc2FnZSwga2V5KTtcblx0ICAgICAqL1xuXHQgICAgQy5IbWFjUklQRU1EMTYwID0gSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKFJJUEVNRDE2MCk7XG5cdH0oTWF0aCkpO1xuXG5cblx0cmV0dXJuIENyeXB0b0pTLlJJUEVNRDE2MDtcblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0KGZ1bmN0aW9uICgpIHtcblx0ICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgdmFyIEMgPSBDcnlwdG9KUztcblx0ICAgIHZhciBDX2xpYiA9IEMubGliO1xuXHQgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTtcblx0ICAgIHZhciBIYXNoZXIgPSBDX2xpYi5IYXNoZXI7XG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvO1xuXG5cdCAgICAvLyBSZXVzYWJsZSBvYmplY3Rcblx0ICAgIHZhciBXID0gW107XG5cblx0ICAgIC8qKlxuXHQgICAgICogU0hBLTEgaGFzaCBhbGdvcml0aG0uXG5cdCAgICAgKi9cblx0ICAgIHZhciBTSEExID0gQ19hbGdvLlNIQTEgPSBIYXNoZXIuZXh0ZW5kKHtcblx0ICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB0aGlzLl9oYXNoID0gbmV3IFdvcmRBcnJheS5pbml0KFtcblx0ICAgICAgICAgICAgICAgIDB4Njc0NTIzMDEsIDB4ZWZjZGFiODksXG5cdCAgICAgICAgICAgICAgICAweDk4YmFkY2ZlLCAweDEwMzI1NDc2LFxuXHQgICAgICAgICAgICAgICAgMHhjM2QyZTFmMFxuXHQgICAgICAgICAgICBdKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgIHZhciBIID0gdGhpcy5faGFzaC53b3JkcztcblxuXHQgICAgICAgICAgICAvLyBXb3JraW5nIHZhcmlhYmxlc1xuXHQgICAgICAgICAgICB2YXIgYSA9IEhbMF07XG5cdCAgICAgICAgICAgIHZhciBiID0gSFsxXTtcblx0ICAgICAgICAgICAgdmFyIGMgPSBIWzJdO1xuXHQgICAgICAgICAgICB2YXIgZCA9IEhbM107XG5cdCAgICAgICAgICAgIHZhciBlID0gSFs0XTtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRhdGlvblxuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDgwOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIGlmIChpIDwgMTYpIHtcblx0ICAgICAgICAgICAgICAgICAgICBXW2ldID0gTVtvZmZzZXQgKyBpXSB8IDA7XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciBuID0gV1tpIC0gM10gXiBXW2kgLSA4XSBeIFdbaSAtIDE0XSBeIFdbaSAtIDE2XTtcblx0ICAgICAgICAgICAgICAgICAgICBXW2ldID0gKG4gPDwgMSkgfCAobiA+Pj4gMzEpO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICB2YXIgdCA9ICgoYSA8PCA1KSB8IChhID4+PiAyNykpICsgZSArIFdbaV07XG5cdCAgICAgICAgICAgICAgICBpZiAoaSA8IDIwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdCArPSAoKGIgJiBjKSB8ICh+YiAmIGQpKSArIDB4NWE4Mjc5OTk7XG5cdCAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGkgPCA0MCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHQgKz0gKGIgXiBjIF4gZCkgKyAweDZlZDllYmExO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpIDwgNjApIHtcblx0ICAgICAgICAgICAgICAgICAgICB0ICs9ICgoYiAmIGMpIHwgKGIgJiBkKSB8IChjICYgZCkpIC0gMHg3MGU0NDMyNDtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAoaSA8IDgwKSAqLyB7XG5cdCAgICAgICAgICAgICAgICAgICAgdCArPSAoYiBeIGMgXiBkKSAtIDB4MzU5ZDNlMmE7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIGUgPSBkO1xuXHQgICAgICAgICAgICAgICAgZCA9IGM7XG5cdCAgICAgICAgICAgICAgICBjID0gKGIgPDwgMzApIHwgKGIgPj4+IDIpO1xuXHQgICAgICAgICAgICAgICAgYiA9IGE7XG5cdCAgICAgICAgICAgICAgICBhID0gdDtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIEludGVybWVkaWF0ZSBoYXNoIHZhbHVlXG5cdCAgICAgICAgICAgIEhbMF0gPSAoSFswXSArIGEpIHwgMDtcblx0ICAgICAgICAgICAgSFsxXSA9IChIWzFdICsgYikgfCAwO1xuXHQgICAgICAgICAgICBIWzJdID0gKEhbMl0gKyBjKSB8IDA7XG5cdCAgICAgICAgICAgIEhbM10gPSAoSFszXSArIGQpIHwgMDtcblx0ICAgICAgICAgICAgSFs0XSA9IChIWzRdICsgZSkgfCAwO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGRhdGEgPSB0aGlzLl9kYXRhO1xuXHQgICAgICAgICAgICB2YXIgZGF0YVdvcmRzID0gZGF0YS53b3JkcztcblxuXHQgICAgICAgICAgICB2YXIgbkJpdHNUb3RhbCA9IHRoaXMuX25EYXRhQnl0ZXMgKiA4O1xuXHQgICAgICAgICAgICB2YXIgbkJpdHNMZWZ0ID0gZGF0YS5zaWdCeXRlcyAqIDg7XG5cblx0ICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmdcblx0ICAgICAgICAgICAgZGF0YVdvcmRzW25CaXRzTGVmdCA+Pj4gNV0gfD0gMHg4MCA8PCAoMjQgLSBuQml0c0xlZnQgJSAzMik7XG5cdCAgICAgICAgICAgIGRhdGFXb3Jkc1soKChuQml0c0xlZnQgKyA2NCkgPj4+IDkpIDw8IDQpICsgMTRdID0gTWF0aC5mbG9vcihuQml0c1RvdGFsIC8gMHgxMDAwMDAwMDApO1xuXHQgICAgICAgICAgICBkYXRhV29yZHNbKCgobkJpdHNMZWZ0ICsgNjQpID4+PiA5KSA8PCA0KSArIDE1XSA9IG5CaXRzVG90YWw7XG5cdCAgICAgICAgICAgIGRhdGEuc2lnQnl0ZXMgPSBkYXRhV29yZHMubGVuZ3RoICogNDtcblxuXHQgICAgICAgICAgICAvLyBIYXNoIGZpbmFsIGJsb2Nrc1xuXHQgICAgICAgICAgICB0aGlzLl9wcm9jZXNzKCk7XG5cblx0ICAgICAgICAgICAgLy8gUmV0dXJuIGZpbmFsIGNvbXB1dGVkIGhhc2hcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2hhc2g7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHZhciBjbG9uZSA9IEhhc2hlci5jbG9uZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgICAgICBjbG9uZS5faGFzaCA9IHRoaXMuX2hhc2guY2xvbmUoKTtcblxuXHQgICAgICAgICAgICByZXR1cm4gY2xvbmU7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIGhhc2hlcidzIG9iamVjdCBpbnRlcmZhY2UuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guXG5cdCAgICAgKlxuXHQgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgaGFzaC5cblx0ICAgICAqXG5cdCAgICAgKiBAc3RhdGljXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5TSEExKCdtZXNzYWdlJyk7XG5cdCAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5TSEExKHdvcmRBcnJheSk7XG5cdCAgICAgKi9cblx0ICAgIEMuU0hBMSA9IEhhc2hlci5fY3JlYXRlSGVscGVyKFNIQTEpO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBITUFDJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC5cblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30ga2V5IFRoZSBzZWNyZXQga2V5LlxuXHQgICAgICpcblx0ICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIEhNQUMuXG5cdCAgICAgKlxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogICAgIHZhciBobWFjID0gQ3J5cHRvSlMuSG1hY1NIQTEobWVzc2FnZSwga2V5KTtcblx0ICAgICAqL1xuXHQgICAgQy5IbWFjU0hBMSA9IEhhc2hlci5fY3JlYXRlSG1hY0hlbHBlcihTSEExKTtcblx0fSgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUy5TSEExO1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIiksIHJlcXVpcmUoXCIuL3NoYTI1NlwiKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCIsIFwiLi9zaGEyNTZcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7XG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvO1xuXHQgICAgdmFyIFNIQTI1NiA9IENfYWxnby5TSEEyNTY7XG5cblx0ICAgIC8qKlxuXHQgICAgICogU0hBLTIyNCBoYXNoIGFsZ29yaXRobS5cblx0ICAgICAqL1xuXHQgICAgdmFyIFNIQTIyNCA9IENfYWxnby5TSEEyMjQgPSBTSEEyNTYuZXh0ZW5kKHtcblx0ICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB0aGlzLl9oYXNoID0gbmV3IFdvcmRBcnJheS5pbml0KFtcblx0ICAgICAgICAgICAgICAgIDB4YzEwNTllZDgsIDB4MzY3Y2Q1MDcsIDB4MzA3MGRkMTcsIDB4ZjcwZTU5MzksXG5cdCAgICAgICAgICAgICAgICAweGZmYzAwYjMxLCAweDY4NTgxNTExLCAweDY0Zjk4ZmE3LCAweGJlZmE0ZmE0XG5cdCAgICAgICAgICAgIF0pO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgaGFzaCA9IFNIQTI1Ni5fZG9GaW5hbGl6ZS5jYWxsKHRoaXMpO1xuXG5cdCAgICAgICAgICAgIGhhc2guc2lnQnl0ZXMgLT0gNDtcblxuXHQgICAgICAgICAgICByZXR1cm4gaGFzaDtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlNIQTIyNCgnbWVzc2FnZScpO1xuXHQgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuU0hBMjI0KHdvcmRBcnJheSk7XG5cdCAgICAgKi9cblx0ICAgIEMuU0hBMjI0ID0gU0hBMjU2Ll9jcmVhdGVIZWxwZXIoU0hBMjI0KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgSE1BQydzIG9iamVjdCBpbnRlcmZhY2UuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGtleSBUaGUgc2VjcmV0IGtleS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBITUFDLlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgaG1hYyA9IENyeXB0b0pTLkhtYWNTSEEyMjQobWVzc2FnZSwga2V5KTtcblx0ICAgICAqL1xuXHQgICAgQy5IbWFjU0hBMjI0ID0gU0hBMjU2Ll9jcmVhdGVIbWFjSGVscGVyKFNIQTIyNCk7XG5cdH0oKSk7XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMuU0hBMjI0O1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZShcIi4vY29yZVwiKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQoZnVuY3Rpb24gKE1hdGgpIHtcblx0ICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgdmFyIEMgPSBDcnlwdG9KUztcblx0ICAgIHZhciBDX2xpYiA9IEMubGliO1xuXHQgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTtcblx0ICAgIHZhciBIYXNoZXIgPSBDX2xpYi5IYXNoZXI7XG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvO1xuXG5cdCAgICAvLyBJbml0aWFsaXphdGlvbiBhbmQgcm91bmQgY29uc3RhbnRzIHRhYmxlc1xuXHQgICAgdmFyIEggPSBbXTtcblx0ICAgIHZhciBLID0gW107XG5cblx0ICAgIC8vIENvbXB1dGUgY29uc3RhbnRzXG5cdCAgICAoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGZ1bmN0aW9uIGlzUHJpbWUobikge1xuXHQgICAgICAgICAgICB2YXIgc3FydE4gPSBNYXRoLnNxcnQobik7XG5cdCAgICAgICAgICAgIGZvciAodmFyIGZhY3RvciA9IDI7IGZhY3RvciA8PSBzcXJ0TjsgZmFjdG9yKyspIHtcblx0ICAgICAgICAgICAgICAgIGlmICghKG4gJSBmYWN0b3IpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIHRydWU7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgZnVuY3Rpb24gZ2V0RnJhY3Rpb25hbEJpdHMobikge1xuXHQgICAgICAgICAgICByZXR1cm4gKChuIC0gKG4gfCAwKSkgKiAweDEwMDAwMDAwMCkgfCAwO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIHZhciBuID0gMjtcblx0ICAgICAgICB2YXIgblByaW1lID0gMDtcblx0ICAgICAgICB3aGlsZSAoblByaW1lIDwgNjQpIHtcblx0ICAgICAgICAgICAgaWYgKGlzUHJpbWUobikpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChuUHJpbWUgPCA4KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgSFtuUHJpbWVdID0gZ2V0RnJhY3Rpb25hbEJpdHMoTWF0aC5wb3cobiwgMSAvIDIpKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIEtbblByaW1lXSA9IGdldEZyYWN0aW9uYWxCaXRzKE1hdGgucG93KG4sIDEgLyAzKSk7XG5cblx0ICAgICAgICAgICAgICAgIG5QcmltZSsrO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgbisrO1xuXHQgICAgICAgIH1cblx0ICAgIH0oKSk7XG5cblx0ICAgIC8vIFJldXNhYmxlIG9iamVjdFxuXHQgICAgdmFyIFcgPSBbXTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTSEEtMjU2IGhhc2ggYWxnb3JpdGhtLlxuXHQgICAgICovXG5cdCAgICB2YXIgU0hBMjU2ID0gQ19hbGdvLlNIQTI1NiA9IEhhc2hlci5leHRlbmQoe1xuXHQgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2hhc2ggPSBuZXcgV29yZEFycmF5LmluaXQoSC5zbGljZSgwKSk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIF9kb1Byb2Nlc3NCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgSCA9IHRoaXMuX2hhc2gud29yZHM7XG5cblx0ICAgICAgICAgICAgLy8gV29ya2luZyB2YXJpYWJsZXNcblx0ICAgICAgICAgICAgdmFyIGEgPSBIWzBdO1xuXHQgICAgICAgICAgICB2YXIgYiA9IEhbMV07XG5cdCAgICAgICAgICAgIHZhciBjID0gSFsyXTtcblx0ICAgICAgICAgICAgdmFyIGQgPSBIWzNdO1xuXHQgICAgICAgICAgICB2YXIgZSA9IEhbNF07XG5cdCAgICAgICAgICAgIHZhciBmID0gSFs1XTtcblx0ICAgICAgICAgICAgdmFyIGcgPSBIWzZdO1xuXHQgICAgICAgICAgICB2YXIgaCA9IEhbN107XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0YXRpb25cblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA2NDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoaSA8IDE2KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgV1tpXSA9IE1bb2Zmc2V0ICsgaV0gfCAwO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgZ2FtbWEweCA9IFdbaSAtIDE1XTtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgZ2FtbWEwICA9ICgoZ2FtbWEweCA8PCAyNSkgfCAoZ2FtbWEweCA+Pj4gNykpICBeXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGdhbW1hMHggPDwgMTQpIHwgKGdhbW1hMHggPj4+IDE4KSkgXlxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChnYW1tYTB4ID4+PiAzKTtcblxuXHQgICAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTF4ID0gV1tpIC0gMl07XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIGdhbW1hMSAgPSAoKGdhbW1hMXggPDwgMTUpIHwgKGdhbW1hMXggPj4+IDE3KSkgXlxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChnYW1tYTF4IDw8IDEzKSB8IChnYW1tYTF4ID4+PiAxOSkpIF5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZ2FtbWExeCA+Pj4gMTApO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgV1tpXSA9IGdhbW1hMCArIFdbaSAtIDddICsgZ2FtbWExICsgV1tpIC0gMTZdO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICB2YXIgY2ggID0gKGUgJiBmKSBeICh+ZSAmIGcpO1xuXHQgICAgICAgICAgICAgICAgdmFyIG1haiA9IChhICYgYikgXiAoYSAmIGMpIF4gKGIgJiBjKTtcblxuXHQgICAgICAgICAgICAgICAgdmFyIHNpZ21hMCA9ICgoYSA8PCAzMCkgfCAoYSA+Pj4gMikpIF4gKChhIDw8IDE5KSB8IChhID4+PiAxMykpIF4gKChhIDw8IDEwKSB8IChhID4+PiAyMikpO1xuXHQgICAgICAgICAgICAgICAgdmFyIHNpZ21hMSA9ICgoZSA8PCAyNikgfCAoZSA+Pj4gNikpIF4gKChlIDw8IDIxKSB8IChlID4+PiAxMSkpIF4gKChlIDw8IDcpICB8IChlID4+PiAyNSkpO1xuXG5cdCAgICAgICAgICAgICAgICB2YXIgdDEgPSBoICsgc2lnbWExICsgY2ggKyBLW2ldICsgV1tpXTtcblx0ICAgICAgICAgICAgICAgIHZhciB0MiA9IHNpZ21hMCArIG1hajtcblxuXHQgICAgICAgICAgICAgICAgaCA9IGc7XG5cdCAgICAgICAgICAgICAgICBnID0gZjtcblx0ICAgICAgICAgICAgICAgIGYgPSBlO1xuXHQgICAgICAgICAgICAgICAgZSA9IChkICsgdDEpIHwgMDtcblx0ICAgICAgICAgICAgICAgIGQgPSBjO1xuXHQgICAgICAgICAgICAgICAgYyA9IGI7XG5cdCAgICAgICAgICAgICAgICBiID0gYTtcblx0ICAgICAgICAgICAgICAgIGEgPSAodDEgKyB0MikgfCAwO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gSW50ZXJtZWRpYXRlIGhhc2ggdmFsdWVcblx0ICAgICAgICAgICAgSFswXSA9IChIWzBdICsgYSkgfCAwO1xuXHQgICAgICAgICAgICBIWzFdID0gKEhbMV0gKyBiKSB8IDA7XG5cdCAgICAgICAgICAgIEhbMl0gPSAoSFsyXSArIGMpIHwgMDtcblx0ICAgICAgICAgICAgSFszXSA9IChIWzNdICsgZCkgfCAwO1xuXHQgICAgICAgICAgICBIWzRdID0gKEhbNF0gKyBlKSB8IDA7XG5cdCAgICAgICAgICAgIEhbNV0gPSAoSFs1XSArIGYpIHwgMDtcblx0ICAgICAgICAgICAgSFs2XSA9IChIWzZdICsgZykgfCAwO1xuXHQgICAgICAgICAgICBIWzddID0gKEhbN10gKyBoKSB8IDA7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIF9kb0ZpbmFsaXplOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgZGF0YSA9IHRoaXMuX2RhdGE7XG5cdCAgICAgICAgICAgIHZhciBkYXRhV29yZHMgPSBkYXRhLndvcmRzO1xuXG5cdCAgICAgICAgICAgIHZhciBuQml0c1RvdGFsID0gdGhpcy5fbkRhdGFCeXRlcyAqIDg7XG5cdCAgICAgICAgICAgIHZhciBuQml0c0xlZnQgPSBkYXRhLnNpZ0J5dGVzICogODtcblxuXHQgICAgICAgICAgICAvLyBBZGQgcGFkZGluZ1xuXHQgICAgICAgICAgICBkYXRhV29yZHNbbkJpdHNMZWZ0ID4+PiA1XSB8PSAweDgwIDw8ICgyNCAtIG5CaXRzTGVmdCAlIDMyKTtcblx0ICAgICAgICAgICAgZGF0YVdvcmRzWygoKG5CaXRzTGVmdCArIDY0KSA+Pj4gOSkgPDwgNCkgKyAxNF0gPSBNYXRoLmZsb29yKG5CaXRzVG90YWwgLyAweDEwMDAwMDAwMCk7XG5cdCAgICAgICAgICAgIGRhdGFXb3Jkc1soKChuQml0c0xlZnQgKyA2NCkgPj4+IDkpIDw8IDQpICsgMTVdID0gbkJpdHNUb3RhbDtcblx0ICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyA9IGRhdGFXb3Jkcy5sZW5ndGggKiA0O1xuXG5cdCAgICAgICAgICAgIC8vIEhhc2ggZmluYWwgYmxvY2tzXG5cdCAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3MoKTtcblxuXHQgICAgICAgICAgICAvLyBSZXR1cm4gZmluYWwgY29tcHV0ZWQgaGFzaFxuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5faGFzaDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdmFyIGNsb25lID0gSGFzaGVyLmNsb25lLmNhbGwodGhpcyk7XG5cdCAgICAgICAgICAgIGNsb25lLl9oYXNoID0gdGhpcy5faGFzaC5jbG9uZSgpO1xuXG5cdCAgICAgICAgICAgIHJldHVybiBjbG9uZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlNIQTI1NignbWVzc2FnZScpO1xuXHQgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuU0hBMjU2KHdvcmRBcnJheSk7XG5cdCAgICAgKi9cblx0ICAgIEMuU0hBMjU2ID0gSGFzaGVyLl9jcmVhdGVIZWxwZXIoU0hBMjU2KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgSE1BQydzIG9iamVjdCBpbnRlcmZhY2UuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGtleSBUaGUgc2VjcmV0IGtleS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBITUFDLlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgaG1hYyA9IENyeXB0b0pTLkhtYWNTSEEyNTYobWVzc2FnZSwga2V5KTtcblx0ICAgICAqL1xuXHQgICAgQy5IbWFjU0hBMjU2ID0gSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKFNIQTI1Nik7XG5cdH0oTWF0aCkpO1xuXG5cblx0cmV0dXJuIENyeXB0b0pTLlNIQTI1NjtcblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7XG5cdGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xuXHRcdC8vIENvbW1vbkpTXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKFwiLi9jb3JlXCIpLCByZXF1aXJlKFwiLi94NjQtY29yZVwiKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCIsIFwiLi94NjQtY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0KGZ1bmN0aW9uIChNYXRoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7XG5cdCAgICB2YXIgSGFzaGVyID0gQ19saWIuSGFzaGVyO1xuXHQgICAgdmFyIENfeDY0ID0gQy54NjQ7XG5cdCAgICB2YXIgWDY0V29yZCA9IENfeDY0LldvcmQ7XG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvO1xuXG5cdCAgICAvLyBDb25zdGFudHMgdGFibGVzXG5cdCAgICB2YXIgUkhPX09GRlNFVFMgPSBbXTtcblx0ICAgIHZhciBQSV9JTkRFWEVTICA9IFtdO1xuXHQgICAgdmFyIFJPVU5EX0NPTlNUQU5UUyA9IFtdO1xuXG5cdCAgICAvLyBDb21wdXRlIENvbnN0YW50c1xuXHQgICAgKGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAvLyBDb21wdXRlIHJobyBvZmZzZXQgY29uc3RhbnRzXG5cdCAgICAgICAgdmFyIHggPSAxLCB5ID0gMDtcblx0ICAgICAgICBmb3IgKHZhciB0ID0gMDsgdCA8IDI0OyB0KyspIHtcblx0ICAgICAgICAgICAgUkhPX09GRlNFVFNbeCArIDUgKiB5XSA9ICgodCArIDEpICogKHQgKyAyKSAvIDIpICUgNjQ7XG5cblx0ICAgICAgICAgICAgdmFyIG5ld1ggPSB5ICUgNTtcblx0ICAgICAgICAgICAgdmFyIG5ld1kgPSAoMiAqIHggKyAzICogeSkgJSA1O1xuXHQgICAgICAgICAgICB4ID0gbmV3WDtcblx0ICAgICAgICAgICAgeSA9IG5ld1k7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLy8gQ29tcHV0ZSBwaSBpbmRleCBjb25zdGFudHNcblx0ICAgICAgICBmb3IgKHZhciB4ID0gMDsgeCA8IDU7IHgrKykge1xuXHQgICAgICAgICAgICBmb3IgKHZhciB5ID0gMDsgeSA8IDU7IHkrKykge1xuXHQgICAgICAgICAgICAgICAgUElfSU5ERVhFU1t4ICsgNSAqIHldID0geSArICgoMiAqIHggKyAzICogeSkgJSA1KSAqIDU7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvLyBDb21wdXRlIHJvdW5kIGNvbnN0YW50c1xuXHQgICAgICAgIHZhciBMRlNSID0gMHgwMTtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDI0OyBpKyspIHtcblx0ICAgICAgICAgICAgdmFyIHJvdW5kQ29uc3RhbnRNc3cgPSAwO1xuXHQgICAgICAgICAgICB2YXIgcm91bmRDb25zdGFudExzdyA9IDA7XG5cblx0ICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCA3OyBqKyspIHtcblx0ICAgICAgICAgICAgICAgIGlmIChMRlNSICYgMHgwMSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciBiaXRQb3NpdGlvbiA9ICgxIDw8IGopIC0gMTtcblx0ICAgICAgICAgICAgICAgICAgICBpZiAoYml0UG9zaXRpb24gPCAzMikge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICByb3VuZENvbnN0YW50THN3IF49IDEgPDwgYml0UG9zaXRpb247XG5cdCAgICAgICAgICAgICAgICAgICAgfSBlbHNlIC8qIGlmIChiaXRQb3NpdGlvbiA+PSAzMikgKi8ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICByb3VuZENvbnN0YW50TXN3IF49IDEgPDwgKGJpdFBvc2l0aW9uIC0gMzIpO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgLy8gQ29tcHV0ZSBuZXh0IExGU1Jcblx0ICAgICAgICAgICAgICAgIGlmIChMRlNSICYgMHg4MCkge1xuXHQgICAgICAgICAgICAgICAgICAgIC8vIFByaW1pdGl2ZSBwb2x5bm9taWFsIG92ZXIgR0YoMik6IHheOCArIHheNiArIHheNSArIHheNCArIDFcblx0ICAgICAgICAgICAgICAgICAgICBMRlNSID0gKExGU1IgPDwgMSkgXiAweDcxO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICBMRlNSIDw8PSAxO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgUk9VTkRfQ09OU1RBTlRTW2ldID0gWDY0V29yZC5jcmVhdGUocm91bmRDb25zdGFudE1zdywgcm91bmRDb25zdGFudExzdyk7XG5cdCAgICAgICAgfVxuXHQgICAgfSgpKTtcblxuXHQgICAgLy8gUmV1c2FibGUgb2JqZWN0cyBmb3IgdGVtcG9yYXJ5IHZhbHVlc1xuXHQgICAgdmFyIFQgPSBbXTtcblx0ICAgIChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTsgaSsrKSB7XG5cdCAgICAgICAgICAgIFRbaV0gPSBYNjRXb3JkLmNyZWF0ZSgpO1xuXHQgICAgICAgIH1cblx0ICAgIH0oKSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogU0hBLTMgaGFzaCBhbGdvcml0aG0uXG5cdCAgICAgKi9cblx0ICAgIHZhciBTSEEzID0gQ19hbGdvLlNIQTMgPSBIYXNoZXIuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gb3V0cHV0TGVuZ3RoXG5cdCAgICAgICAgICogICBUaGUgZGVzaXJlZCBudW1iZXIgb2YgYml0cyBpbiB0aGUgb3V0cHV0IGhhc2guXG5cdCAgICAgICAgICogICBPbmx5IHZhbHVlcyBwZXJtaXR0ZWQgYXJlOiAyMjQsIDI1NiwgMzg0LCA1MTIuXG5cdCAgICAgICAgICogICBEZWZhdWx0OiA1MTJcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjZmc6IEhhc2hlci5jZmcuZXh0ZW5kKHtcblx0ICAgICAgICAgICAgb3V0cHV0TGVuZ3RoOiA1MTJcblx0ICAgICAgICB9KSxcblxuXHQgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHZhciBzdGF0ZSA9IHRoaXMuX3N0YXRlID0gW11cblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICBzdGF0ZVtpXSA9IG5ldyBYNjRXb3JkLmluaXQoKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHRoaXMuYmxvY2tTaXplID0gKDE2MDAgLSAyICogdGhpcy5jZmcub3V0cHV0TGVuZ3RoKSAvIDMyO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfZG9Qcm9jZXNzQmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBzdGF0ZSA9IHRoaXMuX3N0YXRlO1xuXHQgICAgICAgICAgICB2YXIgbkJsb2NrU2l6ZUxhbmVzID0gdGhpcy5ibG9ja1NpemUgLyAyO1xuXG5cdCAgICAgICAgICAgIC8vIEFic29yYlxuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5CbG9ja1NpemVMYW5lczsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgICAgIHZhciBNMmkgID0gTVtvZmZzZXQgKyAyICogaV07XG5cdCAgICAgICAgICAgICAgICB2YXIgTTJpMSA9IE1bb2Zmc2V0ICsgMiAqIGkgKyAxXTtcblxuXHQgICAgICAgICAgICAgICAgLy8gU3dhcCBlbmRpYW5cblx0ICAgICAgICAgICAgICAgIE0yaSA9IChcblx0ICAgICAgICAgICAgICAgICAgICAoKChNMmkgPDwgOCkgIHwgKE0yaSA+Pj4gMjQpKSAmIDB4MDBmZjAwZmYpIHxcblx0ICAgICAgICAgICAgICAgICAgICAoKChNMmkgPDwgMjQpIHwgKE0yaSA+Pj4gOCkpICAmIDB4ZmYwMGZmMDApXG5cdCAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgTTJpMSA9IChcblx0ICAgICAgICAgICAgICAgICAgICAoKChNMmkxIDw8IDgpICB8IChNMmkxID4+PiAyNCkpICYgMHgwMGZmMDBmZikgfFxuXHQgICAgICAgICAgICAgICAgICAgICgoKE0yaTEgPDwgMjQpIHwgKE0yaTEgPj4+IDgpKSAgJiAweGZmMDBmZjAwKVxuXHQgICAgICAgICAgICAgICAgKTtcblxuXHQgICAgICAgICAgICAgICAgLy8gQWJzb3JiIG1lc3NhZ2UgaW50byBzdGF0ZVxuXHQgICAgICAgICAgICAgICAgdmFyIGxhbmUgPSBzdGF0ZVtpXTtcblx0ICAgICAgICAgICAgICAgIGxhbmUuaGlnaCBePSBNMmkxO1xuXHQgICAgICAgICAgICAgICAgbGFuZS5sb3cgIF49IE0yaTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIFJvdW5kc1xuXHQgICAgICAgICAgICBmb3IgKHZhciByb3VuZCA9IDA7IHJvdW5kIDwgMjQ7IHJvdW5kKyspIHtcblx0ICAgICAgICAgICAgICAgIC8vIFRoZXRhXG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciB4ID0gMDsgeCA8IDU7IHgrKykge1xuXHQgICAgICAgICAgICAgICAgICAgIC8vIE1peCBjb2x1bW4gbGFuZXNcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgdE1zdyA9IDAsIHRMc3cgPSAwO1xuXHQgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIHkgPSAwOyB5IDwgNTsgeSsrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsYW5lID0gc3RhdGVbeCArIDUgKiB5XTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgdE1zdyBePSBsYW5lLmhpZ2g7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRMc3cgXj0gbGFuZS5sb3c7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAgICAgLy8gVGVtcG9yYXJ5IHZhbHVlc1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciBUeCA9IFRbeF07XG5cdCAgICAgICAgICAgICAgICAgICAgVHguaGlnaCA9IHRNc3c7XG5cdCAgICAgICAgICAgICAgICAgICAgVHgubG93ICA9IHRMc3c7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciB4ID0gMDsgeCA8IDU7IHgrKykge1xuXHQgICAgICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciBUeDQgPSBUWyh4ICsgNCkgJSA1XTtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgVHgxID0gVFsoeCArIDEpICUgNV07XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIFR4MU1zdyA9IFR4MS5oaWdoO1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciBUeDFMc3cgPSBUeDEubG93O1xuXG5cdCAgICAgICAgICAgICAgICAgICAgLy8gTWl4IHN1cnJvdW5kaW5nIGNvbHVtbnNcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgdE1zdyA9IFR4NC5oaWdoIF4gKChUeDFNc3cgPDwgMSkgfCAoVHgxTHN3ID4+PiAzMSkpO1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciB0THN3ID0gVHg0LmxvdyAgXiAoKFR4MUxzdyA8PCAxKSB8IChUeDFNc3cgPj4+IDMxKSk7XG5cdCAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgeSA9IDA7IHkgPCA1OyB5KyspIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxhbmUgPSBzdGF0ZVt4ICsgNSAqIHldO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBsYW5lLmhpZ2ggXj0gdE1zdztcblx0ICAgICAgICAgICAgICAgICAgICAgICAgbGFuZS5sb3cgIF49IHRMc3c7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAvLyBSaG8gUGlcblx0ICAgICAgICAgICAgICAgIGZvciAodmFyIGxhbmVJbmRleCA9IDE7IGxhbmVJbmRleCA8IDI1OyBsYW5lSW5kZXgrKykge1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciB0TXN3O1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciB0THN3O1xuXG5cdCAgICAgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIGxhbmUgPSBzdGF0ZVtsYW5lSW5kZXhdO1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciBsYW5lTXN3ID0gbGFuZS5oaWdoO1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciBsYW5lTHN3ID0gbGFuZS5sb3c7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIHJob09mZnNldCA9IFJIT19PRkZTRVRTW2xhbmVJbmRleF07XG5cblx0ICAgICAgICAgICAgICAgICAgICAvLyBSb3RhdGUgbGFuZXNcblx0ICAgICAgICAgICAgICAgICAgICBpZiAocmhvT2Zmc2V0IDwgMzIpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgdE1zdyA9IChsYW5lTXN3IDw8IHJob09mZnNldCkgfCAobGFuZUxzdyA+Pj4gKDMyIC0gcmhvT2Zmc2V0KSk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRMc3cgPSAobGFuZUxzdyA8PCByaG9PZmZzZXQpIHwgKGxhbmVNc3cgPj4+ICgzMiAtIHJob09mZnNldCkpO1xuXHQgICAgICAgICAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAocmhvT2Zmc2V0ID49IDMyKSAqLyB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRNc3cgPSAobGFuZUxzdyA8PCAocmhvT2Zmc2V0IC0gMzIpKSB8IChsYW5lTXN3ID4+PiAoNjQgLSByaG9PZmZzZXQpKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgdExzdyA9IChsYW5lTXN3IDw8IChyaG9PZmZzZXQgLSAzMikpIHwgKGxhbmVMc3cgPj4+ICg2NCAtIHJob09mZnNldCkpO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgIC8vIFRyYW5zcG9zZSBsYW5lc1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciBUUGlMYW5lID0gVFtQSV9JTkRFWEVTW2xhbmVJbmRleF1dO1xuXHQgICAgICAgICAgICAgICAgICAgIFRQaUxhbmUuaGlnaCA9IHRNc3c7XG5cdCAgICAgICAgICAgICAgICAgICAgVFBpTGFuZS5sb3cgID0gdExzdztcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgLy8gUmhvIHBpIGF0IHggPSB5ID0gMFxuXHQgICAgICAgICAgICAgICAgdmFyIFQwID0gVFswXTtcblx0ICAgICAgICAgICAgICAgIHZhciBzdGF0ZTAgPSBzdGF0ZVswXTtcblx0ICAgICAgICAgICAgICAgIFQwLmhpZ2ggPSBzdGF0ZTAuaGlnaDtcblx0ICAgICAgICAgICAgICAgIFQwLmxvdyAgPSBzdGF0ZTAubG93O1xuXG5cdCAgICAgICAgICAgICAgICAvLyBDaGlcblx0ICAgICAgICAgICAgICAgIGZvciAodmFyIHggPSAwOyB4IDwgNTsgeCsrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgeSA9IDA7IHkgPCA1OyB5KyspIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsYW5lSW5kZXggPSB4ICsgNSAqIHk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsYW5lID0gc3RhdGVbbGFuZUluZGV4XTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgdmFyIFRMYW5lID0gVFtsYW5lSW5kZXhdO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB2YXIgVHgxTGFuZSA9IFRbKCh4ICsgMSkgJSA1KSArIDUgKiB5XTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgdmFyIFR4MkxhbmUgPSBUWygoeCArIDIpICUgNSkgKyA1ICogeV07XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWl4IHJvd3Ncblx0ICAgICAgICAgICAgICAgICAgICAgICAgbGFuZS5oaWdoID0gVExhbmUuaGlnaCBeICh+VHgxTGFuZS5oaWdoICYgVHgyTGFuZS5oaWdoKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgbGFuZS5sb3cgID0gVExhbmUubG93ICBeICh+VHgxTGFuZS5sb3cgICYgVHgyTGFuZS5sb3cpO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgLy8gSW90YVxuXHQgICAgICAgICAgICAgICAgdmFyIGxhbmUgPSBzdGF0ZVswXTtcblx0ICAgICAgICAgICAgICAgIHZhciByb3VuZENvbnN0YW50ID0gUk9VTkRfQ09OU1RBTlRTW3JvdW5kXTtcblx0ICAgICAgICAgICAgICAgIGxhbmUuaGlnaCBePSByb3VuZENvbnN0YW50LmhpZ2g7XG5cdCAgICAgICAgICAgICAgICBsYW5lLmxvdyAgXj0gcm91bmRDb25zdGFudC5sb3c7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBkYXRhID0gdGhpcy5fZGF0YTtcblx0ICAgICAgICAgICAgdmFyIGRhdGFXb3JkcyA9IGRhdGEud29yZHM7XG5cdCAgICAgICAgICAgIHZhciBuQml0c1RvdGFsID0gdGhpcy5fbkRhdGFCeXRlcyAqIDg7XG5cdCAgICAgICAgICAgIHZhciBuQml0c0xlZnQgPSBkYXRhLnNpZ0J5dGVzICogODtcblx0ICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZUJpdHMgPSB0aGlzLmJsb2NrU2l6ZSAqIDMyO1xuXG5cdCAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nXG5cdCAgICAgICAgICAgIGRhdGFXb3Jkc1tuQml0c0xlZnQgPj4+IDVdIHw9IDB4MSA8PCAoMjQgLSBuQml0c0xlZnQgJSAzMik7XG5cdCAgICAgICAgICAgIGRhdGFXb3Jkc1soKE1hdGguY2VpbCgobkJpdHNMZWZ0ICsgMSkgLyBibG9ja1NpemVCaXRzKSAqIGJsb2NrU2l6ZUJpdHMpID4+PiA1KSAtIDFdIHw9IDB4ODA7XG5cdCAgICAgICAgICAgIGRhdGEuc2lnQnl0ZXMgPSBkYXRhV29yZHMubGVuZ3RoICogNDtcblxuXHQgICAgICAgICAgICAvLyBIYXNoIGZpbmFsIGJsb2Nrc1xuXHQgICAgICAgICAgICB0aGlzLl9wcm9jZXNzKCk7XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBzdGF0ZSA9IHRoaXMuX3N0YXRlO1xuXHQgICAgICAgICAgICB2YXIgb3V0cHV0TGVuZ3RoQnl0ZXMgPSB0aGlzLmNmZy5vdXRwdXRMZW5ndGggLyA4O1xuXHQgICAgICAgICAgICB2YXIgb3V0cHV0TGVuZ3RoTGFuZXMgPSBvdXRwdXRMZW5ndGhCeXRlcyAvIDg7XG5cblx0ICAgICAgICAgICAgLy8gU3F1ZWV6ZVxuXHQgICAgICAgICAgICB2YXIgaGFzaFdvcmRzID0gW107XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3V0cHV0TGVuZ3RoTGFuZXM7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgICAgICB2YXIgbGFuZSA9IHN0YXRlW2ldO1xuXHQgICAgICAgICAgICAgICAgdmFyIGxhbmVNc3cgPSBsYW5lLmhpZ2g7XG5cdCAgICAgICAgICAgICAgICB2YXIgbGFuZUxzdyA9IGxhbmUubG93O1xuXG5cdCAgICAgICAgICAgICAgICAvLyBTd2FwIGVuZGlhblxuXHQgICAgICAgICAgICAgICAgbGFuZU1zdyA9IChcblx0ICAgICAgICAgICAgICAgICAgICAoKChsYW5lTXN3IDw8IDgpICB8IChsYW5lTXN3ID4+PiAyNCkpICYgMHgwMGZmMDBmZikgfFxuXHQgICAgICAgICAgICAgICAgICAgICgoKGxhbmVNc3cgPDwgMjQpIHwgKGxhbmVNc3cgPj4+IDgpKSAgJiAweGZmMDBmZjAwKVxuXHQgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgICAgIGxhbmVMc3cgPSAoXG5cdCAgICAgICAgICAgICAgICAgICAgKCgobGFuZUxzdyA8PCA4KSAgfCAobGFuZUxzdyA+Pj4gMjQpKSAmIDB4MDBmZjAwZmYpIHxcblx0ICAgICAgICAgICAgICAgICAgICAoKChsYW5lTHN3IDw8IDI0KSB8IChsYW5lTHN3ID4+PiA4KSkgICYgMHhmZjAwZmYwMClcblx0ICAgICAgICAgICAgICAgICk7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFNxdWVlemUgc3RhdGUgdG8gcmV0cmlldmUgaGFzaFxuXHQgICAgICAgICAgICAgICAgaGFzaFdvcmRzLnB1c2gobGFuZUxzdyk7XG5cdCAgICAgICAgICAgICAgICBoYXNoV29yZHMucHVzaChsYW5lTXN3KTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIFJldHVybiBmaW5hbCBjb21wdXRlZCBoYXNoXG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgV29yZEFycmF5LmluaXQoaGFzaFdvcmRzLCBvdXRwdXRMZW5ndGhCeXRlcyk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHZhciBjbG9uZSA9IEhhc2hlci5jbG9uZS5jYWxsKHRoaXMpO1xuXG5cdCAgICAgICAgICAgIHZhciBzdGF0ZSA9IGNsb25lLl9zdGF0ZSA9IHRoaXMuX3N0YXRlLnNsaWNlKDApO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDI1OyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIHN0YXRlW2ldID0gc3RhdGVbaV0uY2xvbmUoKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBjbG9uZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlNIQTMoJ21lc3NhZ2UnKTtcblx0ICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlNIQTMod29yZEFycmF5KTtcblx0ICAgICAqL1xuXHQgICAgQy5TSEEzID0gSGFzaGVyLl9jcmVhdGVIZWxwZXIoU0hBMyk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIEhNQUMncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLlxuXHQgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBrZXkgVGhlIHNlY3JldCBrZXkuXG5cdCAgICAgKlxuXHQgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgSE1BQy5cblx0ICAgICAqXG5cdCAgICAgKiBAc3RhdGljXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiAgICAgdmFyIGhtYWMgPSBDcnlwdG9KUy5IbWFjU0hBMyhtZXNzYWdlLCBrZXkpO1xuXHQgICAgICovXG5cdCAgICBDLkhtYWNTSEEzID0gSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKFNIQTMpO1xuXHR9KE1hdGgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUy5TSEEzO1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIiksIHJlcXVpcmUoXCIuL3g2NC1jb3JlXCIpLCByZXF1aXJlKFwiLi9zaGE1MTJcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiLCBcIi4veDY0LWNvcmVcIiwgXCIuL3NoYTUxMlwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0KGZ1bmN0aW9uICgpIHtcblx0ICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgdmFyIEMgPSBDcnlwdG9KUztcblx0ICAgIHZhciBDX3g2NCA9IEMueDY0O1xuXHQgICAgdmFyIFg2NFdvcmQgPSBDX3g2NC5Xb3JkO1xuXHQgICAgdmFyIFg2NFdvcmRBcnJheSA9IENfeDY0LldvcmRBcnJheTtcblx0ICAgIHZhciBDX2FsZ28gPSBDLmFsZ287XG5cdCAgICB2YXIgU0hBNTEyID0gQ19hbGdvLlNIQTUxMjtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTSEEtMzg0IGhhc2ggYWxnb3JpdGhtLlxuXHQgICAgICovXG5cdCAgICB2YXIgU0hBMzg0ID0gQ19hbGdvLlNIQTM4NCA9IFNIQTUxMi5leHRlbmQoe1xuXHQgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2hhc2ggPSBuZXcgWDY0V29yZEFycmF5LmluaXQoW1xuXHQgICAgICAgICAgICAgICAgbmV3IFg2NFdvcmQuaW5pdCgweGNiYmI5ZDVkLCAweGMxMDU5ZWQ4KSwgbmV3IFg2NFdvcmQuaW5pdCgweDYyOWEyOTJhLCAweDM2N2NkNTA3KSxcblx0ICAgICAgICAgICAgICAgIG5ldyBYNjRXb3JkLmluaXQoMHg5MTU5MDE1YSwgMHgzMDcwZGQxNyksIG5ldyBYNjRXb3JkLmluaXQoMHgxNTJmZWNkOCwgMHhmNzBlNTkzOSksXG5cdCAgICAgICAgICAgICAgICBuZXcgWDY0V29yZC5pbml0KDB4NjczMzI2NjcsIDB4ZmZjMDBiMzEpLCBuZXcgWDY0V29yZC5pbml0KDB4OGViNDRhODcsIDB4Njg1ODE1MTEpLFxuXHQgICAgICAgICAgICAgICAgbmV3IFg2NFdvcmQuaW5pdCgweGRiMGMyZTBkLCAweDY0Zjk4ZmE3KSwgbmV3IFg2NFdvcmQuaW5pdCgweDQ3YjU0ODFkLCAweGJlZmE0ZmE0KVxuXHQgICAgICAgICAgICBdKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdmFyIGhhc2ggPSBTSEE1MTIuX2RvRmluYWxpemUuY2FsbCh0aGlzKTtcblxuXHQgICAgICAgICAgICBoYXNoLnNpZ0J5dGVzIC09IDE2O1xuXG5cdCAgICAgICAgICAgIHJldHVybiBoYXNoO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBoYXNoZXIncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLlxuXHQgICAgICpcblx0ICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGhhc2guXG5cdCAgICAgKlxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuU0hBMzg0KCdtZXNzYWdlJyk7XG5cdCAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5TSEEzODQod29yZEFycmF5KTtcblx0ICAgICAqL1xuXHQgICAgQy5TSEEzODQgPSBTSEE1MTIuX2NyZWF0ZUhlbHBlcihTSEEzODQpO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBITUFDJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC5cblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30ga2V5IFRoZSBzZWNyZXQga2V5LlxuXHQgICAgICpcblx0ICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIEhNQUMuXG5cdCAgICAgKlxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogICAgIHZhciBobWFjID0gQ3J5cHRvSlMuSG1hY1NIQTM4NChtZXNzYWdlLCBrZXkpO1xuXHQgICAgICovXG5cdCAgICBDLkhtYWNTSEEzODQgPSBTSEE1MTIuX2NyZWF0ZUhtYWNIZWxwZXIoU0hBMzg0KTtcblx0fSgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUy5TSEEzODQ7XG5cbn0pKTsiLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZShcIi4vY29yZVwiKSwgcmVxdWlyZShcIi4veDY0LWNvcmVcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiLCBcIi4veDY0LWNvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBIYXNoZXIgPSBDX2xpYi5IYXNoZXI7XG5cdCAgICB2YXIgQ194NjQgPSBDLng2NDtcblx0ICAgIHZhciBYNjRXb3JkID0gQ194NjQuV29yZDtcblx0ICAgIHZhciBYNjRXb3JkQXJyYXkgPSBDX3g2NC5Xb3JkQXJyYXk7XG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvO1xuXG5cdCAgICBmdW5jdGlvbiBYNjRXb3JkX2NyZWF0ZSgpIHtcblx0ICAgICAgICByZXR1cm4gWDY0V29yZC5jcmVhdGUuYXBwbHkoWDY0V29yZCwgYXJndW1lbnRzKTtcblx0ICAgIH1cblxuXHQgICAgLy8gQ29uc3RhbnRzXG5cdCAgICB2YXIgSyA9IFtcblx0ICAgICAgICBYNjRXb3JkX2NyZWF0ZSgweDQyOGEyZjk4LCAweGQ3MjhhZTIyKSwgWDY0V29yZF9jcmVhdGUoMHg3MTM3NDQ5MSwgMHgyM2VmNjVjZCksXG5cdCAgICAgICAgWDY0V29yZF9jcmVhdGUoMHhiNWMwZmJjZiwgMHhlYzRkM2IyZiksIFg2NFdvcmRfY3JlYXRlKDB4ZTliNWRiYTUsIDB4ODE4OWRiYmMpLFxuXHQgICAgICAgIFg2NFdvcmRfY3JlYXRlKDB4Mzk1NmMyNWIsIDB4ZjM0OGI1MzgpLCBYNjRXb3JkX2NyZWF0ZSgweDU5ZjExMWYxLCAweGI2MDVkMDE5KSxcblx0ICAgICAgICBYNjRXb3JkX2NyZWF0ZSgweDkyM2Y4MmE0LCAweGFmMTk0ZjliKSwgWDY0V29yZF9jcmVhdGUoMHhhYjFjNWVkNSwgMHhkYTZkODExOCksXG5cdCAgICAgICAgWDY0V29yZF9jcmVhdGUoMHhkODA3YWE5OCwgMHhhMzAzMDI0MiksIFg2NFdvcmRfY3JlYXRlKDB4MTI4MzViMDEsIDB4NDU3MDZmYmUpLFxuXHQgICAgICAgIFg2NFdvcmRfY3JlYXRlKDB4MjQzMTg1YmUsIDB4NGVlNGIyOGMpLCBYNjRXb3JkX2NyZWF0ZSgweDU1MGM3ZGMzLCAweGQ1ZmZiNGUyKSxcblx0ICAgICAgICBYNjRXb3JkX2NyZWF0ZSgweDcyYmU1ZDc0LCAweGYyN2I4OTZmKSwgWDY0V29yZF9jcmVhdGUoMHg4MGRlYjFmZSwgMHgzYjE2OTZiMSksXG5cdCAgICAgICAgWDY0V29yZF9jcmVhdGUoMHg5YmRjMDZhNywgMHgyNWM3MTIzNSksIFg2NFdvcmRfY3JlYXRlKDB4YzE5YmYxNzQsIDB4Y2Y2OTI2OTQpLFxuXHQgICAgICAgIFg2NFdvcmRfY3JlYXRlKDB4ZTQ5YjY5YzEsIDB4OWVmMTRhZDIpLCBYNjRXb3JkX2NyZWF0ZSgweGVmYmU0Nzg2LCAweDM4NGYyNWUzKSxcblx0ICAgICAgICBYNjRXb3JkX2NyZWF0ZSgweDBmYzE5ZGM2LCAweDhiOGNkNWI1KSwgWDY0V29yZF9jcmVhdGUoMHgyNDBjYTFjYywgMHg3N2FjOWM2NSksXG5cdCAgICAgICAgWDY0V29yZF9jcmVhdGUoMHgyZGU5MmM2ZiwgMHg1OTJiMDI3NSksIFg2NFdvcmRfY3JlYXRlKDB4NGE3NDg0YWEsIDB4NmVhNmU0ODMpLFxuXHQgICAgICAgIFg2NFdvcmRfY3JlYXRlKDB4NWNiMGE5ZGMsIDB4YmQ0MWZiZDQpLCBYNjRXb3JkX2NyZWF0ZSgweDc2Zjk4OGRhLCAweDgzMTE1M2I1KSxcblx0ICAgICAgICBYNjRXb3JkX2NyZWF0ZSgweDk4M2U1MTUyLCAweGVlNjZkZmFiKSwgWDY0V29yZF9jcmVhdGUoMHhhODMxYzY2ZCwgMHgyZGI0MzIxMCksXG5cdCAgICAgICAgWDY0V29yZF9jcmVhdGUoMHhiMDAzMjdjOCwgMHg5OGZiMjEzZiksIFg2NFdvcmRfY3JlYXRlKDB4YmY1OTdmYzcsIDB4YmVlZjBlZTQpLFxuXHQgICAgICAgIFg2NFdvcmRfY3JlYXRlKDB4YzZlMDBiZjMsIDB4M2RhODhmYzIpLCBYNjRXb3JkX2NyZWF0ZSgweGQ1YTc5MTQ3LCAweDkzMGFhNzI1KSxcblx0ICAgICAgICBYNjRXb3JkX2NyZWF0ZSgweDA2Y2E2MzUxLCAweGUwMDM4MjZmKSwgWDY0V29yZF9jcmVhdGUoMHgxNDI5Mjk2NywgMHgwYTBlNmU3MCksXG5cdCAgICAgICAgWDY0V29yZF9jcmVhdGUoMHgyN2I3MGE4NSwgMHg0NmQyMmZmYyksIFg2NFdvcmRfY3JlYXRlKDB4MmUxYjIxMzgsIDB4NWMyNmM5MjYpLFxuXHQgICAgICAgIFg2NFdvcmRfY3JlYXRlKDB4NGQyYzZkZmMsIDB4NWFjNDJhZWQpLCBYNjRXb3JkX2NyZWF0ZSgweDUzMzgwZDEzLCAweDlkOTViM2RmKSxcblx0ICAgICAgICBYNjRXb3JkX2NyZWF0ZSgweDY1MGE3MzU0LCAweDhiYWY2M2RlKSwgWDY0V29yZF9jcmVhdGUoMHg3NjZhMGFiYiwgMHgzYzc3YjJhOCksXG5cdCAgICAgICAgWDY0V29yZF9jcmVhdGUoMHg4MWMyYzkyZSwgMHg0N2VkYWVlNiksIFg2NFdvcmRfY3JlYXRlKDB4OTI3MjJjODUsIDB4MTQ4MjM1M2IpLFxuXHQgICAgICAgIFg2NFdvcmRfY3JlYXRlKDB4YTJiZmU4YTEsIDB4NGNmMTAzNjQpLCBYNjRXb3JkX2NyZWF0ZSgweGE4MWE2NjRiLCAweGJjNDIzMDAxKSxcblx0ICAgICAgICBYNjRXb3JkX2NyZWF0ZSgweGMyNGI4YjcwLCAweGQwZjg5NzkxKSwgWDY0V29yZF9jcmVhdGUoMHhjNzZjNTFhMywgMHgwNjU0YmUzMCksXG5cdCAgICAgICAgWDY0V29yZF9jcmVhdGUoMHhkMTkyZTgxOSwgMHhkNmVmNTIxOCksIFg2NFdvcmRfY3JlYXRlKDB4ZDY5OTA2MjQsIDB4NTU2NWE5MTApLFxuXHQgICAgICAgIFg2NFdvcmRfY3JlYXRlKDB4ZjQwZTM1ODUsIDB4NTc3MTIwMmEpLCBYNjRXb3JkX2NyZWF0ZSgweDEwNmFhMDcwLCAweDMyYmJkMWI4KSxcblx0ICAgICAgICBYNjRXb3JkX2NyZWF0ZSgweDE5YTRjMTE2LCAweGI4ZDJkMGM4KSwgWDY0V29yZF9jcmVhdGUoMHgxZTM3NmMwOCwgMHg1MTQxYWI1MyksXG5cdCAgICAgICAgWDY0V29yZF9jcmVhdGUoMHgyNzQ4Nzc0YywgMHhkZjhlZWI5OSksIFg2NFdvcmRfY3JlYXRlKDB4MzRiMGJjYjUsIDB4ZTE5YjQ4YTgpLFxuXHQgICAgICAgIFg2NFdvcmRfY3JlYXRlKDB4MzkxYzBjYjMsIDB4YzVjOTVhNjMpLCBYNjRXb3JkX2NyZWF0ZSgweDRlZDhhYTRhLCAweGUzNDE4YWNiKSxcblx0ICAgICAgICBYNjRXb3JkX2NyZWF0ZSgweDViOWNjYTRmLCAweDc3NjNlMzczKSwgWDY0V29yZF9jcmVhdGUoMHg2ODJlNmZmMywgMHhkNmIyYjhhMyksXG5cdCAgICAgICAgWDY0V29yZF9jcmVhdGUoMHg3NDhmODJlZSwgMHg1ZGVmYjJmYyksIFg2NFdvcmRfY3JlYXRlKDB4NzhhNTYzNmYsIDB4NDMxNzJmNjApLFxuXHQgICAgICAgIFg2NFdvcmRfY3JlYXRlKDB4ODRjODc4MTQsIDB4YTFmMGFiNzIpLCBYNjRXb3JkX2NyZWF0ZSgweDhjYzcwMjA4LCAweDFhNjQzOWVjKSxcblx0ICAgICAgICBYNjRXb3JkX2NyZWF0ZSgweDkwYmVmZmZhLCAweDIzNjMxZTI4KSwgWDY0V29yZF9jcmVhdGUoMHhhNDUwNmNlYiwgMHhkZTgyYmRlOSksXG5cdCAgICAgICAgWDY0V29yZF9jcmVhdGUoMHhiZWY5YTNmNywgMHhiMmM2NzkxNSksIFg2NFdvcmRfY3JlYXRlKDB4YzY3MTc4ZjIsIDB4ZTM3MjUzMmIpLFxuXHQgICAgICAgIFg2NFdvcmRfY3JlYXRlKDB4Y2EyNzNlY2UsIDB4ZWEyNjYxOWMpLCBYNjRXb3JkX2NyZWF0ZSgweGQxODZiOGM3LCAweDIxYzBjMjA3KSxcblx0ICAgICAgICBYNjRXb3JkX2NyZWF0ZSgweGVhZGE3ZGQ2LCAweGNkZTBlYjFlKSwgWDY0V29yZF9jcmVhdGUoMHhmNTdkNGY3ZiwgMHhlZTZlZDE3OCksXG5cdCAgICAgICAgWDY0V29yZF9jcmVhdGUoMHgwNmYwNjdhYSwgMHg3MjE3NmZiYSksIFg2NFdvcmRfY3JlYXRlKDB4MGE2MzdkYzUsIDB4YTJjODk4YTYpLFxuXHQgICAgICAgIFg2NFdvcmRfY3JlYXRlKDB4MTEzZjk4MDQsIDB4YmVmOTBkYWUpLCBYNjRXb3JkX2NyZWF0ZSgweDFiNzEwYjM1LCAweDEzMWM0NzFiKSxcblx0ICAgICAgICBYNjRXb3JkX2NyZWF0ZSgweDI4ZGI3N2Y1LCAweDIzMDQ3ZDg0KSwgWDY0V29yZF9jcmVhdGUoMHgzMmNhYWI3YiwgMHg0MGM3MjQ5MyksXG5cdCAgICAgICAgWDY0V29yZF9jcmVhdGUoMHgzYzllYmUwYSwgMHgxNWM5YmViYyksIFg2NFdvcmRfY3JlYXRlKDB4NDMxZDY3YzQsIDB4OWMxMDBkNGMpLFxuXHQgICAgICAgIFg2NFdvcmRfY3JlYXRlKDB4NGNjNWQ0YmUsIDB4Y2IzZTQyYjYpLCBYNjRXb3JkX2NyZWF0ZSgweDU5N2YyOTljLCAweGZjNjU3ZTJhKSxcblx0ICAgICAgICBYNjRXb3JkX2NyZWF0ZSgweDVmY2I2ZmFiLCAweDNhZDZmYWVjKSwgWDY0V29yZF9jcmVhdGUoMHg2YzQ0MTk4YywgMHg0YTQ3NTgxNylcblx0ICAgIF07XG5cblx0ICAgIC8vIFJldXNhYmxlIG9iamVjdHNcblx0ICAgIHZhciBXID0gW107XG5cdCAgICAoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgODA7IGkrKykge1xuXHQgICAgICAgICAgICBXW2ldID0gWDY0V29yZF9jcmVhdGUoKTtcblx0ICAgICAgICB9XG5cdCAgICB9KCkpO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFNIQS01MTIgaGFzaCBhbGdvcml0aG0uXG5cdCAgICAgKi9cblx0ICAgIHZhciBTSEE1MTIgPSBDX2FsZ28uU0hBNTEyID0gSGFzaGVyLmV4dGVuZCh7XG5cdCAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdGhpcy5faGFzaCA9IG5ldyBYNjRXb3JkQXJyYXkuaW5pdChbXG5cdCAgICAgICAgICAgICAgICBuZXcgWDY0V29yZC5pbml0KDB4NmEwOWU2NjcsIDB4ZjNiY2M5MDgpLCBuZXcgWDY0V29yZC5pbml0KDB4YmI2N2FlODUsIDB4ODRjYWE3M2IpLFxuXHQgICAgICAgICAgICAgICAgbmV3IFg2NFdvcmQuaW5pdCgweDNjNmVmMzcyLCAweGZlOTRmODJiKSwgbmV3IFg2NFdvcmQuaW5pdCgweGE1NGZmNTNhLCAweDVmMWQzNmYxKSxcblx0ICAgICAgICAgICAgICAgIG5ldyBYNjRXb3JkLmluaXQoMHg1MTBlNTI3ZiwgMHhhZGU2ODJkMSksIG5ldyBYNjRXb3JkLmluaXQoMHg5YjA1Njg4YywgMHgyYjNlNmMxZiksXG5cdCAgICAgICAgICAgICAgICBuZXcgWDY0V29yZC5pbml0KDB4MWY4M2Q5YWIsIDB4ZmI0MWJkNmIpLCBuZXcgWDY0V29yZC5pbml0KDB4NWJlMGNkMTksIDB4MTM3ZTIxNzkpXG5cdCAgICAgICAgICAgIF0pO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfZG9Qcm9jZXNzQmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBIID0gdGhpcy5faGFzaC53b3JkcztcblxuXHQgICAgICAgICAgICB2YXIgSDAgPSBIWzBdO1xuXHQgICAgICAgICAgICB2YXIgSDEgPSBIWzFdO1xuXHQgICAgICAgICAgICB2YXIgSDIgPSBIWzJdO1xuXHQgICAgICAgICAgICB2YXIgSDMgPSBIWzNdO1xuXHQgICAgICAgICAgICB2YXIgSDQgPSBIWzRdO1xuXHQgICAgICAgICAgICB2YXIgSDUgPSBIWzVdO1xuXHQgICAgICAgICAgICB2YXIgSDYgPSBIWzZdO1xuXHQgICAgICAgICAgICB2YXIgSDcgPSBIWzddO1xuXG5cdCAgICAgICAgICAgIHZhciBIMGggPSBIMC5oaWdoO1xuXHQgICAgICAgICAgICB2YXIgSDBsID0gSDAubG93O1xuXHQgICAgICAgICAgICB2YXIgSDFoID0gSDEuaGlnaDtcblx0ICAgICAgICAgICAgdmFyIEgxbCA9IEgxLmxvdztcblx0ICAgICAgICAgICAgdmFyIEgyaCA9IEgyLmhpZ2g7XG5cdCAgICAgICAgICAgIHZhciBIMmwgPSBIMi5sb3c7XG5cdCAgICAgICAgICAgIHZhciBIM2ggPSBIMy5oaWdoO1xuXHQgICAgICAgICAgICB2YXIgSDNsID0gSDMubG93O1xuXHQgICAgICAgICAgICB2YXIgSDRoID0gSDQuaGlnaDtcblx0ICAgICAgICAgICAgdmFyIEg0bCA9IEg0Lmxvdztcblx0ICAgICAgICAgICAgdmFyIEg1aCA9IEg1LmhpZ2g7XG5cdCAgICAgICAgICAgIHZhciBINWwgPSBINS5sb3c7XG5cdCAgICAgICAgICAgIHZhciBINmggPSBINi5oaWdoO1xuXHQgICAgICAgICAgICB2YXIgSDZsID0gSDYubG93O1xuXHQgICAgICAgICAgICB2YXIgSDdoID0gSDcuaGlnaDtcblx0ICAgICAgICAgICAgdmFyIEg3bCA9IEg3LmxvdztcblxuXHQgICAgICAgICAgICAvLyBXb3JraW5nIHZhcmlhYmxlc1xuXHQgICAgICAgICAgICB2YXIgYWggPSBIMGg7XG5cdCAgICAgICAgICAgIHZhciBhbCA9IEgwbDtcblx0ICAgICAgICAgICAgdmFyIGJoID0gSDFoO1xuXHQgICAgICAgICAgICB2YXIgYmwgPSBIMWw7XG5cdCAgICAgICAgICAgIHZhciBjaCA9IEgyaDtcblx0ICAgICAgICAgICAgdmFyIGNsID0gSDJsO1xuXHQgICAgICAgICAgICB2YXIgZGggPSBIM2g7XG5cdCAgICAgICAgICAgIHZhciBkbCA9IEgzbDtcblx0ICAgICAgICAgICAgdmFyIGVoID0gSDRoO1xuXHQgICAgICAgICAgICB2YXIgZWwgPSBINGw7XG5cdCAgICAgICAgICAgIHZhciBmaCA9IEg1aDtcblx0ICAgICAgICAgICAgdmFyIGZsID0gSDVsO1xuXHQgICAgICAgICAgICB2YXIgZ2ggPSBINmg7XG5cdCAgICAgICAgICAgIHZhciBnbCA9IEg2bDtcblx0ICAgICAgICAgICAgdmFyIGhoID0gSDdoO1xuXHQgICAgICAgICAgICB2YXIgaGwgPSBIN2w7XG5cblx0ICAgICAgICAgICAgLy8gUm91bmRzXG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgODA7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgdmFyIFdpbDtcblx0ICAgICAgICAgICAgICAgIHZhciBXaWg7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgICAgICB2YXIgV2kgPSBXW2ldO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBFeHRlbmQgbWVzc2FnZVxuXHQgICAgICAgICAgICAgICAgaWYgKGkgPCAxNikge1xuXHQgICAgICAgICAgICAgICAgICAgIFdpaCA9IFdpLmhpZ2ggPSBNW29mZnNldCArIGkgKiAyXSAgICAgfCAwO1xuXHQgICAgICAgICAgICAgICAgICAgIFdpbCA9IFdpLmxvdyAgPSBNW29mZnNldCArIGkgKiAyICsgMV0gfCAwO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICAvLyBHYW1tYTBcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgZ2FtbWEweCAgPSBXW2kgLSAxNV07XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIGdhbW1hMHhoID0gZ2FtbWEweC5oaWdoO1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTB4bCA9IGdhbW1hMHgubG93O1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTBoICA9ICgoZ2FtbWEweGggPj4+IDEpIHwgKGdhbW1hMHhsIDw8IDMxKSkgXiAoKGdhbW1hMHhoID4+PiA4KSB8IChnYW1tYTB4bCA8PCAyNCkpIF4gKGdhbW1hMHhoID4+PiA3KTtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgZ2FtbWEwbCAgPSAoKGdhbW1hMHhsID4+PiAxKSB8IChnYW1tYTB4aCA8PCAzMSkpIF4gKChnYW1tYTB4bCA+Pj4gOCkgfCAoZ2FtbWEweGggPDwgMjQpKSBeICgoZ2FtbWEweGwgPj4+IDcpIHwgKGdhbW1hMHhoIDw8IDI1KSk7XG5cblx0ICAgICAgICAgICAgICAgICAgICAvLyBHYW1tYTFcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgZ2FtbWExeCAgPSBXW2kgLSAyXTtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgZ2FtbWExeGggPSBnYW1tYTF4LmhpZ2g7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIGdhbW1hMXhsID0gZ2FtbWExeC5sb3c7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIGdhbW1hMWggID0gKChnYW1tYTF4aCA+Pj4gMTkpIHwgKGdhbW1hMXhsIDw8IDEzKSkgXiAoKGdhbW1hMXhoIDw8IDMpIHwgKGdhbW1hMXhsID4+PiAyOSkpIF4gKGdhbW1hMXhoID4+PiA2KTtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgZ2FtbWExbCAgPSAoKGdhbW1hMXhsID4+PiAxOSkgfCAoZ2FtbWExeGggPDwgMTMpKSBeICgoZ2FtbWExeGwgPDwgMykgfCAoZ2FtbWExeGggPj4+IDI5KSkgXiAoKGdhbW1hMXhsID4+PiA2KSB8IChnYW1tYTF4aCA8PCAyNikpO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgLy8gV1tpXSA9IGdhbW1hMCArIFdbaSAtIDddICsgZ2FtbWExICsgV1tpIC0gMTZdXG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIFdpNyAgPSBXW2kgLSA3XTtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgV2k3aCA9IFdpNy5oaWdoO1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciBXaTdsID0gV2k3LmxvdztcblxuXHQgICAgICAgICAgICAgICAgICAgIHZhciBXaTE2ICA9IFdbaSAtIDE2XTtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgV2kxNmggPSBXaTE2LmhpZ2g7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIFdpMTZsID0gV2kxNi5sb3c7XG5cblx0ICAgICAgICAgICAgICAgICAgICBXaWwgPSBnYW1tYTBsICsgV2k3bDtcblx0ICAgICAgICAgICAgICAgICAgICBXaWggPSBnYW1tYTBoICsgV2k3aCArICgoV2lsID4+PiAwKSA8IChnYW1tYTBsID4+PiAwKSA/IDEgOiAwKTtcblx0ICAgICAgICAgICAgICAgICAgICBXaWwgPSBXaWwgKyBnYW1tYTFsO1xuXHQgICAgICAgICAgICAgICAgICAgIFdpaCA9IFdpaCArIGdhbW1hMWggKyAoKFdpbCA+Pj4gMCkgPCAoZ2FtbWExbCA+Pj4gMCkgPyAxIDogMCk7XG5cdCAgICAgICAgICAgICAgICAgICAgV2lsID0gV2lsICsgV2kxNmw7XG5cdCAgICAgICAgICAgICAgICAgICAgV2loID0gV2loICsgV2kxNmggKyAoKFdpbCA+Pj4gMCkgPCAoV2kxNmwgPj4+IDApID8gMSA6IDApO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgV2kuaGlnaCA9IFdpaDtcblx0ICAgICAgICAgICAgICAgICAgICBXaS5sb3cgID0gV2lsO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICB2YXIgY2hoICA9IChlaCAmIGZoKSBeICh+ZWggJiBnaCk7XG5cdCAgICAgICAgICAgICAgICB2YXIgY2hsICA9IChlbCAmIGZsKSBeICh+ZWwgJiBnbCk7XG5cdCAgICAgICAgICAgICAgICB2YXIgbWFqaCA9IChhaCAmIGJoKSBeIChhaCAmIGNoKSBeIChiaCAmIGNoKTtcblx0ICAgICAgICAgICAgICAgIHZhciBtYWpsID0gKGFsICYgYmwpIF4gKGFsICYgY2wpIF4gKGJsICYgY2wpO1xuXG5cdCAgICAgICAgICAgICAgICB2YXIgc2lnbWEwaCA9ICgoYWggPj4+IDI4KSB8IChhbCA8PCA0KSkgIF4gKChhaCA8PCAzMCkgIHwgKGFsID4+PiAyKSkgXiAoKGFoIDw8IDI1KSB8IChhbCA+Pj4gNykpO1xuXHQgICAgICAgICAgICAgICAgdmFyIHNpZ21hMGwgPSAoKGFsID4+PiAyOCkgfCAoYWggPDwgNCkpICBeICgoYWwgPDwgMzApICB8IChhaCA+Pj4gMikpIF4gKChhbCA8PCAyNSkgfCAoYWggPj4+IDcpKTtcblx0ICAgICAgICAgICAgICAgIHZhciBzaWdtYTFoID0gKChlaCA+Pj4gMTQpIHwgKGVsIDw8IDE4KSkgXiAoKGVoID4+PiAxOCkgfCAoZWwgPDwgMTQpKSBeICgoZWggPDwgMjMpIHwgKGVsID4+PiA5KSk7XG5cdCAgICAgICAgICAgICAgICB2YXIgc2lnbWExbCA9ICgoZWwgPj4+IDE0KSB8IChlaCA8PCAxOCkpIF4gKChlbCA+Pj4gMTgpIHwgKGVoIDw8IDE0KSkgXiAoKGVsIDw8IDIzKSB8IChlaCA+Pj4gOSkpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyB0MSA9IGggKyBzaWdtYTEgKyBjaCArIEtbaV0gKyBXW2ldXG5cdCAgICAgICAgICAgICAgICB2YXIgS2kgID0gS1tpXTtcblx0ICAgICAgICAgICAgICAgIHZhciBLaWggPSBLaS5oaWdoO1xuXHQgICAgICAgICAgICAgICAgdmFyIEtpbCA9IEtpLmxvdztcblxuXHQgICAgICAgICAgICAgICAgdmFyIHQxbCA9IGhsICsgc2lnbWExbDtcblx0ICAgICAgICAgICAgICAgIHZhciB0MWggPSBoaCArIHNpZ21hMWggKyAoKHQxbCA+Pj4gMCkgPCAoaGwgPj4+IDApID8gMSA6IDApO1xuXHQgICAgICAgICAgICAgICAgdmFyIHQxbCA9IHQxbCArIGNobDtcblx0ICAgICAgICAgICAgICAgIHZhciB0MWggPSB0MWggKyBjaGggKyAoKHQxbCA+Pj4gMCkgPCAoY2hsID4+PiAwKSA/IDEgOiAwKTtcblx0ICAgICAgICAgICAgICAgIHZhciB0MWwgPSB0MWwgKyBLaWw7XG5cdCAgICAgICAgICAgICAgICB2YXIgdDFoID0gdDFoICsgS2loICsgKCh0MWwgPj4+IDApIDwgKEtpbCA+Pj4gMCkgPyAxIDogMCk7XG5cdCAgICAgICAgICAgICAgICB2YXIgdDFsID0gdDFsICsgV2lsO1xuXHQgICAgICAgICAgICAgICAgdmFyIHQxaCA9IHQxaCArIFdpaCArICgodDFsID4+PiAwKSA8IChXaWwgPj4+IDApID8gMSA6IDApO1xuXG5cdCAgICAgICAgICAgICAgICAvLyB0MiA9IHNpZ21hMCArIG1halxuXHQgICAgICAgICAgICAgICAgdmFyIHQybCA9IHNpZ21hMGwgKyBtYWpsO1xuXHQgICAgICAgICAgICAgICAgdmFyIHQyaCA9IHNpZ21hMGggKyBtYWpoICsgKCh0MmwgPj4+IDApIDwgKHNpZ21hMGwgPj4+IDApID8gMSA6IDApO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBVcGRhdGUgd29ya2luZyB2YXJpYWJsZXNcblx0ICAgICAgICAgICAgICAgIGhoID0gZ2g7XG5cdCAgICAgICAgICAgICAgICBobCA9IGdsO1xuXHQgICAgICAgICAgICAgICAgZ2ggPSBmaDtcblx0ICAgICAgICAgICAgICAgIGdsID0gZmw7XG5cdCAgICAgICAgICAgICAgICBmaCA9IGVoO1xuXHQgICAgICAgICAgICAgICAgZmwgPSBlbDtcblx0ICAgICAgICAgICAgICAgIGVsID0gKGRsICsgdDFsKSB8IDA7XG5cdCAgICAgICAgICAgICAgICBlaCA9IChkaCArIHQxaCArICgoZWwgPj4+IDApIDwgKGRsID4+PiAwKSA/IDEgOiAwKSkgfCAwO1xuXHQgICAgICAgICAgICAgICAgZGggPSBjaDtcblx0ICAgICAgICAgICAgICAgIGRsID0gY2w7XG5cdCAgICAgICAgICAgICAgICBjaCA9IGJoO1xuXHQgICAgICAgICAgICAgICAgY2wgPSBibDtcblx0ICAgICAgICAgICAgICAgIGJoID0gYWg7XG5cdCAgICAgICAgICAgICAgICBibCA9IGFsO1xuXHQgICAgICAgICAgICAgICAgYWwgPSAodDFsICsgdDJsKSB8IDA7XG5cdCAgICAgICAgICAgICAgICBhaCA9ICh0MWggKyB0MmggKyAoKGFsID4+PiAwKSA8ICh0MWwgPj4+IDApID8gMSA6IDApKSB8IDA7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBJbnRlcm1lZGlhdGUgaGFzaCB2YWx1ZVxuXHQgICAgICAgICAgICBIMGwgPSBIMC5sb3cgID0gKEgwbCArIGFsKTtcblx0ICAgICAgICAgICAgSDAuaGlnaCA9IChIMGggKyBhaCArICgoSDBsID4+PiAwKSA8IChhbCA+Pj4gMCkgPyAxIDogMCkpO1xuXHQgICAgICAgICAgICBIMWwgPSBIMS5sb3cgID0gKEgxbCArIGJsKTtcblx0ICAgICAgICAgICAgSDEuaGlnaCA9IChIMWggKyBiaCArICgoSDFsID4+PiAwKSA8IChibCA+Pj4gMCkgPyAxIDogMCkpO1xuXHQgICAgICAgICAgICBIMmwgPSBIMi5sb3cgID0gKEgybCArIGNsKTtcblx0ICAgICAgICAgICAgSDIuaGlnaCA9IChIMmggKyBjaCArICgoSDJsID4+PiAwKSA8IChjbCA+Pj4gMCkgPyAxIDogMCkpO1xuXHQgICAgICAgICAgICBIM2wgPSBIMy5sb3cgID0gKEgzbCArIGRsKTtcblx0ICAgICAgICAgICAgSDMuaGlnaCA9IChIM2ggKyBkaCArICgoSDNsID4+PiAwKSA8IChkbCA+Pj4gMCkgPyAxIDogMCkpO1xuXHQgICAgICAgICAgICBINGwgPSBINC5sb3cgID0gKEg0bCArIGVsKTtcblx0ICAgICAgICAgICAgSDQuaGlnaCA9IChINGggKyBlaCArICgoSDRsID4+PiAwKSA8IChlbCA+Pj4gMCkgPyAxIDogMCkpO1xuXHQgICAgICAgICAgICBINWwgPSBINS5sb3cgID0gKEg1bCArIGZsKTtcblx0ICAgICAgICAgICAgSDUuaGlnaCA9IChINWggKyBmaCArICgoSDVsID4+PiAwKSA8IChmbCA+Pj4gMCkgPyAxIDogMCkpO1xuXHQgICAgICAgICAgICBINmwgPSBINi5sb3cgID0gKEg2bCArIGdsKTtcblx0ICAgICAgICAgICAgSDYuaGlnaCA9IChINmggKyBnaCArICgoSDZsID4+PiAwKSA8IChnbCA+Pj4gMCkgPyAxIDogMCkpO1xuXHQgICAgICAgICAgICBIN2wgPSBINy5sb3cgID0gKEg3bCArIGhsKTtcblx0ICAgICAgICAgICAgSDcuaGlnaCA9IChIN2ggKyBoaCArICgoSDdsID4+PiAwKSA8IChobCA+Pj4gMCkgPyAxIDogMCkpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGRhdGEgPSB0aGlzLl9kYXRhO1xuXHQgICAgICAgICAgICB2YXIgZGF0YVdvcmRzID0gZGF0YS53b3JkcztcblxuXHQgICAgICAgICAgICB2YXIgbkJpdHNUb3RhbCA9IHRoaXMuX25EYXRhQnl0ZXMgKiA4O1xuXHQgICAgICAgICAgICB2YXIgbkJpdHNMZWZ0ID0gZGF0YS5zaWdCeXRlcyAqIDg7XG5cblx0ICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmdcblx0ICAgICAgICAgICAgZGF0YVdvcmRzW25CaXRzTGVmdCA+Pj4gNV0gfD0gMHg4MCA8PCAoMjQgLSBuQml0c0xlZnQgJSAzMik7XG5cdCAgICAgICAgICAgIGRhdGFXb3Jkc1soKChuQml0c0xlZnQgKyAxMjgpID4+PiAxMCkgPDwgNSkgKyAzMF0gPSBNYXRoLmZsb29yKG5CaXRzVG90YWwgLyAweDEwMDAwMDAwMCk7XG5cdCAgICAgICAgICAgIGRhdGFXb3Jkc1soKChuQml0c0xlZnQgKyAxMjgpID4+PiAxMCkgPDwgNSkgKyAzMV0gPSBuQml0c1RvdGFsO1xuXHQgICAgICAgICAgICBkYXRhLnNpZ0J5dGVzID0gZGF0YVdvcmRzLmxlbmd0aCAqIDQ7XG5cblx0ICAgICAgICAgICAgLy8gSGFzaCBmaW5hbCBibG9ja3Ncblx0ICAgICAgICAgICAgdGhpcy5fcHJvY2VzcygpO1xuXG5cdCAgICAgICAgICAgIC8vIENvbnZlcnQgaGFzaCB0byAzMi1iaXQgd29yZCBhcnJheSBiZWZvcmUgcmV0dXJuaW5nXG5cdCAgICAgICAgICAgIHZhciBoYXNoID0gdGhpcy5faGFzaC50b1gzMigpO1xuXG5cdCAgICAgICAgICAgIC8vIFJldHVybiBmaW5hbCBjb21wdXRlZCBoYXNoXG5cdCAgICAgICAgICAgIHJldHVybiBoYXNoO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgY2xvbmUgPSBIYXNoZXIuY2xvbmUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAgICAgY2xvbmUuX2hhc2ggPSB0aGlzLl9oYXNoLmNsb25lKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBibG9ja1NpemU6IDEwMjQvMzJcblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBoYXNoZXIncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLlxuXHQgICAgICpcblx0ICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGhhc2guXG5cdCAgICAgKlxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuU0hBNTEyKCdtZXNzYWdlJyk7XG5cdCAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5TSEE1MTIod29yZEFycmF5KTtcblx0ICAgICAqL1xuXHQgICAgQy5TSEE1MTIgPSBIYXNoZXIuX2NyZWF0ZUhlbHBlcihTSEE1MTIpO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBITUFDJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC5cblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30ga2V5IFRoZSBzZWNyZXQga2V5LlxuXHQgICAgICpcblx0ICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIEhNQUMuXG5cdCAgICAgKlxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogICAgIHZhciBobWFjID0gQ3J5cHRvSlMuSG1hY1NIQTUxMihtZXNzYWdlLCBrZXkpO1xuXHQgICAgICovXG5cdCAgICBDLkhtYWNTSEE1MTIgPSBIYXNoZXIuX2NyZWF0ZUhtYWNIZWxwZXIoU0hBNTEyKTtcblx0fSgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUy5TSEE1MTI7XG5cbn0pKTsiLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZShcIi4vY29yZVwiKSwgcmVxdWlyZShcIi4vZW5jLWJhc2U2NFwiKSwgcmVxdWlyZShcIi4vbWQ1XCIpLCByZXF1aXJlKFwiLi9ldnBrZGZcIiksIHJlcXVpcmUoXCIuL2NpcGhlci1jb3JlXCIpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIiwgXCIuL2VuYy1iYXNlNjRcIiwgXCIuL21kNVwiLCBcIi4vZXZwa2RmXCIsIFwiLi9jaXBoZXItY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0KGZ1bmN0aW9uICgpIHtcblx0ICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgdmFyIEMgPSBDcnlwdG9KUztcblx0ICAgIHZhciBDX2xpYiA9IEMubGliO1xuXHQgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTtcblx0ICAgIHZhciBCbG9ja0NpcGhlciA9IENfbGliLkJsb2NrQ2lwaGVyO1xuXHQgICAgdmFyIENfYWxnbyA9IEMuYWxnbztcblxuXHQgICAgLy8gUGVybXV0ZWQgQ2hvaWNlIDEgY29uc3RhbnRzXG5cdCAgICB2YXIgUEMxID0gW1xuXHQgICAgICAgIDU3LCA0OSwgNDEsIDMzLCAyNSwgMTcsIDksICAxLFxuXHQgICAgICAgIDU4LCA1MCwgNDIsIDM0LCAyNiwgMTgsIDEwLCAyLFxuXHQgICAgICAgIDU5LCA1MSwgNDMsIDM1LCAyNywgMTksIDExLCAzLFxuXHQgICAgICAgIDYwLCA1MiwgNDQsIDM2LCA2MywgNTUsIDQ3LCAzOSxcblx0ICAgICAgICAzMSwgMjMsIDE1LCA3LCAgNjIsIDU0LCA0NiwgMzgsXG5cdCAgICAgICAgMzAsIDIyLCAxNCwgNiwgIDYxLCA1MywgNDUsIDM3LFxuXHQgICAgICAgIDI5LCAyMSwgMTMsIDUsICAyOCwgMjAsIDEyLCA0XG5cdCAgICBdO1xuXG5cdCAgICAvLyBQZXJtdXRlZCBDaG9pY2UgMiBjb25zdGFudHNcblx0ICAgIHZhciBQQzIgPSBbXG5cdCAgICAgICAgMTQsIDE3LCAxMSwgMjQsIDEsICA1LFxuXHQgICAgICAgIDMsICAyOCwgMTUsIDYsICAyMSwgMTAsXG5cdCAgICAgICAgMjMsIDE5LCAxMiwgNCwgIDI2LCA4LFxuXHQgICAgICAgIDE2LCA3LCAgMjcsIDIwLCAxMywgMixcblx0ICAgICAgICA0MSwgNTIsIDMxLCAzNywgNDcsIDU1LFxuXHQgICAgICAgIDMwLCA0MCwgNTEsIDQ1LCAzMywgNDgsXG5cdCAgICAgICAgNDQsIDQ5LCAzOSwgNTYsIDM0LCA1Myxcblx0ICAgICAgICA0NiwgNDIsIDUwLCAzNiwgMjksIDMyXG5cdCAgICBdO1xuXG5cdCAgICAvLyBDdW11bGF0aXZlIGJpdCBzaGlmdCBjb25zdGFudHNcblx0ICAgIHZhciBCSVRfU0hJRlRTID0gWzEsICAyLCAgNCwgIDYsICA4LCAgMTAsIDEyLCAxNCwgMTUsIDE3LCAxOSwgMjEsIDIzLCAyNSwgMjcsIDI4XTtcblxuXHQgICAgLy8gU0JPWGVzIGFuZCByb3VuZCBwZXJtdXRhdGlvbiBjb25zdGFudHNcblx0ICAgIHZhciBTQk9YX1AgPSBbXG5cdCAgICAgICAge1xuXHQgICAgICAgICAgICAweDA6IDB4ODA4MjAwLFxuXHQgICAgICAgICAgICAweDEwMDAwMDAwOiAweDgwMDAsXG5cdCAgICAgICAgICAgIDB4MjAwMDAwMDA6IDB4ODA4MDAyLFxuXHQgICAgICAgICAgICAweDMwMDAwMDAwOiAweDIsXG5cdCAgICAgICAgICAgIDB4NDAwMDAwMDA6IDB4MjAwLFxuXHQgICAgICAgICAgICAweDUwMDAwMDAwOiAweDgwODIwMixcblx0ICAgICAgICAgICAgMHg2MDAwMDAwMDogMHg4MDAyMDIsXG5cdCAgICAgICAgICAgIDB4NzAwMDAwMDA6IDB4ODAwMDAwLFxuXHQgICAgICAgICAgICAweDgwMDAwMDAwOiAweDIwMixcblx0ICAgICAgICAgICAgMHg5MDAwMDAwMDogMHg4MDAyMDAsXG5cdCAgICAgICAgICAgIDB4YTAwMDAwMDA6IDB4ODIwMCxcblx0ICAgICAgICAgICAgMHhiMDAwMDAwMDogMHg4MDgwMDAsXG5cdCAgICAgICAgICAgIDB4YzAwMDAwMDA6IDB4ODAwMixcblx0ICAgICAgICAgICAgMHhkMDAwMDAwMDogMHg4MDAwMDIsXG5cdCAgICAgICAgICAgIDB4ZTAwMDAwMDA6IDB4MCxcblx0ICAgICAgICAgICAgMHhmMDAwMDAwMDogMHg4MjAyLFxuXHQgICAgICAgICAgICAweDgwMDAwMDA6IDB4MCxcblx0ICAgICAgICAgICAgMHgxODAwMDAwMDogMHg4MDgyMDIsXG5cdCAgICAgICAgICAgIDB4MjgwMDAwMDA6IDB4ODIwMixcblx0ICAgICAgICAgICAgMHgzODAwMDAwMDogMHg4MDAwLFxuXHQgICAgICAgICAgICAweDQ4MDAwMDAwOiAweDgwODIwMCxcblx0ICAgICAgICAgICAgMHg1ODAwMDAwMDogMHgyMDAsXG5cdCAgICAgICAgICAgIDB4NjgwMDAwMDA6IDB4ODA4MDAyLFxuXHQgICAgICAgICAgICAweDc4MDAwMDAwOiAweDIsXG5cdCAgICAgICAgICAgIDB4ODgwMDAwMDA6IDB4ODAwMjAwLFxuXHQgICAgICAgICAgICAweDk4MDAwMDAwOiAweDgyMDAsXG5cdCAgICAgICAgICAgIDB4YTgwMDAwMDA6IDB4ODA4MDAwLFxuXHQgICAgICAgICAgICAweGI4MDAwMDAwOiAweDgwMDIwMixcblx0ICAgICAgICAgICAgMHhjODAwMDAwMDogMHg4MDAwMDIsXG5cdCAgICAgICAgICAgIDB4ZDgwMDAwMDA6IDB4ODAwMixcblx0ICAgICAgICAgICAgMHhlODAwMDAwMDogMHgyMDIsXG5cdCAgICAgICAgICAgIDB4ZjgwMDAwMDA6IDB4ODAwMDAwLFxuXHQgICAgICAgICAgICAweDE6IDB4ODAwMCxcblx0ICAgICAgICAgICAgMHgxMDAwMDAwMTogMHgyLFxuXHQgICAgICAgICAgICAweDIwMDAwMDAxOiAweDgwODIwMCxcblx0ICAgICAgICAgICAgMHgzMDAwMDAwMTogMHg4MDAwMDAsXG5cdCAgICAgICAgICAgIDB4NDAwMDAwMDE6IDB4ODA4MDAyLFxuXHQgICAgICAgICAgICAweDUwMDAwMDAxOiAweDgyMDAsXG5cdCAgICAgICAgICAgIDB4NjAwMDAwMDE6IDB4MjAwLFxuXHQgICAgICAgICAgICAweDcwMDAwMDAxOiAweDgwMDIwMixcblx0ICAgICAgICAgICAgMHg4MDAwMDAwMTogMHg4MDgyMDIsXG5cdCAgICAgICAgICAgIDB4OTAwMDAwMDE6IDB4ODA4MDAwLFxuXHQgICAgICAgICAgICAweGEwMDAwMDAxOiAweDgwMDAwMixcblx0ICAgICAgICAgICAgMHhiMDAwMDAwMTogMHg4MjAyLFxuXHQgICAgICAgICAgICAweGMwMDAwMDAxOiAweDIwMixcblx0ICAgICAgICAgICAgMHhkMDAwMDAwMTogMHg4MDAyMDAsXG5cdCAgICAgICAgICAgIDB4ZTAwMDAwMDE6IDB4ODAwMixcblx0ICAgICAgICAgICAgMHhmMDAwMDAwMTogMHgwLFxuXHQgICAgICAgICAgICAweDgwMDAwMDE6IDB4ODA4MjAyLFxuXHQgICAgICAgICAgICAweDE4MDAwMDAxOiAweDgwODAwMCxcblx0ICAgICAgICAgICAgMHgyODAwMDAwMTogMHg4MDAwMDAsXG5cdCAgICAgICAgICAgIDB4MzgwMDAwMDE6IDB4MjAwLFxuXHQgICAgICAgICAgICAweDQ4MDAwMDAxOiAweDgwMDAsXG5cdCAgICAgICAgICAgIDB4NTgwMDAwMDE6IDB4ODAwMDAyLFxuXHQgICAgICAgICAgICAweDY4MDAwMDAxOiAweDIsXG5cdCAgICAgICAgICAgIDB4NzgwMDAwMDE6IDB4ODIwMixcblx0ICAgICAgICAgICAgMHg4ODAwMDAwMTogMHg4MDAyLFxuXHQgICAgICAgICAgICAweDk4MDAwMDAxOiAweDgwMDIwMixcblx0ICAgICAgICAgICAgMHhhODAwMDAwMTogMHgyMDIsXG5cdCAgICAgICAgICAgIDB4YjgwMDAwMDE6IDB4ODA4MjAwLFxuXHQgICAgICAgICAgICAweGM4MDAwMDAxOiAweDgwMDIwMCxcblx0ICAgICAgICAgICAgMHhkODAwMDAwMTogMHgwLFxuXHQgICAgICAgICAgICAweGU4MDAwMDAxOiAweDgyMDAsXG5cdCAgICAgICAgICAgIDB4ZjgwMDAwMDE6IDB4ODA4MDAyXG5cdCAgICAgICAgfSxcblx0ICAgICAgICB7XG5cdCAgICAgICAgICAgIDB4MDogMHg0MDA4NDAxMCxcblx0ICAgICAgICAgICAgMHgxMDAwMDAwOiAweDQwMDAsXG5cdCAgICAgICAgICAgIDB4MjAwMDAwMDogMHg4MDAwMCxcblx0ICAgICAgICAgICAgMHgzMDAwMDAwOiAweDQwMDgwMDEwLFxuXHQgICAgICAgICAgICAweDQwMDAwMDA6IDB4NDAwMDAwMTAsXG5cdCAgICAgICAgICAgIDB4NTAwMDAwMDogMHg0MDA4NDAwMCxcblx0ICAgICAgICAgICAgMHg2MDAwMDAwOiAweDQwMDA0MDAwLFxuXHQgICAgICAgICAgICAweDcwMDAwMDA6IDB4MTAsXG5cdCAgICAgICAgICAgIDB4ODAwMDAwMDogMHg4NDAwMCxcblx0ICAgICAgICAgICAgMHg5MDAwMDAwOiAweDQwMDA0MDEwLFxuXHQgICAgICAgICAgICAweGEwMDAwMDA6IDB4NDAwMDAwMDAsXG5cdCAgICAgICAgICAgIDB4YjAwMDAwMDogMHg4NDAxMCxcblx0ICAgICAgICAgICAgMHhjMDAwMDAwOiAweDgwMDEwLFxuXHQgICAgICAgICAgICAweGQwMDAwMDA6IDB4MCxcblx0ICAgICAgICAgICAgMHhlMDAwMDAwOiAweDQwMTAsXG5cdCAgICAgICAgICAgIDB4ZjAwMDAwMDogMHg0MDA4MDAwMCxcblx0ICAgICAgICAgICAgMHg4MDAwMDA6IDB4NDAwMDQwMDAsXG5cdCAgICAgICAgICAgIDB4MTgwMDAwMDogMHg4NDAxMCxcblx0ICAgICAgICAgICAgMHgyODAwMDAwOiAweDEwLFxuXHQgICAgICAgICAgICAweDM4MDAwMDA6IDB4NDAwMDQwMTAsXG5cdCAgICAgICAgICAgIDB4NDgwMDAwMDogMHg0MDA4NDAxMCxcblx0ICAgICAgICAgICAgMHg1ODAwMDAwOiAweDQwMDAwMDAwLFxuXHQgICAgICAgICAgICAweDY4MDAwMDA6IDB4ODAwMDAsXG5cdCAgICAgICAgICAgIDB4NzgwMDAwMDogMHg0MDA4MDAxMCxcblx0ICAgICAgICAgICAgMHg4ODAwMDAwOiAweDgwMDEwLFxuXHQgICAgICAgICAgICAweDk4MDAwMDA6IDB4MCxcblx0ICAgICAgICAgICAgMHhhODAwMDAwOiAweDQwMDAsXG5cdCAgICAgICAgICAgIDB4YjgwMDAwMDogMHg0MDA4MDAwMCxcblx0ICAgICAgICAgICAgMHhjODAwMDAwOiAweDQwMDAwMDEwLFxuXHQgICAgICAgICAgICAweGQ4MDAwMDA6IDB4ODQwMDAsXG5cdCAgICAgICAgICAgIDB4ZTgwMDAwMDogMHg0MDA4NDAwMCxcblx0ICAgICAgICAgICAgMHhmODAwMDAwOiAweDQwMTAsXG5cdCAgICAgICAgICAgIDB4MTAwMDAwMDA6IDB4MCxcblx0ICAgICAgICAgICAgMHgxMTAwMDAwMDogMHg0MDA4MDAxMCxcblx0ICAgICAgICAgICAgMHgxMjAwMDAwMDogMHg0MDAwNDAxMCxcblx0ICAgICAgICAgICAgMHgxMzAwMDAwMDogMHg0MDA4NDAwMCxcblx0ICAgICAgICAgICAgMHgxNDAwMDAwMDogMHg0MDA4MDAwMCxcblx0ICAgICAgICAgICAgMHgxNTAwMDAwMDogMHgxMCxcblx0ICAgICAgICAgICAgMHgxNjAwMDAwMDogMHg4NDAxMCxcblx0ICAgICAgICAgICAgMHgxNzAwMDAwMDogMHg0MDAwLFxuXHQgICAgICAgICAgICAweDE4MDAwMDAwOiAweDQwMTAsXG5cdCAgICAgICAgICAgIDB4MTkwMDAwMDA6IDB4ODAwMDAsXG5cdCAgICAgICAgICAgIDB4MWEwMDAwMDA6IDB4ODAwMTAsXG5cdCAgICAgICAgICAgIDB4MWIwMDAwMDA6IDB4NDAwMDAwMTAsXG5cdCAgICAgICAgICAgIDB4MWMwMDAwMDA6IDB4ODQwMDAsXG5cdCAgICAgICAgICAgIDB4MWQwMDAwMDA6IDB4NDAwMDQwMDAsXG5cdCAgICAgICAgICAgIDB4MWUwMDAwMDA6IDB4NDAwMDAwMDAsXG5cdCAgICAgICAgICAgIDB4MWYwMDAwMDA6IDB4NDAwODQwMTAsXG5cdCAgICAgICAgICAgIDB4MTA4MDAwMDA6IDB4ODQwMTAsXG5cdCAgICAgICAgICAgIDB4MTE4MDAwMDA6IDB4ODAwMDAsXG5cdCAgICAgICAgICAgIDB4MTI4MDAwMDA6IDB4NDAwODAwMDAsXG5cdCAgICAgICAgICAgIDB4MTM4MDAwMDA6IDB4NDAwMCxcblx0ICAgICAgICAgICAgMHgxNDgwMDAwMDogMHg0MDAwNDAwMCxcblx0ICAgICAgICAgICAgMHgxNTgwMDAwMDogMHg0MDA4NDAxMCxcblx0ICAgICAgICAgICAgMHgxNjgwMDAwMDogMHgxMCxcblx0ICAgICAgICAgICAgMHgxNzgwMDAwMDogMHg0MDAwMDAwMCxcblx0ICAgICAgICAgICAgMHgxODgwMDAwMDogMHg0MDA4NDAwMCxcblx0ICAgICAgICAgICAgMHgxOTgwMDAwMDogMHg0MDAwMDAxMCxcblx0ICAgICAgICAgICAgMHgxYTgwMDAwMDogMHg0MDAwNDAxMCxcblx0ICAgICAgICAgICAgMHgxYjgwMDAwMDogMHg4MDAxMCxcblx0ICAgICAgICAgICAgMHgxYzgwMDAwMDogMHgwLFxuXHQgICAgICAgICAgICAweDFkODAwMDAwOiAweDQwMTAsXG5cdCAgICAgICAgICAgIDB4MWU4MDAwMDA6IDB4NDAwODAwMTAsXG5cdCAgICAgICAgICAgIDB4MWY4MDAwMDA6IDB4ODQwMDBcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHtcblx0ICAgICAgICAgICAgMHgwOiAweDEwNCxcblx0ICAgICAgICAgICAgMHgxMDAwMDA6IDB4MCxcblx0ICAgICAgICAgICAgMHgyMDAwMDA6IDB4NDAwMDEwMCxcblx0ICAgICAgICAgICAgMHgzMDAwMDA6IDB4MTAxMDQsXG5cdCAgICAgICAgICAgIDB4NDAwMDAwOiAweDEwMDA0LFxuXHQgICAgICAgICAgICAweDUwMDAwMDogMHg0MDAwMDA0LFxuXHQgICAgICAgICAgICAweDYwMDAwMDogMHg0MDEwMTA0LFxuXHQgICAgICAgICAgICAweDcwMDAwMDogMHg0MDEwMDAwLFxuXHQgICAgICAgICAgICAweDgwMDAwMDogMHg0MDAwMDAwLFxuXHQgICAgICAgICAgICAweDkwMDAwMDogMHg0MDEwMTAwLFxuXHQgICAgICAgICAgICAweGEwMDAwMDogMHgxMDEwMCxcblx0ICAgICAgICAgICAgMHhiMDAwMDA6IDB4NDAxMDAwNCxcblx0ICAgICAgICAgICAgMHhjMDAwMDA6IDB4NDAwMDEwNCxcblx0ICAgICAgICAgICAgMHhkMDAwMDA6IDB4MTAwMDAsXG5cdCAgICAgICAgICAgIDB4ZTAwMDAwOiAweDQsXG5cdCAgICAgICAgICAgIDB4ZjAwMDAwOiAweDEwMCxcblx0ICAgICAgICAgICAgMHg4MDAwMDogMHg0MDEwMTAwLFxuXHQgICAgICAgICAgICAweDE4MDAwMDogMHg0MDEwMDA0LFxuXHQgICAgICAgICAgICAweDI4MDAwMDogMHgwLFxuXHQgICAgICAgICAgICAweDM4MDAwMDogMHg0MDAwMTAwLFxuXHQgICAgICAgICAgICAweDQ4MDAwMDogMHg0MDAwMDA0LFxuXHQgICAgICAgICAgICAweDU4MDAwMDogMHgxMDAwMCxcblx0ICAgICAgICAgICAgMHg2ODAwMDA6IDB4MTAwMDQsXG5cdCAgICAgICAgICAgIDB4NzgwMDAwOiAweDEwNCxcblx0ICAgICAgICAgICAgMHg4ODAwMDA6IDB4NCxcblx0ICAgICAgICAgICAgMHg5ODAwMDA6IDB4MTAwLFxuXHQgICAgICAgICAgICAweGE4MDAwMDogMHg0MDEwMDAwLFxuXHQgICAgICAgICAgICAweGI4MDAwMDogMHgxMDEwNCxcblx0ICAgICAgICAgICAgMHhjODAwMDA6IDB4MTAxMDAsXG5cdCAgICAgICAgICAgIDB4ZDgwMDAwOiAweDQwMDAxMDQsXG5cdCAgICAgICAgICAgIDB4ZTgwMDAwOiAweDQwMTAxMDQsXG5cdCAgICAgICAgICAgIDB4ZjgwMDAwOiAweDQwMDAwMDAsXG5cdCAgICAgICAgICAgIDB4MTAwMDAwMDogMHg0MDEwMTAwLFxuXHQgICAgICAgICAgICAweDExMDAwMDA6IDB4MTAwMDQsXG5cdCAgICAgICAgICAgIDB4MTIwMDAwMDogMHgxMDAwMCxcblx0ICAgICAgICAgICAgMHgxMzAwMDAwOiAweDQwMDAxMDAsXG5cdCAgICAgICAgICAgIDB4MTQwMDAwMDogMHgxMDAsXG5cdCAgICAgICAgICAgIDB4MTUwMDAwMDogMHg0MDEwMTA0LFxuXHQgICAgICAgICAgICAweDE2MDAwMDA6IDB4NDAwMDAwNCxcblx0ICAgICAgICAgICAgMHgxNzAwMDAwOiAweDAsXG5cdCAgICAgICAgICAgIDB4MTgwMDAwMDogMHg0MDAwMTA0LFxuXHQgICAgICAgICAgICAweDE5MDAwMDA6IDB4NDAwMDAwMCxcblx0ICAgICAgICAgICAgMHgxYTAwMDAwOiAweDQsXG5cdCAgICAgICAgICAgIDB4MWIwMDAwMDogMHgxMDEwMCxcblx0ICAgICAgICAgICAgMHgxYzAwMDAwOiAweDQwMTAwMDAsXG5cdCAgICAgICAgICAgIDB4MWQwMDAwMDogMHgxMDQsXG5cdCAgICAgICAgICAgIDB4MWUwMDAwMDogMHgxMDEwNCxcblx0ICAgICAgICAgICAgMHgxZjAwMDAwOiAweDQwMTAwMDQsXG5cdCAgICAgICAgICAgIDB4MTA4MDAwMDogMHg0MDAwMDAwLFxuXHQgICAgICAgICAgICAweDExODAwMDA6IDB4MTA0LFxuXHQgICAgICAgICAgICAweDEyODAwMDA6IDB4NDAxMDEwMCxcblx0ICAgICAgICAgICAgMHgxMzgwMDAwOiAweDAsXG5cdCAgICAgICAgICAgIDB4MTQ4MDAwMDogMHgxMDAwNCxcblx0ICAgICAgICAgICAgMHgxNTgwMDAwOiAweDQwMDAxMDAsXG5cdCAgICAgICAgICAgIDB4MTY4MDAwMDogMHgxMDAsXG5cdCAgICAgICAgICAgIDB4MTc4MDAwMDogMHg0MDEwMDA0LFxuXHQgICAgICAgICAgICAweDE4ODAwMDA6IDB4MTAwMDAsXG5cdCAgICAgICAgICAgIDB4MTk4MDAwMDogMHg0MDEwMTA0LFxuXHQgICAgICAgICAgICAweDFhODAwMDA6IDB4MTAxMDQsXG5cdCAgICAgICAgICAgIDB4MWI4MDAwMDogMHg0MDAwMDA0LFxuXHQgICAgICAgICAgICAweDFjODAwMDA6IDB4NDAwMDEwNCxcblx0ICAgICAgICAgICAgMHgxZDgwMDAwOiAweDQwMTAwMDAsXG5cdCAgICAgICAgICAgIDB4MWU4MDAwMDogMHg0LFxuXHQgICAgICAgICAgICAweDFmODAwMDA6IDB4MTAxMDBcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHtcblx0ICAgICAgICAgICAgMHgwOiAweDgwNDAxMDAwLFxuXHQgICAgICAgICAgICAweDEwMDAwOiAweDgwMDAxMDQwLFxuXHQgICAgICAgICAgICAweDIwMDAwOiAweDQwMTA0MCxcblx0ICAgICAgICAgICAgMHgzMDAwMDogMHg4MDQwMDAwMCxcblx0ICAgICAgICAgICAgMHg0MDAwMDogMHgwLFxuXHQgICAgICAgICAgICAweDUwMDAwOiAweDQwMTAwMCxcblx0ICAgICAgICAgICAgMHg2MDAwMDogMHg4MDAwMDA0MCxcblx0ICAgICAgICAgICAgMHg3MDAwMDogMHg0MDAwNDAsXG5cdCAgICAgICAgICAgIDB4ODAwMDA6IDB4ODAwMDAwMDAsXG5cdCAgICAgICAgICAgIDB4OTAwMDA6IDB4NDAwMDAwLFxuXHQgICAgICAgICAgICAweGEwMDAwOiAweDQwLFxuXHQgICAgICAgICAgICAweGIwMDAwOiAweDgwMDAxMDAwLFxuXHQgICAgICAgICAgICAweGMwMDAwOiAweDgwNDAwMDQwLFxuXHQgICAgICAgICAgICAweGQwMDAwOiAweDEwNDAsXG5cdCAgICAgICAgICAgIDB4ZTAwMDA6IDB4MTAwMCxcblx0ICAgICAgICAgICAgMHhmMDAwMDogMHg4MDQwMTA0MCxcblx0ICAgICAgICAgICAgMHg4MDAwOiAweDgwMDAxMDQwLFxuXHQgICAgICAgICAgICAweDE4MDAwOiAweDQwLFxuXHQgICAgICAgICAgICAweDI4MDAwOiAweDgwNDAwMDQwLFxuXHQgICAgICAgICAgICAweDM4MDAwOiAweDgwMDAxMDAwLFxuXHQgICAgICAgICAgICAweDQ4MDAwOiAweDQwMTAwMCxcblx0ICAgICAgICAgICAgMHg1ODAwMDogMHg4MDQwMTA0MCxcblx0ICAgICAgICAgICAgMHg2ODAwMDogMHgwLFxuXHQgICAgICAgICAgICAweDc4MDAwOiAweDgwNDAwMDAwLFxuXHQgICAgICAgICAgICAweDg4MDAwOiAweDEwMDAsXG5cdCAgICAgICAgICAgIDB4OTgwMDA6IDB4ODA0MDEwMDAsXG5cdCAgICAgICAgICAgIDB4YTgwMDA6IDB4NDAwMDAwLFxuXHQgICAgICAgICAgICAweGI4MDAwOiAweDEwNDAsXG5cdCAgICAgICAgICAgIDB4YzgwMDA6IDB4ODAwMDAwMDAsXG5cdCAgICAgICAgICAgIDB4ZDgwMDA6IDB4NDAwMDQwLFxuXHQgICAgICAgICAgICAweGU4MDAwOiAweDQwMTA0MCxcblx0ICAgICAgICAgICAgMHhmODAwMDogMHg4MDAwMDA0MCxcblx0ICAgICAgICAgICAgMHgxMDAwMDA6IDB4NDAwMDQwLFxuXHQgICAgICAgICAgICAweDExMDAwMDogMHg0MDEwMDAsXG5cdCAgICAgICAgICAgIDB4MTIwMDAwOiAweDgwMDAwMDQwLFxuXHQgICAgICAgICAgICAweDEzMDAwMDogMHgwLFxuXHQgICAgICAgICAgICAweDE0MDAwMDogMHgxMDQwLFxuXHQgICAgICAgICAgICAweDE1MDAwMDogMHg4MDQwMDA0MCxcblx0ICAgICAgICAgICAgMHgxNjAwMDA6IDB4ODA0MDEwMDAsXG5cdCAgICAgICAgICAgIDB4MTcwMDAwOiAweDgwMDAxMDQwLFxuXHQgICAgICAgICAgICAweDE4MDAwMDogMHg4MDQwMTA0MCxcblx0ICAgICAgICAgICAgMHgxOTAwMDA6IDB4ODAwMDAwMDAsXG5cdCAgICAgICAgICAgIDB4MWEwMDAwOiAweDgwNDAwMDAwLFxuXHQgICAgICAgICAgICAweDFiMDAwMDogMHg0MDEwNDAsXG5cdCAgICAgICAgICAgIDB4MWMwMDAwOiAweDgwMDAxMDAwLFxuXHQgICAgICAgICAgICAweDFkMDAwMDogMHg0MDAwMDAsXG5cdCAgICAgICAgICAgIDB4MWUwMDAwOiAweDQwLFxuXHQgICAgICAgICAgICAweDFmMDAwMDogMHgxMDAwLFxuXHQgICAgICAgICAgICAweDEwODAwMDogMHg4MDQwMDAwMCxcblx0ICAgICAgICAgICAgMHgxMTgwMDA6IDB4ODA0MDEwNDAsXG5cdCAgICAgICAgICAgIDB4MTI4MDAwOiAweDAsXG5cdCAgICAgICAgICAgIDB4MTM4MDAwOiAweDQwMTAwMCxcblx0ICAgICAgICAgICAgMHgxNDgwMDA6IDB4NDAwMDQwLFxuXHQgICAgICAgICAgICAweDE1ODAwMDogMHg4MDAwMDAwMCxcblx0ICAgICAgICAgICAgMHgxNjgwMDA6IDB4ODAwMDEwNDAsXG5cdCAgICAgICAgICAgIDB4MTc4MDAwOiAweDQwLFxuXHQgICAgICAgICAgICAweDE4ODAwMDogMHg4MDAwMDA0MCxcblx0ICAgICAgICAgICAgMHgxOTgwMDA6IDB4MTAwMCxcblx0ICAgICAgICAgICAgMHgxYTgwMDA6IDB4ODAwMDEwMDAsXG5cdCAgICAgICAgICAgIDB4MWI4MDAwOiAweDgwNDAwMDQwLFxuXHQgICAgICAgICAgICAweDFjODAwMDogMHgxMDQwLFxuXHQgICAgICAgICAgICAweDFkODAwMDogMHg4MDQwMTAwMCxcblx0ICAgICAgICAgICAgMHgxZTgwMDA6IDB4NDAwMDAwLFxuXHQgICAgICAgICAgICAweDFmODAwMDogMHg0MDEwNDBcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHtcblx0ICAgICAgICAgICAgMHgwOiAweDgwLFxuXHQgICAgICAgICAgICAweDEwMDA6IDB4MTA0MDAwMCxcblx0ICAgICAgICAgICAgMHgyMDAwOiAweDQwMDAwLFxuXHQgICAgICAgICAgICAweDMwMDA6IDB4MjAwMDAwMDAsXG5cdCAgICAgICAgICAgIDB4NDAwMDogMHgyMDA0MDA4MCxcblx0ICAgICAgICAgICAgMHg1MDAwOiAweDEwMDAwODAsXG5cdCAgICAgICAgICAgIDB4NjAwMDogMHgyMTAwMDA4MCxcblx0ICAgICAgICAgICAgMHg3MDAwOiAweDQwMDgwLFxuXHQgICAgICAgICAgICAweDgwMDA6IDB4MTAwMDAwMCxcblx0ICAgICAgICAgICAgMHg5MDAwOiAweDIwMDQwMDAwLFxuXHQgICAgICAgICAgICAweGEwMDA6IDB4MjAwMDAwODAsXG5cdCAgICAgICAgICAgIDB4YjAwMDogMHgyMTA0MDA4MCxcblx0ICAgICAgICAgICAgMHhjMDAwOiAweDIxMDQwMDAwLFxuXHQgICAgICAgICAgICAweGQwMDA6IDB4MCxcblx0ICAgICAgICAgICAgMHhlMDAwOiAweDEwNDAwODAsXG5cdCAgICAgICAgICAgIDB4ZjAwMDogMHgyMTAwMDAwMCxcblx0ICAgICAgICAgICAgMHg4MDA6IDB4MTA0MDA4MCxcblx0ICAgICAgICAgICAgMHgxODAwOiAweDIxMDAwMDgwLFxuXHQgICAgICAgICAgICAweDI4MDA6IDB4ODAsXG5cdCAgICAgICAgICAgIDB4MzgwMDogMHgxMDQwMDAwLFxuXHQgICAgICAgICAgICAweDQ4MDA6IDB4NDAwMDAsXG5cdCAgICAgICAgICAgIDB4NTgwMDogMHgyMDA0MDA4MCxcblx0ICAgICAgICAgICAgMHg2ODAwOiAweDIxMDQwMDAwLFxuXHQgICAgICAgICAgICAweDc4MDA6IDB4MjAwMDAwMDAsXG5cdCAgICAgICAgICAgIDB4ODgwMDogMHgyMDA0MDAwMCxcblx0ICAgICAgICAgICAgMHg5ODAwOiAweDAsXG5cdCAgICAgICAgICAgIDB4YTgwMDogMHgyMTA0MDA4MCxcblx0ICAgICAgICAgICAgMHhiODAwOiAweDEwMDAwODAsXG5cdCAgICAgICAgICAgIDB4YzgwMDogMHgyMDAwMDA4MCxcblx0ICAgICAgICAgICAgMHhkODAwOiAweDIxMDAwMDAwLFxuXHQgICAgICAgICAgICAweGU4MDA6IDB4MTAwMDAwMCxcblx0ICAgICAgICAgICAgMHhmODAwOiAweDQwMDgwLFxuXHQgICAgICAgICAgICAweDEwMDAwOiAweDQwMDAwLFxuXHQgICAgICAgICAgICAweDExMDAwOiAweDgwLFxuXHQgICAgICAgICAgICAweDEyMDAwOiAweDIwMDAwMDAwLFxuXHQgICAgICAgICAgICAweDEzMDAwOiAweDIxMDAwMDgwLFxuXHQgICAgICAgICAgICAweDE0MDAwOiAweDEwMDAwODAsXG5cdCAgICAgICAgICAgIDB4MTUwMDA6IDB4MjEwNDAwMDAsXG5cdCAgICAgICAgICAgIDB4MTYwMDA6IDB4MjAwNDAwODAsXG5cdCAgICAgICAgICAgIDB4MTcwMDA6IDB4MTAwMDAwMCxcblx0ICAgICAgICAgICAgMHgxODAwMDogMHgyMTA0MDA4MCxcblx0ICAgICAgICAgICAgMHgxOTAwMDogMHgyMTAwMDAwMCxcblx0ICAgICAgICAgICAgMHgxYTAwMDogMHgxMDQwMDAwLFxuXHQgICAgICAgICAgICAweDFiMDAwOiAweDIwMDQwMDAwLFxuXHQgICAgICAgICAgICAweDFjMDAwOiAweDQwMDgwLFxuXHQgICAgICAgICAgICAweDFkMDAwOiAweDIwMDAwMDgwLFxuXHQgICAgICAgICAgICAweDFlMDAwOiAweDAsXG5cdCAgICAgICAgICAgIDB4MWYwMDA6IDB4MTA0MDA4MCxcblx0ICAgICAgICAgICAgMHgxMDgwMDogMHgyMTAwMDA4MCxcblx0ICAgICAgICAgICAgMHgxMTgwMDogMHgxMDAwMDAwLFxuXHQgICAgICAgICAgICAweDEyODAwOiAweDEwNDAwMDAsXG5cdCAgICAgICAgICAgIDB4MTM4MDA6IDB4MjAwNDAwODAsXG5cdCAgICAgICAgICAgIDB4MTQ4MDA6IDB4MjAwMDAwMDAsXG5cdCAgICAgICAgICAgIDB4MTU4MDA6IDB4MTA0MDA4MCxcblx0ICAgICAgICAgICAgMHgxNjgwMDogMHg4MCxcblx0ICAgICAgICAgICAgMHgxNzgwMDogMHgyMTA0MDAwMCxcblx0ICAgICAgICAgICAgMHgxODgwMDogMHg0MDA4MCxcblx0ICAgICAgICAgICAgMHgxOTgwMDogMHgyMTA0MDA4MCxcblx0ICAgICAgICAgICAgMHgxYTgwMDogMHgwLFxuXHQgICAgICAgICAgICAweDFiODAwOiAweDIxMDAwMDAwLFxuXHQgICAgICAgICAgICAweDFjODAwOiAweDEwMDAwODAsXG5cdCAgICAgICAgICAgIDB4MWQ4MDA6IDB4NDAwMDAsXG5cdCAgICAgICAgICAgIDB4MWU4MDA6IDB4MjAwNDAwMDAsXG5cdCAgICAgICAgICAgIDB4MWY4MDA6IDB4MjAwMDAwODBcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHtcblx0ICAgICAgICAgICAgMHgwOiAweDEwMDAwMDA4LFxuXHQgICAgICAgICAgICAweDEwMDogMHgyMDAwLFxuXHQgICAgICAgICAgICAweDIwMDogMHgxMDIwMDAwMCxcblx0ICAgICAgICAgICAgMHgzMDA6IDB4MTAyMDIwMDgsXG5cdCAgICAgICAgICAgIDB4NDAwOiAweDEwMDAyMDAwLFxuXHQgICAgICAgICAgICAweDUwMDogMHgyMDAwMDAsXG5cdCAgICAgICAgICAgIDB4NjAwOiAweDIwMDAwOCxcblx0ICAgICAgICAgICAgMHg3MDA6IDB4MTAwMDAwMDAsXG5cdCAgICAgICAgICAgIDB4ODAwOiAweDAsXG5cdCAgICAgICAgICAgIDB4OTAwOiAweDEwMDAyMDA4LFxuXHQgICAgICAgICAgICAweGEwMDogMHgyMDIwMDAsXG5cdCAgICAgICAgICAgIDB4YjAwOiAweDgsXG5cdCAgICAgICAgICAgIDB4YzAwOiAweDEwMjAwMDA4LFxuXHQgICAgICAgICAgICAweGQwMDogMHgyMDIwMDgsXG5cdCAgICAgICAgICAgIDB4ZTAwOiAweDIwMDgsXG5cdCAgICAgICAgICAgIDB4ZjAwOiAweDEwMjAyMDAwLFxuXHQgICAgICAgICAgICAweDgwOiAweDEwMjAwMDAwLFxuXHQgICAgICAgICAgICAweDE4MDogMHgxMDIwMjAwOCxcblx0ICAgICAgICAgICAgMHgyODA6IDB4OCxcblx0ICAgICAgICAgICAgMHgzODA6IDB4MjAwMDAwLFxuXHQgICAgICAgICAgICAweDQ4MDogMHgyMDIwMDgsXG5cdCAgICAgICAgICAgIDB4NTgwOiAweDEwMDAwMDA4LFxuXHQgICAgICAgICAgICAweDY4MDogMHgxMDAwMjAwMCxcblx0ICAgICAgICAgICAgMHg3ODA6IDB4MjAwOCxcblx0ICAgICAgICAgICAgMHg4ODA6IDB4MjAwMDA4LFxuXHQgICAgICAgICAgICAweDk4MDogMHgyMDAwLFxuXHQgICAgICAgICAgICAweGE4MDogMHgxMDAwMjAwOCxcblx0ICAgICAgICAgICAgMHhiODA6IDB4MTAyMDAwMDgsXG5cdCAgICAgICAgICAgIDB4YzgwOiAweDAsXG5cdCAgICAgICAgICAgIDB4ZDgwOiAweDEwMjAyMDAwLFxuXHQgICAgICAgICAgICAweGU4MDogMHgyMDIwMDAsXG5cdCAgICAgICAgICAgIDB4ZjgwOiAweDEwMDAwMDAwLFxuXHQgICAgICAgICAgICAweDEwMDA6IDB4MTAwMDIwMDAsXG5cdCAgICAgICAgICAgIDB4MTEwMDogMHgxMDIwMDAwOCxcblx0ICAgICAgICAgICAgMHgxMjAwOiAweDEwMjAyMDA4LFxuXHQgICAgICAgICAgICAweDEzMDA6IDB4MjAwOCxcblx0ICAgICAgICAgICAgMHgxNDAwOiAweDIwMDAwMCxcblx0ICAgICAgICAgICAgMHgxNTAwOiAweDEwMDAwMDAwLFxuXHQgICAgICAgICAgICAweDE2MDA6IDB4MTAwMDAwMDgsXG5cdCAgICAgICAgICAgIDB4MTcwMDogMHgyMDIwMDAsXG5cdCAgICAgICAgICAgIDB4MTgwMDogMHgyMDIwMDgsXG5cdCAgICAgICAgICAgIDB4MTkwMDogMHgwLFxuXHQgICAgICAgICAgICAweDFhMDA6IDB4OCxcblx0ICAgICAgICAgICAgMHgxYjAwOiAweDEwMjAwMDAwLFxuXHQgICAgICAgICAgICAweDFjMDA6IDB4MjAwMCxcblx0ICAgICAgICAgICAgMHgxZDAwOiAweDEwMDAyMDA4LFxuXHQgICAgICAgICAgICAweDFlMDA6IDB4MTAyMDIwMDAsXG5cdCAgICAgICAgICAgIDB4MWYwMDogMHgyMDAwMDgsXG5cdCAgICAgICAgICAgIDB4MTA4MDogMHg4LFxuXHQgICAgICAgICAgICAweDExODA6IDB4MjAyMDAwLFxuXHQgICAgICAgICAgICAweDEyODA6IDB4MjAwMDAwLFxuXHQgICAgICAgICAgICAweDEzODA6IDB4MTAwMDAwMDgsXG5cdCAgICAgICAgICAgIDB4MTQ4MDogMHgxMDAwMjAwMCxcblx0ICAgICAgICAgICAgMHgxNTgwOiAweDIwMDgsXG5cdCAgICAgICAgICAgIDB4MTY4MDogMHgxMDIwMjAwOCxcblx0ICAgICAgICAgICAgMHgxNzgwOiAweDEwMjAwMDAwLFxuXHQgICAgICAgICAgICAweDE4ODA6IDB4MTAyMDIwMDAsXG5cdCAgICAgICAgICAgIDB4MTk4MDogMHgxMDIwMDAwOCxcblx0ICAgICAgICAgICAgMHgxYTgwOiAweDIwMDAsXG5cdCAgICAgICAgICAgIDB4MWI4MDogMHgyMDIwMDgsXG5cdCAgICAgICAgICAgIDB4MWM4MDogMHgyMDAwMDgsXG5cdCAgICAgICAgICAgIDB4MWQ4MDogMHgwLFxuXHQgICAgICAgICAgICAweDFlODA6IDB4MTAwMDAwMDAsXG5cdCAgICAgICAgICAgIDB4MWY4MDogMHgxMDAwMjAwOFxuXHQgICAgICAgIH0sXG5cdCAgICAgICAge1xuXHQgICAgICAgICAgICAweDA6IDB4MTAwMDAwLFxuXHQgICAgICAgICAgICAweDEwOiAweDIwMDA0MDEsXG5cdCAgICAgICAgICAgIDB4MjA6IDB4NDAwLFxuXHQgICAgICAgICAgICAweDMwOiAweDEwMDQwMSxcblx0ICAgICAgICAgICAgMHg0MDogMHgyMTAwNDAxLFxuXHQgICAgICAgICAgICAweDUwOiAweDAsXG5cdCAgICAgICAgICAgIDB4NjA6IDB4MSxcblx0ICAgICAgICAgICAgMHg3MDogMHgyMTAwMDAxLFxuXHQgICAgICAgICAgICAweDgwOiAweDIwMDA0MDAsXG5cdCAgICAgICAgICAgIDB4OTA6IDB4MTAwMDAxLFxuXHQgICAgICAgICAgICAweGEwOiAweDIwMDAwMDEsXG5cdCAgICAgICAgICAgIDB4YjA6IDB4MjEwMDQwMCxcblx0ICAgICAgICAgICAgMHhjMDogMHgyMTAwMDAwLFxuXHQgICAgICAgICAgICAweGQwOiAweDQwMSxcblx0ICAgICAgICAgICAgMHhlMDogMHgxMDA0MDAsXG5cdCAgICAgICAgICAgIDB4ZjA6IDB4MjAwMDAwMCxcblx0ICAgICAgICAgICAgMHg4OiAweDIxMDAwMDEsXG5cdCAgICAgICAgICAgIDB4MTg6IDB4MCxcblx0ICAgICAgICAgICAgMHgyODogMHgyMDAwNDAxLFxuXHQgICAgICAgICAgICAweDM4OiAweDIxMDA0MDAsXG5cdCAgICAgICAgICAgIDB4NDg6IDB4MTAwMDAwLFxuXHQgICAgICAgICAgICAweDU4OiAweDIwMDAwMDEsXG5cdCAgICAgICAgICAgIDB4Njg6IDB4MjAwMDAwMCxcblx0ICAgICAgICAgICAgMHg3ODogMHg0MDEsXG5cdCAgICAgICAgICAgIDB4ODg6IDB4MTAwNDAxLFxuXHQgICAgICAgICAgICAweDk4OiAweDIwMDA0MDAsXG5cdCAgICAgICAgICAgIDB4YTg6IDB4MjEwMDAwMCxcblx0ICAgICAgICAgICAgMHhiODogMHgxMDAwMDEsXG5cdCAgICAgICAgICAgIDB4Yzg6IDB4NDAwLFxuXHQgICAgICAgICAgICAweGQ4OiAweDIxMDA0MDEsXG5cdCAgICAgICAgICAgIDB4ZTg6IDB4MSxcblx0ICAgICAgICAgICAgMHhmODogMHgxMDA0MDAsXG5cdCAgICAgICAgICAgIDB4MTAwOiAweDIwMDAwMDAsXG5cdCAgICAgICAgICAgIDB4MTEwOiAweDEwMDAwMCxcblx0ICAgICAgICAgICAgMHgxMjA6IDB4MjAwMDQwMSxcblx0ICAgICAgICAgICAgMHgxMzA6IDB4MjEwMDAwMSxcblx0ICAgICAgICAgICAgMHgxNDA6IDB4MTAwMDAxLFxuXHQgICAgICAgICAgICAweDE1MDogMHgyMDAwNDAwLFxuXHQgICAgICAgICAgICAweDE2MDogMHgyMTAwNDAwLFxuXHQgICAgICAgICAgICAweDE3MDogMHgxMDA0MDEsXG5cdCAgICAgICAgICAgIDB4MTgwOiAweDQwMSxcblx0ICAgICAgICAgICAgMHgxOTA6IDB4MjEwMDQwMSxcblx0ICAgICAgICAgICAgMHgxYTA6IDB4MTAwNDAwLFxuXHQgICAgICAgICAgICAweDFiMDogMHgxLFxuXHQgICAgICAgICAgICAweDFjMDogMHgwLFxuXHQgICAgICAgICAgICAweDFkMDogMHgyMTAwMDAwLFxuXHQgICAgICAgICAgICAweDFlMDogMHgyMDAwMDAxLFxuXHQgICAgICAgICAgICAweDFmMDogMHg0MDAsXG5cdCAgICAgICAgICAgIDB4MTA4OiAweDEwMDQwMCxcblx0ICAgICAgICAgICAgMHgxMTg6IDB4MjAwMDQwMSxcblx0ICAgICAgICAgICAgMHgxMjg6IDB4MjEwMDAwMSxcblx0ICAgICAgICAgICAgMHgxMzg6IDB4MSxcblx0ICAgICAgICAgICAgMHgxNDg6IDB4MjAwMDAwMCxcblx0ICAgICAgICAgICAgMHgxNTg6IDB4MTAwMDAwLFxuXHQgICAgICAgICAgICAweDE2ODogMHg0MDEsXG5cdCAgICAgICAgICAgIDB4MTc4OiAweDIxMDA0MDAsXG5cdCAgICAgICAgICAgIDB4MTg4OiAweDIwMDAwMDEsXG5cdCAgICAgICAgICAgIDB4MTk4OiAweDIxMDAwMDAsXG5cdCAgICAgICAgICAgIDB4MWE4OiAweDAsXG5cdCAgICAgICAgICAgIDB4MWI4OiAweDIxMDA0MDEsXG5cdCAgICAgICAgICAgIDB4MWM4OiAweDEwMDQwMSxcblx0ICAgICAgICAgICAgMHgxZDg6IDB4NDAwLFxuXHQgICAgICAgICAgICAweDFlODogMHgyMDAwNDAwLFxuXHQgICAgICAgICAgICAweDFmODogMHgxMDAwMDFcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHtcblx0ICAgICAgICAgICAgMHgwOiAweDgwMDA4MjAsXG5cdCAgICAgICAgICAgIDB4MTogMHgyMDAwMCxcblx0ICAgICAgICAgICAgMHgyOiAweDgwMDAwMDAsXG5cdCAgICAgICAgICAgIDB4MzogMHgyMCxcblx0ICAgICAgICAgICAgMHg0OiAweDIwMDIwLFxuXHQgICAgICAgICAgICAweDU6IDB4ODAyMDgyMCxcblx0ICAgICAgICAgICAgMHg2OiAweDgwMjA4MDAsXG5cdCAgICAgICAgICAgIDB4NzogMHg4MDAsXG5cdCAgICAgICAgICAgIDB4ODogMHg4MDIwMDAwLFxuXHQgICAgICAgICAgICAweDk6IDB4ODAwMDgwMCxcblx0ICAgICAgICAgICAgMHhhOiAweDIwODAwLFxuXHQgICAgICAgICAgICAweGI6IDB4ODAyMDAyMCxcblx0ICAgICAgICAgICAgMHhjOiAweDgyMCxcblx0ICAgICAgICAgICAgMHhkOiAweDAsXG5cdCAgICAgICAgICAgIDB4ZTogMHg4MDAwMDIwLFxuXHQgICAgICAgICAgICAweGY6IDB4MjA4MjAsXG5cdCAgICAgICAgICAgIDB4ODAwMDAwMDA6IDB4ODAwLFxuXHQgICAgICAgICAgICAweDgwMDAwMDAxOiAweDgwMjA4MjAsXG5cdCAgICAgICAgICAgIDB4ODAwMDAwMDI6IDB4ODAwMDgyMCxcblx0ICAgICAgICAgICAgMHg4MDAwMDAwMzogMHg4MDAwMDAwLFxuXHQgICAgICAgICAgICAweDgwMDAwMDA0OiAweDgwMjAwMDAsXG5cdCAgICAgICAgICAgIDB4ODAwMDAwMDU6IDB4MjA4MDAsXG5cdCAgICAgICAgICAgIDB4ODAwMDAwMDY6IDB4MjA4MjAsXG5cdCAgICAgICAgICAgIDB4ODAwMDAwMDc6IDB4MjAsXG5cdCAgICAgICAgICAgIDB4ODAwMDAwMDg6IDB4ODAwMDAyMCxcblx0ICAgICAgICAgICAgMHg4MDAwMDAwOTogMHg4MjAsXG5cdCAgICAgICAgICAgIDB4ODAwMDAwMGE6IDB4MjAwMjAsXG5cdCAgICAgICAgICAgIDB4ODAwMDAwMGI6IDB4ODAyMDgwMCxcblx0ICAgICAgICAgICAgMHg4MDAwMDAwYzogMHgwLFxuXHQgICAgICAgICAgICAweDgwMDAwMDBkOiAweDgwMjAwMjAsXG5cdCAgICAgICAgICAgIDB4ODAwMDAwMGU6IDB4ODAwMDgwMCxcblx0ICAgICAgICAgICAgMHg4MDAwMDAwZjogMHgyMDAwMCxcblx0ICAgICAgICAgICAgMHgxMDogMHgyMDgyMCxcblx0ICAgICAgICAgICAgMHgxMTogMHg4MDIwODAwLFxuXHQgICAgICAgICAgICAweDEyOiAweDIwLFxuXHQgICAgICAgICAgICAweDEzOiAweDgwMCxcblx0ICAgICAgICAgICAgMHgxNDogMHg4MDAwODAwLFxuXHQgICAgICAgICAgICAweDE1OiAweDgwMDAwMjAsXG5cdCAgICAgICAgICAgIDB4MTY6IDB4ODAyMDAyMCxcblx0ICAgICAgICAgICAgMHgxNzogMHgyMDAwMCxcblx0ICAgICAgICAgICAgMHgxODogMHgwLFxuXHQgICAgICAgICAgICAweDE5OiAweDIwMDIwLFxuXHQgICAgICAgICAgICAweDFhOiAweDgwMjAwMDAsXG5cdCAgICAgICAgICAgIDB4MWI6IDB4ODAwMDgyMCxcblx0ICAgICAgICAgICAgMHgxYzogMHg4MDIwODIwLFxuXHQgICAgICAgICAgICAweDFkOiAweDIwODAwLFxuXHQgICAgICAgICAgICAweDFlOiAweDgyMCxcblx0ICAgICAgICAgICAgMHgxZjogMHg4MDAwMDAwLFxuXHQgICAgICAgICAgICAweDgwMDAwMDEwOiAweDIwMDAwLFxuXHQgICAgICAgICAgICAweDgwMDAwMDExOiAweDgwMCxcblx0ICAgICAgICAgICAgMHg4MDAwMDAxMjogMHg4MDIwMDIwLFxuXHQgICAgICAgICAgICAweDgwMDAwMDEzOiAweDIwODIwLFxuXHQgICAgICAgICAgICAweDgwMDAwMDE0OiAweDIwLFxuXHQgICAgICAgICAgICAweDgwMDAwMDE1OiAweDgwMjAwMDAsXG5cdCAgICAgICAgICAgIDB4ODAwMDAwMTY6IDB4ODAwMDAwMCxcblx0ICAgICAgICAgICAgMHg4MDAwMDAxNzogMHg4MDAwODIwLFxuXHQgICAgICAgICAgICAweDgwMDAwMDE4OiAweDgwMjA4MjAsXG5cdCAgICAgICAgICAgIDB4ODAwMDAwMTk6IDB4ODAwMDAyMCxcblx0ICAgICAgICAgICAgMHg4MDAwMDAxYTogMHg4MDAwODAwLFxuXHQgICAgICAgICAgICAweDgwMDAwMDFiOiAweDAsXG5cdCAgICAgICAgICAgIDB4ODAwMDAwMWM6IDB4MjA4MDAsXG5cdCAgICAgICAgICAgIDB4ODAwMDAwMWQ6IDB4ODIwLFxuXHQgICAgICAgICAgICAweDgwMDAwMDFlOiAweDIwMDIwLFxuXHQgICAgICAgICAgICAweDgwMDAwMDFmOiAweDgwMjA4MDBcblx0ICAgICAgICB9XG5cdCAgICBdO1xuXG5cdCAgICAvLyBNYXNrcyB0aGF0IHNlbGVjdCB0aGUgU0JPWCBpbnB1dFxuXHQgICAgdmFyIFNCT1hfTUFTSyA9IFtcblx0ICAgICAgICAweGY4MDAwMDAxLCAweDFmODAwMDAwLCAweDAxZjgwMDAwLCAweDAwMWY4MDAwLFxuXHQgICAgICAgIDB4MDAwMWY4MDAsIDB4MDAwMDFmODAsIDB4MDAwMDAxZjgsIDB4ODAwMDAwMWZcblx0ICAgIF07XG5cblx0ICAgIC8qKlxuXHQgICAgICogREVTIGJsb2NrIGNpcGhlciBhbGdvcml0aG0uXG5cdCAgICAgKi9cblx0ICAgIHZhciBERVMgPSBDX2FsZ28uREVTID0gQmxvY2tDaXBoZXIuZXh0ZW5kKHtcblx0ICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGtleSA9IHRoaXMuX2tleTtcblx0ICAgICAgICAgICAgdmFyIGtleVdvcmRzID0ga2V5LndvcmRzO1xuXG5cdCAgICAgICAgICAgIC8vIFNlbGVjdCA1NiBiaXRzIGFjY29yZGluZyB0byBQQzFcblx0ICAgICAgICAgICAgdmFyIGtleUJpdHMgPSBbXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA1NjsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB2YXIga2V5Qml0UG9zID0gUEMxW2ldIC0gMTtcblx0ICAgICAgICAgICAgICAgIGtleUJpdHNbaV0gPSAoa2V5V29yZHNba2V5Qml0UG9zID4+PiA1XSA+Pj4gKDMxIC0ga2V5Qml0UG9zICUgMzIpKSAmIDE7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBBc3NlbWJsZSAxNiBzdWJrZXlzXG5cdCAgICAgICAgICAgIHZhciBzdWJLZXlzID0gdGhpcy5fc3ViS2V5cyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBuU3ViS2V5ID0gMDsgblN1YktleSA8IDE2OyBuU3ViS2V5KyspIHtcblx0ICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBzdWJrZXlcblx0ICAgICAgICAgICAgICAgIHZhciBzdWJLZXkgPSBzdWJLZXlzW25TdWJLZXldID0gW107XG5cblx0ICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgICAgICB2YXIgYml0U2hpZnQgPSBCSVRfU0hJRlRTW25TdWJLZXldO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBTZWxlY3QgNDggYml0cyBhY2NvcmRpbmcgdG8gUEMyXG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDI0OyBpKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICAvLyBTZWxlY3QgZnJvbSB0aGUgbGVmdCAyOCBrZXkgYml0c1xuXHQgICAgICAgICAgICAgICAgICAgIHN1YktleVsoaSAvIDYpIHwgMF0gfD0ga2V5Qml0c1soKFBDMltpXSAtIDEpICsgYml0U2hpZnQpICUgMjhdIDw8ICgzMSAtIGkgJSA2KTtcblxuXHQgICAgICAgICAgICAgICAgICAgIC8vIFNlbGVjdCBmcm9tIHRoZSByaWdodCAyOCBrZXkgYml0c1xuXHQgICAgICAgICAgICAgICAgICAgIHN1YktleVs0ICsgKChpIC8gNikgfCAwKV0gfD0ga2V5Qml0c1syOCArICgoKFBDMltpICsgMjRdIC0gMSkgKyBiaXRTaGlmdCkgJSAyOCldIDw8ICgzMSAtIGkgJSA2KTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgLy8gU2luY2UgZWFjaCBzdWJrZXkgaXMgYXBwbGllZCB0byBhbiBleHBhbmRlZCAzMi1iaXQgaW5wdXQsXG5cdCAgICAgICAgICAgICAgICAvLyB0aGUgc3Via2V5IGNhbiBiZSBicm9rZW4gaW50byA4IHZhbHVlcyBzY2FsZWQgdG8gMzItYml0cyxcblx0ICAgICAgICAgICAgICAgIC8vIHdoaWNoIGFsbG93cyB0aGUga2V5IHRvIGJlIHVzZWQgd2l0aG91dCBleHBhbnNpb25cblx0ICAgICAgICAgICAgICAgIHN1YktleVswXSA9IChzdWJLZXlbMF0gPDwgMSkgfCAoc3ViS2V5WzBdID4+PiAzMSk7XG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IDc7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgICAgIHN1YktleVtpXSA9IHN1YktleVtpXSA+Pj4gKChpIC0gMSkgKiA0ICsgMyk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICBzdWJLZXlbN10gPSAoc3ViS2V5WzddIDw8IDUpIHwgKHN1YktleVs3XSA+Pj4gMjcpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0ZSBpbnZlcnNlIHN1YmtleXNcblx0ICAgICAgICAgICAgdmFyIGludlN1YktleXMgPSB0aGlzLl9pbnZTdWJLZXlzID0gW107XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgaW52U3ViS2V5c1tpXSA9IHN1YktleXNbMTUgLSBpXTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBlbmNyeXB0QmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgdGhpcy5fZG9DcnlwdEJsb2NrKE0sIG9mZnNldCwgdGhpcy5fc3ViS2V5cyk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGRlY3J5cHRCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCkge1xuXHQgICAgICAgICAgICB0aGlzLl9kb0NyeXB0QmxvY2soTSwgb2Zmc2V0LCB0aGlzLl9pbnZTdWJLZXlzKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvQ3J5cHRCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCwgc3ViS2V5cykge1xuXHQgICAgICAgICAgICAvLyBHZXQgaW5wdXRcblx0ICAgICAgICAgICAgdGhpcy5fbEJsb2NrID0gTVtvZmZzZXRdO1xuXHQgICAgICAgICAgICB0aGlzLl9yQmxvY2sgPSBNW29mZnNldCArIDFdO1xuXG5cdCAgICAgICAgICAgIC8vIEluaXRpYWwgcGVybXV0YXRpb25cblx0ICAgICAgICAgICAgZXhjaGFuZ2VMUi5jYWxsKHRoaXMsIDQsICAweDBmMGYwZjBmKTtcblx0ICAgICAgICAgICAgZXhjaGFuZ2VMUi5jYWxsKHRoaXMsIDE2LCAweDAwMDBmZmZmKTtcblx0ICAgICAgICAgICAgZXhjaGFuZ2VSTC5jYWxsKHRoaXMsIDIsICAweDMzMzMzMzMzKTtcblx0ICAgICAgICAgICAgZXhjaGFuZ2VSTC5jYWxsKHRoaXMsIDgsICAweDAwZmYwMGZmKTtcblx0ICAgICAgICAgICAgZXhjaGFuZ2VMUi5jYWxsKHRoaXMsIDEsICAweDU1NTU1NTU1KTtcblxuXHQgICAgICAgICAgICAvLyBSb3VuZHNcblx0ICAgICAgICAgICAgZm9yICh2YXIgcm91bmQgPSAwOyByb3VuZCA8IDE2OyByb3VuZCsrKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgICAgIHZhciBzdWJLZXkgPSBzdWJLZXlzW3JvdW5kXTtcblx0ICAgICAgICAgICAgICAgIHZhciBsQmxvY2sgPSB0aGlzLl9sQmxvY2s7XG5cdCAgICAgICAgICAgICAgICB2YXIgckJsb2NrID0gdGhpcy5fckJsb2NrO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBGZWlzdGVsIGZ1bmN0aW9uXG5cdCAgICAgICAgICAgICAgICB2YXIgZiA9IDA7XG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDg7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgICAgIGYgfD0gU0JPWF9QW2ldWygockJsb2NrIF4gc3ViS2V5W2ldKSAmIFNCT1hfTUFTS1tpXSkgPj4+IDBdO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgdGhpcy5fbEJsb2NrID0gckJsb2NrO1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fckJsb2NrID0gbEJsb2NrIF4gZjtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIFVuZG8gc3dhcCBmcm9tIGxhc3Qgcm91bmRcblx0ICAgICAgICAgICAgdmFyIHQgPSB0aGlzLl9sQmxvY2s7XG5cdCAgICAgICAgICAgIHRoaXMuX2xCbG9jayA9IHRoaXMuX3JCbG9jaztcblx0ICAgICAgICAgICAgdGhpcy5fckJsb2NrID0gdDtcblxuXHQgICAgICAgICAgICAvLyBGaW5hbCBwZXJtdXRhdGlvblxuXHQgICAgICAgICAgICBleGNoYW5nZUxSLmNhbGwodGhpcywgMSwgIDB4NTU1NTU1NTUpO1xuXHQgICAgICAgICAgICBleGNoYW5nZVJMLmNhbGwodGhpcywgOCwgIDB4MDBmZjAwZmYpO1xuXHQgICAgICAgICAgICBleGNoYW5nZVJMLmNhbGwodGhpcywgMiwgIDB4MzMzMzMzMzMpO1xuXHQgICAgICAgICAgICBleGNoYW5nZUxSLmNhbGwodGhpcywgMTYsIDB4MDAwMGZmZmYpO1xuXHQgICAgICAgICAgICBleGNoYW5nZUxSLmNhbGwodGhpcywgNCwgIDB4MGYwZjBmMGYpO1xuXG5cdCAgICAgICAgICAgIC8vIFNldCBvdXRwdXRcblx0ICAgICAgICAgICAgTVtvZmZzZXRdID0gdGhpcy5fbEJsb2NrO1xuXHQgICAgICAgICAgICBNW29mZnNldCArIDFdID0gdGhpcy5fckJsb2NrO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBrZXlTaXplOiA2NC8zMixcblxuXHQgICAgICAgIGl2U2l6ZTogNjQvMzIsXG5cblx0ICAgICAgICBibG9ja1NpemU6IDY0LzMyXG5cdCAgICB9KTtcblxuXHQgICAgLy8gU3dhcCBiaXRzIGFjcm9zcyB0aGUgbGVmdCBhbmQgcmlnaHQgd29yZHNcblx0ICAgIGZ1bmN0aW9uIGV4Y2hhbmdlTFIob2Zmc2V0LCBtYXNrKSB7XG5cdCAgICAgICAgdmFyIHQgPSAoKHRoaXMuX2xCbG9jayA+Pj4gb2Zmc2V0KSBeIHRoaXMuX3JCbG9jaykgJiBtYXNrO1xuXHQgICAgICAgIHRoaXMuX3JCbG9jayBePSB0O1xuXHQgICAgICAgIHRoaXMuX2xCbG9jayBePSB0IDw8IG9mZnNldDtcblx0ICAgIH1cblxuXHQgICAgZnVuY3Rpb24gZXhjaGFuZ2VSTChvZmZzZXQsIG1hc2spIHtcblx0ICAgICAgICB2YXIgdCA9ICgodGhpcy5fckJsb2NrID4+PiBvZmZzZXQpIF4gdGhpcy5fbEJsb2NrKSAmIG1hc2s7XG5cdCAgICAgICAgdGhpcy5fbEJsb2NrIF49IHQ7XG5cdCAgICAgICAgdGhpcy5fckJsb2NrIF49IHQgPDwgb2Zmc2V0O1xuXHQgICAgfVxuXG5cdCAgICAvKipcblx0ICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9ucyB0byB0aGUgY2lwaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgY2lwaGVydGV4dCA9IENyeXB0b0pTLkRFUy5lbmNyeXB0KG1lc3NhZ2UsIGtleSwgY2ZnKTtcblx0ICAgICAqICAgICB2YXIgcGxhaW50ZXh0ICA9IENyeXB0b0pTLkRFUy5kZWNyeXB0KGNpcGhlcnRleHQsIGtleSwgY2ZnKTtcblx0ICAgICAqL1xuXHQgICAgQy5ERVMgPSBCbG9ja0NpcGhlci5fY3JlYXRlSGVscGVyKERFUyk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogVHJpcGxlLURFUyBibG9jayBjaXBoZXIgYWxnb3JpdGhtLlxuXHQgICAgICovXG5cdCAgICB2YXIgVHJpcGxlREVTID0gQ19hbGdvLlRyaXBsZURFUyA9IEJsb2NrQ2lwaGVyLmV4dGVuZCh7XG5cdCAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBrZXkgPSB0aGlzLl9rZXk7XG5cdCAgICAgICAgICAgIHZhciBrZXlXb3JkcyA9IGtleS53b3Jkcztcblx0ICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHRoZSBrZXkgbGVuZ3RoIGlzIHZhbGlkICg2NCwgMTI4IG9yID49IDE5MiBiaXQpXG5cdCAgICAgICAgICAgIGlmIChrZXlXb3Jkcy5sZW5ndGggIT09IDIgJiYga2V5V29yZHMubGVuZ3RoICE9PSA0ICYmIGtleVdvcmRzLmxlbmd0aCA8IDYpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBrZXkgbGVuZ3RoIC0gM0RFUyByZXF1aXJlcyB0aGUga2V5IGxlbmd0aCB0byBiZSA2NCwgMTI4LCAxOTIgb3IgPjE5Mi4nKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIEV4dGVuZCB0aGUga2V5IGFjY29yZGluZyB0byB0aGUga2V5aW5nIG9wdGlvbnMgZGVmaW5lZCBpbiAzREVTIHN0YW5kYXJkXG5cdCAgICAgICAgICAgIHZhciBrZXkxID0ga2V5V29yZHMuc2xpY2UoMCwgMik7XG5cdCAgICAgICAgICAgIHZhciBrZXkyID0ga2V5V29yZHMubGVuZ3RoIDwgNCA/IGtleVdvcmRzLnNsaWNlKDAsIDIpIDoga2V5V29yZHMuc2xpY2UoMiwgNCk7XG5cdCAgICAgICAgICAgIHZhciBrZXkzID0ga2V5V29yZHMubGVuZ3RoIDwgNiA/IGtleVdvcmRzLnNsaWNlKDAsIDIpIDoga2V5V29yZHMuc2xpY2UoNCwgNik7XG5cblx0ICAgICAgICAgICAgLy8gQ3JlYXRlIERFUyBpbnN0YW5jZXNcblx0ICAgICAgICAgICAgdGhpcy5fZGVzMSA9IERFUy5jcmVhdGVFbmNyeXB0b3IoV29yZEFycmF5LmNyZWF0ZShrZXkxKSk7XG5cdCAgICAgICAgICAgIHRoaXMuX2RlczIgPSBERVMuY3JlYXRlRW5jcnlwdG9yKFdvcmRBcnJheS5jcmVhdGUoa2V5MikpO1xuXHQgICAgICAgICAgICB0aGlzLl9kZXMzID0gREVTLmNyZWF0ZUVuY3J5cHRvcihXb3JkQXJyYXkuY3JlYXRlKGtleTMpKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgZW5jcnlwdEJsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2RlczEuZW5jcnlwdEJsb2NrKE0sIG9mZnNldCk7XG5cdCAgICAgICAgICAgIHRoaXMuX2RlczIuZGVjcnlwdEJsb2NrKE0sIG9mZnNldCk7XG5cdCAgICAgICAgICAgIHRoaXMuX2RlczMuZW5jcnlwdEJsb2NrKE0sIG9mZnNldCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGRlY3J5cHRCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCkge1xuXHQgICAgICAgICAgICB0aGlzLl9kZXMzLmRlY3J5cHRCbG9jayhNLCBvZmZzZXQpO1xuXHQgICAgICAgICAgICB0aGlzLl9kZXMyLmVuY3J5cHRCbG9jayhNLCBvZmZzZXQpO1xuXHQgICAgICAgICAgICB0aGlzLl9kZXMxLmRlY3J5cHRCbG9jayhNLCBvZmZzZXQpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBrZXlTaXplOiAxOTIvMzIsXG5cblx0ICAgICAgICBpdlNpemU6IDY0LzMyLFxuXG5cdCAgICAgICAgYmxvY2tTaXplOiA2NC8zMlxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogU2hvcnRjdXQgZnVuY3Rpb25zIHRvIHRoZSBjaXBoZXIncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0ID0gQ3J5cHRvSlMuVHJpcGxlREVTLmVuY3J5cHQobWVzc2FnZSwga2V5LCBjZmcpO1xuXHQgICAgICogICAgIHZhciBwbGFpbnRleHQgID0gQ3J5cHRvSlMuVHJpcGxlREVTLmRlY3J5cHQoY2lwaGVydGV4dCwga2V5LCBjZmcpO1xuXHQgICAgICovXG5cdCAgICBDLlRyaXBsZURFUyA9IEJsb2NrQ2lwaGVyLl9jcmVhdGVIZWxwZXIoVHJpcGxlREVTKTtcblx0fSgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUy5UcmlwbGVERVM7XG5cbn0pKTsiLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XG5cdGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xuXHRcdC8vIENvbW1vbkpTXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKFwiLi9jb3JlXCIpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAodW5kZWZpbmVkKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBCYXNlID0gQ19saWIuQmFzZTtcblx0ICAgIHZhciBYMzJXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogeDY0IG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfeDY0ID0gQy54NjQgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBIDY0LWJpdCB3b3JkLlxuXHQgICAgICovXG5cdCAgICB2YXIgWDY0V29yZCA9IENfeDY0LldvcmQgPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIDY0LWJpdCB3b3JkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGhpZ2ggVGhlIGhpZ2ggMzIgYml0cy5cblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gbG93IFRoZSBsb3cgMzIgYml0cy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHg2NFdvcmQgPSBDcnlwdG9KUy54NjQuV29yZC5jcmVhdGUoMHgwMDAxMDIwMywgMHgwNDA1MDYwNyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgaW5pdDogZnVuY3Rpb24gKGhpZ2gsIGxvdykge1xuXHQgICAgICAgICAgICB0aGlzLmhpZ2ggPSBoaWdoO1xuXHQgICAgICAgICAgICB0aGlzLmxvdyA9IGxvdztcblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBCaXR3aXNlIE5PVHMgdGhpcyB3b3JkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7WDY0V29yZH0gQSBuZXcgeDY0LVdvcmQgb2JqZWN0IGFmdGVyIG5lZ2F0aW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgbmVnYXRlZCA9IHg2NFdvcmQubm90KCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgLy8gbm90OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIHZhciBoaWdoID0gfnRoaXMuaGlnaDtcblx0ICAgICAgICAgICAgLy8gdmFyIGxvdyA9IH50aGlzLmxvdztcblxuXHQgICAgICAgICAgICAvLyByZXR1cm4gWDY0V29yZC5jcmVhdGUoaGlnaCwgbG93KTtcblx0ICAgICAgICAvLyB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQml0d2lzZSBBTkRzIHRoaXMgd29yZCB3aXRoIHRoZSBwYXNzZWQgd29yZC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7WDY0V29yZH0gd29yZCBUaGUgeDY0LVdvcmQgdG8gQU5EIHdpdGggdGhpcyB3b3JkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7WDY0V29yZH0gQSBuZXcgeDY0LVdvcmQgb2JqZWN0IGFmdGVyIEFORGluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGFuZGVkID0geDY0V29yZC5hbmQoYW5vdGhlclg2NFdvcmQpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIC8vIGFuZDogZnVuY3Rpb24gKHdvcmQpIHtcblx0ICAgICAgICAgICAgLy8gdmFyIGhpZ2ggPSB0aGlzLmhpZ2ggJiB3b3JkLmhpZ2g7XG5cdCAgICAgICAgICAgIC8vIHZhciBsb3cgPSB0aGlzLmxvdyAmIHdvcmQubG93O1xuXG5cdCAgICAgICAgICAgIC8vIHJldHVybiBYNjRXb3JkLmNyZWF0ZShoaWdoLCBsb3cpO1xuXHQgICAgICAgIC8vIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBCaXR3aXNlIE9ScyB0aGlzIHdvcmQgd2l0aCB0aGUgcGFzc2VkIHdvcmQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1g2NFdvcmR9IHdvcmQgVGhlIHg2NC1Xb3JkIHRvIE9SIHdpdGggdGhpcyB3b3JkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7WDY0V29yZH0gQSBuZXcgeDY0LVdvcmQgb2JqZWN0IGFmdGVyIE9SaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgb3JlZCA9IHg2NFdvcmQub3IoYW5vdGhlclg2NFdvcmQpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIC8vIG9yOiBmdW5jdGlvbiAod29yZCkge1xuXHQgICAgICAgICAgICAvLyB2YXIgaGlnaCA9IHRoaXMuaGlnaCB8IHdvcmQuaGlnaDtcblx0ICAgICAgICAgICAgLy8gdmFyIGxvdyA9IHRoaXMubG93IHwgd29yZC5sb3c7XG5cblx0ICAgICAgICAgICAgLy8gcmV0dXJuIFg2NFdvcmQuY3JlYXRlKGhpZ2gsIGxvdyk7XG5cdCAgICAgICAgLy8gfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEJpdHdpc2UgWE9ScyB0aGlzIHdvcmQgd2l0aCB0aGUgcGFzc2VkIHdvcmQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1g2NFdvcmR9IHdvcmQgVGhlIHg2NC1Xb3JkIHRvIFhPUiB3aXRoIHRoaXMgd29yZC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge1g2NFdvcmR9IEEgbmV3IHg2NC1Xb3JkIG9iamVjdCBhZnRlciBYT1JpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciB4b3JlZCA9IHg2NFdvcmQueG9yKGFub3RoZXJYNjRXb3JkKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICAvLyB4b3I6IGZ1bmN0aW9uICh3b3JkKSB7XG5cdCAgICAgICAgICAgIC8vIHZhciBoaWdoID0gdGhpcy5oaWdoIF4gd29yZC5oaWdoO1xuXHQgICAgICAgICAgICAvLyB2YXIgbG93ID0gdGhpcy5sb3cgXiB3b3JkLmxvdztcblxuXHQgICAgICAgICAgICAvLyByZXR1cm4gWDY0V29yZC5jcmVhdGUoaGlnaCwgbG93KTtcblx0ICAgICAgICAvLyB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogU2hpZnRzIHRoaXMgd29yZCBuIGJpdHMgdG8gdGhlIGxlZnQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIGJpdHMgdG8gc2hpZnQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtYNjRXb3JkfSBBIG5ldyB4NjQtV29yZCBvYmplY3QgYWZ0ZXIgc2hpZnRpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBzaGlmdGVkID0geDY0V29yZC5zaGlmdEwoMjUpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIC8vIHNoaWZ0TDogZnVuY3Rpb24gKG4pIHtcblx0ICAgICAgICAgICAgLy8gaWYgKG4gPCAzMikge1xuXHQgICAgICAgICAgICAgICAgLy8gdmFyIGhpZ2ggPSAodGhpcy5oaWdoIDw8IG4pIHwgKHRoaXMubG93ID4+PiAoMzIgLSBuKSk7XG5cdCAgICAgICAgICAgICAgICAvLyB2YXIgbG93ID0gdGhpcy5sb3cgPDwgbjtcblx0ICAgICAgICAgICAgLy8gfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIC8vIHZhciBoaWdoID0gdGhpcy5sb3cgPDwgKG4gLSAzMik7XG5cdCAgICAgICAgICAgICAgICAvLyB2YXIgbG93ID0gMDtcblx0ICAgICAgICAgICAgLy8gfVxuXG5cdCAgICAgICAgICAgIC8vIHJldHVybiBYNjRXb3JkLmNyZWF0ZShoaWdoLCBsb3cpO1xuXHQgICAgICAgIC8vIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBTaGlmdHMgdGhpcyB3b3JkIG4gYml0cyB0byB0aGUgcmlnaHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIGJpdHMgdG8gc2hpZnQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtYNjRXb3JkfSBBIG5ldyB4NjQtV29yZCBvYmplY3QgYWZ0ZXIgc2hpZnRpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBzaGlmdGVkID0geDY0V29yZC5zaGlmdFIoNyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgLy8gc2hpZnRSOiBmdW5jdGlvbiAobikge1xuXHQgICAgICAgICAgICAvLyBpZiAobiA8IDMyKSB7XG5cdCAgICAgICAgICAgICAgICAvLyB2YXIgbG93ID0gKHRoaXMubG93ID4+PiBuKSB8ICh0aGlzLmhpZ2ggPDwgKDMyIC0gbikpO1xuXHQgICAgICAgICAgICAgICAgLy8gdmFyIGhpZ2ggPSB0aGlzLmhpZ2ggPj4+IG47XG5cdCAgICAgICAgICAgIC8vIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAvLyB2YXIgbG93ID0gdGhpcy5oaWdoID4+PiAobiAtIDMyKTtcblx0ICAgICAgICAgICAgICAgIC8vIHZhciBoaWdoID0gMDtcblx0ICAgICAgICAgICAgLy8gfVxuXG5cdCAgICAgICAgICAgIC8vIHJldHVybiBYNjRXb3JkLmNyZWF0ZShoaWdoLCBsb3cpO1xuXHQgICAgICAgIC8vIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBSb3RhdGVzIHRoaXMgd29yZCBuIGJpdHMgdG8gdGhlIGxlZnQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIGJpdHMgdG8gcm90YXRlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7WDY0V29yZH0gQSBuZXcgeDY0LVdvcmQgb2JqZWN0IGFmdGVyIHJvdGF0aW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgcm90YXRlZCA9IHg2NFdvcmQucm90TCgyNSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgLy8gcm90TDogZnVuY3Rpb24gKG4pIHtcblx0ICAgICAgICAgICAgLy8gcmV0dXJuIHRoaXMuc2hpZnRMKG4pLm9yKHRoaXMuc2hpZnRSKDY0IC0gbikpO1xuXHQgICAgICAgIC8vIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBSb3RhdGVzIHRoaXMgd29yZCBuIGJpdHMgdG8gdGhlIHJpZ2h0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHJvdGF0ZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge1g2NFdvcmR9IEEgbmV3IHg2NC1Xb3JkIG9iamVjdCBhZnRlciByb3RhdGluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHJvdGF0ZWQgPSB4NjRXb3JkLnJvdFIoNyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgLy8gcm90UjogZnVuY3Rpb24gKG4pIHtcblx0ICAgICAgICAgICAgLy8gcmV0dXJuIHRoaXMuc2hpZnRSKG4pLm9yKHRoaXMuc2hpZnRMKDY0IC0gbikpO1xuXHQgICAgICAgIC8vIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBBZGRzIHRoaXMgd29yZCB3aXRoIHRoZSBwYXNzZWQgd29yZC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7WDY0V29yZH0gd29yZCBUaGUgeDY0LVdvcmQgdG8gYWRkIHdpdGggdGhpcyB3b3JkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7WDY0V29yZH0gQSBuZXcgeDY0LVdvcmQgb2JqZWN0IGFmdGVyIGFkZGluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGFkZGVkID0geDY0V29yZC5hZGQoYW5vdGhlclg2NFdvcmQpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIC8vIGFkZDogZnVuY3Rpb24gKHdvcmQpIHtcblx0ICAgICAgICAgICAgLy8gdmFyIGxvdyA9ICh0aGlzLmxvdyArIHdvcmQubG93KSB8IDA7XG5cdCAgICAgICAgICAgIC8vIHZhciBjYXJyeSA9IChsb3cgPj4+IDApIDwgKHRoaXMubG93ID4+PiAwKSA/IDEgOiAwO1xuXHQgICAgICAgICAgICAvLyB2YXIgaGlnaCA9ICh0aGlzLmhpZ2ggKyB3b3JkLmhpZ2ggKyBjYXJyeSkgfCAwO1xuXG5cdCAgICAgICAgICAgIC8vIHJldHVybiBYNjRXb3JkLmNyZWF0ZShoaWdoLCBsb3cpO1xuXHQgICAgICAgIC8vIH1cblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEFuIGFycmF5IG9mIDY0LWJpdCB3b3Jkcy5cblx0ICAgICAqXG5cdCAgICAgKiBAcHJvcGVydHkge0FycmF5fSB3b3JkcyBUaGUgYXJyYXkgb2YgQ3J5cHRvSlMueDY0LldvcmQgb2JqZWN0cy5cblx0ICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBzaWdCeXRlcyBUaGUgbnVtYmVyIG9mIHNpZ25pZmljYW50IGJ5dGVzIGluIHRoaXMgd29yZCBhcnJheS5cblx0ICAgICAqL1xuXHQgICAgdmFyIFg2NFdvcmRBcnJheSA9IENfeDY0LldvcmRBcnJheSA9IEJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ld2x5IGNyZWF0ZWQgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IHdvcmRzIChPcHRpb25hbCkgQW4gYXJyYXkgb2YgQ3J5cHRvSlMueDY0LldvcmQgb2JqZWN0cy5cblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gc2lnQnl0ZXMgKE9wdGlvbmFsKSBUaGUgbnVtYmVyIG9mIHNpZ25pZmljYW50IGJ5dGVzIGluIHRoZSB3b3Jkcy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLng2NC5Xb3JkQXJyYXkuY3JlYXRlKCk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLng2NC5Xb3JkQXJyYXkuY3JlYXRlKFtcblx0ICAgICAgICAgKiAgICAgICAgIENyeXB0b0pTLng2NC5Xb3JkLmNyZWF0ZSgweDAwMDEwMjAzLCAweDA0MDUwNjA3KSxcblx0ICAgICAgICAgKiAgICAgICAgIENyeXB0b0pTLng2NC5Xb3JkLmNyZWF0ZSgweDE4MTkxYTFiLCAweDFjMWQxZTFmKVxuXHQgICAgICAgICAqICAgICBdKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMueDY0LldvcmRBcnJheS5jcmVhdGUoW1xuXHQgICAgICAgICAqICAgICAgICAgQ3J5cHRvSlMueDY0LldvcmQuY3JlYXRlKDB4MDAwMTAyMDMsIDB4MDQwNTA2MDcpLFxuXHQgICAgICAgICAqICAgICAgICAgQ3J5cHRvSlMueDY0LldvcmQuY3JlYXRlKDB4MTgxOTFhMWIsIDB4MWMxZDFlMWYpXG5cdCAgICAgICAgICogICAgIF0sIDEwKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAod29yZHMsIHNpZ0J5dGVzKSB7XG5cdCAgICAgICAgICAgIHdvcmRzID0gdGhpcy53b3JkcyA9IHdvcmRzIHx8IFtdO1xuXG5cdCAgICAgICAgICAgIGlmIChzaWdCeXRlcyAhPSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgPSBzaWdCeXRlcztcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgPSB3b3Jkcy5sZW5ndGggKiA4O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIHRoaXMgNjQtYml0IHdvcmQgYXJyYXkgdG8gYSAzMi1iaXQgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge0NyeXB0b0pTLmxpYi5Xb3JkQXJyYXl9IFRoaXMgd29yZCBhcnJheSdzIGRhdGEgYXMgYSAzMi1iaXQgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHgzMldvcmRBcnJheSA9IHg2NFdvcmRBcnJheS50b1gzMigpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHRvWDMyOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgeDY0V29yZHMgPSB0aGlzLndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgeDY0V29yZHNMZW5ndGggPSB4NjRXb3Jkcy5sZW5ndGg7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydFxuXHQgICAgICAgICAgICB2YXIgeDMyV29yZHMgPSBbXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB4NjRXb3Jkc0xlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgeDY0V29yZCA9IHg2NFdvcmRzW2ldO1xuXHQgICAgICAgICAgICAgICAgeDMyV29yZHMucHVzaCh4NjRXb3JkLmhpZ2gpO1xuXHQgICAgICAgICAgICAgICAgeDMyV29yZHMucHVzaCh4NjRXb3JkLmxvdyk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gWDMyV29yZEFycmF5LmNyZWF0ZSh4MzJXb3JkcywgdGhpcy5zaWdCeXRlcyk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENyZWF0ZXMgYSBjb3B5IG9mIHRoaXMgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge1g2NFdvcmRBcnJheX0gVGhlIGNsb25lLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgY2xvbmUgPSB4NjRXb3JkQXJyYXkuY2xvbmUoKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgY2xvbmUgPSBCYXNlLmNsb25lLmNhbGwodGhpcyk7XG5cblx0ICAgICAgICAgICAgLy8gQ2xvbmUgXCJ3b3Jkc1wiIGFycmF5XG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IGNsb25lLndvcmRzID0gdGhpcy53b3Jkcy5zbGljZSgwKTtcblxuXHQgICAgICAgICAgICAvLyBDbG9uZSBlYWNoIFg2NFdvcmQgb2JqZWN0XG5cdCAgICAgICAgICAgIHZhciB3b3Jkc0xlbmd0aCA9IHdvcmRzLmxlbmd0aDtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB3b3Jkc0xlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB3b3Jkc1tpXSA9IHdvcmRzW2ldLmNsb25lKCk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gY2xvbmU7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdH0oKSk7XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlM7XG5cbn0pKTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMudXRpbHMgPSByZXF1aXJlKCcuL2Rlcy91dGlscycpO1xuZXhwb3J0cy5DaXBoZXIgPSByZXF1aXJlKCcuL2Rlcy9jaXBoZXInKTtcbmV4cG9ydHMuREVTID0gcmVxdWlyZSgnLi9kZXMvZGVzJyk7XG5leHBvcnRzLkNCQyA9IHJlcXVpcmUoJy4vZGVzL2NiYycpO1xuZXhwb3J0cy5FREUgPSByZXF1aXJlKCcuL2Rlcy9lZGUnKTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbnZhciBwcm90byA9IHt9O1xuXG5mdW5jdGlvbiBDQkNTdGF0ZShpdikge1xuICBhc3NlcnQuZXF1YWwoaXYubGVuZ3RoLCA4LCAnSW52YWxpZCBJViBsZW5ndGgnKTtcblxuICB0aGlzLml2ID0gbmV3IEFycmF5KDgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuaXYubGVuZ3RoOyBpKyspXG4gICAgdGhpcy5pdltpXSA9IGl2W2ldO1xufVxuXG5mdW5jdGlvbiBpbnN0YW50aWF0ZShCYXNlKSB7XG4gIGZ1bmN0aW9uIENCQyhvcHRpb25zKSB7XG4gICAgQmFzZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuICAgIHRoaXMuX2NiY0luaXQoKTtcbiAgfVxuICBpbmhlcml0cyhDQkMsIEJhc2UpO1xuXG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvdG8pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICBDQkMucHJvdG90eXBlW2tleV0gPSBwcm90b1trZXldO1xuICB9XG5cbiAgQ0JDLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShvcHRpb25zKSB7XG4gICAgcmV0dXJuIG5ldyBDQkMob3B0aW9ucyk7XG4gIH07XG5cbiAgcmV0dXJuIENCQztcbn1cblxuZXhwb3J0cy5pbnN0YW50aWF0ZSA9IGluc3RhbnRpYXRlO1xuXG5wcm90by5fY2JjSW5pdCA9IGZ1bmN0aW9uIF9jYmNJbml0KCkge1xuICB2YXIgc3RhdGUgPSBuZXcgQ0JDU3RhdGUodGhpcy5vcHRpb25zLml2KTtcbiAgdGhpcy5fY2JjU3RhdGUgPSBzdGF0ZTtcbn07XG5cbnByb3RvLl91cGRhdGUgPSBmdW5jdGlvbiBfdXBkYXRlKGlucCwgaW5PZmYsIG91dCwgb3V0T2ZmKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2NiY1N0YXRlO1xuICB2YXIgc3VwZXJQcm90byA9IHRoaXMuY29uc3RydWN0b3Iuc3VwZXJfLnByb3RvdHlwZTtcblxuICB2YXIgaXYgPSBzdGF0ZS5pdjtcbiAgaWYgKHRoaXMudHlwZSA9PT0gJ2VuY3J5cHQnKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJsb2NrU2l6ZTsgaSsrKVxuICAgICAgaXZbaV0gXj0gaW5wW2luT2ZmICsgaV07XG5cbiAgICBzdXBlclByb3RvLl91cGRhdGUuY2FsbCh0aGlzLCBpdiwgMCwgb3V0LCBvdXRPZmYpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJsb2NrU2l6ZTsgaSsrKVxuICAgICAgaXZbaV0gPSBvdXRbb3V0T2ZmICsgaV07XG4gIH0gZWxzZSB7XG4gICAgc3VwZXJQcm90by5fdXBkYXRlLmNhbGwodGhpcywgaW5wLCBpbk9mZiwgb3V0LCBvdXRPZmYpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJsb2NrU2l6ZTsgaSsrKVxuICAgICAgb3V0W291dE9mZiArIGldIF49IGl2W2ldO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJsb2NrU2l6ZTsgaSsrKVxuICAgICAgaXZbaV0gPSBpbnBbaW5PZmYgKyBpXTtcbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcblxuZnVuY3Rpb24gQ2lwaGVyKG9wdGlvbnMpIHtcbiAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcblxuICB0aGlzLnR5cGUgPSB0aGlzLm9wdGlvbnMudHlwZTtcbiAgdGhpcy5ibG9ja1NpemUgPSA4O1xuICB0aGlzLl9pbml0KCk7XG5cbiAgdGhpcy5idWZmZXIgPSBuZXcgQXJyYXkodGhpcy5ibG9ja1NpemUpO1xuICB0aGlzLmJ1ZmZlck9mZiA9IDA7XG59XG5tb2R1bGUuZXhwb3J0cyA9IENpcGhlcjtcblxuQ2lwaGVyLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uIF9pbml0KCkge1xuICAvLyBNaWdodCBiZSBvdmVycmlkZWRcbn07XG5cbkNpcGhlci5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKGRhdGEpIHtcbiAgaWYgKGRhdGEubGVuZ3RoID09PSAwKVxuICAgIHJldHVybiBbXTtcblxuICBpZiAodGhpcy50eXBlID09PSAnZGVjcnlwdCcpXG4gICAgcmV0dXJuIHRoaXMuX3VwZGF0ZURlY3J5cHQoZGF0YSk7XG4gIGVsc2VcbiAgICByZXR1cm4gdGhpcy5fdXBkYXRlRW5jcnlwdChkYXRhKTtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuX2J1ZmZlciA9IGZ1bmN0aW9uIF9idWZmZXIoZGF0YSwgb2ZmKSB7XG4gIC8vIEFwcGVuZCBkYXRhIHRvIGJ1ZmZlclxuICB2YXIgbWluID0gTWF0aC5taW4odGhpcy5idWZmZXIubGVuZ3RoIC0gdGhpcy5idWZmZXJPZmYsIGRhdGEubGVuZ3RoIC0gb2ZmKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtaW47IGkrKylcbiAgICB0aGlzLmJ1ZmZlclt0aGlzLmJ1ZmZlck9mZiArIGldID0gZGF0YVtvZmYgKyBpXTtcbiAgdGhpcy5idWZmZXJPZmYgKz0gbWluO1xuXG4gIC8vIFNoaWZ0IG5leHRcbiAgcmV0dXJuIG1pbjtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuX2ZsdXNoQnVmZmVyID0gZnVuY3Rpb24gX2ZsdXNoQnVmZmVyKG91dCwgb2ZmKSB7XG4gIHRoaXMuX3VwZGF0ZSh0aGlzLmJ1ZmZlciwgMCwgb3V0LCBvZmYpO1xuICB0aGlzLmJ1ZmZlck9mZiA9IDA7XG4gIHJldHVybiB0aGlzLmJsb2NrU2l6ZTtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuX3VwZGF0ZUVuY3J5cHQgPSBmdW5jdGlvbiBfdXBkYXRlRW5jcnlwdChkYXRhKSB7XG4gIHZhciBpbnB1dE9mZiA9IDA7XG4gIHZhciBvdXRwdXRPZmYgPSAwO1xuXG4gIHZhciBjb3VudCA9ICgodGhpcy5idWZmZXJPZmYgKyBkYXRhLmxlbmd0aCkgLyB0aGlzLmJsb2NrU2l6ZSkgfCAwO1xuICB2YXIgb3V0ID0gbmV3IEFycmF5KGNvdW50ICogdGhpcy5ibG9ja1NpemUpO1xuXG4gIGlmICh0aGlzLmJ1ZmZlck9mZiAhPT0gMCkge1xuICAgIGlucHV0T2ZmICs9IHRoaXMuX2J1ZmZlcihkYXRhLCBpbnB1dE9mZik7XG5cbiAgICBpZiAodGhpcy5idWZmZXJPZmYgPT09IHRoaXMuYnVmZmVyLmxlbmd0aClcbiAgICAgIG91dHB1dE9mZiArPSB0aGlzLl9mbHVzaEJ1ZmZlcihvdXQsIG91dHB1dE9mZik7XG4gIH1cblxuICAvLyBXcml0ZSBibG9ja3NcbiAgdmFyIG1heCA9IGRhdGEubGVuZ3RoIC0gKChkYXRhLmxlbmd0aCAtIGlucHV0T2ZmKSAlIHRoaXMuYmxvY2tTaXplKTtcbiAgZm9yICg7IGlucHV0T2ZmIDwgbWF4OyBpbnB1dE9mZiArPSB0aGlzLmJsb2NrU2l6ZSkge1xuICAgIHRoaXMuX3VwZGF0ZShkYXRhLCBpbnB1dE9mZiwgb3V0LCBvdXRwdXRPZmYpO1xuICAgIG91dHB1dE9mZiArPSB0aGlzLmJsb2NrU2l6ZTtcbiAgfVxuXG4gIC8vIFF1ZXVlIHJlc3RcbiAgZm9yICg7IGlucHV0T2ZmIDwgZGF0YS5sZW5ndGg7IGlucHV0T2ZmKyssIHRoaXMuYnVmZmVyT2ZmKyspXG4gICAgdGhpcy5idWZmZXJbdGhpcy5idWZmZXJPZmZdID0gZGF0YVtpbnB1dE9mZl07XG5cbiAgcmV0dXJuIG91dDtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuX3VwZGF0ZURlY3J5cHQgPSBmdW5jdGlvbiBfdXBkYXRlRGVjcnlwdChkYXRhKSB7XG4gIHZhciBpbnB1dE9mZiA9IDA7XG4gIHZhciBvdXRwdXRPZmYgPSAwO1xuXG4gIHZhciBjb3VudCA9IE1hdGguY2VpbCgodGhpcy5idWZmZXJPZmYgKyBkYXRhLmxlbmd0aCkgLyB0aGlzLmJsb2NrU2l6ZSkgLSAxO1xuICB2YXIgb3V0ID0gbmV3IEFycmF5KGNvdW50ICogdGhpcy5ibG9ja1NpemUpO1xuXG4gIC8vIFRPRE8oaW5kdXRueSk6IG9wdGltaXplIGl0LCB0aGlzIGlzIGZhciBmcm9tIG9wdGltYWxcbiAgZm9yICg7IGNvdW50ID4gMDsgY291bnQtLSkge1xuICAgIGlucHV0T2ZmICs9IHRoaXMuX2J1ZmZlcihkYXRhLCBpbnB1dE9mZik7XG4gICAgb3V0cHV0T2ZmICs9IHRoaXMuX2ZsdXNoQnVmZmVyKG91dCwgb3V0cHV0T2ZmKTtcbiAgfVxuXG4gIC8vIEJ1ZmZlciByZXN0IG9mIHRoZSBpbnB1dFxuICBpbnB1dE9mZiArPSB0aGlzLl9idWZmZXIoZGF0YSwgaW5wdXRPZmYpO1xuXG4gIHJldHVybiBvdXQ7XG59O1xuXG5DaXBoZXIucHJvdG90eXBlLmZpbmFsID0gZnVuY3Rpb24gZmluYWwoYnVmZmVyKSB7XG4gIHZhciBmaXJzdDtcbiAgaWYgKGJ1ZmZlcilcbiAgICBmaXJzdCA9IHRoaXMudXBkYXRlKGJ1ZmZlcik7XG5cbiAgdmFyIGxhc3Q7XG4gIGlmICh0aGlzLnR5cGUgPT09ICdlbmNyeXB0JylcbiAgICBsYXN0ID0gdGhpcy5fZmluYWxFbmNyeXB0KCk7XG4gIGVsc2VcbiAgICBsYXN0ID0gdGhpcy5fZmluYWxEZWNyeXB0KCk7XG5cbiAgaWYgKGZpcnN0KVxuICAgIHJldHVybiBmaXJzdC5jb25jYXQobGFzdCk7XG4gIGVsc2VcbiAgICByZXR1cm4gbGFzdDtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuX3BhZCA9IGZ1bmN0aW9uIF9wYWQoYnVmZmVyLCBvZmYpIHtcbiAgaWYgKG9mZiA9PT0gMClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgd2hpbGUgKG9mZiA8IGJ1ZmZlci5sZW5ndGgpXG4gICAgYnVmZmVyW29mZisrXSA9IDA7XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5DaXBoZXIucHJvdG90eXBlLl9maW5hbEVuY3J5cHQgPSBmdW5jdGlvbiBfZmluYWxFbmNyeXB0KCkge1xuICBpZiAoIXRoaXMuX3BhZCh0aGlzLmJ1ZmZlciwgdGhpcy5idWZmZXJPZmYpKVxuICAgIHJldHVybiBbXTtcblxuICB2YXIgb3V0ID0gbmV3IEFycmF5KHRoaXMuYmxvY2tTaXplKTtcbiAgdGhpcy5fdXBkYXRlKHRoaXMuYnVmZmVyLCAwLCBvdXQsIDApO1xuICByZXR1cm4gb3V0O1xufTtcblxuQ2lwaGVyLnByb3RvdHlwZS5fdW5wYWQgPSBmdW5jdGlvbiBfdW5wYWQoYnVmZmVyKSB7XG4gIHJldHVybiBidWZmZXI7XG59O1xuXG5DaXBoZXIucHJvdG90eXBlLl9maW5hbERlY3J5cHQgPSBmdW5jdGlvbiBfZmluYWxEZWNyeXB0KCkge1xuICBhc3NlcnQuZXF1YWwodGhpcy5idWZmZXJPZmYsIHRoaXMuYmxvY2tTaXplLCAnTm90IGVub3VnaCBkYXRhIHRvIGRlY3J5cHQnKTtcbiAgdmFyIG91dCA9IG5ldyBBcnJheSh0aGlzLmJsb2NrU2l6ZSk7XG4gIHRoaXMuX2ZsdXNoQnVmZmVyKG91dCwgMCk7XG5cbiAgcmV0dXJuIHRoaXMuX3VucGFkKG91dCk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxudmFyIGRlcyA9IHJlcXVpcmUoJy4uL2RlcycpO1xudmFyIHV0aWxzID0gZGVzLnV0aWxzO1xudmFyIENpcGhlciA9IGRlcy5DaXBoZXI7XG5cbmZ1bmN0aW9uIERFU1N0YXRlKCkge1xuICB0aGlzLnRtcCA9IG5ldyBBcnJheSgyKTtcbiAgdGhpcy5rZXlzID0gbnVsbDtcbn1cblxuZnVuY3Rpb24gREVTKG9wdGlvbnMpIHtcbiAgQ2lwaGVyLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgdmFyIHN0YXRlID0gbmV3IERFU1N0YXRlKCk7XG4gIHRoaXMuX2Rlc1N0YXRlID0gc3RhdGU7XG5cbiAgdGhpcy5kZXJpdmVLZXlzKHN0YXRlLCBvcHRpb25zLmtleSk7XG59XG5pbmhlcml0cyhERVMsIENpcGhlcik7XG5tb2R1bGUuZXhwb3J0cyA9IERFUztcblxuREVTLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShvcHRpb25zKSB7XG4gIHJldHVybiBuZXcgREVTKG9wdGlvbnMpO1xufTtcblxudmFyIHNoaWZ0VGFibGUgPSBbXG4gIDEsIDEsIDIsIDIsIDIsIDIsIDIsIDIsXG4gIDEsIDIsIDIsIDIsIDIsIDIsIDIsIDFcbl07XG5cbkRFUy5wcm90b3R5cGUuZGVyaXZlS2V5cyA9IGZ1bmN0aW9uIGRlcml2ZUtleXMoc3RhdGUsIGtleSkge1xuICBzdGF0ZS5rZXlzID0gbmV3IEFycmF5KDE2ICogMik7XG5cbiAgYXNzZXJ0LmVxdWFsKGtleS5sZW5ndGgsIHRoaXMuYmxvY2tTaXplLCAnSW52YWxpZCBrZXkgbGVuZ3RoJyk7XG5cbiAgdmFyIGtMID0gdXRpbHMucmVhZFVJbnQzMkJFKGtleSwgMCk7XG4gIHZhciBrUiA9IHV0aWxzLnJlYWRVSW50MzJCRShrZXksIDQpO1xuXG4gIHV0aWxzLnBjMShrTCwga1IsIHN0YXRlLnRtcCwgMCk7XG4gIGtMID0gc3RhdGUudG1wWzBdO1xuICBrUiA9IHN0YXRlLnRtcFsxXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdGF0ZS5rZXlzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgdmFyIHNoaWZ0ID0gc2hpZnRUYWJsZVtpID4+PiAxXTtcbiAgICBrTCA9IHV0aWxzLnIyOHNobChrTCwgc2hpZnQpO1xuICAgIGtSID0gdXRpbHMucjI4c2hsKGtSLCBzaGlmdCk7XG4gICAgdXRpbHMucGMyKGtMLCBrUiwgc3RhdGUua2V5cywgaSk7XG4gIH1cbn07XG5cbkRFUy5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUoaW5wLCBpbk9mZiwgb3V0LCBvdXRPZmYpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fZGVzU3RhdGU7XG5cbiAgdmFyIGwgPSB1dGlscy5yZWFkVUludDMyQkUoaW5wLCBpbk9mZik7XG4gIHZhciByID0gdXRpbHMucmVhZFVJbnQzMkJFKGlucCwgaW5PZmYgKyA0KTtcblxuICAvLyBJbml0aWFsIFBlcm11dGF0aW9uXG4gIHV0aWxzLmlwKGwsIHIsIHN0YXRlLnRtcCwgMCk7XG4gIGwgPSBzdGF0ZS50bXBbMF07XG4gIHIgPSBzdGF0ZS50bXBbMV07XG5cbiAgaWYgKHRoaXMudHlwZSA9PT0gJ2VuY3J5cHQnKVxuICAgIHRoaXMuX2VuY3J5cHQoc3RhdGUsIGwsIHIsIHN0YXRlLnRtcCwgMCk7XG4gIGVsc2VcbiAgICB0aGlzLl9kZWNyeXB0KHN0YXRlLCBsLCByLCBzdGF0ZS50bXAsIDApO1xuXG4gIGwgPSBzdGF0ZS50bXBbMF07XG4gIHIgPSBzdGF0ZS50bXBbMV07XG5cbiAgdXRpbHMud3JpdGVVSW50MzJCRShvdXQsIGwsIG91dE9mZik7XG4gIHV0aWxzLndyaXRlVUludDMyQkUob3V0LCByLCBvdXRPZmYgKyA0KTtcbn07XG5cbkRFUy5wcm90b3R5cGUuX3BhZCA9IGZ1bmN0aW9uIF9wYWQoYnVmZmVyLCBvZmYpIHtcbiAgdmFyIHZhbHVlID0gYnVmZmVyLmxlbmd0aCAtIG9mZjtcbiAgZm9yICh2YXIgaSA9IG9mZjsgaSA8IGJ1ZmZlci5sZW5ndGg7IGkrKylcbiAgICBidWZmZXJbaV0gPSB2YWx1ZTtcblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkRFUy5wcm90b3R5cGUuX3VucGFkID0gZnVuY3Rpb24gX3VucGFkKGJ1ZmZlcikge1xuICB2YXIgcGFkID0gYnVmZmVyW2J1ZmZlci5sZW5ndGggLSAxXTtcbiAgZm9yICh2YXIgaSA9IGJ1ZmZlci5sZW5ndGggLSBwYWQ7IGkgPCBidWZmZXIubGVuZ3RoOyBpKyspXG4gICAgYXNzZXJ0LmVxdWFsKGJ1ZmZlcltpXSwgcGFkKTtcblxuICByZXR1cm4gYnVmZmVyLnNsaWNlKDAsIGJ1ZmZlci5sZW5ndGggLSBwYWQpO1xufTtcblxuREVTLnByb3RvdHlwZS5fZW5jcnlwdCA9IGZ1bmN0aW9uIF9lbmNyeXB0KHN0YXRlLCBsU3RhcnQsIHJTdGFydCwgb3V0LCBvZmYpIHtcbiAgdmFyIGwgPSBsU3RhcnQ7XG4gIHZhciByID0gclN0YXJ0O1xuXG4gIC8vIEFwcGx5IGYoKSB4MTYgdGltZXNcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdGF0ZS5rZXlzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgdmFyIGtleUwgPSBzdGF0ZS5rZXlzW2ldO1xuICAgIHZhciBrZXlSID0gc3RhdGUua2V5c1tpICsgMV07XG5cbiAgICAvLyBmKHIsIGspXG4gICAgdXRpbHMuZXhwYW5kKHIsIHN0YXRlLnRtcCwgMCk7XG5cbiAgICBrZXlMIF49IHN0YXRlLnRtcFswXTtcbiAgICBrZXlSIF49IHN0YXRlLnRtcFsxXTtcbiAgICB2YXIgcyA9IHV0aWxzLnN1YnN0aXR1dGUoa2V5TCwga2V5Uik7XG4gICAgdmFyIGYgPSB1dGlscy5wZXJtdXRlKHMpO1xuXG4gICAgdmFyIHQgPSByO1xuICAgIHIgPSAobCBeIGYpID4+PiAwO1xuICAgIGwgPSB0O1xuICB9XG5cbiAgLy8gUmV2ZXJzZSBJbml0aWFsIFBlcm11dGF0aW9uXG4gIHV0aWxzLnJpcChyLCBsLCBvdXQsIG9mZik7XG59O1xuXG5ERVMucHJvdG90eXBlLl9kZWNyeXB0ID0gZnVuY3Rpb24gX2RlY3J5cHQoc3RhdGUsIGxTdGFydCwgclN0YXJ0LCBvdXQsIG9mZikge1xuICB2YXIgbCA9IHJTdGFydDtcbiAgdmFyIHIgPSBsU3RhcnQ7XG5cbiAgLy8gQXBwbHkgZigpIHgxNiB0aW1lc1xuICBmb3IgKHZhciBpID0gc3RhdGUua2V5cy5sZW5ndGggLSAyOyBpID49IDA7IGkgLT0gMikge1xuICAgIHZhciBrZXlMID0gc3RhdGUua2V5c1tpXTtcbiAgICB2YXIga2V5UiA9IHN0YXRlLmtleXNbaSArIDFdO1xuXG4gICAgLy8gZihyLCBrKVxuICAgIHV0aWxzLmV4cGFuZChsLCBzdGF0ZS50bXAsIDApO1xuXG4gICAga2V5TCBePSBzdGF0ZS50bXBbMF07XG4gICAga2V5UiBePSBzdGF0ZS50bXBbMV07XG4gICAgdmFyIHMgPSB1dGlscy5zdWJzdGl0dXRlKGtleUwsIGtleVIpO1xuICAgIHZhciBmID0gdXRpbHMucGVybXV0ZShzKTtcblxuICAgIHZhciB0ID0gbDtcbiAgICBsID0gKHIgXiBmKSA+Pj4gMDtcbiAgICByID0gdDtcbiAgfVxuXG4gIC8vIFJldmVyc2UgSW5pdGlhbCBQZXJtdXRhdGlvblxuICB1dGlscy5yaXAobCwgciwgb3V0LCBvZmYpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbnZhciBkZXMgPSByZXF1aXJlKCcuLi9kZXMnKTtcbnZhciBDaXBoZXIgPSBkZXMuQ2lwaGVyO1xudmFyIERFUyA9IGRlcy5ERVM7XG5cbmZ1bmN0aW9uIEVERVN0YXRlKHR5cGUsIGtleSkge1xuICBhc3NlcnQuZXF1YWwoa2V5Lmxlbmd0aCwgMjQsICdJbnZhbGlkIGtleSBsZW5ndGgnKTtcblxuICB2YXIgazEgPSBrZXkuc2xpY2UoMCwgOCk7XG4gIHZhciBrMiA9IGtleS5zbGljZSg4LCAxNik7XG4gIHZhciBrMyA9IGtleS5zbGljZSgxNiwgMjQpO1xuXG4gIGlmICh0eXBlID09PSAnZW5jcnlwdCcpIHtcbiAgICB0aGlzLmNpcGhlcnMgPSBbXG4gICAgICBERVMuY3JlYXRlKHsgdHlwZTogJ2VuY3J5cHQnLCBrZXk6IGsxIH0pLFxuICAgICAgREVTLmNyZWF0ZSh7IHR5cGU6ICdkZWNyeXB0Jywga2V5OiBrMiB9KSxcbiAgICAgIERFUy5jcmVhdGUoeyB0eXBlOiAnZW5jcnlwdCcsIGtleTogazMgfSlcbiAgICBdO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuY2lwaGVycyA9IFtcbiAgICAgIERFUy5jcmVhdGUoeyB0eXBlOiAnZGVjcnlwdCcsIGtleTogazMgfSksXG4gICAgICBERVMuY3JlYXRlKHsgdHlwZTogJ2VuY3J5cHQnLCBrZXk6IGsyIH0pLFxuICAgICAgREVTLmNyZWF0ZSh7IHR5cGU6ICdkZWNyeXB0Jywga2V5OiBrMSB9KVxuICAgIF07XG4gIH1cbn1cblxuZnVuY3Rpb24gRURFKG9wdGlvbnMpIHtcbiAgQ2lwaGVyLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgdmFyIHN0YXRlID0gbmV3IEVERVN0YXRlKHRoaXMudHlwZSwgdGhpcy5vcHRpb25zLmtleSk7XG4gIHRoaXMuX2VkZVN0YXRlID0gc3RhdGU7XG59XG5pbmhlcml0cyhFREUsIENpcGhlcik7XG5cbm1vZHVsZS5leHBvcnRzID0gRURFO1xuXG5FREUuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKG9wdGlvbnMpIHtcbiAgcmV0dXJuIG5ldyBFREUob3B0aW9ucyk7XG59O1xuXG5FREUucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiBfdXBkYXRlKGlucCwgaW5PZmYsIG91dCwgb3V0T2ZmKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2VkZVN0YXRlO1xuXG4gIHN0YXRlLmNpcGhlcnNbMF0uX3VwZGF0ZShpbnAsIGluT2ZmLCBvdXQsIG91dE9mZik7XG4gIHN0YXRlLmNpcGhlcnNbMV0uX3VwZGF0ZShvdXQsIG91dE9mZiwgb3V0LCBvdXRPZmYpO1xuICBzdGF0ZS5jaXBoZXJzWzJdLl91cGRhdGUob3V0LCBvdXRPZmYsIG91dCwgb3V0T2ZmKTtcbn07XG5cbkVERS5wcm90b3R5cGUuX3BhZCA9IERFUy5wcm90b3R5cGUuX3BhZDtcbkVERS5wcm90b3R5cGUuX3VucGFkID0gREVTLnByb3RvdHlwZS5fdW5wYWQ7XG4iLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkJFKGJ5dGVzLCBvZmYpIHtcbiAgdmFyIHJlcyA9ICAoYnl0ZXNbMCArIG9mZl0gPDwgMjQpIHxcbiAgICAgICAgICAgICAoYnl0ZXNbMSArIG9mZl0gPDwgMTYpIHxcbiAgICAgICAgICAgICAoYnl0ZXNbMiArIG9mZl0gPDwgOCkgfFxuICAgICAgICAgICAgIGJ5dGVzWzMgKyBvZmZdO1xuICByZXR1cm4gcmVzID4+PiAwO1xufTtcblxuZXhwb3J0cy53cml0ZVVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJCRShieXRlcywgdmFsdWUsIG9mZikge1xuICBieXRlc1swICsgb2ZmXSA9IHZhbHVlID4+PiAyNDtcbiAgYnl0ZXNbMSArIG9mZl0gPSAodmFsdWUgPj4+IDE2KSAmIDB4ZmY7XG4gIGJ5dGVzWzIgKyBvZmZdID0gKHZhbHVlID4+PiA4KSAmIDB4ZmY7XG4gIGJ5dGVzWzMgKyBvZmZdID0gdmFsdWUgJiAweGZmO1xufTtcblxuZXhwb3J0cy5pcCA9IGZ1bmN0aW9uIGlwKGluTCwgaW5SLCBvdXQsIG9mZikge1xuICB2YXIgb3V0TCA9IDA7XG4gIHZhciBvdXRSID0gMDtcblxuICBmb3IgKHZhciBpID0gNjsgaSA+PSAwOyBpIC09IDIpIHtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8PSAyNDsgaiArPSA4KSB7XG4gICAgICBvdXRMIDw8PSAxO1xuICAgICAgb3V0TCB8PSAoaW5SID4+PiAoaiArIGkpKSAmIDE7XG4gICAgfVxuICAgIGZvciAodmFyIGogPSAwOyBqIDw9IDI0OyBqICs9IDgpIHtcbiAgICAgIG91dEwgPDw9IDE7XG4gICAgICBvdXRMIHw9IChpbkwgPj4+IChqICsgaSkpICYgMTtcbiAgICB9XG4gIH1cblxuICBmb3IgKHZhciBpID0gNjsgaSA+PSAwOyBpIC09IDIpIHtcbiAgICBmb3IgKHZhciBqID0gMTsgaiA8PSAyNTsgaiArPSA4KSB7XG4gICAgICBvdXRSIDw8PSAxO1xuICAgICAgb3V0UiB8PSAoaW5SID4+PiAoaiArIGkpKSAmIDE7XG4gICAgfVxuICAgIGZvciAodmFyIGogPSAxOyBqIDw9IDI1OyBqICs9IDgpIHtcbiAgICAgIG91dFIgPDw9IDE7XG4gICAgICBvdXRSIHw9IChpbkwgPj4+IChqICsgaSkpICYgMTtcbiAgICB9XG4gIH1cblxuICBvdXRbb2ZmICsgMF0gPSBvdXRMID4+PiAwO1xuICBvdXRbb2ZmICsgMV0gPSBvdXRSID4+PiAwO1xufTtcblxuZXhwb3J0cy5yaXAgPSBmdW5jdGlvbiByaXAoaW5MLCBpblIsIG91dCwgb2ZmKSB7XG4gIHZhciBvdXRMID0gMDtcbiAgdmFyIG91dFIgPSAwO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgZm9yICh2YXIgaiA9IDI0OyBqID49IDA7IGogLT0gOCkge1xuICAgICAgb3V0TCA8PD0gMTtcbiAgICAgIG91dEwgfD0gKGluUiA+Pj4gKGogKyBpKSkgJiAxO1xuICAgICAgb3V0TCA8PD0gMTtcbiAgICAgIG91dEwgfD0gKGluTCA+Pj4gKGogKyBpKSkgJiAxO1xuICAgIH1cbiAgfVxuICBmb3IgKHZhciBpID0gNDsgaSA8IDg7IGkrKykge1xuICAgIGZvciAodmFyIGogPSAyNDsgaiA+PSAwOyBqIC09IDgpIHtcbiAgICAgIG91dFIgPDw9IDE7XG4gICAgICBvdXRSIHw9IChpblIgPj4+IChqICsgaSkpICYgMTtcbiAgICAgIG91dFIgPDw9IDE7XG4gICAgICBvdXRSIHw9IChpbkwgPj4+IChqICsgaSkpICYgMTtcbiAgICB9XG4gIH1cblxuICBvdXRbb2ZmICsgMF0gPSBvdXRMID4+PiAwO1xuICBvdXRbb2ZmICsgMV0gPSBvdXRSID4+PiAwO1xufTtcblxuZXhwb3J0cy5wYzEgPSBmdW5jdGlvbiBwYzEoaW5MLCBpblIsIG91dCwgb2ZmKSB7XG4gIHZhciBvdXRMID0gMDtcbiAgdmFyIG91dFIgPSAwO1xuXG4gIC8vIDcsIDE1LCAyMywgMzEsIDM5LCA0NywgNTUsIDYzXG4gIC8vIDYsIDE0LCAyMiwgMzAsIDM5LCA0NywgNTUsIDYzXG4gIC8vIDUsIDEzLCAyMSwgMjksIDM5LCA0NywgNTUsIDYzXG4gIC8vIDQsIDEyLCAyMCwgMjhcbiAgZm9yICh2YXIgaSA9IDc7IGkgPj0gNTsgaS0tKSB7XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPD0gMjQ7IGogKz0gOCkge1xuICAgICAgb3V0TCA8PD0gMTtcbiAgICAgIG91dEwgfD0gKGluUiA+PiAoaiArIGkpKSAmIDE7XG4gICAgfVxuICAgIGZvciAodmFyIGogPSAwOyBqIDw9IDI0OyBqICs9IDgpIHtcbiAgICAgIG91dEwgPDw9IDE7XG4gICAgICBvdXRMIHw9IChpbkwgPj4gKGogKyBpKSkgJiAxO1xuICAgIH1cbiAgfVxuICBmb3IgKHZhciBqID0gMDsgaiA8PSAyNDsgaiArPSA4KSB7XG4gICAgb3V0TCA8PD0gMTtcbiAgICBvdXRMIHw9IChpblIgPj4gKGogKyBpKSkgJiAxO1xuICB9XG5cbiAgLy8gMSwgOSwgMTcsIDI1LCAzMywgNDEsIDQ5LCA1N1xuICAvLyAyLCAxMCwgMTgsIDI2LCAzNCwgNDIsIDUwLCA1OFxuICAvLyAzLCAxMSwgMTksIDI3LCAzNSwgNDMsIDUxLCA1OVxuICAvLyAzNiwgNDQsIDUyLCA2MFxuICBmb3IgKHZhciBpID0gMTsgaSA8PSAzOyBpKyspIHtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8PSAyNDsgaiArPSA4KSB7XG4gICAgICBvdXRSIDw8PSAxO1xuICAgICAgb3V0UiB8PSAoaW5SID4+IChqICsgaSkpICYgMTtcbiAgICB9XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPD0gMjQ7IGogKz0gOCkge1xuICAgICAgb3V0UiA8PD0gMTtcbiAgICAgIG91dFIgfD0gKGluTCA+PiAoaiArIGkpKSAmIDE7XG4gICAgfVxuICB9XG4gIGZvciAodmFyIGogPSAwOyBqIDw9IDI0OyBqICs9IDgpIHtcbiAgICBvdXRSIDw8PSAxO1xuICAgIG91dFIgfD0gKGluTCA+PiAoaiArIGkpKSAmIDE7XG4gIH1cblxuICBvdXRbb2ZmICsgMF0gPSBvdXRMID4+PiAwO1xuICBvdXRbb2ZmICsgMV0gPSBvdXRSID4+PiAwO1xufTtcblxuZXhwb3J0cy5yMjhzaGwgPSBmdW5jdGlvbiByMjhzaGwobnVtLCBzaGlmdCkge1xuICByZXR1cm4gKChudW0gPDwgc2hpZnQpICYgMHhmZmZmZmZmKSB8IChudW0gPj4+ICgyOCAtIHNoaWZ0KSk7XG59O1xuXG52YXIgcGMydGFibGUgPSBbXG4gIC8vIGluTCA9PiBvdXRMXG4gIDE0LCAxMSwgMTcsIDQsIDI3LCAyMywgMjUsIDAsXG4gIDEzLCAyMiwgNywgMTgsIDUsIDksIDE2LCAyNCxcbiAgMiwgMjAsIDEyLCAyMSwgMSwgOCwgMTUsIDI2LFxuXG4gIC8vIGluUiA9PiBvdXRSXG4gIDE1LCA0LCAyNSwgMTksIDksIDEsIDI2LCAxNixcbiAgNSwgMTEsIDIzLCA4LCAxMiwgNywgMTcsIDAsXG4gIDIyLCAzLCAxMCwgMTQsIDYsIDIwLCAyNywgMjRcbl07XG5cbmV4cG9ydHMucGMyID0gZnVuY3Rpb24gcGMyKGluTCwgaW5SLCBvdXQsIG9mZikge1xuICB2YXIgb3V0TCA9IDA7XG4gIHZhciBvdXRSID0gMDtcblxuICB2YXIgbGVuID0gcGMydGFibGUubGVuZ3RoID4+PiAxO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgb3V0TCA8PD0gMTtcbiAgICBvdXRMIHw9IChpbkwgPj4+IHBjMnRhYmxlW2ldKSAmIDB4MTtcbiAgfVxuICBmb3IgKHZhciBpID0gbGVuOyBpIDwgcGMydGFibGUubGVuZ3RoOyBpKyspIHtcbiAgICBvdXRSIDw8PSAxO1xuICAgIG91dFIgfD0gKGluUiA+Pj4gcGMydGFibGVbaV0pICYgMHgxO1xuICB9XG5cbiAgb3V0W29mZiArIDBdID0gb3V0TCA+Pj4gMDtcbiAgb3V0W29mZiArIDFdID0gb3V0UiA+Pj4gMDtcbn07XG5cbmV4cG9ydHMuZXhwYW5kID0gZnVuY3Rpb24gZXhwYW5kKHIsIG91dCwgb2ZmKSB7XG4gIHZhciBvdXRMID0gMDtcbiAgdmFyIG91dFIgPSAwO1xuXG4gIG91dEwgPSAoKHIgJiAxKSA8PCA1KSB8IChyID4+PiAyNyk7XG4gIGZvciAodmFyIGkgPSAyMzsgaSA+PSAxNTsgaSAtPSA0KSB7XG4gICAgb3V0TCA8PD0gNjtcbiAgICBvdXRMIHw9IChyID4+PiBpKSAmIDB4M2Y7XG4gIH1cbiAgZm9yICh2YXIgaSA9IDExOyBpID49IDM7IGkgLT0gNCkge1xuICAgIG91dFIgfD0gKHIgPj4+IGkpICYgMHgzZjtcbiAgICBvdXRSIDw8PSA2O1xuICB9XG4gIG91dFIgfD0gKChyICYgMHgxZikgPDwgMSkgfCAociA+Pj4gMzEpO1xuXG4gIG91dFtvZmYgKyAwXSA9IG91dEwgPj4+IDA7XG4gIG91dFtvZmYgKyAxXSA9IG91dFIgPj4+IDA7XG59O1xuXG52YXIgc1RhYmxlID0gW1xuICAxNCwgMCwgNCwgMTUsIDEzLCA3LCAxLCA0LCAyLCAxNCwgMTUsIDIsIDExLCAxMywgOCwgMSxcbiAgMywgMTAsIDEwLCA2LCA2LCAxMiwgMTIsIDExLCA1LCA5LCA5LCA1LCAwLCAzLCA3LCA4LFxuICA0LCAxNSwgMSwgMTIsIDE0LCA4LCA4LCAyLCAxMywgNCwgNiwgOSwgMiwgMSwgMTEsIDcsXG4gIDE1LCA1LCAxMiwgMTEsIDksIDMsIDcsIDE0LCAzLCAxMCwgMTAsIDAsIDUsIDYsIDAsIDEzLFxuXG4gIDE1LCAzLCAxLCAxMywgOCwgNCwgMTQsIDcsIDYsIDE1LCAxMSwgMiwgMywgOCwgNCwgMTQsXG4gIDksIDEyLCA3LCAwLCAyLCAxLCAxMywgMTAsIDEyLCA2LCAwLCA5LCA1LCAxMSwgMTAsIDUsXG4gIDAsIDEzLCAxNCwgOCwgNywgMTAsIDExLCAxLCAxMCwgMywgNCwgMTUsIDEzLCA0LCAxLCAyLFxuICA1LCAxMSwgOCwgNiwgMTIsIDcsIDYsIDEyLCA5LCAwLCAzLCA1LCAyLCAxNCwgMTUsIDksXG5cbiAgMTAsIDEzLCAwLCA3LCA5LCAwLCAxNCwgOSwgNiwgMywgMywgNCwgMTUsIDYsIDUsIDEwLFxuICAxLCAyLCAxMywgOCwgMTIsIDUsIDcsIDE0LCAxMSwgMTIsIDQsIDExLCAyLCAxNSwgOCwgMSxcbiAgMTMsIDEsIDYsIDEwLCA0LCAxMywgOSwgMCwgOCwgNiwgMTUsIDksIDMsIDgsIDAsIDcsXG4gIDExLCA0LCAxLCAxNSwgMiwgMTQsIDEyLCAzLCA1LCAxMSwgMTAsIDUsIDE0LCAyLCA3LCAxMixcblxuICA3LCAxMywgMTMsIDgsIDE0LCAxMSwgMywgNSwgMCwgNiwgNiwgMTUsIDksIDAsIDEwLCAzLFxuICAxLCA0LCAyLCA3LCA4LCAyLCA1LCAxMiwgMTEsIDEsIDEyLCAxMCwgNCwgMTQsIDE1LCA5LFxuICAxMCwgMywgNiwgMTUsIDksIDAsIDAsIDYsIDEyLCAxMCwgMTEsIDEsIDcsIDEzLCAxMywgOCxcbiAgMTUsIDksIDEsIDQsIDMsIDUsIDE0LCAxMSwgNSwgMTIsIDIsIDcsIDgsIDIsIDQsIDE0LFxuXG4gIDIsIDE0LCAxMiwgMTEsIDQsIDIsIDEsIDEyLCA3LCA0LCAxMCwgNywgMTEsIDEzLCA2LCAxLFxuICA4LCA1LCA1LCAwLCAzLCAxNSwgMTUsIDEwLCAxMywgMywgMCwgOSwgMTQsIDgsIDksIDYsXG4gIDQsIDExLCAyLCA4LCAxLCAxMiwgMTEsIDcsIDEwLCAxLCAxMywgMTQsIDcsIDIsIDgsIDEzLFxuICAxNSwgNiwgOSwgMTUsIDEyLCAwLCA1LCA5LCA2LCAxMCwgMywgNCwgMCwgNSwgMTQsIDMsXG5cbiAgMTIsIDEwLCAxLCAxNSwgMTAsIDQsIDE1LCAyLCA5LCA3LCAyLCAxMiwgNiwgOSwgOCwgNSxcbiAgMCwgNiwgMTMsIDEsIDMsIDEzLCA0LCAxNCwgMTQsIDAsIDcsIDExLCA1LCAzLCAxMSwgOCxcbiAgOSwgNCwgMTQsIDMsIDE1LCAyLCA1LCAxMiwgMiwgOSwgOCwgNSwgMTIsIDE1LCAzLCAxMCxcbiAgNywgMTEsIDAsIDE0LCA0LCAxLCAxMCwgNywgMSwgNiwgMTMsIDAsIDExLCA4LCA2LCAxMyxcblxuICA0LCAxMywgMTEsIDAsIDIsIDExLCAxNCwgNywgMTUsIDQsIDAsIDksIDgsIDEsIDEzLCAxMCxcbiAgMywgMTQsIDEyLCAzLCA5LCA1LCA3LCAxMiwgNSwgMiwgMTAsIDE1LCA2LCA4LCAxLCA2LFxuICAxLCA2LCA0LCAxMSwgMTEsIDEzLCAxMywgOCwgMTIsIDEsIDMsIDQsIDcsIDEwLCAxNCwgNyxcbiAgMTAsIDksIDE1LCA1LCA2LCAwLCA4LCAxNSwgMCwgMTQsIDUsIDIsIDksIDMsIDIsIDEyLFxuXG4gIDEzLCAxLCAyLCAxNSwgOCwgMTMsIDQsIDgsIDYsIDEwLCAxNSwgMywgMTEsIDcsIDEsIDQsXG4gIDEwLCAxMiwgOSwgNSwgMywgNiwgMTQsIDExLCA1LCAwLCAwLCAxNCwgMTIsIDksIDcsIDIsXG4gIDcsIDIsIDExLCAxLCA0LCAxNCwgMSwgNywgOSwgNCwgMTIsIDEwLCAxNCwgOCwgMiwgMTMsXG4gIDAsIDE1LCA2LCAxMiwgMTAsIDksIDEzLCAwLCAxNSwgMywgMywgNSwgNSwgNiwgOCwgMTFcbl07XG5cbmV4cG9ydHMuc3Vic3RpdHV0ZSA9IGZ1bmN0aW9uIHN1YnN0aXR1dGUoaW5MLCBpblIpIHtcbiAgdmFyIG91dCA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgdmFyIGIgPSAoaW5MID4+PiAoMTggLSBpICogNikpICYgMHgzZjtcbiAgICB2YXIgc2IgPSBzVGFibGVbaSAqIDB4NDAgKyBiXTtcblxuICAgIG91dCA8PD0gNDtcbiAgICBvdXQgfD0gc2I7XG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICB2YXIgYiA9IChpblIgPj4+ICgxOCAtIGkgKiA2KSkgJiAweDNmO1xuICAgIHZhciBzYiA9IHNUYWJsZVs0ICogMHg0MCArIGkgKiAweDQwICsgYl07XG5cbiAgICBvdXQgPDw9IDQ7XG4gICAgb3V0IHw9IHNiO1xuICB9XG4gIHJldHVybiBvdXQgPj4+IDA7XG59O1xuXG52YXIgcGVybXV0ZVRhYmxlID0gW1xuICAxNiwgMjUsIDEyLCAxMSwgMywgMjAsIDQsIDE1LCAzMSwgMTcsIDksIDYsIDI3LCAxNCwgMSwgMjIsXG4gIDMwLCAyNCwgOCwgMTgsIDAsIDUsIDI5LCAyMywgMTMsIDE5LCAyLCAyNiwgMTAsIDIxLCAyOCwgN1xuXTtcblxuZXhwb3J0cy5wZXJtdXRlID0gZnVuY3Rpb24gcGVybXV0ZShudW0pIHtcbiAgdmFyIG91dCA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcGVybXV0ZVRhYmxlLmxlbmd0aDsgaSsrKSB7XG4gICAgb3V0IDw8PSAxO1xuICAgIG91dCB8PSAobnVtID4+PiBwZXJtdXRlVGFibGVbaV0pICYgMHgxO1xuICB9XG4gIHJldHVybiBvdXQgPj4+IDA7XG59O1xuXG5leHBvcnRzLnBhZFNwbGl0ID0gZnVuY3Rpb24gcGFkU3BsaXQobnVtLCBzaXplLCBncm91cCkge1xuICB2YXIgc3RyID0gbnVtLnRvU3RyaW5nKDIpO1xuICB3aGlsZSAoc3RyLmxlbmd0aCA8IHNpemUpXG4gICAgc3RyID0gJzAnICsgc3RyO1xuXG4gIHZhciBvdXQgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyBpICs9IGdyb3VwKVxuICAgIG91dC5wdXNoKHN0ci5zbGljZShpLCBpICsgZ3JvdXApKTtcbiAgcmV0dXJuIG91dC5qb2luKCcgJyk7XG59O1xuIiwidmFyIGdlbmVyYXRlUHJpbWUgPSByZXF1aXJlKCcuL2xpYi9nZW5lcmF0ZVByaW1lJylcbnZhciBwcmltZXMgPSByZXF1aXJlKCcuL2xpYi9wcmltZXMuanNvbicpXG5cbnZhciBESCA9IHJlcXVpcmUoJy4vbGliL2RoJylcblxuZnVuY3Rpb24gZ2V0RGlmZmllSGVsbG1hbiAobW9kKSB7XG4gIHZhciBwcmltZSA9IG5ldyBCdWZmZXIocHJpbWVzW21vZF0ucHJpbWUsICdoZXgnKVxuICB2YXIgZ2VuID0gbmV3IEJ1ZmZlcihwcmltZXNbbW9kXS5nZW4sICdoZXgnKVxuXG4gIHJldHVybiBuZXcgREgocHJpbWUsIGdlbilcbn1cblxudmFyIEVOQ09ESU5HUyA9IHtcbiAgJ2JpbmFyeSc6IHRydWUsICdoZXgnOiB0cnVlLCAnYmFzZTY0JzogdHJ1ZVxufVxuXG5mdW5jdGlvbiBjcmVhdGVEaWZmaWVIZWxsbWFuIChwcmltZSwgZW5jLCBnZW5lcmF0b3IsIGdlbmMpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihlbmMpIHx8IEVOQ09ESU5HU1tlbmNdID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gY3JlYXRlRGlmZmllSGVsbG1hbihwcmltZSwgJ2JpbmFyeScsIGVuYywgZ2VuZXJhdG9yKVxuICB9XG5cbiAgZW5jID0gZW5jIHx8ICdiaW5hcnknXG4gIGdlbmMgPSBnZW5jIHx8ICdiaW5hcnknXG4gIGdlbmVyYXRvciA9IGdlbmVyYXRvciB8fCBuZXcgQnVmZmVyKFsyXSlcblxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihnZW5lcmF0b3IpKSB7XG4gICAgZ2VuZXJhdG9yID0gbmV3IEJ1ZmZlcihnZW5lcmF0b3IsIGdlbmMpXG4gIH1cblxuICBpZiAodHlwZW9mIHByaW1lID09PSAnbnVtYmVyJykge1xuICAgIHJldHVybiBuZXcgREgoZ2VuZXJhdGVQcmltZShwcmltZSwgZ2VuZXJhdG9yKSwgZ2VuZXJhdG9yLCB0cnVlKVxuICB9XG5cbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIocHJpbWUpKSB7XG4gICAgcHJpbWUgPSBuZXcgQnVmZmVyKHByaW1lLCBlbmMpXG4gIH1cblxuICByZXR1cm4gbmV3IERIKHByaW1lLCBnZW5lcmF0b3IsIHRydWUpXG59XG5cbmV4cG9ydHMuRGlmZmllSGVsbG1hbkdyb3VwID0gZXhwb3J0cy5jcmVhdGVEaWZmaWVIZWxsbWFuR3JvdXAgPSBleHBvcnRzLmdldERpZmZpZUhlbGxtYW4gPSBnZXREaWZmaWVIZWxsbWFuXG5leHBvcnRzLmNyZWF0ZURpZmZpZUhlbGxtYW4gPSBleHBvcnRzLkRpZmZpZUhlbGxtYW4gPSBjcmVhdGVEaWZmaWVIZWxsbWFuXG4iLCJ2YXIgQk4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIE1pbGxlclJhYmluID0gcmVxdWlyZSgnbWlsbGVyLXJhYmluJyk7XG52YXIgbWlsbGVyUmFiaW4gPSBuZXcgTWlsbGVyUmFiaW4oKTtcbnZhciBUV0VOVFlGT1VSID0gbmV3IEJOKDI0KTtcbnZhciBFTEVWRU4gPSBuZXcgQk4oMTEpO1xudmFyIFRFTiA9IG5ldyBCTigxMCk7XG52YXIgVEhSRUUgPSBuZXcgQk4oMyk7XG52YXIgU0VWRU4gPSBuZXcgQk4oNyk7XG52YXIgcHJpbWVzID0gcmVxdWlyZSgnLi9nZW5lcmF0ZVByaW1lJyk7XG52YXIgcmFuZG9tQnl0ZXMgPSByZXF1aXJlKCdyYW5kb21ieXRlcycpO1xubW9kdWxlLmV4cG9ydHMgPSBESDtcblxuZnVuY3Rpb24gc2V0UHVibGljS2V5KHB1YiwgZW5jKSB7XG4gIGVuYyA9IGVuYyB8fCAndXRmOCc7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHB1YikpIHtcbiAgICBwdWIgPSBuZXcgQnVmZmVyKHB1YiwgZW5jKTtcbiAgfVxuICB0aGlzLl9wdWIgPSBuZXcgQk4ocHViKTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbmZ1bmN0aW9uIHNldFByaXZhdGVLZXkocHJpdiwgZW5jKSB7XG4gIGVuYyA9IGVuYyB8fCAndXRmOCc7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHByaXYpKSB7XG4gICAgcHJpdiA9IG5ldyBCdWZmZXIocHJpdiwgZW5jKTtcbiAgfVxuICB0aGlzLl9wcml2ID0gbmV3IEJOKHByaXYpO1xuICByZXR1cm4gdGhpcztcbn1cblxudmFyIHByaW1lQ2FjaGUgPSB7fTtcbmZ1bmN0aW9uIGNoZWNrUHJpbWUocHJpbWUsIGdlbmVyYXRvcikge1xuICB2YXIgZ2VuID0gZ2VuZXJhdG9yLnRvU3RyaW5nKCdoZXgnKTtcbiAgdmFyIGhleCA9IFtnZW4sIHByaW1lLnRvU3RyaW5nKDE2KV0uam9pbignXycpO1xuICBpZiAoaGV4IGluIHByaW1lQ2FjaGUpIHtcbiAgICByZXR1cm4gcHJpbWVDYWNoZVtoZXhdO1xuICB9XG4gIHZhciBlcnJvciA9IDA7XG5cbiAgaWYgKHByaW1lLmlzRXZlbigpIHx8XG4gICAgIXByaW1lcy5zaW1wbGVTaWV2ZSB8fFxuICAgICFwcmltZXMuZmVybWF0VGVzdChwcmltZSkgfHxcbiAgICAhbWlsbGVyUmFiaW4udGVzdChwcmltZSkpIHtcbiAgICAvL25vdCBhIHByaW1lIHNvICsxXG4gICAgZXJyb3IgKz0gMTtcblxuICAgIGlmIChnZW4gPT09ICcwMicgfHwgZ2VuID09PSAnMDUnKSB7XG4gICAgICAvLyB3ZSdkIGJlIGFibGUgdG8gY2hlY2sgdGhlIGdlbmVyYXRvclxuICAgICAgLy8gaXQgd291bGQgZmFpbCBzbyArOFxuICAgICAgZXJyb3IgKz0gODtcbiAgICB9IGVsc2Uge1xuICAgICAgLy93ZSB3b3VsZG4ndCBiZSBhYmxlIHRvIHRlc3QgdGhlIGdlbmVyYXRvclxuICAgICAgLy8gc28gKzRcbiAgICAgIGVycm9yICs9IDQ7XG4gICAgfVxuICAgIHByaW1lQ2FjaGVbaGV4XSA9IGVycm9yO1xuICAgIHJldHVybiBlcnJvcjtcbiAgfVxuICBpZiAoIW1pbGxlclJhYmluLnRlc3QocHJpbWUuc2hybigxKSkpIHtcbiAgICAvL25vdCBhIHNhZmUgcHJpbWVcbiAgICBlcnJvciArPSAyO1xuICB9XG4gIHZhciByZW07XG4gIHN3aXRjaCAoZ2VuKSB7XG4gICAgY2FzZSAnMDInOlxuICAgICAgaWYgKHByaW1lLm1vZChUV0VOVFlGT1VSKS5jbXAoRUxFVkVOKSkge1xuICAgICAgICAvLyB1bnN1aWRhYmxlIGdlbmVyYXRvclxuICAgICAgICBlcnJvciArPSA4O1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnMDUnOlxuICAgICAgcmVtID0gcHJpbWUubW9kKFRFTik7XG4gICAgICBpZiAocmVtLmNtcChUSFJFRSkgJiYgcmVtLmNtcChTRVZFTikpIHtcbiAgICAgICAgLy8gcHJpbWUgbW9kIDEwIG5lZWRzIHRvIGVxdWFsIDMgb3IgN1xuICAgICAgICBlcnJvciArPSA4O1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIGVycm9yICs9IDQ7XG4gIH1cbiAgcHJpbWVDYWNoZVtoZXhdID0gZXJyb3I7XG4gIHJldHVybiBlcnJvcjtcbn1cblxuZnVuY3Rpb24gREgocHJpbWUsIGdlbmVyYXRvciwgbWFsbGVhYmxlKSB7XG4gIHRoaXMuc2V0R2VuZXJhdG9yKGdlbmVyYXRvcik7XG4gIHRoaXMuX19wcmltZSA9IG5ldyBCTihwcmltZSk7XG4gIHRoaXMuX3ByaW1lID0gQk4ubW9udCh0aGlzLl9fcHJpbWUpO1xuICB0aGlzLl9wcmltZUxlbiA9IHByaW1lLmxlbmd0aDtcbiAgdGhpcy5fcHViID0gdW5kZWZpbmVkO1xuICB0aGlzLl9wcml2ID0gdW5kZWZpbmVkO1xuICB0aGlzLl9wcmltZUNvZGUgPSB1bmRlZmluZWQ7XG4gIGlmIChtYWxsZWFibGUpIHtcbiAgICB0aGlzLnNldFB1YmxpY0tleSA9IHNldFB1YmxpY0tleTtcbiAgICB0aGlzLnNldFByaXZhdGVLZXkgPSBzZXRQcml2YXRlS2V5O1xuICB9IGVsc2Uge1xuICAgIHRoaXMuX3ByaW1lQ29kZSA9IDg7XG4gIH1cbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShESC5wcm90b3R5cGUsICd2ZXJpZnlFcnJvcicsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLl9wcmltZUNvZGUgIT09ICdudW1iZXInKSB7XG4gICAgICB0aGlzLl9wcmltZUNvZGUgPSBjaGVja1ByaW1lKHRoaXMuX19wcmltZSwgdGhpcy5fX2dlbik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9wcmltZUNvZGU7XG4gIH1cbn0pO1xuREgucHJvdG90eXBlLmdlbmVyYXRlS2V5cyA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLl9wcml2KSB7XG4gICAgdGhpcy5fcHJpdiA9IG5ldyBCTihyYW5kb21CeXRlcyh0aGlzLl9wcmltZUxlbikpO1xuICB9XG4gIHRoaXMuX3B1YiA9IHRoaXMuX2dlbi50b1JlZCh0aGlzLl9wcmltZSkucmVkUG93KHRoaXMuX3ByaXYpLmZyb21SZWQoKTtcbiAgcmV0dXJuIHRoaXMuZ2V0UHVibGljS2V5KCk7XG59O1xuXG5ESC5wcm90b3R5cGUuY29tcHV0ZVNlY3JldCA9IGZ1bmN0aW9uIChvdGhlcikge1xuICBvdGhlciA9IG5ldyBCTihvdGhlcik7XG4gIG90aGVyID0gb3RoZXIudG9SZWQodGhpcy5fcHJpbWUpO1xuICB2YXIgc2VjcmV0ID0gb3RoZXIucmVkUG93KHRoaXMuX3ByaXYpLmZyb21SZWQoKTtcbiAgdmFyIG91dCA9IG5ldyBCdWZmZXIoc2VjcmV0LnRvQXJyYXkoKSk7XG4gIHZhciBwcmltZSA9IHRoaXMuZ2V0UHJpbWUoKTtcbiAgaWYgKG91dC5sZW5ndGggPCBwcmltZS5sZW5ndGgpIHtcbiAgICB2YXIgZnJvbnQgPSBuZXcgQnVmZmVyKHByaW1lLmxlbmd0aCAtIG91dC5sZW5ndGgpO1xuICAgIGZyb250LmZpbGwoMCk7XG4gICAgb3V0ID0gQnVmZmVyLmNvbmNhdChbZnJvbnQsIG91dF0pO1xuICB9XG4gIHJldHVybiBvdXQ7XG59O1xuXG5ESC5wcm90b3R5cGUuZ2V0UHVibGljS2V5ID0gZnVuY3Rpb24gZ2V0UHVibGljS2V5KGVuYykge1xuICByZXR1cm4gZm9ybWF0UmV0dXJuVmFsdWUodGhpcy5fcHViLCBlbmMpO1xufTtcblxuREgucHJvdG90eXBlLmdldFByaXZhdGVLZXkgPSBmdW5jdGlvbiBnZXRQcml2YXRlS2V5KGVuYykge1xuICByZXR1cm4gZm9ybWF0UmV0dXJuVmFsdWUodGhpcy5fcHJpdiwgZW5jKTtcbn07XG5cbkRILnByb3RvdHlwZS5nZXRQcmltZSA9IGZ1bmN0aW9uIChlbmMpIHtcbiAgcmV0dXJuIGZvcm1hdFJldHVyblZhbHVlKHRoaXMuX19wcmltZSwgZW5jKTtcbn07XG5cbkRILnByb3RvdHlwZS5nZXRHZW5lcmF0b3IgPSBmdW5jdGlvbiAoZW5jKSB7XG4gIHJldHVybiBmb3JtYXRSZXR1cm5WYWx1ZSh0aGlzLl9nZW4sIGVuYyk7XG59O1xuXG5ESC5wcm90b3R5cGUuc2V0R2VuZXJhdG9yID0gZnVuY3Rpb24gKGdlbiwgZW5jKSB7XG4gIGVuYyA9IGVuYyB8fCAndXRmOCc7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGdlbikpIHtcbiAgICBnZW4gPSBuZXcgQnVmZmVyKGdlbiwgZW5jKTtcbiAgfVxuICB0aGlzLl9fZ2VuID0gZ2VuO1xuICB0aGlzLl9nZW4gPSBuZXcgQk4oZ2VuKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBmb3JtYXRSZXR1cm5WYWx1ZShibiwgZW5jKSB7XG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKGJuLnRvQXJyYXkoKSk7XG4gIGlmICghZW5jKSB7XG4gICAgcmV0dXJuIGJ1ZjtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYnVmLnRvU3RyaW5nKGVuYyk7XG4gIH1cbn1cbiIsInZhciByYW5kb21CeXRlcyA9IHJlcXVpcmUoJ3JhbmRvbWJ5dGVzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZpbmRQcmltZTtcbmZpbmRQcmltZS5zaW1wbGVTaWV2ZSA9IHNpbXBsZVNpZXZlO1xuZmluZFByaW1lLmZlcm1hdFRlc3QgPSBmZXJtYXRUZXN0O1xudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciBUV0VOVFlGT1VSID0gbmV3IEJOKDI0KTtcbnZhciBNaWxsZXJSYWJpbiA9IHJlcXVpcmUoJ21pbGxlci1yYWJpbicpO1xudmFyIG1pbGxlclJhYmluID0gbmV3IE1pbGxlclJhYmluKCk7XG52YXIgT05FID0gbmV3IEJOKDEpO1xudmFyIFRXTyA9IG5ldyBCTigyKTtcbnZhciBGSVZFID0gbmV3IEJOKDUpO1xudmFyIFNJWFRFRU4gPSBuZXcgQk4oMTYpO1xudmFyIEVJR0hUID0gbmV3IEJOKDgpO1xudmFyIFRFTiA9IG5ldyBCTigxMCk7XG52YXIgVEhSRUUgPSBuZXcgQk4oMyk7XG52YXIgU0VWRU4gPSBuZXcgQk4oNyk7XG52YXIgRUxFVkVOID0gbmV3IEJOKDExKTtcbnZhciBGT1VSID0gbmV3IEJOKDQpO1xudmFyIFRXRUxWRSA9IG5ldyBCTigxMik7XG52YXIgcHJpbWVzID0gbnVsbDtcblxuZnVuY3Rpb24gX2dldFByaW1lcygpIHtcbiAgaWYgKHByaW1lcyAhPT0gbnVsbClcbiAgICByZXR1cm4gcHJpbWVzO1xuXG4gIHZhciBsaW1pdCA9IDB4MTAwMDAwO1xuICB2YXIgcmVzID0gW107XG4gIHJlc1swXSA9IDI7XG4gIGZvciAodmFyIGkgPSAxLCBrID0gMzsgayA8IGxpbWl0OyBrICs9IDIpIHtcbiAgICB2YXIgc3FydCA9IE1hdGguY2VpbChNYXRoLnNxcnQoaykpO1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgaSAmJiByZXNbal0gPD0gc3FydDsgaisrKVxuICAgICAgaWYgKGsgJSByZXNbal0gPT09IDApXG4gICAgICAgIGJyZWFrO1xuXG4gICAgaWYgKGkgIT09IGogJiYgcmVzW2pdIDw9IHNxcnQpXG4gICAgICBjb250aW51ZTtcblxuICAgIHJlc1tpKytdID0gaztcbiAgfVxuICBwcmltZXMgPSByZXM7XG4gIHJldHVybiByZXM7XG59XG5cbmZ1bmN0aW9uIHNpbXBsZVNpZXZlKHApIHtcbiAgdmFyIHByaW1lcyA9IF9nZXRQcmltZXMoKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHByaW1lcy5sZW5ndGg7IGkrKylcbiAgICBpZiAocC5tb2RuKHByaW1lc1tpXSkgPT09IDApIHtcbiAgICAgIGlmIChwLmNtcG4ocHJpbWVzW2ldKSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGZlcm1hdFRlc3QocCkge1xuICB2YXIgcmVkID0gQk4ubW9udChwKTtcbiAgcmV0dXJuIFRXTy50b1JlZChyZWQpLnJlZFBvdyhwLnN1Ym4oMSkpLmZyb21SZWQoKS5jbXBuKDEpID09PSAwO1xufVxuXG5mdW5jdGlvbiBmaW5kUHJpbWUoYml0cywgZ2VuKSB7XG4gIGlmIChiaXRzIDwgMTYpIHtcbiAgICAvLyB0aGlzIGlzIHdoYXQgb3BlbnNzbCBkb2VzXG4gICAgaWYgKGdlbiA9PT0gMiB8fCBnZW4gPT09IDUpIHtcbiAgICAgIHJldHVybiBuZXcgQk4oWzB4OGMsIDB4N2JdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG5ldyBCTihbMHg4YywgMHgyN10pO1xuICAgIH1cbiAgfVxuICBnZW4gPSBuZXcgQk4oZ2VuKTtcblxuICB2YXIgbnVtLCBuMjtcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIG51bSA9IG5ldyBCTihyYW5kb21CeXRlcyhNYXRoLmNlaWwoYml0cyAvIDgpKSk7XG4gICAgd2hpbGUgKG51bS5iaXRMZW5ndGgoKSA+IGJpdHMpIHtcbiAgICAgIG51bS5pc2hybigxKTtcbiAgICB9XG4gICAgaWYgKG51bS5pc0V2ZW4oKSkge1xuICAgICAgbnVtLmlhZGQoT05FKTtcbiAgICB9XG4gICAgaWYgKCFudW0udGVzdG4oMSkpIHtcbiAgICAgIG51bS5pYWRkKFRXTyk7XG4gICAgfVxuICAgIGlmICghZ2VuLmNtcChUV08pKSB7XG4gICAgICB3aGlsZSAobnVtLm1vZChUV0VOVFlGT1VSKS5jbXAoRUxFVkVOKSkge1xuICAgICAgICBudW0uaWFkZChGT1VSKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCFnZW4uY21wKEZJVkUpKSB7XG4gICAgICB3aGlsZSAobnVtLm1vZChURU4pLmNtcChUSFJFRSkpIHtcbiAgICAgICAgbnVtLmlhZGQoRk9VUik7XG4gICAgICB9XG4gICAgfVxuICAgIG4yID0gbnVtLnNocm4oMSk7XG4gICAgaWYgKHNpbXBsZVNpZXZlKG4yKSAmJiBzaW1wbGVTaWV2ZShudW0pICYmXG4gICAgICBmZXJtYXRUZXN0KG4yKSAmJiBmZXJtYXRUZXN0KG51bSkgJiZcbiAgICAgIG1pbGxlclJhYmluLnRlc3QobjIpICYmIG1pbGxlclJhYmluLnRlc3QobnVtKSkge1xuICAgICAgcmV0dXJuIG51bTtcbiAgICB9XG4gIH1cblxufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZWxsaXB0aWMgPSBleHBvcnRzO1xuXG5lbGxpcHRpYy52ZXJzaW9uID0gcmVxdWlyZSgnLi4vcGFja2FnZS5qc29uJykudmVyc2lvbjtcbmVsbGlwdGljLnV0aWxzID0gcmVxdWlyZSgnLi9lbGxpcHRpYy91dGlscycpO1xuZWxsaXB0aWMucmFuZCA9IHJlcXVpcmUoJ2Jyb3JhbmQnKTtcbmVsbGlwdGljLmN1cnZlID0gcmVxdWlyZSgnLi9lbGxpcHRpYy9jdXJ2ZScpO1xuZWxsaXB0aWMuY3VydmVzID0gcmVxdWlyZSgnLi9lbGxpcHRpYy9jdXJ2ZXMnKTtcblxuLy8gUHJvdG9jb2xzXG5lbGxpcHRpYy5lYyA9IHJlcXVpcmUoJy4vZWxsaXB0aWMvZWMnKTtcbmVsbGlwdGljLmVkZHNhID0gcmVxdWlyZSgnLi9lbGxpcHRpYy9lZGRzYScpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBnZXROQUYgPSB1dGlscy5nZXROQUY7XG52YXIgZ2V0SlNGID0gdXRpbHMuZ2V0SlNGO1xudmFyIGFzc2VydCA9IHV0aWxzLmFzc2VydDtcblxuZnVuY3Rpb24gQmFzZUN1cnZlKHR5cGUsIGNvbmYpIHtcbiAgdGhpcy50eXBlID0gdHlwZTtcbiAgdGhpcy5wID0gbmV3IEJOKGNvbmYucCwgMTYpO1xuXG4gIC8vIFVzZSBNb250Z29tZXJ5LCB3aGVuIHRoZXJlIGlzIG5vIGZhc3QgcmVkdWN0aW9uIGZvciB0aGUgcHJpbWVcbiAgdGhpcy5yZWQgPSBjb25mLnByaW1lID8gQk4ucmVkKGNvbmYucHJpbWUpIDogQk4ubW9udCh0aGlzLnApO1xuXG4gIC8vIFVzZWZ1bCBmb3IgbWFueSBjdXJ2ZXNcbiAgdGhpcy56ZXJvID0gbmV3IEJOKDApLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5vbmUgPSBuZXcgQk4oMSkudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLnR3byA9IG5ldyBCTigyKS50b1JlZCh0aGlzLnJlZCk7XG5cbiAgLy8gQ3VydmUgY29uZmlndXJhdGlvbiwgb3B0aW9uYWxcbiAgdGhpcy5uID0gY29uZi5uICYmIG5ldyBCTihjb25mLm4sIDE2KTtcbiAgdGhpcy5nID0gY29uZi5nICYmIHRoaXMucG9pbnRGcm9tSlNPTihjb25mLmcsIGNvbmYuZ1JlZCk7XG5cbiAgLy8gVGVtcG9yYXJ5IGFycmF5c1xuICB0aGlzLl93bmFmVDEgPSBuZXcgQXJyYXkoNCk7XG4gIHRoaXMuX3duYWZUMiA9IG5ldyBBcnJheSg0KTtcbiAgdGhpcy5fd25hZlQzID0gbmV3IEFycmF5KDQpO1xuICB0aGlzLl93bmFmVDQgPSBuZXcgQXJyYXkoNCk7XG5cbiAgdGhpcy5fYml0TGVuZ3RoID0gdGhpcy5uID8gdGhpcy5uLmJpdExlbmd0aCgpIDogMDtcblxuICAvLyBHZW5lcmFsaXplZCBHcmVnIE1heHdlbGwncyB0cmlja1xuICB2YXIgYWRqdXN0Q291bnQgPSB0aGlzLm4gJiYgdGhpcy5wLmRpdih0aGlzLm4pO1xuICBpZiAoIWFkanVzdENvdW50IHx8IGFkanVzdENvdW50LmNtcG4oMTAwKSA+IDApIHtcbiAgICB0aGlzLnJlZE4gPSBudWxsO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuX21heHdlbGxUcmljayA9IHRydWU7XG4gICAgdGhpcy5yZWROID0gdGhpcy5uLnRvUmVkKHRoaXMucmVkKTtcbiAgfVxufVxubW9kdWxlLmV4cG9ydHMgPSBCYXNlQ3VydmU7XG5cbkJhc2VDdXJ2ZS5wcm90b3R5cGUucG9pbnQgPSBmdW5jdGlvbiBwb2ludCgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbn07XG5cbkJhc2VDdXJ2ZS5wcm90b3R5cGUudmFsaWRhdGUgPSBmdW5jdGlvbiB2YWxpZGF0ZSgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbn07XG5cbkJhc2VDdXJ2ZS5wcm90b3R5cGUuX2ZpeGVkTmFmTXVsID0gZnVuY3Rpb24gX2ZpeGVkTmFmTXVsKHAsIGspIHtcbiAgYXNzZXJ0KHAucHJlY29tcHV0ZWQpO1xuICB2YXIgZG91YmxlcyA9IHAuX2dldERvdWJsZXMoKTtcblxuICB2YXIgbmFmID0gZ2V0TkFGKGssIDEsIHRoaXMuX2JpdExlbmd0aCk7XG4gIHZhciBJID0gKDEgPDwgKGRvdWJsZXMuc3RlcCArIDEpKSAtIChkb3VibGVzLnN0ZXAgJSAyID09PSAwID8gMiA6IDEpO1xuICBJIC89IDM7XG5cbiAgLy8gVHJhbnNsYXRlIGludG8gbW9yZSB3aW5kb3dlZCBmb3JtXG4gIHZhciByZXByID0gW107XG4gIGZvciAodmFyIGogPSAwOyBqIDwgbmFmLmxlbmd0aDsgaiArPSBkb3VibGVzLnN0ZXApIHtcbiAgICB2YXIgbmFmVyA9IDA7XG4gICAgZm9yICh2YXIgayA9IGogKyBkb3VibGVzLnN0ZXAgLSAxOyBrID49IGo7IGstLSlcbiAgICAgIG5hZlcgPSAobmFmVyA8PCAxKSArIG5hZltrXTtcbiAgICByZXByLnB1c2gobmFmVyk7XG4gIH1cblxuICB2YXIgYSA9IHRoaXMuanBvaW50KG51bGwsIG51bGwsIG51bGwpO1xuICB2YXIgYiA9IHRoaXMuanBvaW50KG51bGwsIG51bGwsIG51bGwpO1xuICBmb3IgKHZhciBpID0gSTsgaSA+IDA7IGktLSkge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgcmVwci5sZW5ndGg7IGorKykge1xuICAgICAgdmFyIG5hZlcgPSByZXByW2pdO1xuICAgICAgaWYgKG5hZlcgPT09IGkpXG4gICAgICAgIGIgPSBiLm1peGVkQWRkKGRvdWJsZXMucG9pbnRzW2pdKTtcbiAgICAgIGVsc2UgaWYgKG5hZlcgPT09IC1pKVxuICAgICAgICBiID0gYi5taXhlZEFkZChkb3VibGVzLnBvaW50c1tqXS5uZWcoKSk7XG4gICAgfVxuICAgIGEgPSBhLmFkZChiKTtcbiAgfVxuICByZXR1cm4gYS50b1AoKTtcbn07XG5cbkJhc2VDdXJ2ZS5wcm90b3R5cGUuX3duYWZNdWwgPSBmdW5jdGlvbiBfd25hZk11bChwLCBrKSB7XG4gIHZhciB3ID0gNDtcblxuICAvLyBQcmVjb21wdXRlIHdpbmRvd1xuICB2YXIgbmFmUG9pbnRzID0gcC5fZ2V0TkFGUG9pbnRzKHcpO1xuICB3ID0gbmFmUG9pbnRzLnduZDtcbiAgdmFyIHduZCA9IG5hZlBvaW50cy5wb2ludHM7XG5cbiAgLy8gR2V0IE5BRiBmb3JtXG4gIHZhciBuYWYgPSBnZXROQUYoaywgdywgdGhpcy5fYml0TGVuZ3RoKTtcblxuICAvLyBBZGQgYHRoaXNgKihOKzEpIGZvciBldmVyeSB3LU5BRiBpbmRleFxuICB2YXIgYWNjID0gdGhpcy5qcG9pbnQobnVsbCwgbnVsbCwgbnVsbCk7XG4gIGZvciAodmFyIGkgPSBuYWYubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAvLyBDb3VudCB6ZXJvZXNcbiAgICBmb3IgKHZhciBrID0gMDsgaSA+PSAwICYmIG5hZltpXSA9PT0gMDsgaS0tKVxuICAgICAgaysrO1xuICAgIGlmIChpID49IDApXG4gICAgICBrKys7XG4gICAgYWNjID0gYWNjLmRibHAoayk7XG5cbiAgICBpZiAoaSA8IDApXG4gICAgICBicmVhaztcbiAgICB2YXIgeiA9IG5hZltpXTtcbiAgICBhc3NlcnQoeiAhPT0gMCk7XG4gICAgaWYgKHAudHlwZSA9PT0gJ2FmZmluZScpIHtcbiAgICAgIC8vIEogKy0gUFxuICAgICAgaWYgKHogPiAwKVxuICAgICAgICBhY2MgPSBhY2MubWl4ZWRBZGQod25kWyh6IC0gMSkgPj4gMV0pO1xuICAgICAgZWxzZVxuICAgICAgICBhY2MgPSBhY2MubWl4ZWRBZGQod25kWygteiAtIDEpID4+IDFdLm5lZygpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSiArLSBKXG4gICAgICBpZiAoeiA+IDApXG4gICAgICAgIGFjYyA9IGFjYy5hZGQod25kWyh6IC0gMSkgPj4gMV0pO1xuICAgICAgZWxzZVxuICAgICAgICBhY2MgPSBhY2MuYWRkKHduZFsoLXogLSAxKSA+PiAxXS5uZWcoKSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBwLnR5cGUgPT09ICdhZmZpbmUnID8gYWNjLnRvUCgpIDogYWNjO1xufTtcblxuQmFzZUN1cnZlLnByb3RvdHlwZS5fd25hZk11bEFkZCA9IGZ1bmN0aW9uIF93bmFmTXVsQWRkKGRlZlcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZWZmcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamFjb2JpYW5SZXN1bHQpIHtcbiAgdmFyIHduZFdpZHRoID0gdGhpcy5fd25hZlQxO1xuICB2YXIgd25kID0gdGhpcy5fd25hZlQyO1xuICB2YXIgbmFmID0gdGhpcy5fd25hZlQzO1xuXG4gIC8vIEZpbGwgYWxsIGFycmF5c1xuICB2YXIgbWF4ID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIHZhciBwID0gcG9pbnRzW2ldO1xuICAgIHZhciBuYWZQb2ludHMgPSBwLl9nZXROQUZQb2ludHMoZGVmVyk7XG4gICAgd25kV2lkdGhbaV0gPSBuYWZQb2ludHMud25kO1xuICAgIHduZFtpXSA9IG5hZlBvaW50cy5wb2ludHM7XG4gIH1cblxuICAvLyBDb21iIHNtYWxsIHdpbmRvdyBOQUZzXG4gIGZvciAodmFyIGkgPSBsZW4gLSAxOyBpID49IDE7IGkgLT0gMikge1xuICAgIHZhciBhID0gaSAtIDE7XG4gICAgdmFyIGIgPSBpO1xuICAgIGlmICh3bmRXaWR0aFthXSAhPT0gMSB8fCB3bmRXaWR0aFtiXSAhPT0gMSkge1xuICAgICAgbmFmW2FdID0gZ2V0TkFGKGNvZWZmc1thXSwgd25kV2lkdGhbYV0sIHRoaXMuX2JpdExlbmd0aCk7XG4gICAgICBuYWZbYl0gPSBnZXROQUYoY29lZmZzW2JdLCB3bmRXaWR0aFtiXSwgdGhpcy5fYml0TGVuZ3RoKTtcbiAgICAgIG1heCA9IE1hdGgubWF4KG5hZlthXS5sZW5ndGgsIG1heCk7XG4gICAgICBtYXggPSBNYXRoLm1heChuYWZbYl0ubGVuZ3RoLCBtYXgpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdmFyIGNvbWIgPSBbXG4gICAgICBwb2ludHNbYV0sIC8qIDEgKi9cbiAgICAgIG51bGwsIC8qIDMgKi9cbiAgICAgIG51bGwsIC8qIDUgKi9cbiAgICAgIHBvaW50c1tiXSAvKiA3ICovXG4gICAgXTtcblxuICAgIC8vIFRyeSB0byBhdm9pZCBQcm9qZWN0aXZlIHBvaW50cywgaWYgcG9zc2libGVcbiAgICBpZiAocG9pbnRzW2FdLnkuY21wKHBvaW50c1tiXS55KSA9PT0gMCkge1xuICAgICAgY29tYlsxXSA9IHBvaW50c1thXS5hZGQocG9pbnRzW2JdKTtcbiAgICAgIGNvbWJbMl0gPSBwb2ludHNbYV0udG9KKCkubWl4ZWRBZGQocG9pbnRzW2JdLm5lZygpKTtcbiAgICB9IGVsc2UgaWYgKHBvaW50c1thXS55LmNtcChwb2ludHNbYl0ueS5yZWROZWcoKSkgPT09IDApIHtcbiAgICAgIGNvbWJbMV0gPSBwb2ludHNbYV0udG9KKCkubWl4ZWRBZGQocG9pbnRzW2JdKTtcbiAgICAgIGNvbWJbMl0gPSBwb2ludHNbYV0uYWRkKHBvaW50c1tiXS5uZWcoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbWJbMV0gPSBwb2ludHNbYV0udG9KKCkubWl4ZWRBZGQocG9pbnRzW2JdKTtcbiAgICAgIGNvbWJbMl0gPSBwb2ludHNbYV0udG9KKCkubWl4ZWRBZGQocG9pbnRzW2JdLm5lZygpKTtcbiAgICB9XG5cbiAgICB2YXIgaW5kZXggPSBbXG4gICAgICAtMywgLyogLTEgLTEgKi9cbiAgICAgIC0xLCAvKiAtMSAwICovXG4gICAgICAtNSwgLyogLTEgMSAqL1xuICAgICAgLTcsIC8qIDAgLTEgKi9cbiAgICAgIDAsIC8qIDAgMCAqL1xuICAgICAgNywgLyogMCAxICovXG4gICAgICA1LCAvKiAxIC0xICovXG4gICAgICAxLCAvKiAxIDAgKi9cbiAgICAgIDMgIC8qIDEgMSAqL1xuICAgIF07XG5cbiAgICB2YXIganNmID0gZ2V0SlNGKGNvZWZmc1thXSwgY29lZmZzW2JdKTtcbiAgICBtYXggPSBNYXRoLm1heChqc2ZbMF0ubGVuZ3RoLCBtYXgpO1xuICAgIG5hZlthXSA9IG5ldyBBcnJheShtYXgpO1xuICAgIG5hZltiXSA9IG5ldyBBcnJheShtYXgpO1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWF4OyBqKyspIHtcbiAgICAgIHZhciBqYSA9IGpzZlswXVtqXSB8IDA7XG4gICAgICB2YXIgamIgPSBqc2ZbMV1bal0gfCAwO1xuXG4gICAgICBuYWZbYV1bal0gPSBpbmRleFsoamEgKyAxKSAqIDMgKyAoamIgKyAxKV07XG4gICAgICBuYWZbYl1bal0gPSAwO1xuICAgICAgd25kW2FdID0gY29tYjtcbiAgICB9XG4gIH1cblxuICB2YXIgYWNjID0gdGhpcy5qcG9pbnQobnVsbCwgbnVsbCwgbnVsbCk7XG4gIHZhciB0bXAgPSB0aGlzLl93bmFmVDQ7XG4gIGZvciAodmFyIGkgPSBtYXg7IGkgPj0gMDsgaS0tKSB7XG4gICAgdmFyIGsgPSAwO1xuXG4gICAgd2hpbGUgKGkgPj0gMCkge1xuICAgICAgdmFyIHplcm8gPSB0cnVlO1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBsZW47IGorKykge1xuICAgICAgICB0bXBbal0gPSBuYWZbal1baV0gfCAwO1xuICAgICAgICBpZiAodG1wW2pdICE9PSAwKVxuICAgICAgICAgIHplcm8gPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmICghemVybylcbiAgICAgICAgYnJlYWs7XG4gICAgICBrKys7XG4gICAgICBpLS07XG4gICAgfVxuICAgIGlmIChpID49IDApXG4gICAgICBrKys7XG4gICAgYWNjID0gYWNjLmRibHAoayk7XG4gICAgaWYgKGkgPCAwKVxuICAgICAgYnJlYWs7XG5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IGxlbjsgaisrKSB7XG4gICAgICB2YXIgeiA9IHRtcFtqXTtcbiAgICAgIHZhciBwO1xuICAgICAgaWYgKHogPT09IDApXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgZWxzZSBpZiAoeiA+IDApXG4gICAgICAgIHAgPSB3bmRbal1bKHogLSAxKSA+PiAxXTtcbiAgICAgIGVsc2UgaWYgKHogPCAwKVxuICAgICAgICBwID0gd25kW2pdWygteiAtIDEpID4+IDFdLm5lZygpO1xuXG4gICAgICBpZiAocC50eXBlID09PSAnYWZmaW5lJylcbiAgICAgICAgYWNjID0gYWNjLm1peGVkQWRkKHApO1xuICAgICAgZWxzZVxuICAgICAgICBhY2MgPSBhY2MuYWRkKHApO1xuICAgIH1cbiAgfVxuICAvLyBaZXJvaWZ5IHJlZmVyZW5jZXNcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICB3bmRbaV0gPSBudWxsO1xuXG4gIGlmIChqYWNvYmlhblJlc3VsdClcbiAgICByZXR1cm4gYWNjO1xuICBlbHNlXG4gICAgcmV0dXJuIGFjYy50b1AoKTtcbn07XG5cbmZ1bmN0aW9uIEJhc2VQb2ludChjdXJ2ZSwgdHlwZSkge1xuICB0aGlzLmN1cnZlID0gY3VydmU7XG4gIHRoaXMudHlwZSA9IHR5cGU7XG4gIHRoaXMucHJlY29tcHV0ZWQgPSBudWxsO1xufVxuQmFzZUN1cnZlLkJhc2VQb2ludCA9IEJhc2VQb2ludDtcblxuQmFzZVBvaW50LnByb3RvdHlwZS5lcSA9IGZ1bmN0aW9uIGVxKC8qb3RoZXIqLykge1xuICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuQmFzZVBvaW50LnByb3RvdHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uIHZhbGlkYXRlKCkge1xuICByZXR1cm4gdGhpcy5jdXJ2ZS52YWxpZGF0ZSh0aGlzKTtcbn07XG5cbkJhc2VDdXJ2ZS5wcm90b3R5cGUuZGVjb2RlUG9pbnQgPSBmdW5jdGlvbiBkZWNvZGVQb2ludChieXRlcywgZW5jKSB7XG4gIGJ5dGVzID0gdXRpbHMudG9BcnJheShieXRlcywgZW5jKTtcblxuICB2YXIgbGVuID0gdGhpcy5wLmJ5dGVMZW5ndGgoKTtcblxuICAvLyB1bmNvbXByZXNzZWQsIGh5YnJpZC1vZGQsIGh5YnJpZC1ldmVuXG4gIGlmICgoYnl0ZXNbMF0gPT09IDB4MDQgfHwgYnl0ZXNbMF0gPT09IDB4MDYgfHwgYnl0ZXNbMF0gPT09IDB4MDcpICYmXG4gICAgICBieXRlcy5sZW5ndGggLSAxID09PSAyICogbGVuKSB7XG4gICAgaWYgKGJ5dGVzWzBdID09PSAweDA2KVxuICAgICAgYXNzZXJ0KGJ5dGVzW2J5dGVzLmxlbmd0aCAtIDFdICUgMiA9PT0gMCk7XG4gICAgZWxzZSBpZiAoYnl0ZXNbMF0gPT09IDB4MDcpXG4gICAgICBhc3NlcnQoYnl0ZXNbYnl0ZXMubGVuZ3RoIC0gMV0gJSAyID09PSAxKTtcblxuICAgIHZhciByZXMgPSAgdGhpcy5wb2ludChieXRlcy5zbGljZSgxLCAxICsgbGVuKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXMuc2xpY2UoMSArIGxlbiwgMSArIDIgKiBsZW4pKTtcblxuICAgIHJldHVybiByZXM7XG4gIH0gZWxzZSBpZiAoKGJ5dGVzWzBdID09PSAweDAyIHx8IGJ5dGVzWzBdID09PSAweDAzKSAmJlxuICAgICAgICAgICAgICBieXRlcy5sZW5ndGggLSAxID09PSBsZW4pIHtcbiAgICByZXR1cm4gdGhpcy5wb2ludEZyb21YKGJ5dGVzLnNsaWNlKDEsIDEgKyBsZW4pLCBieXRlc1swXSA9PT0gMHgwMyk7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIHBvaW50IGZvcm1hdCcpO1xufTtcblxuQmFzZVBvaW50LnByb3RvdHlwZS5lbmNvZGVDb21wcmVzc2VkID0gZnVuY3Rpb24gZW5jb2RlQ29tcHJlc3NlZChlbmMpIHtcbiAgcmV0dXJuIHRoaXMuZW5jb2RlKGVuYywgdHJ1ZSk7XG59O1xuXG5CYXNlUG9pbnQucHJvdG90eXBlLl9lbmNvZGUgPSBmdW5jdGlvbiBfZW5jb2RlKGNvbXBhY3QpIHtcbiAgdmFyIGxlbiA9IHRoaXMuY3VydmUucC5ieXRlTGVuZ3RoKCk7XG4gIHZhciB4ID0gdGhpcy5nZXRYKCkudG9BcnJheSgnYmUnLCBsZW4pO1xuXG4gIGlmIChjb21wYWN0KVxuICAgIHJldHVybiBbIHRoaXMuZ2V0WSgpLmlzRXZlbigpID8gMHgwMiA6IDB4MDMgXS5jb25jYXQoeCk7XG5cbiAgcmV0dXJuIFsgMHgwNCBdLmNvbmNhdCh4LCB0aGlzLmdldFkoKS50b0FycmF5KCdiZScsIGxlbikpIDtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKGVuYywgY29tcGFjdCkge1xuICByZXR1cm4gdXRpbHMuZW5jb2RlKHRoaXMuX2VuY29kZShjb21wYWN0KSwgZW5jKTtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUucHJlY29tcHV0ZSA9IGZ1bmN0aW9uIHByZWNvbXB1dGUocG93ZXIpIHtcbiAgaWYgKHRoaXMucHJlY29tcHV0ZWQpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgdmFyIHByZWNvbXB1dGVkID0ge1xuICAgIGRvdWJsZXM6IG51bGwsXG4gICAgbmFmOiBudWxsLFxuICAgIGJldGE6IG51bGxcbiAgfTtcbiAgcHJlY29tcHV0ZWQubmFmID0gdGhpcy5fZ2V0TkFGUG9pbnRzKDgpO1xuICBwcmVjb21wdXRlZC5kb3VibGVzID0gdGhpcy5fZ2V0RG91Ymxlcyg0LCBwb3dlcik7XG4gIHByZWNvbXB1dGVkLmJldGEgPSB0aGlzLl9nZXRCZXRhKCk7XG4gIHRoaXMucHJlY29tcHV0ZWQgPSBwcmVjb21wdXRlZDtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuX2hhc0RvdWJsZXMgPSBmdW5jdGlvbiBfaGFzRG91YmxlcyhrKSB7XG4gIGlmICghdGhpcy5wcmVjb21wdXRlZClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGRvdWJsZXMgPSB0aGlzLnByZWNvbXB1dGVkLmRvdWJsZXM7XG4gIGlmICghZG91YmxlcylcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgcmV0dXJuIGRvdWJsZXMucG9pbnRzLmxlbmd0aCA+PSBNYXRoLmNlaWwoKGsuYml0TGVuZ3RoKCkgKyAxKSAvIGRvdWJsZXMuc3RlcCk7XG59O1xuXG5CYXNlUG9pbnQucHJvdG90eXBlLl9nZXREb3VibGVzID0gZnVuY3Rpb24gX2dldERvdWJsZXMoc3RlcCwgcG93ZXIpIHtcbiAgaWYgKHRoaXMucHJlY29tcHV0ZWQgJiYgdGhpcy5wcmVjb21wdXRlZC5kb3VibGVzKVxuICAgIHJldHVybiB0aGlzLnByZWNvbXB1dGVkLmRvdWJsZXM7XG5cbiAgdmFyIGRvdWJsZXMgPSBbIHRoaXMgXTtcbiAgdmFyIGFjYyA9IHRoaXM7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcG93ZXI7IGkgKz0gc3RlcCkge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgc3RlcDsgaisrKVxuICAgICAgYWNjID0gYWNjLmRibCgpO1xuICAgIGRvdWJsZXMucHVzaChhY2MpO1xuICB9XG4gIHJldHVybiB7XG4gICAgc3RlcDogc3RlcCxcbiAgICBwb2ludHM6IGRvdWJsZXNcbiAgfTtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuX2dldE5BRlBvaW50cyA9IGZ1bmN0aW9uIF9nZXROQUZQb2ludHMod25kKSB7XG4gIGlmICh0aGlzLnByZWNvbXB1dGVkICYmIHRoaXMucHJlY29tcHV0ZWQubmFmKVxuICAgIHJldHVybiB0aGlzLnByZWNvbXB1dGVkLm5hZjtcblxuICB2YXIgcmVzID0gWyB0aGlzIF07XG4gIHZhciBtYXggPSAoMSA8PCB3bmQpIC0gMTtcbiAgdmFyIGRibCA9IG1heCA9PT0gMSA/IG51bGwgOiB0aGlzLmRibCgpO1xuICBmb3IgKHZhciBpID0gMTsgaSA8IG1heDsgaSsrKVxuICAgIHJlc1tpXSA9IHJlc1tpIC0gMV0uYWRkKGRibCk7XG4gIHJldHVybiB7XG4gICAgd25kOiB3bmQsXG4gICAgcG9pbnRzOiByZXNcbiAgfTtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuX2dldEJldGEgPSBmdW5jdGlvbiBfZ2V0QmV0YSgpIHtcbiAgcmV0dXJuIG51bGw7XG59O1xuXG5CYXNlUG9pbnQucHJvdG90eXBlLmRibHAgPSBmdW5jdGlvbiBkYmxwKGspIHtcbiAgdmFyIHIgPSB0aGlzO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGs7IGkrKylcbiAgICByID0gci5kYmwoKTtcbiAgcmV0dXJuIHI7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG52YXIgQmFzZSA9IHJlcXVpcmUoJy4vYmFzZScpO1xuXG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xuXG5mdW5jdGlvbiBFZHdhcmRzQ3VydmUoY29uZikge1xuICAvLyBOT1RFOiBJbXBvcnRhbnQgYXMgd2UgYXJlIGNyZWF0aW5nIHBvaW50IGluIEJhc2UuY2FsbCgpXG4gIHRoaXMudHdpc3RlZCA9IChjb25mLmEgfCAwKSAhPT0gMTtcbiAgdGhpcy5tT25lQSA9IHRoaXMudHdpc3RlZCAmJiAoY29uZi5hIHwgMCkgPT09IC0xO1xuICB0aGlzLmV4dGVuZGVkID0gdGhpcy5tT25lQTtcblxuICBCYXNlLmNhbGwodGhpcywgJ2Vkd2FyZHMnLCBjb25mKTtcblxuICB0aGlzLmEgPSBuZXcgQk4oY29uZi5hLCAxNikudW1vZCh0aGlzLnJlZC5tKTtcbiAgdGhpcy5hID0gdGhpcy5hLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5jID0gbmV3IEJOKGNvbmYuYywgMTYpLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5jMiA9IHRoaXMuYy5yZWRTcXIoKTtcbiAgdGhpcy5kID0gbmV3IEJOKGNvbmYuZCwgMTYpLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5kZCA9IHRoaXMuZC5yZWRBZGQodGhpcy5kKTtcblxuICBhc3NlcnQoIXRoaXMudHdpc3RlZCB8fCB0aGlzLmMuZnJvbVJlZCgpLmNtcG4oMSkgPT09IDApO1xuICB0aGlzLm9uZUMgPSAoY29uZi5jIHwgMCkgPT09IDE7XG59XG5pbmhlcml0cyhFZHdhcmRzQ3VydmUsIEJhc2UpO1xubW9kdWxlLmV4cG9ydHMgPSBFZHdhcmRzQ3VydmU7XG5cbkVkd2FyZHNDdXJ2ZS5wcm90b3R5cGUuX211bEEgPSBmdW5jdGlvbiBfbXVsQShudW0pIHtcbiAgaWYgKHRoaXMubU9uZUEpXG4gICAgcmV0dXJuIG51bS5yZWROZWcoKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmEucmVkTXVsKG51bSk7XG59O1xuXG5FZHdhcmRzQ3VydmUucHJvdG90eXBlLl9tdWxDID0gZnVuY3Rpb24gX211bEMobnVtKSB7XG4gIGlmICh0aGlzLm9uZUMpXG4gICAgcmV0dXJuIG51bTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmMucmVkTXVsKG51bSk7XG59O1xuXG4vLyBKdXN0IGZvciBjb21wYXRpYmlsaXR5IHdpdGggU2hvcnQgY3VydmVcbkVkd2FyZHNDdXJ2ZS5wcm90b3R5cGUuanBvaW50ID0gZnVuY3Rpb24ganBvaW50KHgsIHksIHosIHQpIHtcbiAgcmV0dXJuIHRoaXMucG9pbnQoeCwgeSwgeiwgdCk7XG59O1xuXG5FZHdhcmRzQ3VydmUucHJvdG90eXBlLnBvaW50RnJvbVggPSBmdW5jdGlvbiBwb2ludEZyb21YKHgsIG9kZCkge1xuICB4ID0gbmV3IEJOKHgsIDE2KTtcbiAgaWYgKCF4LnJlZClcbiAgICB4ID0geC50b1JlZCh0aGlzLnJlZCk7XG5cbiAgdmFyIHgyID0geC5yZWRTcXIoKTtcbiAgdmFyIHJocyA9IHRoaXMuYzIucmVkU3ViKHRoaXMuYS5yZWRNdWwoeDIpKTtcbiAgdmFyIGxocyA9IHRoaXMub25lLnJlZFN1Yih0aGlzLmMyLnJlZE11bCh0aGlzLmQpLnJlZE11bCh4MikpO1xuXG4gIHZhciB5MiA9IHJocy5yZWRNdWwobGhzLnJlZEludm0oKSk7XG4gIHZhciB5ID0geTIucmVkU3FydCgpO1xuICBpZiAoeS5yZWRTcXIoKS5yZWRTdWIoeTIpLmNtcCh0aGlzLnplcm8pICE9PSAwKVxuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBwb2ludCcpO1xuXG4gIHZhciBpc09kZCA9IHkuZnJvbVJlZCgpLmlzT2RkKCk7XG4gIGlmIChvZGQgJiYgIWlzT2RkIHx8ICFvZGQgJiYgaXNPZGQpXG4gICAgeSA9IHkucmVkTmVnKCk7XG5cbiAgcmV0dXJuIHRoaXMucG9pbnQoeCwgeSk7XG59O1xuXG5FZHdhcmRzQ3VydmUucHJvdG90eXBlLnBvaW50RnJvbVkgPSBmdW5jdGlvbiBwb2ludEZyb21ZKHksIG9kZCkge1xuICB5ID0gbmV3IEJOKHksIDE2KTtcbiAgaWYgKCF5LnJlZClcbiAgICB5ID0geS50b1JlZCh0aGlzLnJlZCk7XG5cbiAgLy8geF4yID0gKHleMiAtIGNeMikgLyAoY14yIGQgeV4yIC0gYSlcbiAgdmFyIHkyID0geS5yZWRTcXIoKTtcbiAgdmFyIGxocyA9IHkyLnJlZFN1Yih0aGlzLmMyKTtcbiAgdmFyIHJocyA9IHkyLnJlZE11bCh0aGlzLmQpLnJlZE11bCh0aGlzLmMyKS5yZWRTdWIodGhpcy5hKTtcbiAgdmFyIHgyID0gbGhzLnJlZE11bChyaHMucmVkSW52bSgpKTtcblxuICBpZiAoeDIuY21wKHRoaXMuemVybykgPT09IDApIHtcbiAgICBpZiAob2RkKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHBvaW50Jyk7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIHRoaXMucG9pbnQodGhpcy56ZXJvLCB5KTtcbiAgfVxuXG4gIHZhciB4ID0geDIucmVkU3FydCgpO1xuICBpZiAoeC5yZWRTcXIoKS5yZWRTdWIoeDIpLmNtcCh0aGlzLnplcm8pICE9PSAwKVxuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBwb2ludCcpO1xuXG4gIGlmICh4LmZyb21SZWQoKS5pc09kZCgpICE9PSBvZGQpXG4gICAgeCA9IHgucmVkTmVnKCk7XG5cbiAgcmV0dXJuIHRoaXMucG9pbnQoeCwgeSk7XG59O1xuXG5FZHdhcmRzQ3VydmUucHJvdG90eXBlLnZhbGlkYXRlID0gZnVuY3Rpb24gdmFsaWRhdGUocG9pbnQpIHtcbiAgaWYgKHBvaW50LmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gdHJ1ZTtcblxuICAvLyBDdXJ2ZTogQSAqIFheMiArIFleMiA9IENeMiAqICgxICsgRCAqIFheMiAqIFleMilcbiAgcG9pbnQubm9ybWFsaXplKCk7XG5cbiAgdmFyIHgyID0gcG9pbnQueC5yZWRTcXIoKTtcbiAgdmFyIHkyID0gcG9pbnQueS5yZWRTcXIoKTtcbiAgdmFyIGxocyA9IHgyLnJlZE11bCh0aGlzLmEpLnJlZEFkZCh5Mik7XG4gIHZhciByaHMgPSB0aGlzLmMyLnJlZE11bCh0aGlzLm9uZS5yZWRBZGQodGhpcy5kLnJlZE11bCh4MikucmVkTXVsKHkyKSkpO1xuXG4gIHJldHVybiBsaHMuY21wKHJocykgPT09IDA7XG59O1xuXG5mdW5jdGlvbiBQb2ludChjdXJ2ZSwgeCwgeSwgeiwgdCkge1xuICBCYXNlLkJhc2VQb2ludC5jYWxsKHRoaXMsIGN1cnZlLCAncHJvamVjdGl2ZScpO1xuICBpZiAoeCA9PT0gbnVsbCAmJiB5ID09PSBudWxsICYmIHogPT09IG51bGwpIHtcbiAgICB0aGlzLnggPSB0aGlzLmN1cnZlLnplcm87XG4gICAgdGhpcy55ID0gdGhpcy5jdXJ2ZS5vbmU7XG4gICAgdGhpcy56ID0gdGhpcy5jdXJ2ZS5vbmU7XG4gICAgdGhpcy50ID0gdGhpcy5jdXJ2ZS56ZXJvO1xuICAgIHRoaXMuek9uZSA9IHRydWU7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy54ID0gbmV3IEJOKHgsIDE2KTtcbiAgICB0aGlzLnkgPSBuZXcgQk4oeSwgMTYpO1xuICAgIHRoaXMueiA9IHogPyBuZXcgQk4oeiwgMTYpIDogdGhpcy5jdXJ2ZS5vbmU7XG4gICAgdGhpcy50ID0gdCAmJiBuZXcgQk4odCwgMTYpO1xuICAgIGlmICghdGhpcy54LnJlZClcbiAgICAgIHRoaXMueCA9IHRoaXMueC50b1JlZCh0aGlzLmN1cnZlLnJlZCk7XG4gICAgaWYgKCF0aGlzLnkucmVkKVxuICAgICAgdGhpcy55ID0gdGhpcy55LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcbiAgICBpZiAoIXRoaXMuei5yZWQpXG4gICAgICB0aGlzLnogPSB0aGlzLnoudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICAgIGlmICh0aGlzLnQgJiYgIXRoaXMudC5yZWQpXG4gICAgICB0aGlzLnQgPSB0aGlzLnQudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICAgIHRoaXMuek9uZSA9IHRoaXMueiA9PT0gdGhpcy5jdXJ2ZS5vbmU7XG5cbiAgICAvLyBVc2UgZXh0ZW5kZWQgY29vcmRpbmF0ZXNcbiAgICBpZiAodGhpcy5jdXJ2ZS5leHRlbmRlZCAmJiAhdGhpcy50KSB7XG4gICAgICB0aGlzLnQgPSB0aGlzLngucmVkTXVsKHRoaXMueSk7XG4gICAgICBpZiAoIXRoaXMuek9uZSlcbiAgICAgICAgdGhpcy50ID0gdGhpcy50LnJlZE11bCh0aGlzLnoucmVkSW52bSgpKTtcbiAgICB9XG4gIH1cbn1cbmluaGVyaXRzKFBvaW50LCBCYXNlLkJhc2VQb2ludCk7XG5cbkVkd2FyZHNDdXJ2ZS5wcm90b3R5cGUucG9pbnRGcm9tSlNPTiA9IGZ1bmN0aW9uIHBvaW50RnJvbUpTT04ob2JqKSB7XG4gIHJldHVybiBQb2ludC5mcm9tSlNPTih0aGlzLCBvYmopO1xufTtcblxuRWR3YXJkc0N1cnZlLnByb3RvdHlwZS5wb2ludCA9IGZ1bmN0aW9uIHBvaW50KHgsIHksIHosIHQpIHtcbiAgcmV0dXJuIG5ldyBQb2ludCh0aGlzLCB4LCB5LCB6LCB0KTtcbn07XG5cblBvaW50LmZyb21KU09OID0gZnVuY3Rpb24gZnJvbUpTT04oY3VydmUsIG9iaikge1xuICByZXR1cm4gbmV3IFBvaW50KGN1cnZlLCBvYmpbMF0sIG9ialsxXSwgb2JqWzJdKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiAnPEVDIFBvaW50IEluZmluaXR5Pic7XG4gIHJldHVybiAnPEVDIFBvaW50IHg6ICcgKyB0aGlzLnguZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArXG4gICAgICAnIHk6ICcgKyB0aGlzLnkuZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArXG4gICAgICAnIHo6ICcgKyB0aGlzLnouZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArICc+Jztcbn07XG5cblBvaW50LnByb3RvdHlwZS5pc0luZmluaXR5ID0gZnVuY3Rpb24gaXNJbmZpbml0eSgpIHtcbiAgLy8gWFhYIFRoaXMgY29kZSBhc3N1bWVzIHRoYXQgemVybyBpcyBhbHdheXMgemVybyBpbiByZWRcbiAgcmV0dXJuIHRoaXMueC5jbXBuKDApID09PSAwICYmXG4gICAgKHRoaXMueS5jbXAodGhpcy56KSA9PT0gMCB8fFxuICAgICh0aGlzLnpPbmUgJiYgdGhpcy55LmNtcCh0aGlzLmN1cnZlLmMpID09PSAwKSk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuX2V4dERibCA9IGZ1bmN0aW9uIF9leHREYmwoKSB7XG4gIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by10d2lzdGVkLWV4dGVuZGVkLTEuaHRtbFxuICAvLyAgICAgI2RvdWJsaW5nLWRibC0yMDA4LWh3Y2RcbiAgLy8gNE0gKyA0U1xuXG4gIC8vIEEgPSBYMV4yXG4gIHZhciBhID0gdGhpcy54LnJlZFNxcigpO1xuICAvLyBCID0gWTFeMlxuICB2YXIgYiA9IHRoaXMueS5yZWRTcXIoKTtcbiAgLy8gQyA9IDIgKiBaMV4yXG4gIHZhciBjID0gdGhpcy56LnJlZFNxcigpO1xuICBjID0gYy5yZWRJQWRkKGMpO1xuICAvLyBEID0gYSAqIEFcbiAgdmFyIGQgPSB0aGlzLmN1cnZlLl9tdWxBKGEpO1xuICAvLyBFID0gKFgxICsgWTEpXjIgLSBBIC0gQlxuICB2YXIgZSA9IHRoaXMueC5yZWRBZGQodGhpcy55KS5yZWRTcXIoKS5yZWRJU3ViKGEpLnJlZElTdWIoYik7XG4gIC8vIEcgPSBEICsgQlxuICB2YXIgZyA9IGQucmVkQWRkKGIpO1xuICAvLyBGID0gRyAtIENcbiAgdmFyIGYgPSBnLnJlZFN1YihjKTtcbiAgLy8gSCA9IEQgLSBCXG4gIHZhciBoID0gZC5yZWRTdWIoYik7XG4gIC8vIFgzID0gRSAqIEZcbiAgdmFyIG54ID0gZS5yZWRNdWwoZik7XG4gIC8vIFkzID0gRyAqIEhcbiAgdmFyIG55ID0gZy5yZWRNdWwoaCk7XG4gIC8vIFQzID0gRSAqIEhcbiAgdmFyIG50ID0gZS5yZWRNdWwoaCk7XG4gIC8vIFozID0gRiAqIEdcbiAgdmFyIG56ID0gZi5yZWRNdWwoZyk7XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG54LCBueSwgbnosIG50KTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5fcHJvakRibCA9IGZ1bmN0aW9uIF9wcm9qRGJsKCkge1xuICAvLyBoeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tdHdpc3RlZC1wcm9qZWN0aXZlLmh0bWxcbiAgLy8gICAgICNkb3VibGluZy1kYmwtMjAwOC1iYmpscFxuICAvLyAgICAgI2RvdWJsaW5nLWRibC0yMDA3LWJsXG4gIC8vIGFuZCBvdGhlcnNcbiAgLy8gR2VuZXJhbGx5IDNNICsgNFMgb3IgMk0gKyA0U1xuXG4gIC8vIEIgPSAoWDEgKyBZMSleMlxuICB2YXIgYiA9IHRoaXMueC5yZWRBZGQodGhpcy55KS5yZWRTcXIoKTtcbiAgLy8gQyA9IFgxXjJcbiAgdmFyIGMgPSB0aGlzLngucmVkU3FyKCk7XG4gIC8vIEQgPSBZMV4yXG4gIHZhciBkID0gdGhpcy55LnJlZFNxcigpO1xuXG4gIHZhciBueDtcbiAgdmFyIG55O1xuICB2YXIgbno7XG4gIGlmICh0aGlzLmN1cnZlLnR3aXN0ZWQpIHtcbiAgICAvLyBFID0gYSAqIENcbiAgICB2YXIgZSA9IHRoaXMuY3VydmUuX211bEEoYyk7XG4gICAgLy8gRiA9IEUgKyBEXG4gICAgdmFyIGYgPSBlLnJlZEFkZChkKTtcbiAgICBpZiAodGhpcy56T25lKSB7XG4gICAgICAvLyBYMyA9IChCIC0gQyAtIEQpICogKEYgLSAyKVxuICAgICAgbnggPSBiLnJlZFN1YihjKS5yZWRTdWIoZCkucmVkTXVsKGYucmVkU3ViKHRoaXMuY3VydmUudHdvKSk7XG4gICAgICAvLyBZMyA9IEYgKiAoRSAtIEQpXG4gICAgICBueSA9IGYucmVkTXVsKGUucmVkU3ViKGQpKTtcbiAgICAgIC8vIFozID0gRl4yIC0gMiAqIEZcbiAgICAgIG56ID0gZi5yZWRTcXIoKS5yZWRTdWIoZikucmVkU3ViKGYpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBIID0gWjFeMlxuICAgICAgdmFyIGggPSB0aGlzLnoucmVkU3FyKCk7XG4gICAgICAvLyBKID0gRiAtIDIgKiBIXG4gICAgICB2YXIgaiA9IGYucmVkU3ViKGgpLnJlZElTdWIoaCk7XG4gICAgICAvLyBYMyA9IChCLUMtRCkqSlxuICAgICAgbnggPSBiLnJlZFN1YihjKS5yZWRJU3ViKGQpLnJlZE11bChqKTtcbiAgICAgIC8vIFkzID0gRiAqIChFIC0gRClcbiAgICAgIG55ID0gZi5yZWRNdWwoZS5yZWRTdWIoZCkpO1xuICAgICAgLy8gWjMgPSBGICogSlxuICAgICAgbnogPSBmLnJlZE11bChqKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gRSA9IEMgKyBEXG4gICAgdmFyIGUgPSBjLnJlZEFkZChkKTtcbiAgICAvLyBIID0gKGMgKiBaMSleMlxuICAgIHZhciBoID0gdGhpcy5jdXJ2ZS5fbXVsQyh0aGlzLnopLnJlZFNxcigpO1xuICAgIC8vIEogPSBFIC0gMiAqIEhcbiAgICB2YXIgaiA9IGUucmVkU3ViKGgpLnJlZFN1YihoKTtcbiAgICAvLyBYMyA9IGMgKiAoQiAtIEUpICogSlxuICAgIG54ID0gdGhpcy5jdXJ2ZS5fbXVsQyhiLnJlZElTdWIoZSkpLnJlZE11bChqKTtcbiAgICAvLyBZMyA9IGMgKiBFICogKEMgLSBEKVxuICAgIG55ID0gdGhpcy5jdXJ2ZS5fbXVsQyhlKS5yZWRNdWwoYy5yZWRJU3ViKGQpKTtcbiAgICAvLyBaMyA9IEUgKiBKXG4gICAgbnogPSBlLnJlZE11bChqKTtcbiAgfVxuICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChueCwgbnksIG56KTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5kYmwgPSBmdW5jdGlvbiBkYmwoKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBEb3VibGUgaW4gZXh0ZW5kZWQgY29vcmRpbmF0ZXNcbiAgaWYgKHRoaXMuY3VydmUuZXh0ZW5kZWQpXG4gICAgcmV0dXJuIHRoaXMuX2V4dERibCgpO1xuICBlbHNlXG4gICAgcmV0dXJuIHRoaXMuX3Byb2pEYmwoKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5fZXh0QWRkID0gZnVuY3Rpb24gX2V4dEFkZChwKSB7XG4gIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by10d2lzdGVkLWV4dGVuZGVkLTEuaHRtbFxuICAvLyAgICAgI2FkZGl0aW9uLWFkZC0yMDA4LWh3Y2QtM1xuICAvLyA4TVxuXG4gIC8vIEEgPSAoWTEgLSBYMSkgKiAoWTIgLSBYMilcbiAgdmFyIGEgPSB0aGlzLnkucmVkU3ViKHRoaXMueCkucmVkTXVsKHAueS5yZWRTdWIocC54KSk7XG4gIC8vIEIgPSAoWTEgKyBYMSkgKiAoWTIgKyBYMilcbiAgdmFyIGIgPSB0aGlzLnkucmVkQWRkKHRoaXMueCkucmVkTXVsKHAueS5yZWRBZGQocC54KSk7XG4gIC8vIEMgPSBUMSAqIGsgKiBUMlxuICB2YXIgYyA9IHRoaXMudC5yZWRNdWwodGhpcy5jdXJ2ZS5kZCkucmVkTXVsKHAudCk7XG4gIC8vIEQgPSBaMSAqIDIgKiBaMlxuICB2YXIgZCA9IHRoaXMuei5yZWRNdWwocC56LnJlZEFkZChwLnopKTtcbiAgLy8gRSA9IEIgLSBBXG4gIHZhciBlID0gYi5yZWRTdWIoYSk7XG4gIC8vIEYgPSBEIC0gQ1xuICB2YXIgZiA9IGQucmVkU3ViKGMpO1xuICAvLyBHID0gRCArIENcbiAgdmFyIGcgPSBkLnJlZEFkZChjKTtcbiAgLy8gSCA9IEIgKyBBXG4gIHZhciBoID0gYi5yZWRBZGQoYSk7XG4gIC8vIFgzID0gRSAqIEZcbiAgdmFyIG54ID0gZS5yZWRNdWwoZik7XG4gIC8vIFkzID0gRyAqIEhcbiAgdmFyIG55ID0gZy5yZWRNdWwoaCk7XG4gIC8vIFQzID0gRSAqIEhcbiAgdmFyIG50ID0gZS5yZWRNdWwoaCk7XG4gIC8vIFozID0gRiAqIEdcbiAgdmFyIG56ID0gZi5yZWRNdWwoZyk7XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG54LCBueSwgbnosIG50KTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5fcHJvakFkZCA9IGZ1bmN0aW9uIF9wcm9qQWRkKHApIHtcbiAgLy8gaHlwZXJlbGxpcHRpYy5vcmcvRUZEL2cxcC9hdXRvLXR3aXN0ZWQtcHJvamVjdGl2ZS5odG1sXG4gIC8vICAgICAjYWRkaXRpb24tYWRkLTIwMDgtYmJqbHBcbiAgLy8gICAgICNhZGRpdGlvbi1hZGQtMjAwNy1ibFxuICAvLyAxME0gKyAxU1xuXG4gIC8vIEEgPSBaMSAqIFoyXG4gIHZhciBhID0gdGhpcy56LnJlZE11bChwLnopO1xuICAvLyBCID0gQV4yXG4gIHZhciBiID0gYS5yZWRTcXIoKTtcbiAgLy8gQyA9IFgxICogWDJcbiAgdmFyIGMgPSB0aGlzLngucmVkTXVsKHAueCk7XG4gIC8vIEQgPSBZMSAqIFkyXG4gIHZhciBkID0gdGhpcy55LnJlZE11bChwLnkpO1xuICAvLyBFID0gZCAqIEMgKiBEXG4gIHZhciBlID0gdGhpcy5jdXJ2ZS5kLnJlZE11bChjKS5yZWRNdWwoZCk7XG4gIC8vIEYgPSBCIC0gRVxuICB2YXIgZiA9IGIucmVkU3ViKGUpO1xuICAvLyBHID0gQiArIEVcbiAgdmFyIGcgPSBiLnJlZEFkZChlKTtcbiAgLy8gWDMgPSBBICogRiAqICgoWDEgKyBZMSkgKiAoWDIgKyBZMikgLSBDIC0gRClcbiAgdmFyIHRtcCA9IHRoaXMueC5yZWRBZGQodGhpcy55KS5yZWRNdWwocC54LnJlZEFkZChwLnkpKS5yZWRJU3ViKGMpLnJlZElTdWIoZCk7XG4gIHZhciBueCA9IGEucmVkTXVsKGYpLnJlZE11bCh0bXApO1xuICB2YXIgbnk7XG4gIHZhciBuejtcbiAgaWYgKHRoaXMuY3VydmUudHdpc3RlZCkge1xuICAgIC8vIFkzID0gQSAqIEcgKiAoRCAtIGEgKiBDKVxuICAgIG55ID0gYS5yZWRNdWwoZykucmVkTXVsKGQucmVkU3ViKHRoaXMuY3VydmUuX211bEEoYykpKTtcbiAgICAvLyBaMyA9IEYgKiBHXG4gICAgbnogPSBmLnJlZE11bChnKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBZMyA9IEEgKiBHICogKEQgLSBDKVxuICAgIG55ID0gYS5yZWRNdWwoZykucmVkTXVsKGQucmVkU3ViKGMpKTtcbiAgICAvLyBaMyA9IGMgKiBGICogR1xuICAgIG56ID0gdGhpcy5jdXJ2ZS5fbXVsQyhmKS5yZWRNdWwoZyk7XG4gIH1cbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobngsIG55LCBueik7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gYWRkKHApIHtcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiBwO1xuICBpZiAocC5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgaWYgKHRoaXMuY3VydmUuZXh0ZW5kZWQpXG4gICAgcmV0dXJuIHRoaXMuX2V4dEFkZChwKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLl9wcm9qQWRkKHApO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm11bCA9IGZ1bmN0aW9uIG11bChrKSB7XG4gIGlmICh0aGlzLl9oYXNEb3VibGVzKGspKVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl9maXhlZE5hZk11bCh0aGlzLCBrKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl93bmFmTXVsKHRoaXMsIGspO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm11bEFkZCA9IGZ1bmN0aW9uIG11bEFkZChrMSwgcCwgazIpIHtcbiAgcmV0dXJuIHRoaXMuY3VydmUuX3duYWZNdWxBZGQoMSwgWyB0aGlzLCBwIF0sIFsgazEsIGsyIF0sIDIsIGZhbHNlKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5qbXVsQWRkID0gZnVuY3Rpb24gam11bEFkZChrMSwgcCwgazIpIHtcbiAgcmV0dXJuIHRoaXMuY3VydmUuX3duYWZNdWxBZGQoMSwgWyB0aGlzLCBwIF0sIFsgazEsIGsyIF0sIDIsIHRydWUpO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm5vcm1hbGl6ZSA9IGZ1bmN0aW9uIG5vcm1hbGl6ZSgpIHtcbiAgaWYgKHRoaXMuek9uZSlcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBOb3JtYWxpemUgY29vcmRpbmF0ZXNcbiAgdmFyIHppID0gdGhpcy56LnJlZEludm0oKTtcbiAgdGhpcy54ID0gdGhpcy54LnJlZE11bCh6aSk7XG4gIHRoaXMueSA9IHRoaXMueS5yZWRNdWwoemkpO1xuICBpZiAodGhpcy50KVxuICAgIHRoaXMudCA9IHRoaXMudC5yZWRNdWwoemkpO1xuICB0aGlzLnogPSB0aGlzLmN1cnZlLm9uZTtcbiAgdGhpcy56T25lID0gdHJ1ZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUubmVnID0gZnVuY3Rpb24gbmVnKCkge1xuICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludCh0aGlzLngucmVkTmVnKCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMueSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy56LFxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnQgJiYgdGhpcy50LnJlZE5lZygpKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5nZXRYID0gZnVuY3Rpb24gZ2V0WCgpIHtcbiAgdGhpcy5ub3JtYWxpemUoKTtcbiAgcmV0dXJuIHRoaXMueC5mcm9tUmVkKCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZ2V0WSA9IGZ1bmN0aW9uIGdldFkoKSB7XG4gIHRoaXMubm9ybWFsaXplKCk7XG4gIHJldHVybiB0aGlzLnkuZnJvbVJlZCgpO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmVxID0gZnVuY3Rpb24gZXEob3RoZXIpIHtcbiAgcmV0dXJuIHRoaXMgPT09IG90aGVyIHx8XG4gICAgICAgICB0aGlzLmdldFgoKS5jbXAob3RoZXIuZ2V0WCgpKSA9PT0gMCAmJlxuICAgICAgICAgdGhpcy5nZXRZKCkuY21wKG90aGVyLmdldFkoKSkgPT09IDA7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZXFYVG9QID0gZnVuY3Rpb24gZXFYVG9QKHgpIHtcbiAgdmFyIHJ4ID0geC50b1JlZCh0aGlzLmN1cnZlLnJlZCkucmVkTXVsKHRoaXMueik7XG4gIGlmICh0aGlzLnguY21wKHJ4KSA9PT0gMClcbiAgICByZXR1cm4gdHJ1ZTtcblxuICB2YXIgeGMgPSB4LmNsb25lKCk7XG4gIHZhciB0ID0gdGhpcy5jdXJ2ZS5yZWROLnJlZE11bCh0aGlzLnopO1xuICBmb3IgKDs7KSB7XG4gICAgeGMuaWFkZCh0aGlzLmN1cnZlLm4pO1xuICAgIGlmICh4Yy5jbXAodGhpcy5jdXJ2ZS5wKSA+PSAwKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgcngucmVkSUFkZCh0KTtcbiAgICBpZiAodGhpcy54LmNtcChyeCkgPT09IDApXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufTtcblxuLy8gQ29tcGF0aWJpbGl0eSB3aXRoIEJhc2VDdXJ2ZVxuUG9pbnQucHJvdG90eXBlLnRvUCA9IFBvaW50LnByb3RvdHlwZS5ub3JtYWxpemU7XG5Qb2ludC5wcm90b3R5cGUubWl4ZWRBZGQgPSBQb2ludC5wcm90b3R5cGUuYWRkO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3VydmUgPSBleHBvcnRzO1xuXG5jdXJ2ZS5iYXNlID0gcmVxdWlyZSgnLi9iYXNlJyk7XG5jdXJ2ZS5zaG9ydCA9IHJlcXVpcmUoJy4vc2hvcnQnKTtcbmN1cnZlLm1vbnQgPSByZXF1aXJlKCcuL21vbnQnKTtcbmN1cnZlLmVkd2FyZHMgPSByZXF1aXJlKCcuL2Vkd2FyZHMnKTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG52YXIgQmFzZSA9IHJlcXVpcmUoJy4vYmFzZScpO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xuXG5mdW5jdGlvbiBNb250Q3VydmUoY29uZikge1xuICBCYXNlLmNhbGwodGhpcywgJ21vbnQnLCBjb25mKTtcblxuICB0aGlzLmEgPSBuZXcgQk4oY29uZi5hLCAxNikudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLmIgPSBuZXcgQk4oY29uZi5iLCAxNikudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLmk0ID0gbmV3IEJOKDQpLnRvUmVkKHRoaXMucmVkKS5yZWRJbnZtKCk7XG4gIHRoaXMudHdvID0gbmV3IEJOKDIpLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5hMjQgPSB0aGlzLmk0LnJlZE11bCh0aGlzLmEucmVkQWRkKHRoaXMudHdvKSk7XG59XG5pbmhlcml0cyhNb250Q3VydmUsIEJhc2UpO1xubW9kdWxlLmV4cG9ydHMgPSBNb250Q3VydmU7XG5cbk1vbnRDdXJ2ZS5wcm90b3R5cGUudmFsaWRhdGUgPSBmdW5jdGlvbiB2YWxpZGF0ZShwb2ludCkge1xuICB2YXIgeCA9IHBvaW50Lm5vcm1hbGl6ZSgpLng7XG4gIHZhciB4MiA9IHgucmVkU3FyKCk7XG4gIHZhciByaHMgPSB4Mi5yZWRNdWwoeCkucmVkQWRkKHgyLnJlZE11bCh0aGlzLmEpKS5yZWRBZGQoeCk7XG4gIHZhciB5ID0gcmhzLnJlZFNxcnQoKTtcblxuICByZXR1cm4geS5yZWRTcXIoKS5jbXAocmhzKSA9PT0gMDtcbn07XG5cbmZ1bmN0aW9uIFBvaW50KGN1cnZlLCB4LCB6KSB7XG4gIEJhc2UuQmFzZVBvaW50LmNhbGwodGhpcywgY3VydmUsICdwcm9qZWN0aXZlJyk7XG4gIGlmICh4ID09PSBudWxsICYmIHogPT09IG51bGwpIHtcbiAgICB0aGlzLnggPSB0aGlzLmN1cnZlLm9uZTtcbiAgICB0aGlzLnogPSB0aGlzLmN1cnZlLnplcm87XG4gIH0gZWxzZSB7XG4gICAgdGhpcy54ID0gbmV3IEJOKHgsIDE2KTtcbiAgICB0aGlzLnogPSBuZXcgQk4oeiwgMTYpO1xuICAgIGlmICghdGhpcy54LnJlZClcbiAgICAgIHRoaXMueCA9IHRoaXMueC50b1JlZCh0aGlzLmN1cnZlLnJlZCk7XG4gICAgaWYgKCF0aGlzLnoucmVkKVxuICAgICAgdGhpcy56ID0gdGhpcy56LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcbiAgfVxufVxuaW5oZXJpdHMoUG9pbnQsIEJhc2UuQmFzZVBvaW50KTtcblxuTW9udEN1cnZlLnByb3RvdHlwZS5kZWNvZGVQb2ludCA9IGZ1bmN0aW9uIGRlY29kZVBvaW50KGJ5dGVzLCBlbmMpIHtcbiAgcmV0dXJuIHRoaXMucG9pbnQodXRpbHMudG9BcnJheShieXRlcywgZW5jKSwgMSk7XG59O1xuXG5Nb250Q3VydmUucHJvdG90eXBlLnBvaW50ID0gZnVuY3Rpb24gcG9pbnQoeCwgeikge1xuICByZXR1cm4gbmV3IFBvaW50KHRoaXMsIHgsIHopO1xufTtcblxuTW9udEN1cnZlLnByb3RvdHlwZS5wb2ludEZyb21KU09OID0gZnVuY3Rpb24gcG9pbnRGcm9tSlNPTihvYmopIHtcbiAgcmV0dXJuIFBvaW50LmZyb21KU09OKHRoaXMsIG9iaik7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUucHJlY29tcHV0ZSA9IGZ1bmN0aW9uIHByZWNvbXB1dGUoKSB7XG4gIC8vIE5vLW9wXG59O1xuXG5Qb2ludC5wcm90b3R5cGUuX2VuY29kZSA9IGZ1bmN0aW9uIF9lbmNvZGUoKSB7XG4gIHJldHVybiB0aGlzLmdldFgoKS50b0FycmF5KCdiZScsIHRoaXMuY3VydmUucC5ieXRlTGVuZ3RoKCkpO1xufTtcblxuUG9pbnQuZnJvbUpTT04gPSBmdW5jdGlvbiBmcm9tSlNPTihjdXJ2ZSwgb2JqKSB7XG4gIHJldHVybiBuZXcgUG9pbnQoY3VydmUsIG9ialswXSwgb2JqWzFdIHx8IGN1cnZlLm9uZSk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QoKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gJzxFQyBQb2ludCBJbmZpbml0eT4nO1xuICByZXR1cm4gJzxFQyBQb2ludCB4OiAnICsgdGhpcy54LmZyb21SZWQoKS50b1N0cmluZygxNiwgMikgK1xuICAgICAgJyB6OiAnICsgdGhpcy56LmZyb21SZWQoKS50b1N0cmluZygxNiwgMikgKyAnPic7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuaXNJbmZpbml0eSA9IGZ1bmN0aW9uIGlzSW5maW5pdHkoKSB7XG4gIC8vIFhYWCBUaGlzIGNvZGUgYXNzdW1lcyB0aGF0IHplcm8gaXMgYWx3YXlzIHplcm8gaW4gcmVkXG4gIHJldHVybiB0aGlzLnouY21wbigwKSA9PT0gMDtcbn07XG5cblBvaW50LnByb3RvdHlwZS5kYmwgPSBmdW5jdGlvbiBkYmwoKSB7XG4gIC8vIGh0dHA6Ly9oeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tbW9udGdvbS14ei5odG1sI2RvdWJsaW5nLWRibC0xOTg3LW0tM1xuICAvLyAyTSArIDJTICsgNEFcblxuICAvLyBBID0gWDEgKyBaMVxuICB2YXIgYSA9IHRoaXMueC5yZWRBZGQodGhpcy56KTtcbiAgLy8gQUEgPSBBXjJcbiAgdmFyIGFhID0gYS5yZWRTcXIoKTtcbiAgLy8gQiA9IFgxIC0gWjFcbiAgdmFyIGIgPSB0aGlzLngucmVkU3ViKHRoaXMueik7XG4gIC8vIEJCID0gQl4yXG4gIHZhciBiYiA9IGIucmVkU3FyKCk7XG4gIC8vIEMgPSBBQSAtIEJCXG4gIHZhciBjID0gYWEucmVkU3ViKGJiKTtcbiAgLy8gWDMgPSBBQSAqIEJCXG4gIHZhciBueCA9IGFhLnJlZE11bChiYik7XG4gIC8vIFozID0gQyAqIChCQiArIEEyNCAqIEMpXG4gIHZhciBueiA9IGMucmVkTXVsKGJiLnJlZEFkZCh0aGlzLmN1cnZlLmEyNC5yZWRNdWwoYykpKTtcbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobngsIG56KTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiBhZGQoKSB7XG4gIHRocm93IG5ldyBFcnJvcignTm90IHN1cHBvcnRlZCBvbiBNb250Z29tZXJ5IGN1cnZlJyk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZGlmZkFkZCA9IGZ1bmN0aW9uIGRpZmZBZGQocCwgZGlmZikge1xuICAvLyBodHRwOi8vaHlwZXJlbGxpcHRpYy5vcmcvRUZEL2cxcC9hdXRvLW1vbnRnb20teHouaHRtbCNkaWZmYWRkLWRhZGQtMTk4Ny1tLTNcbiAgLy8gNE0gKyAyUyArIDZBXG5cbiAgLy8gQSA9IFgyICsgWjJcbiAgdmFyIGEgPSB0aGlzLngucmVkQWRkKHRoaXMueik7XG4gIC8vIEIgPSBYMiAtIFoyXG4gIHZhciBiID0gdGhpcy54LnJlZFN1Yih0aGlzLnopO1xuICAvLyBDID0gWDMgKyBaM1xuICB2YXIgYyA9IHAueC5yZWRBZGQocC56KTtcbiAgLy8gRCA9IFgzIC0gWjNcbiAgdmFyIGQgPSBwLngucmVkU3ViKHAueik7XG4gIC8vIERBID0gRCAqIEFcbiAgdmFyIGRhID0gZC5yZWRNdWwoYSk7XG4gIC8vIENCID0gQyAqIEJcbiAgdmFyIGNiID0gYy5yZWRNdWwoYik7XG4gIC8vIFg1ID0gWjEgKiAoREEgKyBDQileMlxuICB2YXIgbnggPSBkaWZmLnoucmVkTXVsKGRhLnJlZEFkZChjYikucmVkU3FyKCkpO1xuICAvLyBaNSA9IFgxICogKERBIC0gQ0IpXjJcbiAgdmFyIG56ID0gZGlmZi54LnJlZE11bChkYS5yZWRJU3ViKGNiKS5yZWRTcXIoKSk7XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG54LCBueik7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUubXVsID0gZnVuY3Rpb24gbXVsKGspIHtcbiAgdmFyIHQgPSBrLmNsb25lKCk7XG4gIHZhciBhID0gdGhpczsgLy8gKE4gLyAyKSAqIFEgKyBRXG4gIHZhciBiID0gdGhpcy5jdXJ2ZS5wb2ludChudWxsLCBudWxsKTsgLy8gKE4gLyAyKSAqIFFcbiAgdmFyIGMgPSB0aGlzOyAvLyBRXG5cbiAgZm9yICh2YXIgYml0cyA9IFtdOyB0LmNtcG4oMCkgIT09IDA7IHQuaXVzaHJuKDEpKVxuICAgIGJpdHMucHVzaCh0LmFuZGxuKDEpKTtcblxuICBmb3IgKHZhciBpID0gYml0cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGlmIChiaXRzW2ldID09PSAwKSB7XG4gICAgICAvLyBOICogUSArIFEgPSAoKE4gLyAyKSAqIFEgKyBRKSkgKyAoTiAvIDIpICogUVxuICAgICAgYSA9IGEuZGlmZkFkZChiLCBjKTtcbiAgICAgIC8vIE4gKiBRID0gMiAqICgoTiAvIDIpICogUSArIFEpKVxuICAgICAgYiA9IGIuZGJsKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE4gKiBRID0gKChOIC8gMikgKiBRICsgUSkgKyAoKE4gLyAyKSAqIFEpXG4gICAgICBiID0gYS5kaWZmQWRkKGIsIGMpO1xuICAgICAgLy8gTiAqIFEgKyBRID0gMiAqICgoTiAvIDIpICogUSArIFEpXG4gICAgICBhID0gYS5kYmwoKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGI7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUubXVsQWRkID0gZnVuY3Rpb24gbXVsQWRkKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBzdXBwb3J0ZWQgb24gTW9udGdvbWVyeSBjdXJ2ZScpO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmp1bWxBZGQgPSBmdW5jdGlvbiBqdW1sQWRkKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBzdXBwb3J0ZWQgb24gTW9udGdvbWVyeSBjdXJ2ZScpO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmVxID0gZnVuY3Rpb24gZXEob3RoZXIpIHtcbiAgcmV0dXJuIHRoaXMuZ2V0WCgpLmNtcChvdGhlci5nZXRYKCkpID09PSAwO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm5vcm1hbGl6ZSA9IGZ1bmN0aW9uIG5vcm1hbGl6ZSgpIHtcbiAgdGhpcy54ID0gdGhpcy54LnJlZE11bCh0aGlzLnoucmVkSW52bSgpKTtcbiAgdGhpcy56ID0gdGhpcy5jdXJ2ZS5vbmU7XG4gIHJldHVybiB0aGlzO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmdldFggPSBmdW5jdGlvbiBnZXRYKCkge1xuICAvLyBOb3JtYWxpemUgY29vcmRpbmF0ZXNcbiAgdGhpcy5ub3JtYWxpemUoKTtcblxuICByZXR1cm4gdGhpcy54LmZyb21SZWQoKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbnZhciBCYXNlID0gcmVxdWlyZSgnLi9iYXNlJyk7XG5cbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG5cbmZ1bmN0aW9uIFNob3J0Q3VydmUoY29uZikge1xuICBCYXNlLmNhbGwodGhpcywgJ3Nob3J0JywgY29uZik7XG5cbiAgdGhpcy5hID0gbmV3IEJOKGNvbmYuYSwgMTYpLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5iID0gbmV3IEJOKGNvbmYuYiwgMTYpLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy50aW52ID0gdGhpcy50d28ucmVkSW52bSgpO1xuXG4gIHRoaXMuemVyb0EgPSB0aGlzLmEuZnJvbVJlZCgpLmNtcG4oMCkgPT09IDA7XG4gIHRoaXMudGhyZWVBID0gdGhpcy5hLmZyb21SZWQoKS5zdWIodGhpcy5wKS5jbXBuKC0zKSA9PT0gMDtcblxuICAvLyBJZiB0aGUgY3VydmUgaXMgZW5kb21vcnBoaWMsIHByZWNhbGN1bGF0ZSBiZXRhIGFuZCBsYW1iZGFcbiAgdGhpcy5lbmRvID0gdGhpcy5fZ2V0RW5kb21vcnBoaXNtKGNvbmYpO1xuICB0aGlzLl9lbmRvV25hZlQxID0gbmV3IEFycmF5KDQpO1xuICB0aGlzLl9lbmRvV25hZlQyID0gbmV3IEFycmF5KDQpO1xufVxuaW5oZXJpdHMoU2hvcnRDdXJ2ZSwgQmFzZSk7XG5tb2R1bGUuZXhwb3J0cyA9IFNob3J0Q3VydmU7XG5cblNob3J0Q3VydmUucHJvdG90eXBlLl9nZXRFbmRvbW9ycGhpc20gPSBmdW5jdGlvbiBfZ2V0RW5kb21vcnBoaXNtKGNvbmYpIHtcbiAgLy8gTm8gZWZmaWNpZW50IGVuZG9tb3JwaGlzbVxuICBpZiAoIXRoaXMuemVyb0EgfHwgIXRoaXMuZyB8fCAhdGhpcy5uIHx8IHRoaXMucC5tb2RuKDMpICE9PSAxKVxuICAgIHJldHVybjtcblxuICAvLyBDb21wdXRlIGJldGEgYW5kIGxhbWJkYSwgdGhhdCBsYW1iZGEgKiBQID0gKGJldGEgKiBQeDsgUHkpXG4gIHZhciBiZXRhO1xuICB2YXIgbGFtYmRhO1xuICBpZiAoY29uZi5iZXRhKSB7XG4gICAgYmV0YSA9IG5ldyBCTihjb25mLmJldGEsIDE2KS50b1JlZCh0aGlzLnJlZCk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGJldGFzID0gdGhpcy5fZ2V0RW5kb1Jvb3RzKHRoaXMucCk7XG4gICAgLy8gQ2hvb3NlIHRoZSBzbWFsbGVzdCBiZXRhXG4gICAgYmV0YSA9IGJldGFzWzBdLmNtcChiZXRhc1sxXSkgPCAwID8gYmV0YXNbMF0gOiBiZXRhc1sxXTtcbiAgICBiZXRhID0gYmV0YS50b1JlZCh0aGlzLnJlZCk7XG4gIH1cbiAgaWYgKGNvbmYubGFtYmRhKSB7XG4gICAgbGFtYmRhID0gbmV3IEJOKGNvbmYubGFtYmRhLCAxNik7XG4gIH0gZWxzZSB7XG4gICAgLy8gQ2hvb3NlIHRoZSBsYW1iZGEgdGhhdCBpcyBtYXRjaGluZyBzZWxlY3RlZCBiZXRhXG4gICAgdmFyIGxhbWJkYXMgPSB0aGlzLl9nZXRFbmRvUm9vdHModGhpcy5uKTtcbiAgICBpZiAodGhpcy5nLm11bChsYW1iZGFzWzBdKS54LmNtcCh0aGlzLmcueC5yZWRNdWwoYmV0YSkpID09PSAwKSB7XG4gICAgICBsYW1iZGEgPSBsYW1iZGFzWzBdO1xuICAgIH0gZWxzZSB7XG4gICAgICBsYW1iZGEgPSBsYW1iZGFzWzFdO1xuICAgICAgYXNzZXJ0KHRoaXMuZy5tdWwobGFtYmRhKS54LmNtcCh0aGlzLmcueC5yZWRNdWwoYmV0YSkpID09PSAwKTtcbiAgICB9XG4gIH1cblxuICAvLyBHZXQgYmFzaXMgdmVjdG9ycywgdXNlZCBmb3IgYmFsYW5jZWQgbGVuZ3RoLXR3byByZXByZXNlbnRhdGlvblxuICB2YXIgYmFzaXM7XG4gIGlmIChjb25mLmJhc2lzKSB7XG4gICAgYmFzaXMgPSBjb25mLmJhc2lzLm1hcChmdW5jdGlvbih2ZWMpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGE6IG5ldyBCTih2ZWMuYSwgMTYpLFxuICAgICAgICBiOiBuZXcgQk4odmVjLmIsIDE2KVxuICAgICAgfTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBiYXNpcyA9IHRoaXMuX2dldEVuZG9CYXNpcyhsYW1iZGEpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBiZXRhOiBiZXRhLFxuICAgIGxhbWJkYTogbGFtYmRhLFxuICAgIGJhc2lzOiBiYXNpc1xuICB9O1xufTtcblxuU2hvcnRDdXJ2ZS5wcm90b3R5cGUuX2dldEVuZG9Sb290cyA9IGZ1bmN0aW9uIF9nZXRFbmRvUm9vdHMobnVtKSB7XG4gIC8vIEZpbmQgcm9vdHMgb2YgZm9yIHheMiArIHggKyAxIGluIEZcbiAgLy8gUm9vdCA9ICgtMSArLSBTcXJ0KC0zKSkgLyAyXG4gIC8vXG4gIHZhciByZWQgPSBudW0gPT09IHRoaXMucCA/IHRoaXMucmVkIDogQk4ubW9udChudW0pO1xuICB2YXIgdGludiA9IG5ldyBCTigyKS50b1JlZChyZWQpLnJlZEludm0oKTtcbiAgdmFyIG50aW52ID0gdGludi5yZWROZWcoKTtcblxuICB2YXIgcyA9IG5ldyBCTigzKS50b1JlZChyZWQpLnJlZE5lZygpLnJlZFNxcnQoKS5yZWRNdWwodGludik7XG5cbiAgdmFyIGwxID0gbnRpbnYucmVkQWRkKHMpLmZyb21SZWQoKTtcbiAgdmFyIGwyID0gbnRpbnYucmVkU3ViKHMpLmZyb21SZWQoKTtcbiAgcmV0dXJuIFsgbDEsIGwyIF07XG59O1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS5fZ2V0RW5kb0Jhc2lzID0gZnVuY3Rpb24gX2dldEVuZG9CYXNpcyhsYW1iZGEpIHtcbiAgLy8gYXByeFNxcnQgPj0gc3FydCh0aGlzLm4pXG4gIHZhciBhcHJ4U3FydCA9IHRoaXMubi51c2hybihNYXRoLmZsb29yKHRoaXMubi5iaXRMZW5ndGgoKSAvIDIpKTtcblxuICAvLyAzLjc0XG4gIC8vIFJ1biBFR0NELCB1bnRpbCByKEwgKyAxKSA8IGFwcnhTcXJ0XG4gIHZhciB1ID0gbGFtYmRhO1xuICB2YXIgdiA9IHRoaXMubi5jbG9uZSgpO1xuICB2YXIgeDEgPSBuZXcgQk4oMSk7XG4gIHZhciB5MSA9IG5ldyBCTigwKTtcbiAgdmFyIHgyID0gbmV3IEJOKDApO1xuICB2YXIgeTIgPSBuZXcgQk4oMSk7XG5cbiAgLy8gTk9URTogYWxsIHZlY3RvcnMgYXJlIHJvb3RzIG9mOiBhICsgYiAqIGxhbWJkYSA9IDAgKG1vZCBuKVxuICB2YXIgYTA7XG4gIHZhciBiMDtcbiAgLy8gRmlyc3QgdmVjdG9yXG4gIHZhciBhMTtcbiAgdmFyIGIxO1xuICAvLyBTZWNvbmQgdmVjdG9yXG4gIHZhciBhMjtcbiAgdmFyIGIyO1xuXG4gIHZhciBwcmV2UjtcbiAgdmFyIGkgPSAwO1xuICB2YXIgcjtcbiAgdmFyIHg7XG4gIHdoaWxlICh1LmNtcG4oMCkgIT09IDApIHtcbiAgICB2YXIgcSA9IHYuZGl2KHUpO1xuICAgIHIgPSB2LnN1YihxLm11bCh1KSk7XG4gICAgeCA9IHgyLnN1YihxLm11bCh4MSkpO1xuICAgIHZhciB5ID0geTIuc3ViKHEubXVsKHkxKSk7XG5cbiAgICBpZiAoIWExICYmIHIuY21wKGFwcnhTcXJ0KSA8IDApIHtcbiAgICAgIGEwID0gcHJldlIubmVnKCk7XG4gICAgICBiMCA9IHgxO1xuICAgICAgYTEgPSByLm5lZygpO1xuICAgICAgYjEgPSB4O1xuICAgIH0gZWxzZSBpZiAoYTEgJiYgKytpID09PSAyKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgcHJldlIgPSByO1xuXG4gICAgdiA9IHU7XG4gICAgdSA9IHI7XG4gICAgeDIgPSB4MTtcbiAgICB4MSA9IHg7XG4gICAgeTIgPSB5MTtcbiAgICB5MSA9IHk7XG4gIH1cbiAgYTIgPSByLm5lZygpO1xuICBiMiA9IHg7XG5cbiAgdmFyIGxlbjEgPSBhMS5zcXIoKS5hZGQoYjEuc3FyKCkpO1xuICB2YXIgbGVuMiA9IGEyLnNxcigpLmFkZChiMi5zcXIoKSk7XG4gIGlmIChsZW4yLmNtcChsZW4xKSA+PSAwKSB7XG4gICAgYTIgPSBhMDtcbiAgICBiMiA9IGIwO1xuICB9XG5cbiAgLy8gTm9ybWFsaXplIHNpZ25zXG4gIGlmIChhMS5uZWdhdGl2ZSkge1xuICAgIGExID0gYTEubmVnKCk7XG4gICAgYjEgPSBiMS5uZWcoKTtcbiAgfVxuICBpZiAoYTIubmVnYXRpdmUpIHtcbiAgICBhMiA9IGEyLm5lZygpO1xuICAgIGIyID0gYjIubmVnKCk7XG4gIH1cblxuICByZXR1cm4gW1xuICAgIHsgYTogYTEsIGI6IGIxIH0sXG4gICAgeyBhOiBhMiwgYjogYjIgfVxuICBdO1xufTtcblxuU2hvcnRDdXJ2ZS5wcm90b3R5cGUuX2VuZG9TcGxpdCA9IGZ1bmN0aW9uIF9lbmRvU3BsaXQoaykge1xuICB2YXIgYmFzaXMgPSB0aGlzLmVuZG8uYmFzaXM7XG4gIHZhciB2MSA9IGJhc2lzWzBdO1xuICB2YXIgdjIgPSBiYXNpc1sxXTtcblxuICB2YXIgYzEgPSB2Mi5iLm11bChrKS5kaXZSb3VuZCh0aGlzLm4pO1xuICB2YXIgYzIgPSB2MS5iLm5lZygpLm11bChrKS5kaXZSb3VuZCh0aGlzLm4pO1xuXG4gIHZhciBwMSA9IGMxLm11bCh2MS5hKTtcbiAgdmFyIHAyID0gYzIubXVsKHYyLmEpO1xuICB2YXIgcTEgPSBjMS5tdWwodjEuYik7XG4gIHZhciBxMiA9IGMyLm11bCh2Mi5iKTtcblxuICAvLyBDYWxjdWxhdGUgYW5zd2VyXG4gIHZhciBrMSA9IGsuc3ViKHAxKS5zdWIocDIpO1xuICB2YXIgazIgPSBxMS5hZGQocTIpLm5lZygpO1xuICByZXR1cm4geyBrMTogazEsIGsyOiBrMiB9O1xufTtcblxuU2hvcnRDdXJ2ZS5wcm90b3R5cGUucG9pbnRGcm9tWCA9IGZ1bmN0aW9uIHBvaW50RnJvbVgoeCwgb2RkKSB7XG4gIHggPSBuZXcgQk4oeCwgMTYpO1xuICBpZiAoIXgucmVkKVxuICAgIHggPSB4LnRvUmVkKHRoaXMucmVkKTtcblxuICB2YXIgeTIgPSB4LnJlZFNxcigpLnJlZE11bCh4KS5yZWRJQWRkKHgucmVkTXVsKHRoaXMuYSkpLnJlZElBZGQodGhpcy5iKTtcbiAgdmFyIHkgPSB5Mi5yZWRTcXJ0KCk7XG4gIGlmICh5LnJlZFNxcigpLnJlZFN1Yih5MikuY21wKHRoaXMuemVybykgIT09IDApXG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHBvaW50Jyk7XG5cbiAgLy8gWFhYIElzIHRoZXJlIGFueSB3YXkgdG8gdGVsbCBpZiB0aGUgbnVtYmVyIGlzIG9kZCB3aXRob3V0IGNvbnZlcnRpbmcgaXRcbiAgLy8gdG8gbm9uLXJlZCBmb3JtP1xuICB2YXIgaXNPZGQgPSB5LmZyb21SZWQoKS5pc09kZCgpO1xuICBpZiAob2RkICYmICFpc09kZCB8fCAhb2RkICYmIGlzT2RkKVxuICAgIHkgPSB5LnJlZE5lZygpO1xuXG4gIHJldHVybiB0aGlzLnBvaW50KHgsIHkpO1xufTtcblxuU2hvcnRDdXJ2ZS5wcm90b3R5cGUudmFsaWRhdGUgPSBmdW5jdGlvbiB2YWxpZGF0ZShwb2ludCkge1xuICBpZiAocG9pbnQuaW5mKVxuICAgIHJldHVybiB0cnVlO1xuXG4gIHZhciB4ID0gcG9pbnQueDtcbiAgdmFyIHkgPSBwb2ludC55O1xuXG4gIHZhciBheCA9IHRoaXMuYS5yZWRNdWwoeCk7XG4gIHZhciByaHMgPSB4LnJlZFNxcigpLnJlZE11bCh4KS5yZWRJQWRkKGF4KS5yZWRJQWRkKHRoaXMuYik7XG4gIHJldHVybiB5LnJlZFNxcigpLnJlZElTdWIocmhzKS5jbXBuKDApID09PSAwO1xufTtcblxuU2hvcnRDdXJ2ZS5wcm90b3R5cGUuX2VuZG9XbmFmTXVsQWRkID1cbiAgICBmdW5jdGlvbiBfZW5kb1duYWZNdWxBZGQocG9pbnRzLCBjb2VmZnMsIGphY29iaWFuUmVzdWx0KSB7XG4gIHZhciBucG9pbnRzID0gdGhpcy5fZW5kb1duYWZUMTtcbiAgdmFyIG5jb2VmZnMgPSB0aGlzLl9lbmRvV25hZlQyO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHBvaW50cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBzcGxpdCA9IHRoaXMuX2VuZG9TcGxpdChjb2VmZnNbaV0pO1xuICAgIHZhciBwID0gcG9pbnRzW2ldO1xuICAgIHZhciBiZXRhID0gcC5fZ2V0QmV0YSgpO1xuXG4gICAgaWYgKHNwbGl0LmsxLm5lZ2F0aXZlKSB7XG4gICAgICBzcGxpdC5rMS5pbmVnKCk7XG4gICAgICBwID0gcC5uZWcodHJ1ZSk7XG4gICAgfVxuICAgIGlmIChzcGxpdC5rMi5uZWdhdGl2ZSkge1xuICAgICAgc3BsaXQuazIuaW5lZygpO1xuICAgICAgYmV0YSA9IGJldGEubmVnKHRydWUpO1xuICAgIH1cblxuICAgIG5wb2ludHNbaSAqIDJdID0gcDtcbiAgICBucG9pbnRzW2kgKiAyICsgMV0gPSBiZXRhO1xuICAgIG5jb2VmZnNbaSAqIDJdID0gc3BsaXQuazE7XG4gICAgbmNvZWZmc1tpICogMiArIDFdID0gc3BsaXQuazI7XG4gIH1cbiAgdmFyIHJlcyA9IHRoaXMuX3duYWZNdWxBZGQoMSwgbnBvaW50cywgbmNvZWZmcywgaSAqIDIsIGphY29iaWFuUmVzdWx0KTtcblxuICAvLyBDbGVhbi11cCByZWZlcmVuY2VzIHRvIHBvaW50cyBhbmQgY29lZmZpY2llbnRzXG4gIGZvciAodmFyIGogPSAwOyBqIDwgaSAqIDI7IGorKykge1xuICAgIG5wb2ludHNbal0gPSBudWxsO1xuICAgIG5jb2VmZnNbal0gPSBudWxsO1xuICB9XG4gIHJldHVybiByZXM7XG59O1xuXG5mdW5jdGlvbiBQb2ludChjdXJ2ZSwgeCwgeSwgaXNSZWQpIHtcbiAgQmFzZS5CYXNlUG9pbnQuY2FsbCh0aGlzLCBjdXJ2ZSwgJ2FmZmluZScpO1xuICBpZiAoeCA9PT0gbnVsbCAmJiB5ID09PSBudWxsKSB7XG4gICAgdGhpcy54ID0gbnVsbDtcbiAgICB0aGlzLnkgPSBudWxsO1xuICAgIHRoaXMuaW5mID0gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnggPSBuZXcgQk4oeCwgMTYpO1xuICAgIHRoaXMueSA9IG5ldyBCTih5LCAxNik7XG4gICAgLy8gRm9yY2UgcmVkZ29tZXJ5IHJlcHJlc2VudGF0aW9uIHdoZW4gbG9hZGluZyBmcm9tIEpTT05cbiAgICBpZiAoaXNSZWQpIHtcbiAgICAgIHRoaXMueC5mb3JjZVJlZCh0aGlzLmN1cnZlLnJlZCk7XG4gICAgICB0aGlzLnkuZm9yY2VSZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMueC5yZWQpXG4gICAgICB0aGlzLnggPSB0aGlzLngudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICAgIGlmICghdGhpcy55LnJlZClcbiAgICAgIHRoaXMueSA9IHRoaXMueS50b1JlZCh0aGlzLmN1cnZlLnJlZCk7XG4gICAgdGhpcy5pbmYgPSBmYWxzZTtcbiAgfVxufVxuaW5oZXJpdHMoUG9pbnQsIEJhc2UuQmFzZVBvaW50KTtcblxuU2hvcnRDdXJ2ZS5wcm90b3R5cGUucG9pbnQgPSBmdW5jdGlvbiBwb2ludCh4LCB5LCBpc1JlZCkge1xuICByZXR1cm4gbmV3IFBvaW50KHRoaXMsIHgsIHksIGlzUmVkKTtcbn07XG5cblNob3J0Q3VydmUucHJvdG90eXBlLnBvaW50RnJvbUpTT04gPSBmdW5jdGlvbiBwb2ludEZyb21KU09OKG9iaiwgcmVkKSB7XG4gIHJldHVybiBQb2ludC5mcm9tSlNPTih0aGlzLCBvYmosIHJlZCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuX2dldEJldGEgPSBmdW5jdGlvbiBfZ2V0QmV0YSgpIHtcbiAgaWYgKCF0aGlzLmN1cnZlLmVuZG8pXG4gICAgcmV0dXJuO1xuXG4gIHZhciBwcmUgPSB0aGlzLnByZWNvbXB1dGVkO1xuICBpZiAocHJlICYmIHByZS5iZXRhKVxuICAgIHJldHVybiBwcmUuYmV0YTtcblxuICB2YXIgYmV0YSA9IHRoaXMuY3VydmUucG9pbnQodGhpcy54LnJlZE11bCh0aGlzLmN1cnZlLmVuZG8uYmV0YSksIHRoaXMueSk7XG4gIGlmIChwcmUpIHtcbiAgICB2YXIgY3VydmUgPSB0aGlzLmN1cnZlO1xuICAgIHZhciBlbmRvTXVsID0gZnVuY3Rpb24ocCkge1xuICAgICAgcmV0dXJuIGN1cnZlLnBvaW50KHAueC5yZWRNdWwoY3VydmUuZW5kby5iZXRhKSwgcC55KTtcbiAgICB9O1xuICAgIHByZS5iZXRhID0gYmV0YTtcbiAgICBiZXRhLnByZWNvbXB1dGVkID0ge1xuICAgICAgYmV0YTogbnVsbCxcbiAgICAgIG5hZjogcHJlLm5hZiAmJiB7XG4gICAgICAgIHduZDogcHJlLm5hZi53bmQsXG4gICAgICAgIHBvaW50czogcHJlLm5hZi5wb2ludHMubWFwKGVuZG9NdWwpXG4gICAgICB9LFxuICAgICAgZG91YmxlczogcHJlLmRvdWJsZXMgJiYge1xuICAgICAgICBzdGVwOiBwcmUuZG91Ymxlcy5zdGVwLFxuICAgICAgICBwb2ludHM6IHByZS5kb3VibGVzLnBvaW50cy5tYXAoZW5kb011bClcbiAgICAgIH1cbiAgICB9O1xuICB9XG4gIHJldHVybiBiZXRhO1xufTtcblxuUG9pbnQucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgaWYgKCF0aGlzLnByZWNvbXB1dGVkKVxuICAgIHJldHVybiBbIHRoaXMueCwgdGhpcy55IF07XG5cbiAgcmV0dXJuIFsgdGhpcy54LCB0aGlzLnksIHRoaXMucHJlY29tcHV0ZWQgJiYge1xuICAgIGRvdWJsZXM6IHRoaXMucHJlY29tcHV0ZWQuZG91YmxlcyAmJiB7XG4gICAgICBzdGVwOiB0aGlzLnByZWNvbXB1dGVkLmRvdWJsZXMuc3RlcCxcbiAgICAgIHBvaW50czogdGhpcy5wcmVjb21wdXRlZC5kb3VibGVzLnBvaW50cy5zbGljZSgxKVxuICAgIH0sXG4gICAgbmFmOiB0aGlzLnByZWNvbXB1dGVkLm5hZiAmJiB7XG4gICAgICB3bmQ6IHRoaXMucHJlY29tcHV0ZWQubmFmLnduZCxcbiAgICAgIHBvaW50czogdGhpcy5wcmVjb21wdXRlZC5uYWYucG9pbnRzLnNsaWNlKDEpXG4gICAgfVxuICB9IF07XG59O1xuXG5Qb2ludC5mcm9tSlNPTiA9IGZ1bmN0aW9uIGZyb21KU09OKGN1cnZlLCBvYmosIHJlZCkge1xuICBpZiAodHlwZW9mIG9iaiA9PT0gJ3N0cmluZycpXG4gICAgb2JqID0gSlNPTi5wYXJzZShvYmopO1xuICB2YXIgcmVzID0gY3VydmUucG9pbnQob2JqWzBdLCBvYmpbMV0sIHJlZCk7XG4gIGlmICghb2JqWzJdKVxuICAgIHJldHVybiByZXM7XG5cbiAgZnVuY3Rpb24gb2JqMnBvaW50KG9iaikge1xuICAgIHJldHVybiBjdXJ2ZS5wb2ludChvYmpbMF0sIG9ialsxXSwgcmVkKTtcbiAgfVxuXG4gIHZhciBwcmUgPSBvYmpbMl07XG4gIHJlcy5wcmVjb21wdXRlZCA9IHtcbiAgICBiZXRhOiBudWxsLFxuICAgIGRvdWJsZXM6IHByZS5kb3VibGVzICYmIHtcbiAgICAgIHN0ZXA6IHByZS5kb3VibGVzLnN0ZXAsXG4gICAgICBwb2ludHM6IFsgcmVzIF0uY29uY2F0KHByZS5kb3VibGVzLnBvaW50cy5tYXAob2JqMnBvaW50KSlcbiAgICB9LFxuICAgIG5hZjogcHJlLm5hZiAmJiB7XG4gICAgICB3bmQ6IHByZS5uYWYud25kLFxuICAgICAgcG9pbnRzOiBbIHJlcyBdLmNvbmNhdChwcmUubmFmLnBvaW50cy5tYXAob2JqMnBvaW50KSlcbiAgICB9XG4gIH07XG4gIHJldHVybiByZXM7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QoKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gJzxFQyBQb2ludCBJbmZpbml0eT4nO1xuICByZXR1cm4gJzxFQyBQb2ludCB4OiAnICsgdGhpcy54LmZyb21SZWQoKS50b1N0cmluZygxNiwgMikgK1xuICAgICAgJyB5OiAnICsgdGhpcy55LmZyb21SZWQoKS50b1N0cmluZygxNiwgMikgKyAnPic7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuaXNJbmZpbml0eSA9IGZ1bmN0aW9uIGlzSW5maW5pdHkoKSB7XG4gIHJldHVybiB0aGlzLmluZjtcbn07XG5cblBvaW50LnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiBhZGQocCkge1xuICAvLyBPICsgUCA9IFBcbiAgaWYgKHRoaXMuaW5mKVxuICAgIHJldHVybiBwO1xuXG4gIC8vIFAgKyBPID0gUFxuICBpZiAocC5pbmYpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gUCArIFAgPSAyUFxuICBpZiAodGhpcy5lcShwKSlcbiAgICByZXR1cm4gdGhpcy5kYmwoKTtcblxuICAvLyBQICsgKC1QKSA9IE9cbiAgaWYgKHRoaXMubmVnKCkuZXEocCkpXG4gICAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobnVsbCwgbnVsbCk7XG5cbiAgLy8gUCArIFEgPSBPXG4gIGlmICh0aGlzLnguY21wKHAueCkgPT09IDApXG4gICAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobnVsbCwgbnVsbCk7XG5cbiAgdmFyIGMgPSB0aGlzLnkucmVkU3ViKHAueSk7XG4gIGlmIChjLmNtcG4oMCkgIT09IDApXG4gICAgYyA9IGMucmVkTXVsKHRoaXMueC5yZWRTdWIocC54KS5yZWRJbnZtKCkpO1xuICB2YXIgbnggPSBjLnJlZFNxcigpLnJlZElTdWIodGhpcy54KS5yZWRJU3ViKHAueCk7XG4gIHZhciBueSA9IGMucmVkTXVsKHRoaXMueC5yZWRTdWIobngpKS5yZWRJU3ViKHRoaXMueSk7XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG54LCBueSk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZGJsID0gZnVuY3Rpb24gZGJsKCkge1xuICBpZiAodGhpcy5pbmYpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gMlAgPSBPXG4gIHZhciB5czEgPSB0aGlzLnkucmVkQWRkKHRoaXMueSk7XG4gIGlmICh5czEuY21wbigwKSA9PT0gMClcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChudWxsLCBudWxsKTtcblxuICB2YXIgYSA9IHRoaXMuY3VydmUuYTtcblxuICB2YXIgeDIgPSB0aGlzLngucmVkU3FyKCk7XG4gIHZhciBkeWludiA9IHlzMS5yZWRJbnZtKCk7XG4gIHZhciBjID0geDIucmVkQWRkKHgyKS5yZWRJQWRkKHgyKS5yZWRJQWRkKGEpLnJlZE11bChkeWludik7XG5cbiAgdmFyIG54ID0gYy5yZWRTcXIoKS5yZWRJU3ViKHRoaXMueC5yZWRBZGQodGhpcy54KSk7XG4gIHZhciBueSA9IGMucmVkTXVsKHRoaXMueC5yZWRTdWIobngpKS5yZWRJU3ViKHRoaXMueSk7XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG54LCBueSk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZ2V0WCA9IGZ1bmN0aW9uIGdldFgoKSB7XG4gIHJldHVybiB0aGlzLnguZnJvbVJlZCgpO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmdldFkgPSBmdW5jdGlvbiBnZXRZKCkge1xuICByZXR1cm4gdGhpcy55LmZyb21SZWQoKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5tdWwgPSBmdW5jdGlvbiBtdWwoaykge1xuICBrID0gbmV3IEJOKGssIDE2KTtcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiB0aGlzO1xuICBlbHNlIGlmICh0aGlzLl9oYXNEb3VibGVzKGspKVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl9maXhlZE5hZk11bCh0aGlzLCBrKTtcbiAgZWxzZSBpZiAodGhpcy5jdXJ2ZS5lbmRvKVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl9lbmRvV25hZk11bEFkZChbIHRoaXMgXSwgWyBrIF0pO1xuICBlbHNlXG4gICAgcmV0dXJuIHRoaXMuY3VydmUuX3duYWZNdWwodGhpcywgayk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUubXVsQWRkID0gZnVuY3Rpb24gbXVsQWRkKGsxLCBwMiwgazIpIHtcbiAgdmFyIHBvaW50cyA9IFsgdGhpcywgcDIgXTtcbiAgdmFyIGNvZWZmcyA9IFsgazEsIGsyIF07XG4gIGlmICh0aGlzLmN1cnZlLmVuZG8pXG4gICAgcmV0dXJuIHRoaXMuY3VydmUuX2VuZG9XbmFmTXVsQWRkKHBvaW50cywgY29lZmZzKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl93bmFmTXVsQWRkKDEsIHBvaW50cywgY29lZmZzLCAyKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5qbXVsQWRkID0gZnVuY3Rpb24gam11bEFkZChrMSwgcDIsIGsyKSB7XG4gIHZhciBwb2ludHMgPSBbIHRoaXMsIHAyIF07XG4gIHZhciBjb2VmZnMgPSBbIGsxLCBrMiBdO1xuICBpZiAodGhpcy5jdXJ2ZS5lbmRvKVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl9lbmRvV25hZk11bEFkZChwb2ludHMsIGNvZWZmcywgdHJ1ZSk7XG4gIGVsc2VcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5fd25hZk11bEFkZCgxLCBwb2ludHMsIGNvZWZmcywgMiwgdHJ1ZSk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZXEgPSBmdW5jdGlvbiBlcShwKSB7XG4gIHJldHVybiB0aGlzID09PSBwIHx8XG4gICAgICAgICB0aGlzLmluZiA9PT0gcC5pbmYgJiZcbiAgICAgICAgICAgICAodGhpcy5pbmYgfHwgdGhpcy54LmNtcChwLngpID09PSAwICYmIHRoaXMueS5jbXAocC55KSA9PT0gMCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUubmVnID0gZnVuY3Rpb24gbmVnKF9wcmVjb21wdXRlKSB7XG4gIGlmICh0aGlzLmluZilcbiAgICByZXR1cm4gdGhpcztcblxuICB2YXIgcmVzID0gdGhpcy5jdXJ2ZS5wb2ludCh0aGlzLngsIHRoaXMueS5yZWROZWcoKSk7XG4gIGlmIChfcHJlY29tcHV0ZSAmJiB0aGlzLnByZWNvbXB1dGVkKSB7XG4gICAgdmFyIHByZSA9IHRoaXMucHJlY29tcHV0ZWQ7XG4gICAgdmFyIG5lZ2F0ZSA9IGZ1bmN0aW9uKHApIHtcbiAgICAgIHJldHVybiBwLm5lZygpO1xuICAgIH07XG4gICAgcmVzLnByZWNvbXB1dGVkID0ge1xuICAgICAgbmFmOiBwcmUubmFmICYmIHtcbiAgICAgICAgd25kOiBwcmUubmFmLnduZCxcbiAgICAgICAgcG9pbnRzOiBwcmUubmFmLnBvaW50cy5tYXAobmVnYXRlKVxuICAgICAgfSxcbiAgICAgIGRvdWJsZXM6IHByZS5kb3VibGVzICYmIHtcbiAgICAgICAgc3RlcDogcHJlLmRvdWJsZXMuc3RlcCxcbiAgICAgICAgcG9pbnRzOiBwcmUuZG91Ymxlcy5wb2ludHMubWFwKG5lZ2F0ZSlcbiAgICAgIH1cbiAgICB9O1xuICB9XG4gIHJldHVybiByZXM7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUudG9KID0gZnVuY3Rpb24gdG9KKCkge1xuICBpZiAodGhpcy5pbmYpXG4gICAgcmV0dXJuIHRoaXMuY3VydmUuanBvaW50KG51bGwsIG51bGwsIG51bGwpO1xuXG4gIHZhciByZXMgPSB0aGlzLmN1cnZlLmpwb2ludCh0aGlzLngsIHRoaXMueSwgdGhpcy5jdXJ2ZS5vbmUpO1xuICByZXR1cm4gcmVzO1xufTtcblxuZnVuY3Rpb24gSlBvaW50KGN1cnZlLCB4LCB5LCB6KSB7XG4gIEJhc2UuQmFzZVBvaW50LmNhbGwodGhpcywgY3VydmUsICdqYWNvYmlhbicpO1xuICBpZiAoeCA9PT0gbnVsbCAmJiB5ID09PSBudWxsICYmIHogPT09IG51bGwpIHtcbiAgICB0aGlzLnggPSB0aGlzLmN1cnZlLm9uZTtcbiAgICB0aGlzLnkgPSB0aGlzLmN1cnZlLm9uZTtcbiAgICB0aGlzLnogPSBuZXcgQk4oMCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy54ID0gbmV3IEJOKHgsIDE2KTtcbiAgICB0aGlzLnkgPSBuZXcgQk4oeSwgMTYpO1xuICAgIHRoaXMueiA9IG5ldyBCTih6LCAxNik7XG4gIH1cbiAgaWYgKCF0aGlzLngucmVkKVxuICAgIHRoaXMueCA9IHRoaXMueC50b1JlZCh0aGlzLmN1cnZlLnJlZCk7XG4gIGlmICghdGhpcy55LnJlZClcbiAgICB0aGlzLnkgPSB0aGlzLnkudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICBpZiAoIXRoaXMuei5yZWQpXG4gICAgdGhpcy56ID0gdGhpcy56LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcblxuICB0aGlzLnpPbmUgPSB0aGlzLnogPT09IHRoaXMuY3VydmUub25lO1xufVxuaW5oZXJpdHMoSlBvaW50LCBCYXNlLkJhc2VQb2ludCk7XG5cblNob3J0Q3VydmUucHJvdG90eXBlLmpwb2ludCA9IGZ1bmN0aW9uIGpwb2ludCh4LCB5LCB6KSB7XG4gIHJldHVybiBuZXcgSlBvaW50KHRoaXMsIHgsIHksIHopO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS50b1AgPSBmdW5jdGlvbiB0b1AoKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChudWxsLCBudWxsKTtcblxuICB2YXIgemludiA9IHRoaXMuei5yZWRJbnZtKCk7XG4gIHZhciB6aW52MiA9IHppbnYucmVkU3FyKCk7XG4gIHZhciBheCA9IHRoaXMueC5yZWRNdWwoemludjIpO1xuICB2YXIgYXkgPSB0aGlzLnkucmVkTXVsKHppbnYyKS5yZWRNdWwoemludik7XG5cbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQoYXgsIGF5KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUubmVnID0gZnVuY3Rpb24gbmVnKCkge1xuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQodGhpcy54LCB0aGlzLnkucmVkTmVnKCksIHRoaXMueik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZChwKSB7XG4gIC8vIE8gKyBQID0gUFxuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHA7XG5cbiAgLy8gUCArIE8gPSBQXG4gIGlmIChwLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyAxMk0gKyA0UyArIDdBXG4gIHZhciBwejIgPSBwLnoucmVkU3FyKCk7XG4gIHZhciB6MiA9IHRoaXMuei5yZWRTcXIoKTtcbiAgdmFyIHUxID0gdGhpcy54LnJlZE11bChwejIpO1xuICB2YXIgdTIgPSBwLngucmVkTXVsKHoyKTtcbiAgdmFyIHMxID0gdGhpcy55LnJlZE11bChwejIucmVkTXVsKHAueikpO1xuICB2YXIgczIgPSBwLnkucmVkTXVsKHoyLnJlZE11bCh0aGlzLnopKTtcblxuICB2YXIgaCA9IHUxLnJlZFN1Yih1Mik7XG4gIHZhciByID0gczEucmVkU3ViKHMyKTtcbiAgaWYgKGguY21wbigwKSA9PT0gMCkge1xuICAgIGlmIChyLmNtcG4oMCkgIT09IDApXG4gICAgICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobnVsbCwgbnVsbCwgbnVsbCk7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIHRoaXMuZGJsKCk7XG4gIH1cblxuICB2YXIgaDIgPSBoLnJlZFNxcigpO1xuICB2YXIgaDMgPSBoMi5yZWRNdWwoaCk7XG4gIHZhciB2ID0gdTEucmVkTXVsKGgyKTtcblxuICB2YXIgbnggPSByLnJlZFNxcigpLnJlZElBZGQoaDMpLnJlZElTdWIodikucmVkSVN1Yih2KTtcbiAgdmFyIG55ID0gci5yZWRNdWwodi5yZWRJU3ViKG54KSkucmVkSVN1YihzMS5yZWRNdWwoaDMpKTtcbiAgdmFyIG56ID0gdGhpcy56LnJlZE11bChwLnopLnJlZE11bChoKTtcblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobngsIG55LCBueik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLm1peGVkQWRkID0gZnVuY3Rpb24gbWl4ZWRBZGQocCkge1xuICAvLyBPICsgUCA9IFBcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiBwLnRvSigpO1xuXG4gIC8vIFAgKyBPID0gUFxuICBpZiAocC5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gOE0gKyAzUyArIDdBXG4gIHZhciB6MiA9IHRoaXMuei5yZWRTcXIoKTtcbiAgdmFyIHUxID0gdGhpcy54O1xuICB2YXIgdTIgPSBwLngucmVkTXVsKHoyKTtcbiAgdmFyIHMxID0gdGhpcy55O1xuICB2YXIgczIgPSBwLnkucmVkTXVsKHoyKS5yZWRNdWwodGhpcy56KTtcblxuICB2YXIgaCA9IHUxLnJlZFN1Yih1Mik7XG4gIHZhciByID0gczEucmVkU3ViKHMyKTtcbiAgaWYgKGguY21wbigwKSA9PT0gMCkge1xuICAgIGlmIChyLmNtcG4oMCkgIT09IDApXG4gICAgICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobnVsbCwgbnVsbCwgbnVsbCk7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIHRoaXMuZGJsKCk7XG4gIH1cblxuICB2YXIgaDIgPSBoLnJlZFNxcigpO1xuICB2YXIgaDMgPSBoMi5yZWRNdWwoaCk7XG4gIHZhciB2ID0gdTEucmVkTXVsKGgyKTtcblxuICB2YXIgbnggPSByLnJlZFNxcigpLnJlZElBZGQoaDMpLnJlZElTdWIodikucmVkSVN1Yih2KTtcbiAgdmFyIG55ID0gci5yZWRNdWwodi5yZWRJU3ViKG54KSkucmVkSVN1YihzMS5yZWRNdWwoaDMpKTtcbiAgdmFyIG56ID0gdGhpcy56LnJlZE11bChoKTtcblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobngsIG55LCBueik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLmRibHAgPSBmdW5jdGlvbiBkYmxwKHBvdykge1xuICBpZiAocG93ID09PSAwKVxuICAgIHJldHVybiB0aGlzO1xuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRoaXM7XG4gIGlmICghcG93KVxuICAgIHJldHVybiB0aGlzLmRibCgpO1xuXG4gIGlmICh0aGlzLmN1cnZlLnplcm9BIHx8IHRoaXMuY3VydmUudGhyZWVBKSB7XG4gICAgdmFyIHIgPSB0aGlzO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG93OyBpKyspXG4gICAgICByID0gci5kYmwoKTtcbiAgICByZXR1cm4gcjtcbiAgfVxuXG4gIC8vIDFNICsgMlMgKyAxQSArIE4gKiAoNFMgKyA1TSArIDhBKVxuICAvLyBOID0gMSA9PiA2TSArIDZTICsgOUFcbiAgdmFyIGEgPSB0aGlzLmN1cnZlLmE7XG4gIHZhciB0aW52ID0gdGhpcy5jdXJ2ZS50aW52O1xuXG4gIHZhciBqeCA9IHRoaXMueDtcbiAgdmFyIGp5ID0gdGhpcy55O1xuICB2YXIganogPSB0aGlzLno7XG4gIHZhciBqejQgPSBqei5yZWRTcXIoKS5yZWRTcXIoKTtcblxuICAvLyBSZXVzZSByZXN1bHRzXG4gIHZhciBqeWQgPSBqeS5yZWRBZGQoankpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHBvdzsgaSsrKSB7XG4gICAgdmFyIGp4MiA9IGp4LnJlZFNxcigpO1xuICAgIHZhciBqeWQyID0ganlkLnJlZFNxcigpO1xuICAgIHZhciBqeWQ0ID0ganlkMi5yZWRTcXIoKTtcbiAgICB2YXIgYyA9IGp4Mi5yZWRBZGQoangyKS5yZWRJQWRkKGp4MikucmVkSUFkZChhLnJlZE11bChqejQpKTtcblxuICAgIHZhciB0MSA9IGp4LnJlZE11bChqeWQyKTtcbiAgICB2YXIgbnggPSBjLnJlZFNxcigpLnJlZElTdWIodDEucmVkQWRkKHQxKSk7XG4gICAgdmFyIHQyID0gdDEucmVkSVN1YihueCk7XG4gICAgdmFyIGRueSA9IGMucmVkTXVsKHQyKTtcbiAgICBkbnkgPSBkbnkucmVkSUFkZChkbnkpLnJlZElTdWIoanlkNCk7XG4gICAgdmFyIG56ID0ganlkLnJlZE11bChqeik7XG4gICAgaWYgKGkgKyAxIDwgcG93KVxuICAgICAgano0ID0gano0LnJlZE11bChqeWQ0KTtcblxuICAgIGp4ID0gbng7XG4gICAganogPSBuejtcbiAgICBqeWQgPSBkbnk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQoangsIGp5ZC5yZWRNdWwodGludiksIGp6KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUuZGJsID0gZnVuY3Rpb24gZGJsKCkge1xuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgaWYgKHRoaXMuY3VydmUuemVyb0EpXG4gICAgcmV0dXJuIHRoaXMuX3plcm9EYmwoKTtcbiAgZWxzZSBpZiAodGhpcy5jdXJ2ZS50aHJlZUEpXG4gICAgcmV0dXJuIHRoaXMuX3RocmVlRGJsKCk7XG4gIGVsc2VcbiAgICByZXR1cm4gdGhpcy5fZGJsKCk7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLl96ZXJvRGJsID0gZnVuY3Rpb24gX3plcm9EYmwoKSB7XG4gIHZhciBueDtcbiAgdmFyIG55O1xuICB2YXIgbno7XG4gIC8vIFogPSAxXG4gIGlmICh0aGlzLnpPbmUpIHtcbiAgICAvLyBoeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tc2hvcnR3LWphY29iaWFuLTAuaHRtbFxuICAgIC8vICAgICAjZG91YmxpbmctbWRibC0yMDA3LWJsXG4gICAgLy8gMU0gKyA1UyArIDE0QVxuXG4gICAgLy8gWFggPSBYMV4yXG4gICAgdmFyIHh4ID0gdGhpcy54LnJlZFNxcigpO1xuICAgIC8vIFlZID0gWTFeMlxuICAgIHZhciB5eSA9IHRoaXMueS5yZWRTcXIoKTtcbiAgICAvLyBZWVlZID0gWVleMlxuICAgIHZhciB5eXl5ID0geXkucmVkU3FyKCk7XG4gICAgLy8gUyA9IDIgKiAoKFgxICsgWVkpXjIgLSBYWCAtIFlZWVkpXG4gICAgdmFyIHMgPSB0aGlzLngucmVkQWRkKHl5KS5yZWRTcXIoKS5yZWRJU3ViKHh4KS5yZWRJU3ViKHl5eXkpO1xuICAgIHMgPSBzLnJlZElBZGQocyk7XG4gICAgLy8gTSA9IDMgKiBYWCArIGE7IGEgPSAwXG4gICAgdmFyIG0gPSB4eC5yZWRBZGQoeHgpLnJlZElBZGQoeHgpO1xuICAgIC8vIFQgPSBNIF4gMiAtIDIqU1xuICAgIHZhciB0ID0gbS5yZWRTcXIoKS5yZWRJU3ViKHMpLnJlZElTdWIocyk7XG5cbiAgICAvLyA4ICogWVlZWVxuICAgIHZhciB5eXl5OCA9IHl5eXkucmVkSUFkZCh5eXl5KTtcbiAgICB5eXl5OCA9IHl5eXk4LnJlZElBZGQoeXl5eTgpO1xuICAgIHl5eXk4ID0geXl5eTgucmVkSUFkZCh5eXl5OCk7XG5cbiAgICAvLyBYMyA9IFRcbiAgICBueCA9IHQ7XG4gICAgLy8gWTMgPSBNICogKFMgLSBUKSAtIDggKiBZWVlZXG4gICAgbnkgPSBtLnJlZE11bChzLnJlZElTdWIodCkpLnJlZElTdWIoeXl5eTgpO1xuICAgIC8vIFozID0gMipZMVxuICAgIG56ID0gdGhpcy55LnJlZEFkZCh0aGlzLnkpO1xuICB9IGVsc2Uge1xuICAgIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by1zaG9ydHctamFjb2JpYW4tMC5odG1sXG4gICAgLy8gICAgICNkb3VibGluZy1kYmwtMjAwOS1sXG4gICAgLy8gMk0gKyA1UyArIDEzQVxuXG4gICAgLy8gQSA9IFgxXjJcbiAgICB2YXIgYSA9IHRoaXMueC5yZWRTcXIoKTtcbiAgICAvLyBCID0gWTFeMlxuICAgIHZhciBiID0gdGhpcy55LnJlZFNxcigpO1xuICAgIC8vIEMgPSBCXjJcbiAgICB2YXIgYyA9IGIucmVkU3FyKCk7XG4gICAgLy8gRCA9IDIgKiAoKFgxICsgQileMiAtIEEgLSBDKVxuICAgIHZhciBkID0gdGhpcy54LnJlZEFkZChiKS5yZWRTcXIoKS5yZWRJU3ViKGEpLnJlZElTdWIoYyk7XG4gICAgZCA9IGQucmVkSUFkZChkKTtcbiAgICAvLyBFID0gMyAqIEFcbiAgICB2YXIgZSA9IGEucmVkQWRkKGEpLnJlZElBZGQoYSk7XG4gICAgLy8gRiA9IEVeMlxuICAgIHZhciBmID0gZS5yZWRTcXIoKTtcblxuICAgIC8vIDggKiBDXG4gICAgdmFyIGM4ID0gYy5yZWRJQWRkKGMpO1xuICAgIGM4ID0gYzgucmVkSUFkZChjOCk7XG4gICAgYzggPSBjOC5yZWRJQWRkKGM4KTtcblxuICAgIC8vIFgzID0gRiAtIDIgKiBEXG4gICAgbnggPSBmLnJlZElTdWIoZCkucmVkSVN1YihkKTtcbiAgICAvLyBZMyA9IEUgKiAoRCAtIFgzKSAtIDggKiBDXG4gICAgbnkgPSBlLnJlZE11bChkLnJlZElTdWIobngpKS5yZWRJU3ViKGM4KTtcbiAgICAvLyBaMyA9IDIgKiBZMSAqIFoxXG4gICAgbnogPSB0aGlzLnkucmVkTXVsKHRoaXMueik7XG4gICAgbnogPSBuei5yZWRJQWRkKG56KTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmN1cnZlLmpwb2ludChueCwgbnksIG56KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUuX3RocmVlRGJsID0gZnVuY3Rpb24gX3RocmVlRGJsKCkge1xuICB2YXIgbng7XG4gIHZhciBueTtcbiAgdmFyIG56O1xuICAvLyBaID0gMVxuICBpZiAodGhpcy56T25lKSB7XG4gICAgLy8gaHlwZXJlbGxpcHRpYy5vcmcvRUZEL2cxcC9hdXRvLXNob3J0dy1qYWNvYmlhbi0zLmh0bWxcbiAgICAvLyAgICAgI2RvdWJsaW5nLW1kYmwtMjAwNy1ibFxuICAgIC8vIDFNICsgNVMgKyAxNUFcblxuICAgIC8vIFhYID0gWDFeMlxuICAgIHZhciB4eCA9IHRoaXMueC5yZWRTcXIoKTtcbiAgICAvLyBZWSA9IFkxXjJcbiAgICB2YXIgeXkgPSB0aGlzLnkucmVkU3FyKCk7XG4gICAgLy8gWVlZWSA9IFlZXjJcbiAgICB2YXIgeXl5eSA9IHl5LnJlZFNxcigpO1xuICAgIC8vIFMgPSAyICogKChYMSArIFlZKV4yIC0gWFggLSBZWVlZKVxuICAgIHZhciBzID0gdGhpcy54LnJlZEFkZCh5eSkucmVkU3FyKCkucmVkSVN1Yih4eCkucmVkSVN1Yih5eXl5KTtcbiAgICBzID0gcy5yZWRJQWRkKHMpO1xuICAgIC8vIE0gPSAzICogWFggKyBhXG4gICAgdmFyIG0gPSB4eC5yZWRBZGQoeHgpLnJlZElBZGQoeHgpLnJlZElBZGQodGhpcy5jdXJ2ZS5hKTtcbiAgICAvLyBUID0gTV4yIC0gMiAqIFNcbiAgICB2YXIgdCA9IG0ucmVkU3FyKCkucmVkSVN1YihzKS5yZWRJU3ViKHMpO1xuICAgIC8vIFgzID0gVFxuICAgIG54ID0gdDtcbiAgICAvLyBZMyA9IE0gKiAoUyAtIFQpIC0gOCAqIFlZWVlcbiAgICB2YXIgeXl5eTggPSB5eXl5LnJlZElBZGQoeXl5eSk7XG4gICAgeXl5eTggPSB5eXl5OC5yZWRJQWRkKHl5eXk4KTtcbiAgICB5eXl5OCA9IHl5eXk4LnJlZElBZGQoeXl5eTgpO1xuICAgIG55ID0gbS5yZWRNdWwocy5yZWRJU3ViKHQpKS5yZWRJU3ViKHl5eXk4KTtcbiAgICAvLyBaMyA9IDIgKiBZMVxuICAgIG56ID0gdGhpcy55LnJlZEFkZCh0aGlzLnkpO1xuICB9IGVsc2Uge1xuICAgIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by1zaG9ydHctamFjb2JpYW4tMy5odG1sI2RvdWJsaW5nLWRibC0yMDAxLWJcbiAgICAvLyAzTSArIDVTXG5cbiAgICAvLyBkZWx0YSA9IFoxXjJcbiAgICB2YXIgZGVsdGEgPSB0aGlzLnoucmVkU3FyKCk7XG4gICAgLy8gZ2FtbWEgPSBZMV4yXG4gICAgdmFyIGdhbW1hID0gdGhpcy55LnJlZFNxcigpO1xuICAgIC8vIGJldGEgPSBYMSAqIGdhbW1hXG4gICAgdmFyIGJldGEgPSB0aGlzLngucmVkTXVsKGdhbW1hKTtcbiAgICAvLyBhbHBoYSA9IDMgKiAoWDEgLSBkZWx0YSkgKiAoWDEgKyBkZWx0YSlcbiAgICB2YXIgYWxwaGEgPSB0aGlzLngucmVkU3ViKGRlbHRhKS5yZWRNdWwodGhpcy54LnJlZEFkZChkZWx0YSkpO1xuICAgIGFscGhhID0gYWxwaGEucmVkQWRkKGFscGhhKS5yZWRJQWRkKGFscGhhKTtcbiAgICAvLyBYMyA9IGFscGhhXjIgLSA4ICogYmV0YVxuICAgIHZhciBiZXRhNCA9IGJldGEucmVkSUFkZChiZXRhKTtcbiAgICBiZXRhNCA9IGJldGE0LnJlZElBZGQoYmV0YTQpO1xuICAgIHZhciBiZXRhOCA9IGJldGE0LnJlZEFkZChiZXRhNCk7XG4gICAgbnggPSBhbHBoYS5yZWRTcXIoKS5yZWRJU3ViKGJldGE4KTtcbiAgICAvLyBaMyA9IChZMSArIFoxKV4yIC0gZ2FtbWEgLSBkZWx0YVxuICAgIG56ID0gdGhpcy55LnJlZEFkZCh0aGlzLnopLnJlZFNxcigpLnJlZElTdWIoZ2FtbWEpLnJlZElTdWIoZGVsdGEpO1xuICAgIC8vIFkzID0gYWxwaGEgKiAoNCAqIGJldGEgLSBYMykgLSA4ICogZ2FtbWFeMlxuICAgIHZhciBnZ2FtbWE4ID0gZ2FtbWEucmVkU3FyKCk7XG4gICAgZ2dhbW1hOCA9IGdnYW1tYTgucmVkSUFkZChnZ2FtbWE4KTtcbiAgICBnZ2FtbWE4ID0gZ2dhbW1hOC5yZWRJQWRkKGdnYW1tYTgpO1xuICAgIGdnYW1tYTggPSBnZ2FtbWE4LnJlZElBZGQoZ2dhbW1hOCk7XG4gICAgbnkgPSBhbHBoYS5yZWRNdWwoYmV0YTQucmVkSVN1YihueCkpLnJlZElTdWIoZ2dhbW1hOCk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobngsIG55LCBueik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLl9kYmwgPSBmdW5jdGlvbiBfZGJsKCkge1xuICB2YXIgYSA9IHRoaXMuY3VydmUuYTtcblxuICAvLyA0TSArIDZTICsgMTBBXG4gIHZhciBqeCA9IHRoaXMueDtcbiAgdmFyIGp5ID0gdGhpcy55O1xuICB2YXIganogPSB0aGlzLno7XG4gIHZhciBqejQgPSBqei5yZWRTcXIoKS5yZWRTcXIoKTtcblxuICB2YXIgangyID0gangucmVkU3FyKCk7XG4gIHZhciBqeTIgPSBqeS5yZWRTcXIoKTtcblxuICB2YXIgYyA9IGp4Mi5yZWRBZGQoangyKS5yZWRJQWRkKGp4MikucmVkSUFkZChhLnJlZE11bChqejQpKTtcblxuICB2YXIganhkNCA9IGp4LnJlZEFkZChqeCk7XG4gIGp4ZDQgPSBqeGQ0LnJlZElBZGQoanhkNCk7XG4gIHZhciB0MSA9IGp4ZDQucmVkTXVsKGp5Mik7XG4gIHZhciBueCA9IGMucmVkU3FyKCkucmVkSVN1Yih0MS5yZWRBZGQodDEpKTtcbiAgdmFyIHQyID0gdDEucmVkSVN1YihueCk7XG5cbiAgdmFyIGp5ZDggPSBqeTIucmVkU3FyKCk7XG4gIGp5ZDggPSBqeWQ4LnJlZElBZGQoanlkOCk7XG4gIGp5ZDggPSBqeWQ4LnJlZElBZGQoanlkOCk7XG4gIGp5ZDggPSBqeWQ4LnJlZElBZGQoanlkOCk7XG4gIHZhciBueSA9IGMucmVkTXVsKHQyKS5yZWRJU3ViKGp5ZDgpO1xuICB2YXIgbnogPSBqeS5yZWRBZGQoankpLnJlZE11bChqeik7XG5cbiAgcmV0dXJuIHRoaXMuY3VydmUuanBvaW50KG54LCBueSwgbnopO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS50cnBsID0gZnVuY3Rpb24gdHJwbCgpIHtcbiAgaWYgKCF0aGlzLmN1cnZlLnplcm9BKVxuICAgIHJldHVybiB0aGlzLmRibCgpLmFkZCh0aGlzKTtcblxuICAvLyBoeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tc2hvcnR3LWphY29iaWFuLTAuaHRtbCN0cmlwbGluZy10cGwtMjAwNy1ibFxuICAvLyA1TSArIDEwUyArIC4uLlxuXG4gIC8vIFhYID0gWDFeMlxuICB2YXIgeHggPSB0aGlzLngucmVkU3FyKCk7XG4gIC8vIFlZID0gWTFeMlxuICB2YXIgeXkgPSB0aGlzLnkucmVkU3FyKCk7XG4gIC8vIFpaID0gWjFeMlxuICB2YXIgenogPSB0aGlzLnoucmVkU3FyKCk7XG4gIC8vIFlZWVkgPSBZWV4yXG4gIHZhciB5eXl5ID0geXkucmVkU3FyKCk7XG4gIC8vIE0gPSAzICogWFggKyBhICogWloyOyBhID0gMFxuICB2YXIgbSA9IHh4LnJlZEFkZCh4eCkucmVkSUFkZCh4eCk7XG4gIC8vIE1NID0gTV4yXG4gIHZhciBtbSA9IG0ucmVkU3FyKCk7XG4gIC8vIEUgPSA2ICogKChYMSArIFlZKV4yIC0gWFggLSBZWVlZKSAtIE1NXG4gIHZhciBlID0gdGhpcy54LnJlZEFkZCh5eSkucmVkU3FyKCkucmVkSVN1Yih4eCkucmVkSVN1Yih5eXl5KTtcbiAgZSA9IGUucmVkSUFkZChlKTtcbiAgZSA9IGUucmVkQWRkKGUpLnJlZElBZGQoZSk7XG4gIGUgPSBlLnJlZElTdWIobW0pO1xuICAvLyBFRSA9IEVeMlxuICB2YXIgZWUgPSBlLnJlZFNxcigpO1xuICAvLyBUID0gMTYqWVlZWVxuICB2YXIgdCA9IHl5eXkucmVkSUFkZCh5eXl5KTtcbiAgdCA9IHQucmVkSUFkZCh0KTtcbiAgdCA9IHQucmVkSUFkZCh0KTtcbiAgdCA9IHQucmVkSUFkZCh0KTtcbiAgLy8gVSA9IChNICsgRSleMiAtIE1NIC0gRUUgLSBUXG4gIHZhciB1ID0gbS5yZWRJQWRkKGUpLnJlZFNxcigpLnJlZElTdWIobW0pLnJlZElTdWIoZWUpLnJlZElTdWIodCk7XG4gIC8vIFgzID0gNCAqIChYMSAqIEVFIC0gNCAqIFlZICogVSlcbiAgdmFyIHl5dTQgPSB5eS5yZWRNdWwodSk7XG4gIHl5dTQgPSB5eXU0LnJlZElBZGQoeXl1NCk7XG4gIHl5dTQgPSB5eXU0LnJlZElBZGQoeXl1NCk7XG4gIHZhciBueCA9IHRoaXMueC5yZWRNdWwoZWUpLnJlZElTdWIoeXl1NCk7XG4gIG54ID0gbngucmVkSUFkZChueCk7XG4gIG54ID0gbngucmVkSUFkZChueCk7XG4gIC8vIFkzID0gOCAqIFkxICogKFUgKiAoVCAtIFUpIC0gRSAqIEVFKVxuICB2YXIgbnkgPSB0aGlzLnkucmVkTXVsKHUucmVkTXVsKHQucmVkSVN1Yih1KSkucmVkSVN1YihlLnJlZE11bChlZSkpKTtcbiAgbnkgPSBueS5yZWRJQWRkKG55KTtcbiAgbnkgPSBueS5yZWRJQWRkKG55KTtcbiAgbnkgPSBueS5yZWRJQWRkKG55KTtcbiAgLy8gWjMgPSAoWjEgKyBFKV4yIC0gWlogLSBFRVxuICB2YXIgbnogPSB0aGlzLnoucmVkQWRkKGUpLnJlZFNxcigpLnJlZElTdWIoenopLnJlZElTdWIoZWUpO1xuXG4gIHJldHVybiB0aGlzLmN1cnZlLmpwb2ludChueCwgbnksIG56KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUubXVsID0gZnVuY3Rpb24gbXVsKGssIGtiYXNlKSB7XG4gIGsgPSBuZXcgQk4oaywga2Jhc2UpO1xuXG4gIHJldHVybiB0aGlzLmN1cnZlLl93bmFmTXVsKHRoaXMsIGspO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS5lcSA9IGZ1bmN0aW9uIGVxKHApIHtcbiAgaWYgKHAudHlwZSA9PT0gJ2FmZmluZScpXG4gICAgcmV0dXJuIHRoaXMuZXEocC50b0ooKSk7XG5cbiAgaWYgKHRoaXMgPT09IHApXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgLy8geDEgKiB6Ml4yID09IHgyICogejFeMlxuICB2YXIgejIgPSB0aGlzLnoucmVkU3FyKCk7XG4gIHZhciBwejIgPSBwLnoucmVkU3FyKCk7XG4gIGlmICh0aGlzLngucmVkTXVsKHB6MikucmVkSVN1YihwLngucmVkTXVsKHoyKSkuY21wbigwKSAhPT0gMClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgLy8geTEgKiB6Ml4zID09IHkyICogejFeM1xuICB2YXIgejMgPSB6Mi5yZWRNdWwodGhpcy56KTtcbiAgdmFyIHB6MyA9IHB6Mi5yZWRNdWwocC56KTtcbiAgcmV0dXJuIHRoaXMueS5yZWRNdWwocHozKS5yZWRJU3ViKHAueS5yZWRNdWwoejMpKS5jbXBuKDApID09PSAwO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS5lcVhUb1AgPSBmdW5jdGlvbiBlcVhUb1AoeCkge1xuICB2YXIgenMgPSB0aGlzLnoucmVkU3FyKCk7XG4gIHZhciByeCA9IHgudG9SZWQodGhpcy5jdXJ2ZS5yZWQpLnJlZE11bCh6cyk7XG4gIGlmICh0aGlzLnguY21wKHJ4KSA9PT0gMClcbiAgICByZXR1cm4gdHJ1ZTtcblxuICB2YXIgeGMgPSB4LmNsb25lKCk7XG4gIHZhciB0ID0gdGhpcy5jdXJ2ZS5yZWROLnJlZE11bCh6cyk7XG4gIGZvciAoOzspIHtcbiAgICB4Yy5pYWRkKHRoaXMuY3VydmUubik7XG4gICAgaWYgKHhjLmNtcCh0aGlzLmN1cnZlLnApID49IDApXG4gICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICByeC5yZWRJQWRkKHQpO1xuICAgIGlmICh0aGlzLnguY21wKHJ4KSA9PT0gMClcbiAgICAgIHJldHVybiB0cnVlO1xuICB9XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0KCkge1xuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuICc8RUMgSlBvaW50IEluZmluaXR5Pic7XG4gIHJldHVybiAnPEVDIEpQb2ludCB4OiAnICsgdGhpcy54LnRvU3RyaW5nKDE2LCAyKSArXG4gICAgICAnIHk6ICcgKyB0aGlzLnkudG9TdHJpbmcoMTYsIDIpICtcbiAgICAgICcgejogJyArIHRoaXMuei50b1N0cmluZygxNiwgMikgKyAnPic7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLmlzSW5maW5pdHkgPSBmdW5jdGlvbiBpc0luZmluaXR5KCkge1xuICAvLyBYWFggVGhpcyBjb2RlIGFzc3VtZXMgdGhhdCB6ZXJvIGlzIGFsd2F5cyB6ZXJvIGluIHJlZFxuICByZXR1cm4gdGhpcy56LmNtcG4oMCkgPT09IDA7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3VydmVzID0gZXhwb3J0cztcblxudmFyIGhhc2ggPSByZXF1aXJlKCdoYXNoLmpzJyk7XG52YXIgY3VydmUgPSByZXF1aXJlKCcuL2N1cnZlJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG5cbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG5cbmZ1bmN0aW9uIFByZXNldEN1cnZlKG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMudHlwZSA9PT0gJ3Nob3J0JylcbiAgICB0aGlzLmN1cnZlID0gbmV3IGN1cnZlLnNob3J0KG9wdGlvbnMpO1xuICBlbHNlIGlmIChvcHRpb25zLnR5cGUgPT09ICdlZHdhcmRzJylcbiAgICB0aGlzLmN1cnZlID0gbmV3IGN1cnZlLmVkd2FyZHMob3B0aW9ucyk7XG4gIGVsc2VcbiAgICB0aGlzLmN1cnZlID0gbmV3IGN1cnZlLm1vbnQob3B0aW9ucyk7XG4gIHRoaXMuZyA9IHRoaXMuY3VydmUuZztcbiAgdGhpcy5uID0gdGhpcy5jdXJ2ZS5uO1xuICB0aGlzLmhhc2ggPSBvcHRpb25zLmhhc2g7XG5cbiAgYXNzZXJ0KHRoaXMuZy52YWxpZGF0ZSgpLCAnSW52YWxpZCBjdXJ2ZScpO1xuICBhc3NlcnQodGhpcy5nLm11bCh0aGlzLm4pLmlzSW5maW5pdHkoKSwgJ0ludmFsaWQgY3VydmUsIEcqTiAhPSBPJyk7XG59XG5jdXJ2ZXMuUHJlc2V0Q3VydmUgPSBQcmVzZXRDdXJ2ZTtcblxuZnVuY3Rpb24gZGVmaW5lQ3VydmUobmFtZSwgb3B0aW9ucykge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3VydmVzLCBuYW1lLCB7XG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBjdXJ2ZSA9IG5ldyBQcmVzZXRDdXJ2ZShvcHRpb25zKTtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdXJ2ZXMsIG5hbWUsIHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICB2YWx1ZTogY3VydmVcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGN1cnZlO1xuICAgIH1cbiAgfSk7XG59XG5cbmRlZmluZUN1cnZlKCdwMTkyJywge1xuICB0eXBlOiAnc2hvcnQnLFxuICBwcmltZTogJ3AxOTInLFxuICBwOiAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmUgZmZmZmZmZmYgZmZmZmZmZmYnLFxuICBhOiAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmUgZmZmZmZmZmYgZmZmZmZmZmMnLFxuICBiOiAnNjQyMTA1MTkgZTU5YzgwZTcgMGZhN2U5YWIgNzIyNDMwNDkgZmViOGRlZWMgYzE0NmI5YjEnLFxuICBuOiAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgOTlkZWY4MzYgMTQ2YmM5YjEgYjRkMjI4MzEnLFxuICBoYXNoOiBoYXNoLnNoYTI1NixcbiAgZ1JlZDogZmFsc2UsXG4gIGc6IFtcbiAgICAnMTg4ZGE4MGUgYjAzMDkwZjYgN2NiZjIwZWIgNDNhMTg4MDAgZjRmZjBhZmQgODJmZjEwMTInLFxuICAgICcwNzE5MmI5NSBmZmM4ZGE3OCA2MzEwMTFlZCA2YjI0Y2RkNSA3M2Y5NzdhMSAxZTc5NDgxMSdcbiAgXVxufSk7XG5cbmRlZmluZUN1cnZlKCdwMjI0Jywge1xuICB0eXBlOiAnc2hvcnQnLFxuICBwcmltZTogJ3AyMjQnLFxuICBwOiAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgMDAwMDAwMDAgMDAwMDAwMDAgMDAwMDAwMDEnLFxuICBhOiAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmUgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmUnLFxuICBiOiAnYjQwNTBhODUgMGMwNGIzYWIgZjU0MTMyNTYgNTA0NGIwYjcgZDdiZmQ4YmEgMjcwYjM5NDMgMjM1NWZmYjQnLFxuICBuOiAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZjE2YTIgZTBiOGYwM2UgMTNkZDI5NDUgNWM1YzJhM2QnLFxuICBoYXNoOiBoYXNoLnNoYTI1NixcbiAgZ1JlZDogZmFsc2UsXG4gIGc6IFtcbiAgICAnYjcwZTBjYmQgNmJiNGJmN2YgMzIxMzkwYjkgNGEwM2MxZDMgNTZjMjExMjIgMzQzMjgwZDYgMTE1YzFkMjEnLFxuICAgICdiZDM3NjM4OCBiNWY3MjNmYiA0YzIyZGZlNiBjZDQzNzVhMCA1YTA3NDc2NCA0NGQ1ODE5OSA4NTAwN2UzNCdcbiAgXVxufSk7XG5cbmRlZmluZUN1cnZlKCdwMjU2Jywge1xuICB0eXBlOiAnc2hvcnQnLFxuICBwcmltZTogbnVsbCxcbiAgcDogJ2ZmZmZmZmZmIDAwMDAwMDAxIDAwMDAwMDAwIDAwMDAwMDAwIDAwMDAwMDAwIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmJyxcbiAgYTogJ2ZmZmZmZmZmIDAwMDAwMDAxIDAwMDAwMDAwIDAwMDAwMDAwIDAwMDAwMDAwIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZjJyxcbiAgYjogJzVhYzYzNWQ4IGFhM2E5M2U3IGIzZWJiZDU1IDc2OTg4NmJjIDY1MWQwNmIwIGNjNTNiMGY2IDNiY2UzYzNlIDI3ZDI2MDRiJyxcbiAgbjogJ2ZmZmZmZmZmIDAwMDAwMDAwIGZmZmZmZmZmIGZmZmZmZmZmIGJjZTZmYWFkIGE3MTc5ZTg0IGYzYjljYWMyIGZjNjMyNTUxJyxcbiAgaGFzaDogaGFzaC5zaGEyNTYsXG4gIGdSZWQ6IGZhbHNlLFxuICBnOiBbXG4gICAgJzZiMTdkMWYyIGUxMmM0MjQ3IGY4YmNlNmU1IDYzYTQ0MGYyIDc3MDM3ZDgxIDJkZWIzM2EwIGY0YTEzOTQ1IGQ4OThjMjk2JyxcbiAgICAnNGZlMzQyZTIgZmUxYTdmOWIgOGVlN2ViNGEgN2MwZjllMTYgMmJjZTMzNTcgNmIzMTVlY2UgY2JiNjQwNjggMzdiZjUxZjUnXG4gIF1cbn0pO1xuXG5kZWZpbmVDdXJ2ZSgncDM4NCcsIHtcbiAgdHlwZTogJ3Nob3J0JyxcbiAgcHJpbWU6IG51bGwsXG4gIHA6ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiAnICtcbiAgICAgJ2ZmZmZmZmZlIGZmZmZmZmZmIDAwMDAwMDAwIDAwMDAwMDAwIGZmZmZmZmZmJyxcbiAgYTogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmICcgK1xuICAgICAnZmZmZmZmZmUgZmZmZmZmZmYgMDAwMDAwMDAgMDAwMDAwMDAgZmZmZmZmZmMnLFxuICBiOiAnYjMzMTJmYTcgZTIzZWU3ZTQgOTg4ZTA1NmIgZTNmODJkMTkgMTgxZDljNmUgZmU4MTQxMTIgMDMxNDA4OGYgJyArXG4gICAgICc1MDEzODc1YSBjNjU2Mzk4ZCA4YTJlZDE5ZCAyYTg1YzhlZCBkM2VjMmFlZicsXG4gIG46ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBjNzYzNGQ4MSAnICtcbiAgICAgJ2Y0MzcyZGRmIDU4MWEwZGIyIDQ4YjBhNzdhIGVjZWMxOTZhIGNjYzUyOTczJyxcbiAgaGFzaDogaGFzaC5zaGEzODQsXG4gIGdSZWQ6IGZhbHNlLFxuICBnOiBbXG4gICAgJ2FhODdjYTIyIGJlOGIwNTM3IDhlYjFjNzFlIGYzMjBhZDc0IDZlMWQzYjYyIDhiYTc5Yjk4IDU5Zjc0MWUwIDgyNTQyYTM4ICcgK1xuICAgICc1NTAyZjI1ZCBiZjU1Mjk2YyAzYTU0NWUzOCA3Mjc2MGFiNycsXG4gICAgJzM2MTdkZTRhIDk2MjYyYzZmIDVkOWU5OGJmIDkyOTJkYzI5IGY4ZjQxZGJkIDI4OWExNDdjIGU5ZGEzMTEzIGI1ZjBiOGMwICcgK1xuICAgICcwYTYwYjFjZSAxZDdlODE5ZCA3YTQzMWQ3YyA5MGVhMGU1ZidcbiAgXVxufSk7XG5cbmRlZmluZUN1cnZlKCdwNTIxJywge1xuICB0eXBlOiAnc2hvcnQnLFxuICBwcmltZTogbnVsbCxcbiAgcDogJzAwMDAwMWZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmICcgK1xuICAgICAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgJyArXG4gICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZicsXG4gIGE6ICcwMDAwMDFmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiAnICtcbiAgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmICcgK1xuICAgICAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmMnLFxuICBiOiAnMDAwMDAwNTEgOTUzZWI5NjEgOGUxYzlhMWYgOTI5YTIxYTAgYjY4NTQwZWUgYTJkYTcyNWIgJyArXG4gICAgICc5OWIzMTVmMyBiOGI0ODk5MSA4ZWYxMDllMSA1NjE5Mzk1MSBlYzdlOTM3YiAxNjUyYzBiZCAnICtcbiAgICAgJzNiYjFiZjA3IDM1NzNkZjg4IDNkMmMzNGYxIGVmNDUxZmQ0IDZiNTAzZjAwJyxcbiAgbjogJzAwMDAwMWZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmICcgK1xuICAgICAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmEgNTE4Njg3ODMgYmYyZjk2NmIgN2ZjYzAxNDggJyArXG4gICAgICdmNzA5YTVkMCAzYmI1YzliOCA4OTljNDdhZSBiYjZmYjcxZSA5MTM4NjQwOScsXG4gIGhhc2g6IGhhc2guc2hhNTEyLFxuICBnUmVkOiBmYWxzZSxcbiAgZzogW1xuICAgICcwMDAwMDBjNiA4NThlMDZiNyAwNDA0ZTljZCA5ZTNlY2I2NiAyMzk1YjQ0MiA5YzY0ODEzOSAnICtcbiAgICAnMDUzZmI1MjEgZjgyOGFmNjAgNmI0ZDNkYmEgYTE0YjVlNzcgZWZlNzU5MjggZmUxZGMxMjcgJyArXG4gICAgJ2EyZmZhOGRlIDMzNDhiM2MxIDg1NmE0MjliIGY5N2U3ZTMxIGMyZTViZDY2JyxcbiAgICAnMDAwMDAxMTggMzkyOTZhNzggOWEzYmMwMDQgNWM4YTVmYjQgMmM3ZDFiZDkgOThmNTQ0NDkgJyArXG4gICAgJzU3OWI0NDY4IDE3YWZiZDE3IDI3M2U2NjJjIDk3ZWU3Mjk5IDVlZjQyNjQwIGM1NTBiOTAxICcgK1xuICAgICczZmFkMDc2MSAzNTNjNzA4NiBhMjcyYzI0MCA4OGJlOTQ3NiA5ZmQxNjY1MCdcbiAgXVxufSk7XG5cbmRlZmluZUN1cnZlKCdjdXJ2ZTI1NTE5Jywge1xuICB0eXBlOiAnbW9udCcsXG4gIHByaW1lOiAncDI1NTE5JyxcbiAgcDogJzdmZmZmZmZmZmZmZmZmZmYgZmZmZmZmZmZmZmZmZmZmZiBmZmZmZmZmZmZmZmZmZmZmIGZmZmZmZmZmZmZmZmZmZWQnLFxuICBhOiAnNzZkMDYnLFxuICBiOiAnMScsXG4gIG46ICcxMDAwMDAwMDAwMDAwMDAwIDAwMDAwMDAwMDAwMDAwMDAgMTRkZWY5ZGVhMmY3OWNkNiA1ODEyNjMxYTVjZjVkM2VkJyxcbiAgaGFzaDogaGFzaC5zaGEyNTYsXG4gIGdSZWQ6IGZhbHNlLFxuICBnOiBbXG4gICAgJzknXG4gIF1cbn0pO1xuXG5kZWZpbmVDdXJ2ZSgnZWQyNTUxOScsIHtcbiAgdHlwZTogJ2Vkd2FyZHMnLFxuICBwcmltZTogJ3AyNTUxOScsXG4gIHA6ICc3ZmZmZmZmZmZmZmZmZmZmIGZmZmZmZmZmZmZmZmZmZmYgZmZmZmZmZmZmZmZmZmZmZiBmZmZmZmZmZmZmZmZmZmVkJyxcbiAgYTogJy0xJyxcbiAgYzogJzEnLFxuICAvLyAtMTIxNjY1ICogKDEyMTY2Nl4oLTEpKSAobW9kIFApXG4gIGQ6ICc1MjAzNmNlZTJiNmZmZTczIDhjYzc0MDc5Nzc3OWU4OTggMDA3MDBhNGQ0MTQxZDhhYiA3NWViNGRjYTEzNTk3OGEzJyxcbiAgbjogJzEwMDAwMDAwMDAwMDAwMDAgMDAwMDAwMDAwMDAwMDAwMCAxNGRlZjlkZWEyZjc5Y2Q2IDU4MTI2MzFhNWNmNWQzZWQnLFxuICBoYXNoOiBoYXNoLnNoYTI1NixcbiAgZ1JlZDogZmFsc2UsXG4gIGc6IFtcbiAgICAnMjE2OTM2ZDNjZDZlNTNmZWMwYTRlMjMxZmRkNmRjNWM2OTJjYzc2MDk1MjVhN2IyYzk1NjJkNjA4ZjI1ZDUxYScsXG5cbiAgICAvLyA0LzVcbiAgICAnNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY1OCdcbiAgXVxufSk7XG5cbnZhciBwcmU7XG50cnkge1xuICBwcmUgPSByZXF1aXJlKCcuL3ByZWNvbXB1dGVkL3NlY3AyNTZrMScpO1xufSBjYXRjaCAoZSkge1xuICBwcmUgPSB1bmRlZmluZWQ7XG59XG5cbmRlZmluZUN1cnZlKCdzZWNwMjU2azEnLCB7XG4gIHR5cGU6ICdzaG9ydCcsXG4gIHByaW1lOiAnazI1NicsXG4gIHA6ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZSBmZmZmZmMyZicsXG4gIGE6ICcwJyxcbiAgYjogJzcnLFxuICBuOiAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmUgYmFhZWRjZTYgYWY0OGEwM2IgYmZkMjVlOGMgZDAzNjQxNDEnLFxuICBoOiAnMScsXG4gIGhhc2g6IGhhc2guc2hhMjU2LFxuXG4gIC8vIFByZWNvbXB1dGVkIGVuZG9tb3JwaGlzbVxuICBiZXRhOiAnN2FlOTZhMmI2NTdjMDcxMDZlNjQ0NzllYWMzNDM0ZTk5Y2YwNDk3NTEyZjU4OTk1YzEzOTZjMjg3MTk1MDFlZScsXG4gIGxhbWJkYTogJzUzNjNhZDRjYzA1YzMwZTBhNTI2MWMwMjg4MTI2NDVhMTIyZTIyZWEyMDgxNjY3OGRmMDI5NjdjMWIyM2JkNzInLFxuICBiYXNpczogW1xuICAgIHtcbiAgICAgIGE6ICczMDg2ZDIyMWE3ZDQ2YmNkZTg2YzkwZTQ5Mjg0ZWIxNScsXG4gICAgICBiOiAnLWU0NDM3ZWQ2MDEwZTg4Mjg2ZjU0N2ZhOTBhYmZlNGMzJ1xuICAgIH0sXG4gICAge1xuICAgICAgYTogJzExNGNhNTBmN2E4ZTJmM2Y2NTdjMTEwOGQ5ZDQ0Y2ZkOCcsXG4gICAgICBiOiAnMzA4NmQyMjFhN2Q0NmJjZGU4NmM5MGU0OTI4NGViMTUnXG4gICAgfVxuICBdLFxuXG4gIGdSZWQ6IGZhbHNlLFxuICBnOiBbXG4gICAgJzc5YmU2NjdlZjlkY2JiYWM1NWEwNjI5NWNlODcwYjA3MDI5YmZjZGIyZGNlMjhkOTU5ZjI4MTViMTZmODE3OTgnLFxuICAgICc0ODNhZGE3NzI2YTNjNDY1NWRhNGZiZmMwZTExMDhhOGZkMTdiNDQ4YTY4NTU0MTk5YzQ3ZDA4ZmZiMTBkNGI4JyxcbiAgICBwcmVcbiAgXVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgSG1hY0RSQkcgPSByZXF1aXJlKCdobWFjLWRyYmcnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgY3VydmVzID0gcmVxdWlyZSgnLi4vY3VydmVzJyk7XG52YXIgcmFuZCA9IHJlcXVpcmUoJ2Jyb3JhbmQnKTtcbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG5cbnZhciBLZXlQYWlyID0gcmVxdWlyZSgnLi9rZXknKTtcbnZhciBTaWduYXR1cmUgPSByZXF1aXJlKCcuL3NpZ25hdHVyZScpO1xuXG5mdW5jdGlvbiBFQyhvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBFQykpXG4gICAgcmV0dXJuIG5ldyBFQyhvcHRpb25zKTtcblxuICAvLyBTaG9ydGN1dCBgZWxsaXB0aWMuZWMoY3VydmUtbmFtZSlgXG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycpIHtcbiAgICBhc3NlcnQoY3VydmVzLmhhc093blByb3BlcnR5KG9wdGlvbnMpLCAnVW5rbm93biBjdXJ2ZSAnICsgb3B0aW9ucyk7XG5cbiAgICBvcHRpb25zID0gY3VydmVzW29wdGlvbnNdO1xuICB9XG5cbiAgLy8gU2hvcnRjdXQgZm9yIGBlbGxpcHRpYy5lYyhlbGxpcHRpYy5jdXJ2ZXMuY3VydmVOYW1lKWBcbiAgaWYgKG9wdGlvbnMgaW5zdGFuY2VvZiBjdXJ2ZXMuUHJlc2V0Q3VydmUpXG4gICAgb3B0aW9ucyA9IHsgY3VydmU6IG9wdGlvbnMgfTtcblxuICB0aGlzLmN1cnZlID0gb3B0aW9ucy5jdXJ2ZS5jdXJ2ZTtcbiAgdGhpcy5uID0gdGhpcy5jdXJ2ZS5uO1xuICB0aGlzLm5oID0gdGhpcy5uLnVzaHJuKDEpO1xuICB0aGlzLmcgPSB0aGlzLmN1cnZlLmc7XG5cbiAgLy8gUG9pbnQgb24gY3VydmVcbiAgdGhpcy5nID0gb3B0aW9ucy5jdXJ2ZS5nO1xuICB0aGlzLmcucHJlY29tcHV0ZShvcHRpb25zLmN1cnZlLm4uYml0TGVuZ3RoKCkgKyAxKTtcblxuICAvLyBIYXNoIGZvciBmdW5jdGlvbiBmb3IgRFJCR1xuICB0aGlzLmhhc2ggPSBvcHRpb25zLmhhc2ggfHwgb3B0aW9ucy5jdXJ2ZS5oYXNoO1xufVxubW9kdWxlLmV4cG9ydHMgPSBFQztcblxuRUMucHJvdG90eXBlLmtleVBhaXIgPSBmdW5jdGlvbiBrZXlQYWlyKG9wdGlvbnMpIHtcbiAgcmV0dXJuIG5ldyBLZXlQYWlyKHRoaXMsIG9wdGlvbnMpO1xufTtcblxuRUMucHJvdG90eXBlLmtleUZyb21Qcml2YXRlID0gZnVuY3Rpb24ga2V5RnJvbVByaXZhdGUocHJpdiwgZW5jKSB7XG4gIHJldHVybiBLZXlQYWlyLmZyb21Qcml2YXRlKHRoaXMsIHByaXYsIGVuYyk7XG59O1xuXG5FQy5wcm90b3R5cGUua2V5RnJvbVB1YmxpYyA9IGZ1bmN0aW9uIGtleUZyb21QdWJsaWMocHViLCBlbmMpIHtcbiAgcmV0dXJuIEtleVBhaXIuZnJvbVB1YmxpYyh0aGlzLCBwdWIsIGVuYyk7XG59O1xuXG5FQy5wcm90b3R5cGUuZ2VuS2V5UGFpciA9IGZ1bmN0aW9uIGdlbktleVBhaXIob3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMpXG4gICAgb3B0aW9ucyA9IHt9O1xuXG4gIC8vIEluc3RhbnRpYXRlIEhtYWNfRFJCR1xuICB2YXIgZHJiZyA9IG5ldyBIbWFjRFJCRyh7XG4gICAgaGFzaDogdGhpcy5oYXNoLFxuICAgIHBlcnM6IG9wdGlvbnMucGVycyxcbiAgICBwZXJzRW5jOiBvcHRpb25zLnBlcnNFbmMgfHwgJ3V0ZjgnLFxuICAgIGVudHJvcHk6IG9wdGlvbnMuZW50cm9weSB8fCByYW5kKHRoaXMuaGFzaC5obWFjU3RyZW5ndGgpLFxuICAgIGVudHJvcHlFbmM6IG9wdGlvbnMuZW50cm9weSAmJiBvcHRpb25zLmVudHJvcHlFbmMgfHwgJ3V0ZjgnLFxuICAgIG5vbmNlOiB0aGlzLm4udG9BcnJheSgpXG4gIH0pO1xuXG4gIHZhciBieXRlcyA9IHRoaXMubi5ieXRlTGVuZ3RoKCk7XG4gIHZhciBuczIgPSB0aGlzLm4uc3ViKG5ldyBCTigyKSk7XG4gIGRvIHtcbiAgICB2YXIgcHJpdiA9IG5ldyBCTihkcmJnLmdlbmVyYXRlKGJ5dGVzKSk7XG4gICAgaWYgKHByaXYuY21wKG5zMikgPiAwKVxuICAgICAgY29udGludWU7XG5cbiAgICBwcml2LmlhZGRuKDEpO1xuICAgIHJldHVybiB0aGlzLmtleUZyb21Qcml2YXRlKHByaXYpO1xuICB9IHdoaWxlICh0cnVlKTtcbn07XG5cbkVDLnByb3RvdHlwZS5fdHJ1bmNhdGVUb04gPSBmdW5jdGlvbiB0cnVuY2F0ZVRvTihtc2csIHRydW5jT25seSkge1xuICB2YXIgZGVsdGEgPSBtc2cuYnl0ZUxlbmd0aCgpICogOCAtIHRoaXMubi5iaXRMZW5ndGgoKTtcbiAgaWYgKGRlbHRhID4gMClcbiAgICBtc2cgPSBtc2cudXNocm4oZGVsdGEpO1xuICBpZiAoIXRydW5jT25seSAmJiBtc2cuY21wKHRoaXMubikgPj0gMClcbiAgICByZXR1cm4gbXNnLnN1Yih0aGlzLm4pO1xuICBlbHNlXG4gICAgcmV0dXJuIG1zZztcbn07XG5cbkVDLnByb3RvdHlwZS5zaWduID0gZnVuY3Rpb24gc2lnbihtc2csIGtleSwgZW5jLCBvcHRpb25zKSB7XG4gIGlmICh0eXBlb2YgZW5jID09PSAnb2JqZWN0Jykge1xuICAgIG9wdGlvbnMgPSBlbmM7XG4gICAgZW5jID0gbnVsbDtcbiAgfVxuICBpZiAoIW9wdGlvbnMpXG4gICAgb3B0aW9ucyA9IHt9O1xuXG4gIGtleSA9IHRoaXMua2V5RnJvbVByaXZhdGUoa2V5LCBlbmMpO1xuICBtc2cgPSB0aGlzLl90cnVuY2F0ZVRvTihuZXcgQk4obXNnLCAxNikpO1xuXG4gIC8vIFplcm8tZXh0ZW5kIGtleSB0byBwcm92aWRlIGVub3VnaCBlbnRyb3B5XG4gIHZhciBieXRlcyA9IHRoaXMubi5ieXRlTGVuZ3RoKCk7XG4gIHZhciBia2V5ID0ga2V5LmdldFByaXZhdGUoKS50b0FycmF5KCdiZScsIGJ5dGVzKTtcblxuICAvLyBaZXJvLWV4dGVuZCBub25jZSB0byBoYXZlIHRoZSBzYW1lIGJ5dGUgc2l6ZSBhcyBOXG4gIHZhciBub25jZSA9IG1zZy50b0FycmF5KCdiZScsIGJ5dGVzKTtcblxuICAvLyBJbnN0YW50aWF0ZSBIbWFjX0RSQkdcbiAgdmFyIGRyYmcgPSBuZXcgSG1hY0RSQkcoe1xuICAgIGhhc2g6IHRoaXMuaGFzaCxcbiAgICBlbnRyb3B5OiBia2V5LFxuICAgIG5vbmNlOiBub25jZSxcbiAgICBwZXJzOiBvcHRpb25zLnBlcnMsXG4gICAgcGVyc0VuYzogb3B0aW9ucy5wZXJzRW5jIHx8ICd1dGY4J1xuICB9KTtcblxuICAvLyBOdW1iZXIgb2YgYnl0ZXMgdG8gZ2VuZXJhdGVcbiAgdmFyIG5zMSA9IHRoaXMubi5zdWIobmV3IEJOKDEpKTtcblxuICBmb3IgKHZhciBpdGVyID0gMDsgdHJ1ZTsgaXRlcisrKSB7XG4gICAgdmFyIGsgPSBvcHRpb25zLmsgP1xuICAgICAgICBvcHRpb25zLmsoaXRlcikgOlxuICAgICAgICBuZXcgQk4oZHJiZy5nZW5lcmF0ZSh0aGlzLm4uYnl0ZUxlbmd0aCgpKSk7XG4gICAgayA9IHRoaXMuX3RydW5jYXRlVG9OKGssIHRydWUpO1xuICAgIGlmIChrLmNtcG4oMSkgPD0gMCB8fCBrLmNtcChuczEpID49IDApXG4gICAgICBjb250aW51ZTtcblxuICAgIHZhciBrcCA9IHRoaXMuZy5tdWwoayk7XG4gICAgaWYgKGtwLmlzSW5maW5pdHkoKSlcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgdmFyIGtwWCA9IGtwLmdldFgoKTtcbiAgICB2YXIgciA9IGtwWC51bW9kKHRoaXMubik7XG4gICAgaWYgKHIuY21wbigwKSA9PT0gMClcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgdmFyIHMgPSBrLmludm0odGhpcy5uKS5tdWwoci5tdWwoa2V5LmdldFByaXZhdGUoKSkuaWFkZChtc2cpKTtcbiAgICBzID0gcy51bW9kKHRoaXMubik7XG4gICAgaWYgKHMuY21wbigwKSA9PT0gMClcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgdmFyIHJlY292ZXJ5UGFyYW0gPSAoa3AuZ2V0WSgpLmlzT2RkKCkgPyAxIDogMCkgfFxuICAgICAgICAgICAgICAgICAgICAgICAgKGtwWC5jbXAocikgIT09IDAgPyAyIDogMCk7XG5cbiAgICAvLyBVc2UgY29tcGxlbWVudCBvZiBgc2AsIGlmIGl0IGlzID4gYG4gLyAyYFxuICAgIGlmIChvcHRpb25zLmNhbm9uaWNhbCAmJiBzLmNtcCh0aGlzLm5oKSA+IDApIHtcbiAgICAgIHMgPSB0aGlzLm4uc3ViKHMpO1xuICAgICAgcmVjb3ZlcnlQYXJhbSBePSAxO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgU2lnbmF0dXJlKHsgcjogciwgczogcywgcmVjb3ZlcnlQYXJhbTogcmVjb3ZlcnlQYXJhbSB9KTtcbiAgfVxufTtcblxuRUMucHJvdG90eXBlLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtc2csIHNpZ25hdHVyZSwga2V5LCBlbmMpIHtcbiAgbXNnID0gdGhpcy5fdHJ1bmNhdGVUb04obmV3IEJOKG1zZywgMTYpKTtcbiAga2V5ID0gdGhpcy5rZXlGcm9tUHVibGljKGtleSwgZW5jKTtcbiAgc2lnbmF0dXJlID0gbmV3IFNpZ25hdHVyZShzaWduYXR1cmUsICdoZXgnKTtcblxuICAvLyBQZXJmb3JtIHByaW1pdGl2ZSB2YWx1ZXMgdmFsaWRhdGlvblxuICB2YXIgciA9IHNpZ25hdHVyZS5yO1xuICB2YXIgcyA9IHNpZ25hdHVyZS5zO1xuICBpZiAoci5jbXBuKDEpIDwgMCB8fCByLmNtcCh0aGlzLm4pID49IDApXG4gICAgcmV0dXJuIGZhbHNlO1xuICBpZiAocy5jbXBuKDEpIDwgMCB8fCBzLmNtcCh0aGlzLm4pID49IDApXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIFZhbGlkYXRlIHNpZ25hdHVyZVxuICB2YXIgc2ludiA9IHMuaW52bSh0aGlzLm4pO1xuICB2YXIgdTEgPSBzaW52Lm11bChtc2cpLnVtb2QodGhpcy5uKTtcbiAgdmFyIHUyID0gc2ludi5tdWwocikudW1vZCh0aGlzLm4pO1xuXG4gIGlmICghdGhpcy5jdXJ2ZS5fbWF4d2VsbFRyaWNrKSB7XG4gICAgdmFyIHAgPSB0aGlzLmcubXVsQWRkKHUxLCBrZXkuZ2V0UHVibGljKCksIHUyKTtcbiAgICBpZiAocC5pc0luZmluaXR5KCkpXG4gICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICByZXR1cm4gcC5nZXRYKCkudW1vZCh0aGlzLm4pLmNtcChyKSA9PT0gMDtcbiAgfVxuXG4gIC8vIE5PVEU6IEdyZWcgTWF4d2VsbCdzIHRyaWNrLCBpbnNwaXJlZCBieTpcbiAgLy8gaHR0cHM6Ly9naXQuaW8vdmFkM0tcblxuICB2YXIgcCA9IHRoaXMuZy5qbXVsQWRkKHUxLCBrZXkuZ2V0UHVibGljKCksIHUyKTtcbiAgaWYgKHAuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiBmYWxzZTtcblxuICAvLyBDb21wYXJlIGBwLnhgIG9mIEphY29iaWFuIHBvaW50IHdpdGggYHJgLFxuICAvLyB0aGlzIHdpbGwgZG8gYHAueCA9PSByICogcC56XjJgIGluc3RlYWQgb2YgbXVsdGlwbHlpbmcgYHAueGAgYnkgdGhlXG4gIC8vIGludmVyc2Ugb2YgYHAuel4yYFxuICByZXR1cm4gcC5lcVhUb1Aocik7XG59O1xuXG5FQy5wcm90b3R5cGUucmVjb3ZlclB1YktleSA9IGZ1bmN0aW9uKG1zZywgc2lnbmF0dXJlLCBqLCBlbmMpIHtcbiAgYXNzZXJ0KCgzICYgaikgPT09IGosICdUaGUgcmVjb3ZlcnkgcGFyYW0gaXMgbW9yZSB0aGFuIHR3byBiaXRzJyk7XG4gIHNpZ25hdHVyZSA9IG5ldyBTaWduYXR1cmUoc2lnbmF0dXJlLCBlbmMpO1xuXG4gIHZhciBuID0gdGhpcy5uO1xuICB2YXIgZSA9IG5ldyBCTihtc2cpO1xuICB2YXIgciA9IHNpZ25hdHVyZS5yO1xuICB2YXIgcyA9IHNpZ25hdHVyZS5zO1xuXG4gIC8vIEEgc2V0IExTQiBzaWduaWZpZXMgdGhhdCB0aGUgeS1jb29yZGluYXRlIGlzIG9kZFxuICB2YXIgaXNZT2RkID0gaiAmIDE7XG4gIHZhciBpc1NlY29uZEtleSA9IGogPj4gMTtcbiAgaWYgKHIuY21wKHRoaXMuY3VydmUucC51bW9kKHRoaXMuY3VydmUubikpID49IDAgJiYgaXNTZWNvbmRLZXkpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZmluZCBzZW5jb25kIGtleSBjYW5kaW5hdGUnKTtcblxuICAvLyAxLjEuIExldCB4ID0gciArIGpuLlxuICBpZiAoaXNTZWNvbmRLZXkpXG4gICAgciA9IHRoaXMuY3VydmUucG9pbnRGcm9tWChyLmFkZCh0aGlzLmN1cnZlLm4pLCBpc1lPZGQpO1xuICBlbHNlXG4gICAgciA9IHRoaXMuY3VydmUucG9pbnRGcm9tWChyLCBpc1lPZGQpO1xuXG4gIHZhciBySW52ID0gc2lnbmF0dXJlLnIuaW52bShuKTtcbiAgdmFyIHMxID0gbi5zdWIoZSkubXVsKHJJbnYpLnVtb2Qobik7XG4gIHZhciBzMiA9IHMubXVsKHJJbnYpLnVtb2Qobik7XG5cbiAgLy8gMS42LjEgQ29tcHV0ZSBRID0gcl4tMSAoc1IgLSAgZUcpXG4gIC8vICAgICAgICAgICAgICAgUSA9IHJeLTEgKHNSICsgLWVHKVxuICByZXR1cm4gdGhpcy5nLm11bEFkZChzMSwgciwgczIpO1xufTtcblxuRUMucHJvdG90eXBlLmdldEtleVJlY292ZXJ5UGFyYW0gPSBmdW5jdGlvbihlLCBzaWduYXR1cmUsIFEsIGVuYykge1xuICBzaWduYXR1cmUgPSBuZXcgU2lnbmF0dXJlKHNpZ25hdHVyZSwgZW5jKTtcbiAgaWYgKHNpZ25hdHVyZS5yZWNvdmVyeVBhcmFtICE9PSBudWxsKVxuICAgIHJldHVybiBzaWduYXR1cmUucmVjb3ZlcnlQYXJhbTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIHZhciBRcHJpbWU7XG4gICAgdHJ5IHtcbiAgICAgIFFwcmltZSA9IHRoaXMucmVjb3ZlclB1YktleShlLCBzaWduYXR1cmUsIGkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChRcHJpbWUuZXEoUSkpXG4gICAgICByZXR1cm4gaTtcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBmaW5kIHZhbGlkIHJlY292ZXJ5IGZhY3RvcicpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xuXG5mdW5jdGlvbiBLZXlQYWlyKGVjLCBvcHRpb25zKSB7XG4gIHRoaXMuZWMgPSBlYztcbiAgdGhpcy5wcml2ID0gbnVsbDtcbiAgdGhpcy5wdWIgPSBudWxsO1xuXG4gIC8vIEtleVBhaXIoZWMsIHsgcHJpdjogLi4uLCBwdWI6IC4uLiB9KVxuICBpZiAob3B0aW9ucy5wcml2KVxuICAgIHRoaXMuX2ltcG9ydFByaXZhdGUob3B0aW9ucy5wcml2LCBvcHRpb25zLnByaXZFbmMpO1xuICBpZiAob3B0aW9ucy5wdWIpXG4gICAgdGhpcy5faW1wb3J0UHVibGljKG9wdGlvbnMucHViLCBvcHRpb25zLnB1YkVuYyk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEtleVBhaXI7XG5cbktleVBhaXIuZnJvbVB1YmxpYyA9IGZ1bmN0aW9uIGZyb21QdWJsaWMoZWMsIHB1YiwgZW5jKSB7XG4gIGlmIChwdWIgaW5zdGFuY2VvZiBLZXlQYWlyKVxuICAgIHJldHVybiBwdWI7XG5cbiAgcmV0dXJuIG5ldyBLZXlQYWlyKGVjLCB7XG4gICAgcHViOiBwdWIsXG4gICAgcHViRW5jOiBlbmNcbiAgfSk7XG59O1xuXG5LZXlQYWlyLmZyb21Qcml2YXRlID0gZnVuY3Rpb24gZnJvbVByaXZhdGUoZWMsIHByaXYsIGVuYykge1xuICBpZiAocHJpdiBpbnN0YW5jZW9mIEtleVBhaXIpXG4gICAgcmV0dXJuIHByaXY7XG5cbiAgcmV0dXJuIG5ldyBLZXlQYWlyKGVjLCB7XG4gICAgcHJpdjogcHJpdixcbiAgICBwcml2RW5jOiBlbmNcbiAgfSk7XG59O1xuXG5LZXlQYWlyLnByb3RvdHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uIHZhbGlkYXRlKCkge1xuICB2YXIgcHViID0gdGhpcy5nZXRQdWJsaWMoKTtcblxuICBpZiAocHViLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCByZWFzb246ICdJbnZhbGlkIHB1YmxpYyBrZXknIH07XG4gIGlmICghcHViLnZhbGlkYXRlKCkpXG4gICAgcmV0dXJuIHsgcmVzdWx0OiBmYWxzZSwgcmVhc29uOiAnUHVibGljIGtleSBpcyBub3QgYSBwb2ludCcgfTtcbiAgaWYgKCFwdWIubXVsKHRoaXMuZWMuY3VydmUubikuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiB7IHJlc3VsdDogZmFsc2UsIHJlYXNvbjogJ1B1YmxpYyBrZXkgKiBOICE9IE8nIH07XG5cbiAgcmV0dXJuIHsgcmVzdWx0OiB0cnVlLCByZWFzb246IG51bGwgfTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLmdldFB1YmxpYyA9IGZ1bmN0aW9uIGdldFB1YmxpYyhjb21wYWN0LCBlbmMpIHtcbiAgLy8gY29tcGFjdCBpcyBvcHRpb25hbCBhcmd1bWVudFxuICBpZiAodHlwZW9mIGNvbXBhY3QgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jID0gY29tcGFjdDtcbiAgICBjb21wYWN0ID0gbnVsbDtcbiAgfVxuXG4gIGlmICghdGhpcy5wdWIpXG4gICAgdGhpcy5wdWIgPSB0aGlzLmVjLmcubXVsKHRoaXMucHJpdik7XG5cbiAgaWYgKCFlbmMpXG4gICAgcmV0dXJuIHRoaXMucHViO1xuXG4gIHJldHVybiB0aGlzLnB1Yi5lbmNvZGUoZW5jLCBjb21wYWN0KTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLmdldFByaXZhdGUgPSBmdW5jdGlvbiBnZXRQcml2YXRlKGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdGhpcy5wcml2LnRvU3RyaW5nKDE2LCAyKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLnByaXY7XG59O1xuXG5LZXlQYWlyLnByb3RvdHlwZS5faW1wb3J0UHJpdmF0ZSA9IGZ1bmN0aW9uIF9pbXBvcnRQcml2YXRlKGtleSwgZW5jKSB7XG4gIHRoaXMucHJpdiA9IG5ldyBCTihrZXksIGVuYyB8fCAxNik7XG5cbiAgLy8gRW5zdXJlIHRoYXQgdGhlIHByaXYgd29uJ3QgYmUgYmlnZ2VyIHRoYW4gbiwgb3RoZXJ3aXNlIHdlIG1heSBmYWlsXG4gIC8vIGluIGZpeGVkIG11bHRpcGxpY2F0aW9uIG1ldGhvZFxuICB0aGlzLnByaXYgPSB0aGlzLnByaXYudW1vZCh0aGlzLmVjLmN1cnZlLm4pO1xufTtcblxuS2V5UGFpci5wcm90b3R5cGUuX2ltcG9ydFB1YmxpYyA9IGZ1bmN0aW9uIF9pbXBvcnRQdWJsaWMoa2V5LCBlbmMpIHtcbiAgaWYgKGtleS54IHx8IGtleS55KSB7XG4gICAgLy8gTW9udGdvbWVyeSBwb2ludHMgb25seSBoYXZlIGFuIGB4YCBjb29yZGluYXRlLlxuICAgIC8vIFdlaWVyc3RyYXNzL0Vkd2FyZHMgcG9pbnRzIG9uIHRoZSBvdGhlciBoYW5kIGhhdmUgYm90aCBgeGAgYW5kXG4gICAgLy8gYHlgIGNvb3JkaW5hdGVzLlxuICAgIGlmICh0aGlzLmVjLmN1cnZlLnR5cGUgPT09ICdtb250Jykge1xuICAgICAgYXNzZXJ0KGtleS54LCAnTmVlZCB4IGNvb3JkaW5hdGUnKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZWMuY3VydmUudHlwZSA9PT0gJ3Nob3J0JyB8fFxuICAgICAgICAgICAgICAgdGhpcy5lYy5jdXJ2ZS50eXBlID09PSAnZWR3YXJkcycpIHtcbiAgICAgIGFzc2VydChrZXkueCAmJiBrZXkueSwgJ05lZWQgYm90aCB4IGFuZCB5IGNvb3JkaW5hdGUnKTtcbiAgICB9XG4gICAgdGhpcy5wdWIgPSB0aGlzLmVjLmN1cnZlLnBvaW50KGtleS54LCBrZXkueSk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHRoaXMucHViID0gdGhpcy5lYy5jdXJ2ZS5kZWNvZGVQb2ludChrZXksIGVuYyk7XG59O1xuXG4vLyBFQ0RIXG5LZXlQYWlyLnByb3RvdHlwZS5kZXJpdmUgPSBmdW5jdGlvbiBkZXJpdmUocHViKSB7XG4gIHJldHVybiBwdWIubXVsKHRoaXMucHJpdikuZ2V0WCgpO1xufTtcblxuLy8gRUNEU0FcbktleVBhaXIucHJvdG90eXBlLnNpZ24gPSBmdW5jdGlvbiBzaWduKG1zZywgZW5jLCBvcHRpb25zKSB7XG4gIHJldHVybiB0aGlzLmVjLnNpZ24obXNnLCB0aGlzLCBlbmMsIG9wdGlvbnMpO1xufTtcblxuS2V5UGFpci5wcm90b3R5cGUudmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1zZywgc2lnbmF0dXJlKSB7XG4gIHJldHVybiB0aGlzLmVjLnZlcmlmeShtc2csIHNpZ25hdHVyZSwgdGhpcyk7XG59O1xuXG5LZXlQYWlyLnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgcmV0dXJuICc8S2V5IHByaXY6ICcgKyAodGhpcy5wcml2ICYmIHRoaXMucHJpdi50b1N0cmluZygxNiwgMikpICtcbiAgICAgICAgICcgcHViOiAnICsgKHRoaXMucHViICYmIHRoaXMucHViLmluc3BlY3QoKSkgKyAnID4nO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG5cbmZ1bmN0aW9uIFNpZ25hdHVyZShvcHRpb25zLCBlbmMpIHtcbiAgaWYgKG9wdGlvbnMgaW5zdGFuY2VvZiBTaWduYXR1cmUpXG4gICAgcmV0dXJuIG9wdGlvbnM7XG5cbiAgaWYgKHRoaXMuX2ltcG9ydERFUihvcHRpb25zLCBlbmMpKVxuICAgIHJldHVybjtcblxuICBhc3NlcnQob3B0aW9ucy5yICYmIG9wdGlvbnMucywgJ1NpZ25hdHVyZSB3aXRob3V0IHIgb3IgcycpO1xuICB0aGlzLnIgPSBuZXcgQk4ob3B0aW9ucy5yLCAxNik7XG4gIHRoaXMucyA9IG5ldyBCTihvcHRpb25zLnMsIDE2KTtcbiAgaWYgKG9wdGlvbnMucmVjb3ZlcnlQYXJhbSA9PT0gdW5kZWZpbmVkKVxuICAgIHRoaXMucmVjb3ZlcnlQYXJhbSA9IG51bGw7XG4gIGVsc2VcbiAgICB0aGlzLnJlY292ZXJ5UGFyYW0gPSBvcHRpb25zLnJlY292ZXJ5UGFyYW07XG59XG5tb2R1bGUuZXhwb3J0cyA9IFNpZ25hdHVyZTtcblxuZnVuY3Rpb24gUG9zaXRpb24oKSB7XG4gIHRoaXMucGxhY2UgPSAwO1xufVxuXG5mdW5jdGlvbiBnZXRMZW5ndGgoYnVmLCBwKSB7XG4gIHZhciBpbml0aWFsID0gYnVmW3AucGxhY2UrK107XG4gIGlmICghKGluaXRpYWwgJiAweDgwKSkge1xuICAgIHJldHVybiBpbml0aWFsO1xuICB9XG4gIHZhciBvY3RldExlbiA9IGluaXRpYWwgJiAweGY7XG5cbiAgLy8gSW5kZWZpbml0ZSBsZW5ndGggb3Igb3ZlcmZsb3dcbiAgaWYgKG9jdGV0TGVuID09PSAwIHx8IG9jdGV0TGVuID4gNCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciB2YWwgPSAwO1xuICBmb3IgKHZhciBpID0gMCwgb2ZmID0gcC5wbGFjZTsgaSA8IG9jdGV0TGVuOyBpKyssIG9mZisrKSB7XG4gICAgdmFsIDw8PSA4O1xuICAgIHZhbCB8PSBidWZbb2ZmXTtcbiAgICB2YWwgPj4+PSAwO1xuICB9XG5cbiAgLy8gTGVhZGluZyB6ZXJvZXNcbiAgaWYgKHZhbCA8PSAweDdmKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcC5wbGFjZSA9IG9mZjtcbiAgcmV0dXJuIHZhbDtcbn1cblxuZnVuY3Rpb24gcm1QYWRkaW5nKGJ1Zikge1xuICB2YXIgaSA9IDA7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoIC0gMTtcbiAgd2hpbGUgKCFidWZbaV0gJiYgIShidWZbaSArIDFdICYgMHg4MCkgJiYgaSA8IGxlbikge1xuICAgIGkrKztcbiAgfVxuICBpZiAoaSA9PT0gMCkge1xuICAgIHJldHVybiBidWY7XG4gIH1cbiAgcmV0dXJuIGJ1Zi5zbGljZShpKTtcbn1cblxuU2lnbmF0dXJlLnByb3RvdHlwZS5faW1wb3J0REVSID0gZnVuY3Rpb24gX2ltcG9ydERFUihkYXRhLCBlbmMpIHtcbiAgZGF0YSA9IHV0aWxzLnRvQXJyYXkoZGF0YSwgZW5jKTtcbiAgdmFyIHAgPSBuZXcgUG9zaXRpb24oKTtcbiAgaWYgKGRhdGFbcC5wbGFjZSsrXSAhPT0gMHgzMCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgbGVuID0gZ2V0TGVuZ3RoKGRhdGEsIHApO1xuICBpZiAobGVuID09PSBmYWxzZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoKGxlbiArIHAucGxhY2UpICE9PSBkYXRhLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoZGF0YVtwLnBsYWNlKytdICE9PSAweDAyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBybGVuID0gZ2V0TGVuZ3RoKGRhdGEsIHApO1xuICBpZiAocmxlbiA9PT0gZmFsc2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHIgPSBkYXRhLnNsaWNlKHAucGxhY2UsIHJsZW4gKyBwLnBsYWNlKTtcbiAgcC5wbGFjZSArPSBybGVuO1xuICBpZiAoZGF0YVtwLnBsYWNlKytdICE9PSAweDAyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBzbGVuID0gZ2V0TGVuZ3RoKGRhdGEsIHApO1xuICBpZiAoc2xlbiA9PT0gZmFsc2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGRhdGEubGVuZ3RoICE9PSBzbGVuICsgcC5wbGFjZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgcyA9IGRhdGEuc2xpY2UocC5wbGFjZSwgc2xlbiArIHAucGxhY2UpO1xuICBpZiAoclswXSA9PT0gMCkge1xuICAgIGlmIChyWzFdICYgMHg4MCkge1xuICAgICAgciA9IHIuc2xpY2UoMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIExlYWRpbmcgemVyb2VzXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIGlmIChzWzBdID09PSAwKSB7XG4gICAgaWYgKHNbMV0gJiAweDgwKSB7XG4gICAgICBzID0gcy5zbGljZSgxKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTGVhZGluZyB6ZXJvZXNcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICB0aGlzLnIgPSBuZXcgQk4ocik7XG4gIHRoaXMucyA9IG5ldyBCTihzKTtcbiAgdGhpcy5yZWNvdmVyeVBhcmFtID0gbnVsbDtcblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdExlbmd0aChhcnIsIGxlbikge1xuICBpZiAobGVuIDwgMHg4MCkge1xuICAgIGFyci5wdXNoKGxlbik7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBvY3RldHMgPSAxICsgKE1hdGgubG9nKGxlbikgLyBNYXRoLkxOMiA+Pj4gMyk7XG4gIGFyci5wdXNoKG9jdGV0cyB8IDB4ODApO1xuICB3aGlsZSAoLS1vY3RldHMpIHtcbiAgICBhcnIucHVzaCgobGVuID4+PiAob2N0ZXRzIDw8IDMpKSAmIDB4ZmYpO1xuICB9XG4gIGFyci5wdXNoKGxlbik7XG59XG5cblNpZ25hdHVyZS5wcm90b3R5cGUudG9ERVIgPSBmdW5jdGlvbiB0b0RFUihlbmMpIHtcbiAgdmFyIHIgPSB0aGlzLnIudG9BcnJheSgpO1xuICB2YXIgcyA9IHRoaXMucy50b0FycmF5KCk7XG5cbiAgLy8gUGFkIHZhbHVlc1xuICBpZiAoclswXSAmIDB4ODApXG4gICAgciA9IFsgMCBdLmNvbmNhdChyKTtcbiAgLy8gUGFkIHZhbHVlc1xuICBpZiAoc1swXSAmIDB4ODApXG4gICAgcyA9IFsgMCBdLmNvbmNhdChzKTtcblxuICByID0gcm1QYWRkaW5nKHIpO1xuICBzID0gcm1QYWRkaW5nKHMpO1xuXG4gIHdoaWxlICghc1swXSAmJiAhKHNbMV0gJiAweDgwKSkge1xuICAgIHMgPSBzLnNsaWNlKDEpO1xuICB9XG4gIHZhciBhcnIgPSBbIDB4MDIgXTtcbiAgY29uc3RydWN0TGVuZ3RoKGFyciwgci5sZW5ndGgpO1xuICBhcnIgPSBhcnIuY29uY2F0KHIpO1xuICBhcnIucHVzaCgweDAyKTtcbiAgY29uc3RydWN0TGVuZ3RoKGFyciwgcy5sZW5ndGgpO1xuICB2YXIgYmFja0hhbGYgPSBhcnIuY29uY2F0KHMpO1xuICB2YXIgcmVzID0gWyAweDMwIF07XG4gIGNvbnN0cnVjdExlbmd0aChyZXMsIGJhY2tIYWxmLmxlbmd0aCk7XG4gIHJlcyA9IHJlcy5jb25jYXQoYmFja0hhbGYpO1xuICByZXR1cm4gdXRpbHMuZW5jb2RlKHJlcywgZW5jKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNoID0gcmVxdWlyZSgnaGFzaC5qcycpO1xudmFyIGN1cnZlcyA9IHJlcXVpcmUoJy4uL2N1cnZlcycpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG52YXIgcGFyc2VCeXRlcyA9IHV0aWxzLnBhcnNlQnl0ZXM7XG52YXIgS2V5UGFpciA9IHJlcXVpcmUoJy4va2V5Jyk7XG52YXIgU2lnbmF0dXJlID0gcmVxdWlyZSgnLi9zaWduYXR1cmUnKTtcblxuZnVuY3Rpb24gRUREU0EoY3VydmUpIHtcbiAgYXNzZXJ0KGN1cnZlID09PSAnZWQyNTUxOScsICdvbmx5IHRlc3RlZCB3aXRoIGVkMjU1MTkgc28gZmFyJyk7XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEVERFNBKSlcbiAgICByZXR1cm4gbmV3IEVERFNBKGN1cnZlKTtcblxuICB2YXIgY3VydmUgPSBjdXJ2ZXNbY3VydmVdLmN1cnZlO1xuICB0aGlzLmN1cnZlID0gY3VydmU7XG4gIHRoaXMuZyA9IGN1cnZlLmc7XG4gIHRoaXMuZy5wcmVjb21wdXRlKGN1cnZlLm4uYml0TGVuZ3RoKCkgKyAxKTtcblxuICB0aGlzLnBvaW50Q2xhc3MgPSBjdXJ2ZS5wb2ludCgpLmNvbnN0cnVjdG9yO1xuICB0aGlzLmVuY29kaW5nTGVuZ3RoID0gTWF0aC5jZWlsKGN1cnZlLm4uYml0TGVuZ3RoKCkgLyA4KTtcbiAgdGhpcy5oYXNoID0gaGFzaC5zaGE1MTI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gRUREU0E7XG5cbi8qKlxuKiBAcGFyYW0ge0FycmF5fFN0cmluZ30gbWVzc2FnZSAtIG1lc3NhZ2UgYnl0ZXNcbiogQHBhcmFtIHtBcnJheXxTdHJpbmd8S2V5UGFpcn0gc2VjcmV0IC0gc2VjcmV0IGJ5dGVzIG9yIGEga2V5cGFpclxuKiBAcmV0dXJucyB7U2lnbmF0dXJlfSAtIHNpZ25hdHVyZVxuKi9cbkVERFNBLnByb3RvdHlwZS5zaWduID0gZnVuY3Rpb24gc2lnbihtZXNzYWdlLCBzZWNyZXQpIHtcbiAgbWVzc2FnZSA9IHBhcnNlQnl0ZXMobWVzc2FnZSk7XG4gIHZhciBrZXkgPSB0aGlzLmtleUZyb21TZWNyZXQoc2VjcmV0KTtcbiAgdmFyIHIgPSB0aGlzLmhhc2hJbnQoa2V5Lm1lc3NhZ2VQcmVmaXgoKSwgbWVzc2FnZSk7XG4gIHZhciBSID0gdGhpcy5nLm11bChyKTtcbiAgdmFyIFJlbmNvZGVkID0gdGhpcy5lbmNvZGVQb2ludChSKTtcbiAgdmFyIHNfID0gdGhpcy5oYXNoSW50KFJlbmNvZGVkLCBrZXkucHViQnl0ZXMoKSwgbWVzc2FnZSlcbiAgICAgICAgICAgICAgIC5tdWwoa2V5LnByaXYoKSk7XG4gIHZhciBTID0gci5hZGQoc18pLnVtb2QodGhpcy5jdXJ2ZS5uKTtcbiAgcmV0dXJuIHRoaXMubWFrZVNpZ25hdHVyZSh7IFI6IFIsIFM6IFMsIFJlbmNvZGVkOiBSZW5jb2RlZCB9KTtcbn07XG5cbi8qKlxuKiBAcGFyYW0ge0FycmF5fSBtZXNzYWdlIC0gbWVzc2FnZSBieXRlc1xuKiBAcGFyYW0ge0FycmF5fFN0cmluZ3xTaWduYXR1cmV9IHNpZyAtIHNpZyBieXRlc1xuKiBAcGFyYW0ge0FycmF5fFN0cmluZ3xQb2ludHxLZXlQYWlyfSBwdWIgLSBwdWJsaWMga2V5XG4qIEByZXR1cm5zIHtCb29sZWFufSAtIHRydWUgaWYgcHVibGljIGtleSBtYXRjaGVzIHNpZyBvZiBtZXNzYWdlXG4qL1xuRUREU0EucHJvdG90eXBlLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlLCBzaWcsIHB1Yikge1xuICBtZXNzYWdlID0gcGFyc2VCeXRlcyhtZXNzYWdlKTtcbiAgc2lnID0gdGhpcy5tYWtlU2lnbmF0dXJlKHNpZyk7XG4gIHZhciBrZXkgPSB0aGlzLmtleUZyb21QdWJsaWMocHViKTtcbiAgdmFyIGggPSB0aGlzLmhhc2hJbnQoc2lnLlJlbmNvZGVkKCksIGtleS5wdWJCeXRlcygpLCBtZXNzYWdlKTtcbiAgdmFyIFNHID0gdGhpcy5nLm11bChzaWcuUygpKTtcbiAgdmFyIFJwbHVzQWggPSBzaWcuUigpLmFkZChrZXkucHViKCkubXVsKGgpKTtcbiAgcmV0dXJuIFJwbHVzQWguZXEoU0cpO1xufTtcblxuRUREU0EucHJvdG90eXBlLmhhc2hJbnQgPSBmdW5jdGlvbiBoYXNoSW50KCkge1xuICB2YXIgaGFzaCA9IHRoaXMuaGFzaCgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcbiAgICBoYXNoLnVwZGF0ZShhcmd1bWVudHNbaV0pO1xuICByZXR1cm4gdXRpbHMuaW50RnJvbUxFKGhhc2guZGlnZXN0KCkpLnVtb2QodGhpcy5jdXJ2ZS5uKTtcbn07XG5cbkVERFNBLnByb3RvdHlwZS5rZXlGcm9tUHVibGljID0gZnVuY3Rpb24ga2V5RnJvbVB1YmxpYyhwdWIpIHtcbiAgcmV0dXJuIEtleVBhaXIuZnJvbVB1YmxpYyh0aGlzLCBwdWIpO1xufTtcblxuRUREU0EucHJvdG90eXBlLmtleUZyb21TZWNyZXQgPSBmdW5jdGlvbiBrZXlGcm9tU2VjcmV0KHNlY3JldCkge1xuICByZXR1cm4gS2V5UGFpci5mcm9tU2VjcmV0KHRoaXMsIHNlY3JldCk7XG59O1xuXG5FRERTQS5wcm90b3R5cGUubWFrZVNpZ25hdHVyZSA9IGZ1bmN0aW9uIG1ha2VTaWduYXR1cmUoc2lnKSB7XG4gIGlmIChzaWcgaW5zdGFuY2VvZiBTaWduYXR1cmUpXG4gICAgcmV0dXJuIHNpZztcbiAgcmV0dXJuIG5ldyBTaWduYXR1cmUodGhpcywgc2lnKTtcbn07XG5cbi8qKlxuKiAqIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9kcmFmdC1qb3NlZnNzb24tZWRkc2EtZWQyNTUxOS0wMyNzZWN0aW9uLTUuMlxuKlxuKiBFRERTQSBkZWZpbmVzIG1ldGhvZHMgZm9yIGVuY29kaW5nIGFuZCBkZWNvZGluZyBwb2ludHMgYW5kIGludGVnZXJzLiBUaGVzZSBhcmVcbiogaGVscGVyIGNvbnZlbmllbmNlIG1ldGhvZHMsIHRoYXQgcGFzcyBhbG9uZyB0byB1dGlsaXR5IGZ1bmN0aW9ucyBpbXBsaWVkXG4qIHBhcmFtZXRlcnMuXG4qXG4qL1xuRUREU0EucHJvdG90eXBlLmVuY29kZVBvaW50ID0gZnVuY3Rpb24gZW5jb2RlUG9pbnQocG9pbnQpIHtcbiAgdmFyIGVuYyA9IHBvaW50LmdldFkoKS50b0FycmF5KCdsZScsIHRoaXMuZW5jb2RpbmdMZW5ndGgpO1xuICBlbmNbdGhpcy5lbmNvZGluZ0xlbmd0aCAtIDFdIHw9IHBvaW50LmdldFgoKS5pc09kZCgpID8gMHg4MCA6IDA7XG4gIHJldHVybiBlbmM7XG59O1xuXG5FRERTQS5wcm90b3R5cGUuZGVjb2RlUG9pbnQgPSBmdW5jdGlvbiBkZWNvZGVQb2ludChieXRlcykge1xuICBieXRlcyA9IHV0aWxzLnBhcnNlQnl0ZXMoYnl0ZXMpO1xuXG4gIHZhciBsYXN0SXggPSBieXRlcy5sZW5ndGggLSAxO1xuICB2YXIgbm9ybWVkID0gYnl0ZXMuc2xpY2UoMCwgbGFzdEl4KS5jb25jYXQoYnl0ZXNbbGFzdEl4XSAmIH4weDgwKTtcbiAgdmFyIHhJc09kZCA9IChieXRlc1tsYXN0SXhdICYgMHg4MCkgIT09IDA7XG5cbiAgdmFyIHkgPSB1dGlscy5pbnRGcm9tTEUobm9ybWVkKTtcbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnRGcm9tWSh5LCB4SXNPZGQpO1xufTtcblxuRUREU0EucHJvdG90eXBlLmVuY29kZUludCA9IGZ1bmN0aW9uIGVuY29kZUludChudW0pIHtcbiAgcmV0dXJuIG51bS50b0FycmF5KCdsZScsIHRoaXMuZW5jb2RpbmdMZW5ndGgpO1xufTtcblxuRUREU0EucHJvdG90eXBlLmRlY29kZUludCA9IGZ1bmN0aW9uIGRlY29kZUludChieXRlcykge1xuICByZXR1cm4gdXRpbHMuaW50RnJvbUxFKGJ5dGVzKTtcbn07XG5cbkVERFNBLnByb3RvdHlwZS5pc1BvaW50ID0gZnVuY3Rpb24gaXNQb2ludCh2YWwpIHtcbiAgcmV0dXJuIHZhbCBpbnN0YW5jZW9mIHRoaXMucG9pbnRDbGFzcztcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xudmFyIHBhcnNlQnl0ZXMgPSB1dGlscy5wYXJzZUJ5dGVzO1xudmFyIGNhY2hlZFByb3BlcnR5ID0gdXRpbHMuY2FjaGVkUHJvcGVydHk7XG5cbi8qKlxuKiBAcGFyYW0ge0VERFNBfSBlZGRzYSAtIGluc3RhbmNlXG4qIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgLSBwdWJsaWMvcHJpdmF0ZSBrZXkgcGFyYW1ldGVyc1xuKlxuKiBAcGFyYW0ge0FycmF5PEJ5dGU+fSBbcGFyYW1zLnNlY3JldF0gLSBzZWNyZXQgc2VlZCBieXRlc1xuKiBAcGFyYW0ge1BvaW50fSBbcGFyYW1zLnB1Yl0gLSBwdWJsaWMga2V5IHBvaW50IChha2EgYEFgIGluIGVkZHNhIHRlcm1zKVxuKiBAcGFyYW0ge0FycmF5PEJ5dGU+fSBbcGFyYW1zLnB1Yl0gLSBwdWJsaWMga2V5IHBvaW50IGVuY29kZWQgYXMgYnl0ZXNcbipcbiovXG5mdW5jdGlvbiBLZXlQYWlyKGVkZHNhLCBwYXJhbXMpIHtcbiAgdGhpcy5lZGRzYSA9IGVkZHNhO1xuICB0aGlzLl9zZWNyZXQgPSBwYXJzZUJ5dGVzKHBhcmFtcy5zZWNyZXQpO1xuICBpZiAoZWRkc2EuaXNQb2ludChwYXJhbXMucHViKSlcbiAgICB0aGlzLl9wdWIgPSBwYXJhbXMucHViO1xuICBlbHNlXG4gICAgdGhpcy5fcHViQnl0ZXMgPSBwYXJzZUJ5dGVzKHBhcmFtcy5wdWIpO1xufVxuXG5LZXlQYWlyLmZyb21QdWJsaWMgPSBmdW5jdGlvbiBmcm9tUHVibGljKGVkZHNhLCBwdWIpIHtcbiAgaWYgKHB1YiBpbnN0YW5jZW9mIEtleVBhaXIpXG4gICAgcmV0dXJuIHB1YjtcbiAgcmV0dXJuIG5ldyBLZXlQYWlyKGVkZHNhLCB7IHB1YjogcHViIH0pO1xufTtcblxuS2V5UGFpci5mcm9tU2VjcmV0ID0gZnVuY3Rpb24gZnJvbVNlY3JldChlZGRzYSwgc2VjcmV0KSB7XG4gIGlmIChzZWNyZXQgaW5zdGFuY2VvZiBLZXlQYWlyKVxuICAgIHJldHVybiBzZWNyZXQ7XG4gIHJldHVybiBuZXcgS2V5UGFpcihlZGRzYSwgeyBzZWNyZXQ6IHNlY3JldCB9KTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLnNlY3JldCA9IGZ1bmN0aW9uIHNlY3JldCgpIHtcbiAgcmV0dXJuIHRoaXMuX3NlY3JldDtcbn07XG5cbmNhY2hlZFByb3BlcnR5KEtleVBhaXIsICdwdWJCeXRlcycsIGZ1bmN0aW9uIHB1YkJ5dGVzKCkge1xuICByZXR1cm4gdGhpcy5lZGRzYS5lbmNvZGVQb2ludCh0aGlzLnB1YigpKTtcbn0pO1xuXG5jYWNoZWRQcm9wZXJ0eShLZXlQYWlyLCAncHViJywgZnVuY3Rpb24gcHViKCkge1xuICBpZiAodGhpcy5fcHViQnl0ZXMpXG4gICAgcmV0dXJuIHRoaXMuZWRkc2EuZGVjb2RlUG9pbnQodGhpcy5fcHViQnl0ZXMpO1xuICByZXR1cm4gdGhpcy5lZGRzYS5nLm11bCh0aGlzLnByaXYoKSk7XG59KTtcblxuY2FjaGVkUHJvcGVydHkoS2V5UGFpciwgJ3ByaXZCeXRlcycsIGZ1bmN0aW9uIHByaXZCeXRlcygpIHtcbiAgdmFyIGVkZHNhID0gdGhpcy5lZGRzYTtcbiAgdmFyIGhhc2ggPSB0aGlzLmhhc2goKTtcbiAgdmFyIGxhc3RJeCA9IGVkZHNhLmVuY29kaW5nTGVuZ3RoIC0gMTtcblxuICB2YXIgYSA9IGhhc2guc2xpY2UoMCwgZWRkc2EuZW5jb2RpbmdMZW5ndGgpO1xuICBhWzBdICY9IDI0ODtcbiAgYVtsYXN0SXhdICY9IDEyNztcbiAgYVtsYXN0SXhdIHw9IDY0O1xuXG4gIHJldHVybiBhO1xufSk7XG5cbmNhY2hlZFByb3BlcnR5KEtleVBhaXIsICdwcml2JywgZnVuY3Rpb24gcHJpdigpIHtcbiAgcmV0dXJuIHRoaXMuZWRkc2EuZGVjb2RlSW50KHRoaXMucHJpdkJ5dGVzKCkpO1xufSk7XG5cbmNhY2hlZFByb3BlcnR5KEtleVBhaXIsICdoYXNoJywgZnVuY3Rpb24gaGFzaCgpIHtcbiAgcmV0dXJuIHRoaXMuZWRkc2EuaGFzaCgpLnVwZGF0ZSh0aGlzLnNlY3JldCgpKS5kaWdlc3QoKTtcbn0pO1xuXG5jYWNoZWRQcm9wZXJ0eShLZXlQYWlyLCAnbWVzc2FnZVByZWZpeCcsIGZ1bmN0aW9uIG1lc3NhZ2VQcmVmaXgoKSB7XG4gIHJldHVybiB0aGlzLmhhc2goKS5zbGljZSh0aGlzLmVkZHNhLmVuY29kaW5nTGVuZ3RoKTtcbn0pO1xuXG5LZXlQYWlyLnByb3RvdHlwZS5zaWduID0gZnVuY3Rpb24gc2lnbihtZXNzYWdlKSB7XG4gIGFzc2VydCh0aGlzLl9zZWNyZXQsICdLZXlQYWlyIGNhbiBvbmx5IHZlcmlmeScpO1xuICByZXR1cm4gdGhpcy5lZGRzYS5zaWduKG1lc3NhZ2UsIHRoaXMpO1xufTtcblxuS2V5UGFpci5wcm90b3R5cGUudmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UsIHNpZykge1xuICByZXR1cm4gdGhpcy5lZGRzYS52ZXJpZnkobWVzc2FnZSwgc2lnLCB0aGlzKTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLmdldFNlY3JldCA9IGZ1bmN0aW9uIGdldFNlY3JldChlbmMpIHtcbiAgYXNzZXJ0KHRoaXMuX3NlY3JldCwgJ0tleVBhaXIgaXMgcHVibGljIG9ubHknKTtcbiAgcmV0dXJuIHV0aWxzLmVuY29kZSh0aGlzLnNlY3JldCgpLCBlbmMpO1xufTtcblxuS2V5UGFpci5wcm90b3R5cGUuZ2V0UHVibGljID0gZnVuY3Rpb24gZ2V0UHVibGljKGVuYykge1xuICByZXR1cm4gdXRpbHMuZW5jb2RlKHRoaXMucHViQnl0ZXMoKSwgZW5jKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gS2V5UGFpcjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xudmFyIGNhY2hlZFByb3BlcnR5ID0gdXRpbHMuY2FjaGVkUHJvcGVydHk7XG52YXIgcGFyc2VCeXRlcyA9IHV0aWxzLnBhcnNlQnl0ZXM7XG5cbi8qKlxuKiBAcGFyYW0ge0VERFNBfSBlZGRzYSAtIGVkZHNhIGluc3RhbmNlXG4qIEBwYXJhbSB7QXJyYXk8Qnl0ZXM+fE9iamVjdH0gc2lnIC1cbiogQHBhcmFtIHtBcnJheTxCeXRlcz58UG9pbnR9IFtzaWcuUl0gLSBSIHBvaW50IGFzIFBvaW50IG9yIGJ5dGVzXG4qIEBwYXJhbSB7QXJyYXk8Qnl0ZXM+fGJufSBbc2lnLlNdIC0gUyBzY2FsYXIgYXMgYm4gb3IgYnl0ZXNcbiogQHBhcmFtIHtBcnJheTxCeXRlcz59IFtzaWcuUmVuY29kZWRdIC0gUiBwb2ludCBlbmNvZGVkXG4qIEBwYXJhbSB7QXJyYXk8Qnl0ZXM+fSBbc2lnLlNlbmNvZGVkXSAtIFMgc2NhbGFyIGVuY29kZWRcbiovXG5mdW5jdGlvbiBTaWduYXR1cmUoZWRkc2EsIHNpZykge1xuICB0aGlzLmVkZHNhID0gZWRkc2E7XG5cbiAgaWYgKHR5cGVvZiBzaWcgIT09ICdvYmplY3QnKVxuICAgIHNpZyA9IHBhcnNlQnl0ZXMoc2lnKTtcblxuICBpZiAoQXJyYXkuaXNBcnJheShzaWcpKSB7XG4gICAgc2lnID0ge1xuICAgICAgUjogc2lnLnNsaWNlKDAsIGVkZHNhLmVuY29kaW5nTGVuZ3RoKSxcbiAgICAgIFM6IHNpZy5zbGljZShlZGRzYS5lbmNvZGluZ0xlbmd0aClcbiAgICB9O1xuICB9XG5cbiAgYXNzZXJ0KHNpZy5SICYmIHNpZy5TLCAnU2lnbmF0dXJlIHdpdGhvdXQgUiBvciBTJyk7XG5cbiAgaWYgKGVkZHNhLmlzUG9pbnQoc2lnLlIpKVxuICAgIHRoaXMuX1IgPSBzaWcuUjtcbiAgaWYgKHNpZy5TIGluc3RhbmNlb2YgQk4pXG4gICAgdGhpcy5fUyA9IHNpZy5TO1xuXG4gIHRoaXMuX1JlbmNvZGVkID0gQXJyYXkuaXNBcnJheShzaWcuUikgPyBzaWcuUiA6IHNpZy5SZW5jb2RlZDtcbiAgdGhpcy5fU2VuY29kZWQgPSBBcnJheS5pc0FycmF5KHNpZy5TKSA/IHNpZy5TIDogc2lnLlNlbmNvZGVkO1xufVxuXG5jYWNoZWRQcm9wZXJ0eShTaWduYXR1cmUsICdTJywgZnVuY3Rpb24gUygpIHtcbiAgcmV0dXJuIHRoaXMuZWRkc2EuZGVjb2RlSW50KHRoaXMuU2VuY29kZWQoKSk7XG59KTtcblxuY2FjaGVkUHJvcGVydHkoU2lnbmF0dXJlLCAnUicsIGZ1bmN0aW9uIFIoKSB7XG4gIHJldHVybiB0aGlzLmVkZHNhLmRlY29kZVBvaW50KHRoaXMuUmVuY29kZWQoKSk7XG59KTtcblxuY2FjaGVkUHJvcGVydHkoU2lnbmF0dXJlLCAnUmVuY29kZWQnLCBmdW5jdGlvbiBSZW5jb2RlZCgpIHtcbiAgcmV0dXJuIHRoaXMuZWRkc2EuZW5jb2RlUG9pbnQodGhpcy5SKCkpO1xufSk7XG5cbmNhY2hlZFByb3BlcnR5KFNpZ25hdHVyZSwgJ1NlbmNvZGVkJywgZnVuY3Rpb24gU2VuY29kZWQoKSB7XG4gIHJldHVybiB0aGlzLmVkZHNhLmVuY29kZUludCh0aGlzLlMoKSk7XG59KTtcblxuU2lnbmF0dXJlLnByb3RvdHlwZS50b0J5dGVzID0gZnVuY3Rpb24gdG9CeXRlcygpIHtcbiAgcmV0dXJuIHRoaXMuUmVuY29kZWQoKS5jb25jYXQodGhpcy5TZW5jb2RlZCgpKTtcbn07XG5cblNpZ25hdHVyZS5wcm90b3R5cGUudG9IZXggPSBmdW5jdGlvbiB0b0hleCgpIHtcbiAgcmV0dXJuIHV0aWxzLmVuY29kZSh0aGlzLnRvQnl0ZXMoKSwgJ2hleCcpLnRvVXBwZXJDYXNlKCk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFNpZ25hdHVyZTtcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBkb3VibGVzOiB7XG4gICAgc3RlcDogNCxcbiAgICBwb2ludHM6IFtcbiAgICAgIFtcbiAgICAgICAgJ2U2MGZjZTkzYjU5ZTllYzUzMDExYWFiYzIxYzIzZTk3YjJhMzEzNjliODdhNWFlOWM0NGVlODllMmE2ZGVjMGEnLFxuICAgICAgICAnZjdlMzUwNzM5OWU1OTU5MjlkYjk5ZjM0ZjU3OTM3MTAxMjk2ODkxZTQ0ZDIzZjBiZTFmMzJjY2U2OTYxNjgyMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4MjgyMjYzMjEyYzYwOWQ5ZWEyYTZlM2UxNzJkZTIzOGQ4YzM5Y2FiZDVhYzFjYTEwNjQ2ZTIzZmQ1ZjUxNTA4JyxcbiAgICAgICAgJzExZjhhODA5ODU1N2RmZTQ1ZTgyNTZlODMwYjYwYWNlNjJkNjEzYWMyZjdiMTdiZWQzMWI2ZWFmZjZlMjZjYWYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMTc1ZTE1OWY3MjhiODY1YTcyZjk5Y2M2YzZmYzg0NmRlMGI5MzgzM2ZkMjIyMmVkNzNmY2U1YjU1MWU1YjczOScsXG4gICAgICAgICdkMzUwNmUwZDllM2M3OWViYTRlZjk3YTUxZmY3MWY1ZWFjYjU5NTVhZGQyNDM0NWM2ZWZhNmZmZWU5ZmVkNjk1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzM2M2Q5MGQ0NDdiMDBjOWM5OWNlYWMwNWI2MjYyZWUwNTM0NDFjN2U1NTU1MmZmZTUyNmJhZDhmODNmZjQ2NDAnLFxuICAgICAgICAnNGUyNzNhZGZjNzMyMjIxOTUzYjQ0NTM5N2YzMzYzMTQ1YjlhODkwMDgxOTllY2I2MjAwM2M3ZjNiZWU5ZGU5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzhiNGI1ZjE2NWRmM2MyYmU4YzYyNDRiNWI3NDU2Mzg4NDNlNGE3ODFhMTViY2QxYjY5Zjc5YTU1ZGZmZGY4MGMnLFxuICAgICAgICAnNGFhZDBhNmY2OGQzMDhiNGIzZmJkNzgxM2FiMGRhMDRmOWUzMzY1NDYxNjJlZTU2YjNlZmYwYzY1ZmQ0ZmQzNidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3MjNjYmFhNmU1ZGI5OTZkNmJmNzcxYzAwYmQ1NDhjN2I3MDBkYmZmYTZjMGU3N2JjYjYxMTU5MjUyMzJmY2RhJyxcbiAgICAgICAgJzk2ZTg2N2I1NTk1Y2M0OThhOTIxMTM3NDg4ODI0ZDZlMjY2MGEwNjUzNzc5NDk0ODAxZGMwNjlkOWViMzlmNWYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZWViZmE0ZDQ5M2JlYmY5OGJhNWZlZWM4MTJjMmQzYjUwOTQ3OTYxMjM3YTkxOTgzOWE1MzNlY2EwZTdkZDdmYScsXG4gICAgICAgICc1ZDlhOGNhMzk3MGVmMGYyNjllZTdlZGFmMTc4MDg5ZDlhZTRjZGMzYTcxMWY3MTJkZGZkNGZkYWUxZGU4OTk5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzEwMGY0NGRhNjk2ZTcxNjcyNzkxZDBhMDliN2JkZTQ1OWYxMjE1YTI5YjNjMDNiZmVmZDc4MzViMzlhNDhkYjAnLFxuICAgICAgICAnY2RkOWUxMzE5MmEwMGI3NzJlYzhmMzMwMGMwOTA2NjZiN2ZmNGExOGZmNTE5NWFjMGZiZDVjZDYyYmM2NWEwOSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlMTAzMWJlMjYyYzdlZDFiMWRjOTIyN2E0YTA0YzAxN2E3N2Y4ZDQ0NjRmM2IzODUyYzhhY2RlNmU1MzRmZDJkJyxcbiAgICAgICAgJzlkNzA2MTkyODk0MDQwNWU2YmI2YTQxNzY1OTc1MzVhZjI5MmRkNDE5ZTFjZWQ3OWE0NGYxOGYyOTQ1NmEwMGQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZmVlYTZjYWU0NmQ1NWI1MzBhYzI4MzlmMTQzYmQ3ZWM1Y2Y4YjI2NmE0MWQ2YWY1MmQ1ZTY4OGQ5MDk0Njk2ZCcsXG4gICAgICAgICdlNTdjNmI2Yzk3ZGNlMWJhYjA2ZTRlMTJiZjNlY2Q1Yzk4MWM4OTU3Y2M0MTQ0MmQzMTU1ZGViZjE4MDkwMDg4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2RhNjdhOTFkOTEwNDljZGNiMzY3YmU0YmU2ZmZjYTNjZmVlZDY1N2Q4MDg1ODNkZTMzZmE5NzhiYzFlYzZjYjEnLFxuICAgICAgICAnOWJhY2FhMzU0ODE2NDJiYzQxZjQ2M2Y3ZWM5NzgwZTVkZWM3YWRjNTA4Zjc0MGExN2U5ZWE4ZTI3YTY4YmUxZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc1MzkwNGZhYTBiMzM0Y2RkYTZlMDAwOTM1ZWYyMjE1MWVjMDhkMGY3YmIxMTA2OWY1NzU0NWNjYzFhMzdiN2MwJyxcbiAgICAgICAgJzViYzA4N2QwYmM4MDEwNmQ4OGM5ZWNjYWMyMGQzYzFjMTM5OTk5ODFlMTQ0MzQ2OTlkY2IwOTZiMDIyNzcxYzgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOGU3YmNkMGJkMzU5ODNhNzcxOWNjYTc3NjRjYTkwNjc3OWI1M2EwNDNhOWI4YmNhZWZmOTU5ZjQzYWQ4NjA0NycsXG4gICAgICAgICcxMGI3NzcwYjJhM2RhNGIzOTQwMzEwNDIwY2E5NTE0NTc5ZTg4ZTJlNDdmZDY4YjNlYTEwMDQ3ZTg0NjAzNzJhJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzM4NWVlZDM0YzFjZGZmMjFlNmQwODE4Njg5YjgxYmRlNzFhN2Y0ZjE4Mzk3ZTY2OTBhODQxZTE1OTljNDM4NjInLFxuICAgICAgICAnMjgzYmViYzNlOGVhMjNmNTY3MDFkZTE5ZTllYmY0NTc2YjMwNGVlYzIwODZkYzhjYzA0NThmZTU1NDJlNTQ1MydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc2ZjlkOWI4MDNlY2YxOTE2MzdjNzNhNDQxM2RmYTE4MGZkZGY4NGE1OTQ3ZmJjOWM2MDZlZDg2YzNmYWMzYTcnLFxuICAgICAgICAnN2M4MGM2OGU2MDMwNTliYTY5YjhlMmEzMGU0NWM0ZDQ3ZWE0ZGQyZjVjMjgxMDAyZDg2ODkwNjAzYTg0MjE2MCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczMzIyZDQwMTI0M2M0ZTI1ODJhMjE0N2MxMDRkNmVjYmY3NzRkMTYzZGIwZjVlNTMxM2I3ZTBlNzQyZDBlNmJkJyxcbiAgICAgICAgJzU2ZTcwNzk3ZTk2NjRlZjViZmIwMTliYzRkZGFmOWI3MjgwNWY2M2VhMjg3M2FmNjI0ZjNhMmU5NmMyOGIyYTAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnODU2NzJjN2QyZGUwYjdkYTJiZDE3NzBkODk2NjU4Njg3NDFiM2Y5YWY3NjQzMzk3NzIxZDc0ZDI4MTM0YWI4MycsXG4gICAgICAgICc3YzQ4MWI5YjViNDNiMmViNjM3NDA0OWJmYTYyYzJlNWU3N2YxN2ZjYzUyOThmNDRjOGUzMDk0Zjc5MDMxM2E2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzk0OGJmODA5YjE5ODhhNDZiMDZjOWYxOTE5NDEzYjEwZjkyMjZjNjBmNjY4ODMyZmZkOTU5YWY2MGM4MmEwYScsXG4gICAgICAgICc1M2E1NjI4NTZkY2I2NjQ2ZGM2Yjc0YzVkMWMzNDE4YzZkNGRmZjA4Yzk3Y2QyYmVkNGNiN2Y4OGQ4YzhlNTg5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzYyNjBjZTdmNDYxODAxYzM0ZjA2N2NlMGYwMjg3M2E4ZjFiMGU0NGRmYzY5NzUyYWNjZWNkODE5ZjM4ZmQ4ZTgnLFxuICAgICAgICAnYmMyZGE4MmI2ZmE1YjU3MWE3ZjA5MDQ5Nzc2YTFlZjdlY2QyOTIyMzgwNTFjMTk4YzFhODRlOTViMmI0YWUxNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlNTAzN2RlMGFmYzFkOGQ0M2Q4MzQ4NDE0YmJmNDEwMzA0M2VjOGY1NzViZmRjNDMyOTUzY2M4ZDIwMzdmYTJkJyxcbiAgICAgICAgJzQ1NzE1MzRiYWE5NGQzYjVmOWY5OGQwOWZiOTkwYmRkYmQ1ZjViMDNlYzQ4MWYxMGUwZTVkYzg0MWQ3NTViZGEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTA2MzcyYjBmNGEyMDdhZGY1ZWE5MDVlOGYxNzcxYjRlN2U4ZGJkMWM2YTZjNWI3MjU4NjZhMGFlNGZjZTcyNScsXG4gICAgICAgICc3YTkwODk3NGJjZTE4Y2ZlMTJhMjdiYjJhZDVhNDg4Y2Q3NDg0YTc3ODcxMDQ4NzBiMjcwMzRmOTRlZWUzMWRkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzIxM2M3YTcxNWNkNWQ0NTM1OGQwYmJmOWRjMGNlMDIyMDRiMTBiZGRlMmEzZjU4NTQwYWQ2OTA4ZDA1NTk3NTQnLFxuICAgICAgICAnNGI2ZGFkMGI1YWU0NjI1MDcwMTNhZDA2MjQ1YmExOTBiYjQ4NTBmNWYzNmE3ZWVkZGZmMmMyNzUzNGI0NThmMidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc0ZTdjMjcyYTdhZjRiMzRlOGRiYjkzNTJhNTQxOWE4N2UyODM4YzcwYWRjNjJjZGRmMGNjM2EzYjA4ZmJkNTNjJyxcbiAgICAgICAgJzE3NzQ5Yzc2NmM5ZDBiMThlMTZmZDA5ZjZkZWY2ODFiNTMwYjk2MTRiZmY3ZGQzM2UwYjM5NDE4MTdkY2FhZTYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZmVhNzRlM2RiZTc3OGIxYjEwZjIzOGFkNjE2ODZhYTVjNzZlM2RiMmJlNDMwNTc2MzI0MjdlMjg0MGZiMjdiNicsXG4gICAgICAgICc2ZTA1NjhkYjliMGIxMzI5N2NmNjc0ZGVjY2I2YWY5MzEyNmI1OTZiOTczZjdiNzc3MDFkM2RiN2YyM2NiOTZmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc2ZTY0MTEzZjY3N2NmMGUxMGEyNTcwZDU5OTk2OGQzMTU0NGUxNzliNzYwNDMyOTUyYzAyYTQ0MTdiZGRlMzknLFxuICAgICAgICAnYzkwZGRmOGRlZTRlOTVjZjU3NzA2NmQ3MDY4MWYwZDM1ZTJhMzNkMmI1NmQyMDMyYjRiMTc1MmQxOTAxYWMwMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdjNzM4YzU2YjAzYjJhYmUxZTgyODFiYWE3NDNmOGY5YThmN2NjNjQzZGYyNmNiZWUzYWIxNTAyNDJiY2JiODkxJyxcbiAgICAgICAgJzg5M2ZiNTc4OTUxYWQyNTM3ZjcxOGYyZWFjYmZiYmJiODIzMTRlZWY3ODgwY2ZlOTE3ZTczNWQ5Njk5YTg0YzMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDg5NTYyNjU0OGI2NWI4MWUyNjRjNzYzN2M5NzI4NzdkMWQ3MmU1ZjNhOTI1MDE0MzcyZTlmNjU4OGY2YzE0YicsXG4gICAgICAgICdmZWJmYWEzOGYyYmM3ZWFlNzI4ZWM2MDgxOGMzNDBlYjAzNDI4ZDYzMmJiMDY3ZTE3OTM2M2VkNzVkN2Q5OTFmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2I4ZGE5NDAzMmE5NTc1MThlYjBmNjQzMzU3MWU4NzYxY2VmZmM3MzY5M2U4NGVkZDQ5MTUwYTU2NGY2NzZlMDMnLFxuICAgICAgICAnMjgwNGRmYTQ0ODA1YTFlNGQ3Yzk5Y2M5NzYyODA4YjA5MmNjNTg0ZDk1ZmYzYjUxMTQ4OGU0ZTc0ZWZkZjZlNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlODBmZWExNDQ0MWZiMzNhN2Q4YWRhYjk0NzVkN2ZhYjIwMTllZmZiNTE1NmE3OTJmMWExMTc3OGUzYzBkZjVkJyxcbiAgICAgICAgJ2VlZDFkZTdmNjM4ZTAwNzcxZTg5NzY4Y2EzY2E5NDQ3MmQxNTVlODBhZjMyMmVhOWZjYjQyOTFiNmFjOWVjNzgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYTMwMTY5N2JkZmNkNzA0MzEzYmE0OGU1MWQ1Njc1NDNmMmExODIwMzFlZmQ2OTE1ZGRjMDdiYmNjNGUxNjA3MCcsXG4gICAgICAgICc3MzcwZjkxY2ZiNjdlNGY1MDgxODA5ZmEyNWQ0MGY5YjE3MzVkYmY3YzBhMTFhMTMwYzBkMWEwNDFlMTc3ZWExJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzkwYWQ4NWIzODlkNmI5MzY0NjNmOWQwNTEyNjc4ZGUyMDhjYzMzMGIxMTMwN2ZmZmFiN2FjNjNlM2ZiMDRlZDQnLFxuICAgICAgICAnZTUwN2EzNjIwYTM4MjYxYWZmZGNiZDk0MjcyMjJiODM5YWVmYWJlMTU4Mjg5NGQ5OTFkNGQ0OGNiNmVmMTUwJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzhmNjhiOWQyZjYzYjVmMzM5MjM5YzFhZDk4MWYxNjJlZTg4YzU2Nzg3MjNlYTMzNTFiN2I0NDRjOWVjNGMwZGEnLFxuICAgICAgICAnNjYyYTlmMmRiYTA2Mzk4NmRlMWQ5MGMyYjZiZTIxNWRiYmVhMmNmZTk1NTEwYmZkZjIzY2JmNzk1MDFmZmY4MidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlNGYzZmIwMTc2YWY4NWQ2NWZmOTlmZjkxOThjMzYwOTFmNDhlODY1MDM2ODFlM2U2Njg2ZmQ1MDUzMjMxZTExJyxcbiAgICAgICAgJzFlNjM2MzNhZDBlZjRmMWMxNjYxYTZkMGVhMDJiNzI4NmNjN2U3NGVjOTUxZDFjOTgyMmMzODU3NmZlYjczYmMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOGMwMGZhOWIxOGViZjMzMWViOTYxNTM3YTQ1YTQyNjZjNzAzNGYyZjBkNGUxZDA3MTZmYjZlYWUyMGVhZTI5ZScsXG4gICAgICAgICdlZmE0NzI2N2ZlYTUyMWExYTlkYzM0M2EzNzM2Yzk3NGMyZmFkYWZhODFlMzZjNTRlN2QyYTRjNjY3MDI0MTRiJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2U3YTI2Y2U2OWRkNDgyOWYzZTEwY2VjMGE5ZTk4ZWQzMTQzZDA4NGYzMDhiOTJjMDk5N2ZkZGZjNjBjYjNlNDEnLFxuICAgICAgICAnMmE3NThlMzAwZmE3OTg0YjQ3MWIwMDZhMWFhZmJiMThkMGE2YjJjMDQyMGU4M2UyMGU4YTk0MjFjZjJjZmQ1MSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdiNjQ1OWUwZWUzNjYyZWM4ZDIzNTQwYzIyM2JjYmRjNTcxY2JjYjk2N2Q3OTQyNGYzY2YyOWViM2RlNmI4MGVmJyxcbiAgICAgICAgJzY3Yzg3NmQwNmYzZTA2ZGUxZGFkZjE2ZTU2NjFkYjNjNGIzYWU2ZDQ4ZTM1YjJmZjMwYmYwYjYxYTcxYmE0NSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkNjhhODBjODI4MGJiODQwNzkzMjM0YWExMThmMDYyMzFkNmYxZmM2N2U3M2M1YTVkZWRhMGY1YjQ5Njk0M2U4JyxcbiAgICAgICAgJ2RiOGJhOWZmZjRiNTg2ZDAwYzRiMWY5MTc3YjBlMjhiNWIwZTdiOGY3ODQ1Mjk1YTI5NGM4NDI2NmIxMzMxMjAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzI0YWVkN2RmNjVjODA0MjUyZGMwMjcwOTA3YTMwYjA5NjEyYWViOTczNDQ5Y2VhNDA5NTk4MGZjMjhkM2Q1ZCcsXG4gICAgICAgICc2NDhhMzY1Nzc0YjYxZjJmZjEzMGMwYzM1YWVjMWY0ZjE5MjEzYjBjN2UzMzI4NDM5NjcyMjRhZjk2YWI3Yzg0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzRkZjljMTQ5MTljZGU2MWY2ZDUxZGZkYmU1ZmVlNWRjZWVjNDE0M2JhOGQxY2E4ODhlOGJkMzczZmQwNTRjOTYnLFxuICAgICAgICAnMzVlYzUxMDkyZDg3MjgwNTA5NzRjMjNhMWQ4NWQ0YjVkNTA2Y2RjMjg4NDkwMTkyZWJhYzA2Y2FkMTBkNWQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOWMzOTE5YTg0YTQ3NDg3MGZhZWQ4YTljMWNjNjYwMjE1MjM0ODkwNTRkN2YwMzA4Y2JmYzk5YzhhYzFmOThjZCcsXG4gICAgICAgICdkZGI4NGYwZjRhNGRkZDU3NTg0ZjA0NGJmMjYwZTY0MTkwNTMyNmY3NmM2NGM4ZTZiZTdlNWUwM2Q0ZmM1OTlkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzYwNTcxNzBiMWRkMTJmZGY4ZGUwNWYyODFkOGUwNmJiOTFlMTQ5M2E4YjkxZDRjYzVhMjEzODIxMjBhOTU5ZTUnLFxuICAgICAgICAnOWExYWYwYjI2YTZhNDgwN2FkZDlhMmRhZjcxZGYyNjI0NjUxNTJiYzNlZTI0YzY1ZTg5OWJlOTMyMzg1YTJhOCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhNTc2ZGY4ZTIzYTA4NDExNDIxNDM5YTQ1MThkYTMxODgwY2VmMGZiYTdkNGRmMTJiMWE2OTczZWVjYjk0MjY2JyxcbiAgICAgICAgJzQwYTZiZjIwZTc2NjQwYjJjOTJiOTdhZmU1OGNkODJjNDMyZTEwYTdmNTE0ZDlmM2VlOGJlMTFhZTFiMjhlYzgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzc3OGE3OGMyOGRlYzNlMzBhMDVmZTk2MjlkZThjMzhiYjMwZDFmNWNmOWEzYTIwOGY3NjM4ODliZTU4YWQ3MScsXG4gICAgICAgICczNDYyNmQ5YWI1YTViMjJmZjcwOThlMTJmMmZmNTgwMDg3YjM4NDExZmYyNGFjNTYzYjUxM2ZjMWZkOWY0M2FjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzkyODk1NWVlNjM3YTg0NDYzNzI5ZmQzMGU3YWZkMmVkNWY5NjI3NGU1YWQ3ZTVjYjA5ZWRhOWMwNmQ5MDNhYycsXG4gICAgICAgICdjMjU2MjEwMDNkM2Y0MmE4MjdiNzhhMTMwOTNhOTVlZWFjM2QyNmVmYThhOGQ4M2ZjNTE4MGU5MzViY2QwOTFmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzg1ZDBmZWYzZWM2ZGIxMDkzOTkwNjRmM2EwZTNiMjg1NTY0NWI0YTkwN2FkMzU0NTI3YWFlNzUxNjNkODI3NTEnLFxuICAgICAgICAnMWYwMzY0ODQxM2EzOGMwYmUyOWQ0OTZlNTgyY2Y1NjYzZTg3NTFlOTY4NzczMzE1ODJjMjM3YTI0ZWIxZjk2MidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmZjJiMGRjZTk3ZWVjZTk3YzFjOWI2MDQxNzk4Yjg1ZGZkZmI2ZDg4ODJkYTIwMzA4ZjU0MDQ4MjQ1MjYwODdlJyxcbiAgICAgICAgJzQ5M2QxM2ZlZjUyNGJhMTg4YWY0YzRkYzU0ZDA3OTM2YzdiN2VkNmZiOTBlMmNlYjJjOTUxZTAxZjBjMjk5MDcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnODI3ZmJiZTRiMWU4ODBlYTllZDJiMmU2MzAxYjIxMmI1N2YxZWUxNDhjZDZkZDI4NzgwZTVlMmNmODU2ZTI0MScsXG4gICAgICAgICdjNjBmOWM5MjNjNzI3YjBiNzFiZWYyYzY3ZDFkMTI2ODdmZjdhNjMxODY5MDMxNjZkNjA1YjY4YmFlYzI5M2VjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2VhYTY0OWYyMWY1MWJkYmFlN2JlNGFlMzRjZTZlNTIxN2E1OGZkY2U3ZjQ3ZjlhYTdmM2I1OGZhMjEyMGUyYjMnLFxuICAgICAgICAnYmUzMjc5ZWQ1YmJiYjAzYWM2OWE4MGY4OTg3OWFhNWEwMWE2Yjk2NWYxM2Y3ZTU5ZDQ3YTUzMDViYTVhZDkzZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlNGE0MmQ0M2M1Y2YxNjlkOTM5MWRmNmRlY2Y0MmVlNTQxYjZkOGYwYzlhMTM3NDAxZTIzNjMyZGRhMzRkMjRmJyxcbiAgICAgICAgJzRkOWY5MmU3MTZkMWM3MzUyNmZjOTljY2ZiOGFkMzRjZTg4NmVlZGZhOGQ4ZTRmMTNhN2Y3MTMxZGViYTk0MTQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMWVjODBmZWYzNjBjYmRkOTU0MTYwZmFkYWIzNTJiNmI5MmI1MzU3NmE4OGZlYTQ5NDcxNzNiOWQ0MzAwYmYxOScsXG4gICAgICAgICdhZWVmZTkzNzU2YjUzNDBkMmYzYTQ5NThhN2FiYmY1ZTAxNDZlNzdmNjI5NWEwN2I2NzFjZGMxY2MxMDdjZWZkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzE0NmE3NzhjMDQ2NzBjMmY5MWIwMGFmNDY4MGRmYThiY2UzNDkwNzE3ZDU4YmE4ODlkZGI1OTI4MzY2NjQyYmUnLFxuICAgICAgICAnYjMxOGUwZWMzMzU0MDI4YWRkNjY5ODI3ZjlkNGIyODcwYWFhOTcxZDJmN2U1ZWQxZDBiMjk3NDgzZDgzZWZkMCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmYTUwYzBmNjFkMjJlNWYwN2UzYWNlYmIxYWEwN2IxMjhkMDAxMjIwOWEyOGI5Nzc2ZDc2YTg3OTMxODBlZWY5JyxcbiAgICAgICAgJzZiODRjNjkyMjM5N2ViYTliNzJjZDI4NzIyODFhNjhhNWU2ODMyOTNhNTdhMjEzYjM4Y2Q4ZDdkM2Y0ZjI4MTEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZGExZDYxZDBjYTcyMWExMWIxYTViZjZiN2Q4OGU4NDIxYTI4OGFiNWQ1YmJhNTIyMGU1M2QzMmI1ZjA2N2VjMicsXG4gICAgICAgICc4MTU3ZjU1YTdjOTkzMDZjNzljMDc2NjE2MWM5MWUyOTY2YTczODk5ZDI3OWI0OGE2NTVmYmEwZjFhZDgzNmYxJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2E4ZTI4MmZmMGM5NzA2OTA3MjE1ZmY5OGU4ZmQ0MTY2MTUzMTFkZTA0NDZmMWUwNjJhNzNiMDYxMGQwNjRlMTMnLFxuICAgICAgICAnN2Y5NzM1NWI4ZGI4MWMwOWFiZmI3ZjNjNWIyNTE1ODg4YjY3OWEzZTUwZGQ2YmQ2Y2VmN2M3MzExMWY0Y2MwYydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxNzRhNTNiOWM5YTI4NTg3MmQzOWU1NmU2OTEzY2FiMTVkNTliMWZhNTEyNTA4YzAyMmYzODJkZTgzMTk0OTdjJyxcbiAgICAgICAgJ2NjYzlkYzM3YWJmYzljMTY1N2I0MTU1ZjJjNDdmOWU2NjQ2YjNhMWQ4Y2I5ODU0MzgzZGExM2FjMDc5YWZhNzMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOTU5Mzk2OTgxOTQzNzg1YzNkM2U1N2VkZjUwMThjZGJlMDM5ZTczMGU0OTE4YjNkODg0ZmRmZjA5NDc1YjdiYScsXG4gICAgICAgICcyZTdlNTUyODg4YzMzMWRkOGJhMDM4NmE0YjljZDY4NDljNjUzZjY0Yzg3MDkzODVlOWI4YWJmODc1MjRmMmZkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2QyYTYzYTUwYWU0MDFlNTZkNjQ1YTExNTNiMTA5YThmY2NhMGE0M2Q1NjFmYmEyZGJiNTEzNDBjOWQ4MmIxNTEnLFxuICAgICAgICAnZTgyZDg2ZmI2NDQzZmNiNzU2NWFlZTU4YjI5NDgyMjBhNzBmNzUwYWY0ODRjYTUyZDQxNDIxNzRkY2Y4OTQwNSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc2NDU4N2UyMzM1NDcxZWI4OTBlZTc4OTZkN2NmZGM4NjZiYWNiZGJkMzgzOTMxN2IzNDM2ZjliNDU2MTdlMDczJyxcbiAgICAgICAgJ2Q5OWZjZGQ1YmY2OTAyZTJhZTk2ZGQ2NDQ3YzI5OWExODViOTBhMzkxMzNhZWFiMzU4Mjk5ZTVlOWZhZjY1ODknXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnODQ4MWJkZTBlNGU0ZDg4NWIzYTU0NmQzZTU0OWRlMDQyZjBhYTZjZWEyNTBlN2ZkMzU4ZDZjODZkZDQ1ZTQ1OCcsXG4gICAgICAgICczOGVlN2I4Y2JhNTQwNGRkODRhMjViZjM5Y2VjYjJjYTkwMGE3OWM0MmIyNjJlNTU2ZDY0YjFiNTk3NzkwNTdlJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzEzNDY0YTU3YTc4MTAyYWE2MmI2OTc5YWU4MTdmNDYzN2ZmY2ZlZDNjNGIxY2UzMGJjZDYzMDNmNmNhZjY2NmInLFxuICAgICAgICAnNjliZTE1OTAwNDYxNDU4MGVmN2U0MzM0NTNjY2IwY2E0OGYzMDBhODFkMDk0MmUxM2Y0OTVhOTA3ZjZlY2MyNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdiYzRhOWRmNWI3MTNmZTJlOWFlZjQzMGJjYzFkYzk3YTBjZDljY2VkZTJmMjg1ODhjYWRhM2EwZDJkODNmMzY2JyxcbiAgICAgICAgJ2QzYTgxY2E2ZTc4NWMwNjM4MzkzN2FkZjRiNzk4Y2FhNmU4YTlmYmZhNTQ3YjE2ZDc1OGQ2NjY1ODFmMzNjMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4YzI4YTk3YmY4Mjk4YmMwZDIzZDhjNzQ5NDUyYTMyZTY5NGI2NWUzMGE5NDcyYTM5NTRhYjMwZmU1MzI0Y2FhJyxcbiAgICAgICAgJzQwYTMwNDYzYTMzMDUxOTMzNzhmZWRmMzFmN2NjMGViN2FlNzg0ZjA0NTFjYjk0NTllNzFkYzczY2JlZjk0ODInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOGVhOTY2NjEzOTUyN2E4YzFkZDk0Y2U0ZjA3MWZkMjNjOGIzNTBjNWE0YmIzMzc0OGM0YmExMTFmYWNjYWUwJyxcbiAgICAgICAgJzYyMGVmYWJiYzhlZTI3ODJlMjRlN2MwY2ZiOTVjNWQ3MzViNzgzYmU5Y2YwZjhlOTU1YWYzNGEzMGU2MmI5NDUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZGQzNjI1ZmFlZjViYTA2MDc0NjY5NzE2YmJkMzc4OGQ4OWJkZGU4MTU5NTk5NjgwOTJmNzZjYzRlYjlhOTc4NycsXG4gICAgICAgICc3YTE4OGZhMzUyMGUzMGQ0NjFkYTI1MDEwNDU3MzFjYTk0MTQ2MTk4Mjg4MzM5NTkzN2Y2OGQwMGM2NDRhNTczJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2Y3MTBkNzlkOWViOTYyMjk3ZTRmNjIzMmI0MGU4ZjdmZWIyYmM2MzgxNDYxNGQ2OTJjMTJkZTc1MjQwODIyMWUnLFxuICAgICAgICAnZWE5OGU2NzIzMmQzYjMyOTVkM2I1MzU1MzIxMTVjY2FjODYxMmM3MjE4NTE2MTc1MjZhZTQ3YTljNzdiZmM4MidcbiAgICAgIF1cbiAgICBdXG4gIH0sXG4gIG5hZjoge1xuICAgIHduZDogNyxcbiAgICBwb2ludHM6IFtcbiAgICAgIFtcbiAgICAgICAgJ2Y5MzA4YTAxOTI1OGMzMTA0OTM0NGY4NWY4OWQ1MjI5YjUzMWM4NDU4MzZmOTliMDg2MDFmMTEzYmNlMDM2ZjknLFxuICAgICAgICAnMzg4ZjdiMGY2MzJkZTgxNDBmZTMzN2U2MmEzN2YzNTY2NTAwYTk5OTM0YzIyMzFiNmNiOWZkNzU4NGI4ZTY3MidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyZjhiZGU0ZDFhMDcyMDkzNTViNGE3MjUwYTVjNTEyOGU4OGI4NGJkZGM2MTlhYjdjYmE4ZDU2OWIyNDBlZmU0JyxcbiAgICAgICAgJ2Q4YWMyMjI2MzZlNWUzZDZkNGRiYTlkZGE2YzljNDI2Zjc4ODI3MWJhYjBkNjg0MGRjYTg3ZDNhYTZhYzYyZDYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNWNiZGYwNjQ2ZTVkYjRlYWEzOThmMzY1ZjJlYTdhMGUzZDQxOWI3ZTAzMzBlMzljZTkyYmRkZWRjYWM0ZjliYycsXG4gICAgICAgICc2YWViY2E0MGJhMjU1OTYwYTMxNzhkNmQ4NjFhNTRkYmE4MTNkMGI4MTNmZGU3YjVhNTA4MjYyODA4NzI2NGRhJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2FjZDQ4NGUyZjBjN2Y2NTMwOWFkMTc4YTlmNTU5YWJkZTA5Nzk2OTc0YzU3ZTcxNGMzNWYxMTBkZmMyN2NjYmUnLFxuICAgICAgICAnY2MzMzg5MjFiMGE3ZDlmZDY0MzgwOTcxNzYzYjYxZTlhZGQ4ODhhNDM3NWY4ZTBmMDVjYzI2MmFjNjRmOWMzNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3NzRhZTdmODU4YTk0MTFlNWVmNDI0NmI3MGM2NWFhYzU2NDk5ODBiZTVjMTc4OTFiYmVjMTc4OTVkYTAwOGNiJyxcbiAgICAgICAgJ2Q5ODRhMDMyZWI2YjVlMTkwMjQzZGQ1NmQ3YjdiMzY1MzcyZGIxZTJkZmY5ZDZhODMwMWQ3NGM5Yzk1M2M2MWInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZjI4NzczYzJkOTc1Mjg4YmM3ZDFkMjA1YzM3NDg2NTFiMDc1ZmJjNjYxMGU1OGNkZGVlZGRmOGYxOTQwNWFhOCcsXG4gICAgICAgICdhYjA5MDJlOGQ4ODBhODk3NTgyMTJlYjY1Y2RhZjQ3M2ExYTA2ZGE1MjFmYTkxZjI5YjVjYjUyZGIwM2VkODEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDc5MjRkNGY3ZDQzZWE5NjVhNDY1YWUzMDk1ZmY0MTEzMWU1OTQ2ZjNjODVmNzllNDRhZGJjZjhlMjdlMDgwZScsXG4gICAgICAgICc1ODFlMjg3MmE4NmM3MmE2ODM4NDJlYzIyOGNjNmRlZmVhNDBhZjJiZDg5NmQzYTVjNTA0ZGM5ZmY2YTI2YjU4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2RlZmRlYTRjZGI2Nzc3NTBhNDIwZmVlODA3ZWFjZjIxZWI5ODk4YWU3OWI5NzY4NzY2ZTRmYWEwNGEyZDRhMzQnLFxuICAgICAgICAnNDIxMWFiMDY5NDYzNTE2OGU5OTdiMGVhZDJhOTNkYWVjZWQxZjRhMDRhOTVjMGY2Y2ZiMTk5ZjY5ZTU2ZWI3NydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyYjRlYTBhNzk3YTQ0M2QyOTNlZjVjZmY0NDRmNDk3OWYwNmFjZmViZDdlODZkMjc3NDc1NjU2MTM4Mzg1YjZjJyxcbiAgICAgICAgJzg1ZTg5YmMwMzc5NDVkOTNiMzQzMDgzYjVhMWM4NjEzMWEwMWY2MGM1MDI2OTc2M2I1NzBjODU0ZTVjMDliN2EnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzUyYmJmNGE0Y2RkMTI1NjRmOTNmYTMzMmNlMzMzMzAxZDlhZDQwMjcxZjgxMDcxODEzNDBhZWYyNWJlNTlkNScsXG4gICAgICAgICczMjFlYjQwNzUzNDhmNTM0ZDU5YzE4MjU5ZGRhM2UxZjRhMWIzYjJlNzFiMTAzOWM2N2JkM2Q4YmNmODE5OThjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzJmYTIxMDRkNmIzOGQxMWIwMjMwMDEwNTU5ODc5MTI0ZTQyYWI4ZGZlZmY1ZmYyOWRjOWNkYWRkNGVjYWNjM2YnLFxuICAgICAgICAnMmRlMTA2ODI5NWRkODY1YjY0NTY5MzM1YmQ1ZGQ4MDE4MWQ3MGVjZmM4ODI2NDg0MjNiYTc2YjUzMmI3ZDY3J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzkyNDgyNzliMDliNGQ2OGRhYjIxYTliMDY2ZWRkYTgzMjYzYzNkODRlMDk1NzJlMjY5Y2EwY2Q3ZjU0NTM3MTQnLFxuICAgICAgICAnNzMwMTZmN2JmMjM0YWFkZTVkMWFhNzFiZGVhMmIxZmYzZmMwZGUyYTg4NzkxMmZmZTU0YTMyY2U5N2NiMzQwMidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkYWVkNGYyYmUzYThiZjI3OGU3MDEzMmZiMGJlYjc1MjJmNTcwZTE0NGJmNjE1YzA3ZTk5NmQ0NDNkZWU4NzI5JyxcbiAgICAgICAgJ2E2OWRjZTRhN2Q2Yzk4ZThkNGExYWNhODdlZjhkNzAwM2Y4M2MyMzBmM2FmYTcyNmFiNDBlNTIyOTBiZTFjNTUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYzQ0ZDEyYzcwNjVkODEyZThhY2YyOGQ3Y2JiMTlmOTAxMWVjZDllOWZkZjI4MWIwZTZhM2I1ZTg3ZDIyZTdkYicsXG4gICAgICAgICcyMTE5YTQ2MGNlMzI2Y2RjNzZjNDU5MjZjOTgyZmRhYzBlMTA2ZTg2MWVkZjYxYzVhMDM5MDYzZjBlMGU2NDgyJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzZhMjQ1YmY2ZGM2OTg1MDRjODlhMjBjZmRlZDYwODUzMTUyYjY5NTMzNmMyODA2M2I2MWM2NWNiZDI2OWU2YjQnLFxuICAgICAgICAnZTAyMmNmNDJjMmJkNGE3MDhiM2Y1MTI2ZjE2YTI0YWQ4YjMzYmE0OGQwNDIzYjZlZmQ1ZTYzNDgxMDBkOGE4MidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxNjk3ZmZhNmZkOWRlNjI3YzA3N2UzZDJmZTU0MTA4NGNlMTMzMDBiMGJlYzExNDZmOTVhZTU3ZjBkMGJkNmE1JyxcbiAgICAgICAgJ2I5YzM5OGYxODY4MDZmNWQyNzU2MTUwNmU0NTU3NDMzYTJjZjE1MDA5ZTQ5OGFlN2FkZWU5ZDYzZDAxYjIzOTYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNjA1YmRiMDE5OTgxNzE4Yjk4NmQwZjA3ZTgzNGNiMGQ5ZGViODM2MGZmYjdmNjFkZjk4MjM0NWVmMjdhNzQ3OScsXG4gICAgICAgICcyOTcyZDJkZTRmOGQyMDY4MWE3OGQ5M2VjOTZmZTIzYzI2YmZhZTg0ZmIxNGRiNDNiMDFlMWU5MDU2YjhjNDknXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNjJkMTRkYWI0MTUwYmY0OTc0MDJmZGM0NWEyMTVlMTBkY2IwMWMzNTQ5NTliMTBjZmUzMWM3ZTlkODdmZjMzZCcsXG4gICAgICAgICc4MGZjMDZiZDhjYzViMDEwOTgwODhhMTk1MGVlZDBkYjAxYWExMzI5NjdhYjQ3MjIzNWY1NjQyNDgzYjI1ZWFmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzgwYzYwYWQwMDQwZjI3ZGFkZTViNGIwNmM0MDhlNTZiMmM1MGU5ZjU2YjliOGI0MjVlNTU1YzJmODYzMDhiNmYnLFxuICAgICAgICAnMWMzODMwM2YxY2M1YzMwZjI2ZTY2YmFkN2ZlNzJmNzBhNjVlZWQ0Y2JlNzAyNGViMWFhMDFmNTY0MzBiZDU3YSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3YTkzNzVhZDYxNjdhZDU0YWE3NGM2MzQ4Y2M1NGQzNDRjYzVkYzk0ODdkODQ3MDQ5ZDVlYWJiMGZhMDNjOGZiJyxcbiAgICAgICAgJ2QwZTNmYTllY2E4NzI2OTA5NTU5ZTBkNzkyNjkwNDZiZGM1OWVhMTBjNzBjZTJiMDJkNDk5ZWMyMjRkYzdmNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkNTI4ZWNkOWI2OTZiNTRjOTA3YTllZDA0NTQ0N2E3OWJiNDA4ZWMzOWI2OGRmNTA0YmI1MWY0NTliYzNmZmM5JyxcbiAgICAgICAgJ2VlY2Y0MTI1MzEzNmU1Zjk5OTY2ZjIxODgxZmQ2NTZlYmM0MzQ1NDA1YzUyMGRiYzA2MzQ2NWI1MjE0MDk5MzMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNDkzNzBhNGI1ZjQzNDEyZWEyNWY1MTRlOGVjZGFkMDUyNjYxMTVlNGE3ZWNiMTM4NzIzMTgwOGY4YjQ1OTYzJyxcbiAgICAgICAgJzc1OGYzZjQxYWZkNmVkNDI4YjMwODFiMDUxMmZkNjJhNTRjM2YzYWZiYjViNjc2NGI2NTMwNTJhMTI5NDljOWEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzdmMjMwOTM2ZWU4OGNiYmQ3M2RmOTMwZDY0NzAyZWY4ODFkODExZTBlMTQ5OGUyZjFjMTNlYjFmYzM0NWQ3NCcsXG4gICAgICAgICc5NThlZjQyYTc4ODZiNjQwMGEwODI2NmU5YmExYjM3ODk2Yzk1MzMwZDk3MDc3Y2JiZThlYjNjNzY3MWM2MGQ2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2YyZGFjOTkxY2M0Y2U0YjllYTQ0ODg3ZTVjN2MwYmNlNThjODAwNzRhYjlkNGRiYWViMjg1MzFiNzczOWY1MzAnLFxuICAgICAgICAnZTBkZWRjOWIzYjJmOGRhZDRkYTFmMzJkZWMyNTMxZGY5ZWI1ZmJlYjA1OThlNGZkMWExMTdkYmE3MDNhM2MzNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc0NjNiM2Q5ZjY2MjYyMWZiMWI0YmU4ZmJiZTI1MjAxMjVhMjE2Y2RmYzlkYWUzZGViY2JhNDg1MGM2OTBkNDViJyxcbiAgICAgICAgJzVlZDQzMGQ3OGMyOTZjMzU0MzExNDMwNmRkODYyMmQ3YzYyMmUyN2M5NzBhMWRlMzFjYjM3N2IwMWFmNzMwN2UnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZjE2ZjgwNDI0NGU0NmUyYTA5MjMyZDRhZmYzYjU5OTc2Yjk4ZmFjMTQzMjhhMmQxYTMyNDk2YjQ5OTk4ZjI0NycsXG4gICAgICAgICdjZWRhYmQ5YjgyMjAzZjdlMTNkMjA2ZmNkZjRlMzNkOTJhNmM1M2MyNmU1Y2NlMjZkNjU3OTk2MmM0ZTMxZGY2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2NhZjc1NDI3MmRjODQ1NjNiMDM1MmI3YTE0MzExYWY1NWQyNDUzMTVhY2UyN2M2NTM2OWUxNWY3MTUxZDQxZDEnLFxuICAgICAgICAnY2I0NzQ2NjBlZjM1ZjVmMmE0MWI2NDNmYTVlNDYwNTc1ZjRmYTliNzk2MjIzMmE1YzMyZjkwODMxOGEwNDQ3NidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyNjAwY2E0YjI4MmNiOTg2Zjg1ZDBmMTcwOTk3OWQ4YjQ0YTA5YzA3Y2I4NmQ3YzEyNDQ5N2JjODZmMDgyMTIwJyxcbiAgICAgICAgJzQxMTliODg3NTNjMTViZDZhNjkzYjAzZmNkZGJiNDVkNWFjNmJlNzRhYjVmMGVmNDRiMGJlOTQ3NWE3ZTRiNDAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzYzNWNhNzJkN2U4NDMyYzMzOGVjNTNjZDEyMjIwYmMwMWM0ODY4NWUyNGY3ZGM4YzYwMmE3NzQ2OTk4ZTQzNScsXG4gICAgICAgICc5MWI2NDk2MDk0ODlkNjEzZDFkNWU1OTBmNzhlNmQ3NGVjZmMwNjFkNTcwNDhiYWQ5ZTc2ZjMwMmM1YjljNjEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzU0ZTMyMzlmMzI1NTcwY2RiYmY0YTg3ZGVlZThhNjZiN2YyYjMzNDc5ZDQ2OGZiYzFhNTA3NDNiZjU2Y2MxOCcsXG4gICAgICAgICc2NzNmYjg2ZTViZGEzMGZiM2NkMGVkMzA0ZWE0OWEwMjNlZTMzZDAxOTdhNjk1ZDBjNWQ5ODA5M2M1MzY2ODMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTNlNmJkMTA3MWExZTk2YWZmNTc4NTljODJkNTcwZjAzMzA4MDA2NjFkMWM5NTJmOWZlMjY5NDY5MWQ5YjllOCcsXG4gICAgICAgICc1OWM5ZTBiYmEzOTRlNzZmNDBjMGFhNTgzNzlhM2NiNmE1YTIyODM5OTNlOTBjNDE2NzAwMmFmNDkyMGUzN2Y1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzE4NmI0ODNkMDU2YTAzMzgyNmFlNzNkODhmNzMyOTg1YzRjY2IxZjMyYmEzNWY0YjRjYzQ3ZmRjZjA0YWE2ZWInLFxuICAgICAgICAnM2I5NTJkMzJjNjdjZjc3ZTJlMTc0NDZlMjA0MTgwYWIyMWZiODA5MDg5NTEzOGI0YTRhNzk3Zjg2ZTgwODg4YidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkZjlkNzBhNmI5ODc2Y2U1NDRjOTg1NjFmNGJlNGY3MjU0NDJlNmQyYjczN2Q5YzkxYTgzMjE3MjRjZTA5NjNmJyxcbiAgICAgICAgJzU1ZWIyZGFmZDg0ZDZjY2Q1Zjg2MmI3ODVkYzM5ZDRhYjE1NzIyMjcyMGVmOWRhMjE3YjhjNDVjZjJiYTI0MTcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNWVkZDVjYzIzYzUxZTg3YTQ5N2NhODE1ZDVkY2UwZjhhYjUyNTU0Zjg0OWVkODk5NWRlNjRjNWYzNGNlNzE0MycsXG4gICAgICAgICdlZmFlOWM4ZGJjMTQxMzA2NjFlOGNlYzAzMGM4OWFkMGMxM2M2NmMwZDE3YTI5MDVjZGM3MDZhYjczOTlhODY4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzI5MDc5OGMyYjY0NzY4MzBkYTEyZmUwMjI4N2U5ZTc3N2FhM2ZiYTFjMzU1YjE3YTcyMmQzNjJmODQ2MTRmYmEnLFxuICAgICAgICAnZTM4ZGE3NmRjZDQ0MDYyMTk4OGQwMGJjZjc5YWYyNWQ1YjI5YzA5NGRiMmEyMzE0NmQwMDNhZmQ0MTk0M2U3YSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhZjNjNDIzYTk1ZDlmNWIzMDU0NzU0ZWZhMTUwYWMzOWNkMjk1NTJmZTM2MDI1NzM2MmRmZGVjZWY0MDUzYjQ1JyxcbiAgICAgICAgJ2Y5OGEzZmQ4MzFlYjJiNzQ5YTkzYjBlNmYzNWNmYjQwYzhjZDVhYTY2N2ExNTU4MWJjMmZlZGVkNDk4ZmQ5YzYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzY2ZGJiMjRkMTM0ZTc0NWNjY2FhMjhjOTliZjI3NDkwNmJiNjZiMjZkY2Y5OGRmOGQyZmVkNTBkODg0MjQ5YScsXG4gICAgICAgICc3NDRiMTE1MmVhY2JlNWUzOGRjYzg4Nzk4MGRhMzhiODk3NTg0YTY1ZmEwNmNlZGQyYzkyNGY5N2NiYWM1OTk2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzU5ZGJmNDZmOGM5NDc1OWJhMjEyNzdjMzM3ODRmNDE2NDVmN2I0NGY2YzU5NmE1OGNlOTJlNjY2MTkxYWJlM2UnLFxuICAgICAgICAnYzUzNGFkNDQxNzVmYmMzMDBmNGVhNmNlNjQ4MzA5YTA0MmNlNzM5YTc5MTk3OThjZDg1ZTIxNmM0YTMwN2Y2ZSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmMTNhZGE5NTEwM2M0NTM3MzA1ZTY5MWU3NGU5YTRhOGRkNjQ3ZTcxMWE5NWU3M2NiNjJkYzYwMThjZmQ4N2I4JyxcbiAgICAgICAgJ2UxMzgxN2I0NGVlMTRkZTY2M2JmNGJjODA4MzQxZjMyNjk0OWUyMWE2YTc1YzI1NzA3Nzg0MTliZGFmNTczM2QnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzc1NGI0ZmEwZThhY2VkMDZkNDE2N2EyYzU5Y2NhNGNkYTE4NjljMDZlYmFkZmI2NDg4NTUwMDE1YTg4NTIyYycsXG4gICAgICAgICczMGU5M2U4NjRlNjY5ZDgyMjI0Yjk2N2MzMDIwYjhmYThkMWU0ZTM1MGI2Y2JjYzUzN2E0OGI1Nzg0MTE2M2EyJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzk0OGRjYWRmNTk5MGUwNDhhYTM4NzRkNDZhYmVmOWQ3MDE4NThmOTVkZTgwNDFkMmE2ODI4Yzk5ZTIyNjI1MTknLFxuICAgICAgICAnZTQ5MWE0MjUzN2Y2ZTU5N2Q1ZDI4YTMyMjRiMWJjMjVkZjkxNTRlZmJkMmVmMWQyY2JiYTJjYWU1MzQ3ZDU3ZSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3OTYyNDE0NDUwYzc2YzE2ODljN2I0OGY4MjAyZWMzN2ZiMjI0Y2Y1YWMwYmZhMTU3MDMyOGE4YTNkN2M3N2FiJyxcbiAgICAgICAgJzEwMGI2MTBlYzRmZmI0NzYwZDVjMWZjMTMzZWY2ZjZiMTI1MDdhMDUxZjA0YWM1NzYwYWZhNWIyOWRiODM0MzcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzUxNDA4NzgzNDk2NGI1NGIxNWIxNjA2NDRkOTE1NDg1YTE2OTc3MjI1Yjg4NDdiYjBkZDA4NTEzN2VjNDdjYScsXG4gICAgICAgICdlZjBhZmJiMjA1NjIwNTQ0OGUxNjUyYzQ4ZTgxMjdmYzYwMzllNzdjMTVjMjM3OGI3ZTdkMTVhMGRlMjkzMzExJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2QzY2MzMGFkNmI0ODNlNGJjNzljZTJjOWRkOGJjNTQ5OTNlOTQ3ZWI4ZGY3ODdiNDQyOTQzZDNmN2I1MjdlYWYnLFxuICAgICAgICAnOGIzNzhhMjJkODI3Mjc4ZDg5YzVlOWJlOGY5NTA4YWUzYzJhZDQ2MjkwMzU4NjMwYWZiMzRkYjA0ZWVkZTBhNCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxNjI0ZDg0NzgwNzMyODYwY2UxYzc4ZmNiZmVmZTA4YjJiMjk4MjNkYjkxM2Y2NDkzOTc1YmEwZmY0ODQ3NjEwJyxcbiAgICAgICAgJzY4NjUxY2Y5YjZkYTkwM2UwOTE0NDQ4YzZjZDlkNGNhODk2ODc4ZjUyODJiZTRjOGNjMDZlMmE0MDQwNzg1NzUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzMzY2U4MGRhOTU1YThhMjY5MDJjOTU2MzNlNjJhOTg1MTkyNDc0YjVhZjIwN2RhNmRmN2I0ZmQ1ZmM2MWNkNCcsXG4gICAgICAgICdmNTQzNWEyYmQyYmFkZjdkNDg1YTRkOGI4ZGI5ZmNjZTNlMWVmOGUwMjAxZTQ1NzhjNTQ2NzNiYzFkYzVlYTFkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzE1ZDk0NDEyNTQ5NDUwNjRjZjFhMWMzM2JiZDNiNDlmODk2NmM1MDkyMTcxZTY5OWVmMjU4ZGZhYjgxYzA0NWMnLFxuICAgICAgICAnZDU2ZWIzMGI2OTQ2M2U3MjM0ZjUxMzdiNzNiODQxNzc0MzQ4MDBiYWNlYmZjNjg1ZmMzN2JiZTllZmU0MDcwZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhMWQwZmNmMmVjOWRlNjc1YjYxMjEzNmU1Y2U3MGQyNzFjMjE0MTdjOWQyYjhhYWFhYzEzODU5OWQwNzE3OTQwJyxcbiAgICAgICAgJ2VkZDc3ZjUwYmNiNWEzY2FiMmU5MDczNzMwOTY2N2YyNjQxNDYyYTU0MDcwZjNkNTE5MjEyZDM5YzE5N2E2MjknXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTIyZmJlMTVjMGFmOGNjYzU3ODBjMDczNWY4NGRiZTlhNzkwYmFkZWU4MjQ1YzA2YzdjYTM3MzMxY2IzNjk4MCcsXG4gICAgICAgICdhODU1YmFiYWQ1Y2Q2MGM4OGI0MzBhNjlmNTNhMWE3YTM4Mjg5MTU0OTY0Nzk5YmU0M2QwNmQ3N2QzMWRhMDYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzExMDkxZGQ5ODYwZThlMjBlZTEzNDczYzExNTVmNWY2OTYzNWUzOTQ3MDRlYWE3NDAwOTQ1MjI0NmNmYTliMycsXG4gICAgICAgICc2NmRiNjU2Zjg3ZDFmMDRmZmZkMWYwNDc4OGMwNjgzMDg3MWVjNWE2NGZlZWU2ODViZDgwZjBiMTI4NmQ4Mzc0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzM0YzFmZDA0ZDMwMWJlODliMzFjMDQ0MmQzZTZhYzI0ODgzOTI4YjQ1YTkzNDA3ODE4NjdkNDIzMmVjMmRiZGYnLFxuICAgICAgICAnOTQxNDY4NWU5N2IxYjU5NTRiZDQ2ZjczMDE3NDEzNmQ1N2YxY2VlYjQ4NzQ0M2RjNTMyMTg1N2JhNzNhYmVlJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2YyMTllYTVkNmI1NDcwMWMxYzE0ZGU1YjU1N2ViNDJhOGQxM2YzYWJiY2QwOGFmZmNjMmE1ZTZiMDQ5YjhkNjMnLFxuICAgICAgICAnNGNiOTU5NTdlODNkNDBiMGY3M2FmNDU0NGNjY2Y2YjFmNGIwOGQzYzA3YjI3ZmI4ZDhjMjk2MmE0MDA3NjZkMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkN2I4NzQwZjc0YThmYmFhYjFmNjgzZGI4ZjQ1ZGUyNjU0M2E1NDkwYmNhNjI3MDg3MjM2OTEyNDY5YTBiNDQ4JyxcbiAgICAgICAgJ2ZhNzc5NjgxMjhkOWM5MmVlMTAxMGYzMzdhZDQ3MTdlZmYxNWRiNWVkM2MwNDliMzQxMWUwMzE1ZWFhNDU5M2InXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzJkMzFjMjIyZjhmNmYwZWY4NmY3Yzk4ZDNhMzMzNWVhZDViY2QzMmFiZGQ5NDI4OWZlNGQzMDkxYWE4MjRiZicsXG4gICAgICAgICc1ZjMwMzJmNTg5MjE1NmUzOWNjZDNkNzkxNWI5ZTFkYTJlNmRhYzllNmYyNmU5NjExMThkMTRiODQ2MmUxNjYxJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc0NjFmMzcxOTE0YWIzMjY3MTA0NWExNTVkOTgzMWVhODc5M2Q3N2NkNTk1OTJjNDM0MGY4NmNiYzE4MzQ3YjUnLFxuICAgICAgICAnOGVjMGJhMjM4Yjk2YmVjMGNiZGRkY2FlMGFhNDQyNTQyZWVlMWZmNTBjOTg2ZWE2YjM5ODQ3YjNjYzA5MmZmNidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlZTA3OWFkYjFkZjE4NjAwNzQzNTZhMjVhYTM4MjA2YTZkNzE2YjJjM2U2NzQ1M2QyODc2OThiYWQ3YjJiMmQ2JyxcbiAgICAgICAgJzhkYzI0MTJhYWZlM2JlNWM0YzVmMzdlMGVjYzVmOWY2YTQ0Njk4OWFmMDRjNGUyNWViYWFjNDc5ZWMxYzhjMWUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMTZlYzkzZTQ0N2VjODNmMDQ2N2IxODMwMmVlNjIwZjdlNjVkZTMzMTg3NGM5ZGM3MmJmZDg2MTZiYTlkYTZiNScsXG4gICAgICAgICc1ZTQ2MzExNTBlNjJmYjQwZDBlOGMyYTdjYTU4MDRhMzlkNTgxODZhNTBlNDk3MTM5NjI2Nzc4ZTI1YjA2NzRkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2VhYTVmOTgwYzI0NWY2ZjAzODk3ODI5MGFmYTcwYjZiZDg4NTU4OTdmOThiNmFhNDg1Yjk2MDY1ZDUzN2JkOTknLFxuICAgICAgICAnZjY1ZjVkM2UyOTJjMmUwODE5YTUyODM5MWM5OTQ2MjRkNzg0ODY5ZDdlNmVhNjdmYjE4MDQxMDI0ZWRjMDdkYydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3OGM5NDA3NTQ0YWMxMzI2OTJlZTE5MTBhMDI0Mzk5NThhZTA0ODc3MTUxMzQyZWE5NmM0YjZiMzVhNDlmNTEnLFxuICAgICAgICAnZjNlMDMxOTE2OWViOWI4NWQ1NDA0Nzk1NTM5YTVlNjhmYTFmYmQ1ODNjMDY0ZDI0NjJiNjc1ZjE5NGEzZGRiNCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc0OTRmNGJlMjE5YTFhNzcwMTZkY2Q4Mzg0MzFhZWEwMDAxY2RjOGFlN2E2ZmM2ODg3MjY1NzhkOTcwMjg1N2E1JyxcbiAgICAgICAgJzQyMjQyYTk2OTI4M2E1ZjMzOWJhN2YwNzVlMzZiYTJhZjkyNWNlMzBkNzY3ZWQ2ZTU1ZjRiMDMxODgwZDU2MmMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYTU5OGE4MDMwZGE2ZDg2YzZiYzdmMmY1MTQ0ZWE1NDlkMjgyMTFlYTU4ZmFhNzBlYmY0YzFlNjY1YzFmZTliNScsXG4gICAgICAgICcyMDRiNWQ2Zjg0ODIyYzMwN2U0YjRhNzE0MDczN2FlYzIzZmM2M2I2NWIzNWY4NmExMDAyNmRiZDJkODY0ZTZiJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2M0MTkxNjM2NWFiYjJiNWQwOTE5MmY1ZjJkYmVhZmVjMjA4ZjAyMGYxMjU3MGExODRkYmFkYzNlNTg1OTU5OTcnLFxuICAgICAgICAnNGYxNDM1MWQwMDg3ZWZhNDlkMjQ1YjMyODk4NDk4OWQ1Y2FmOTQ1MGYzNGJmYzBlZDE2ZTk2YjU4ZmE5OTEzJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzg0MWQ2MDYzYTU4NmZhNDc1YTcyNDYwNGRhMDNiYzViOTJhMmUwZDJlMGEzNmFjZmU0YzczYTU1MTQ3NDI4ODEnLFxuICAgICAgICAnNzM4NjdmNTljMDY1OWU4MTkwNGY5YTFjNzU0MzY5OGU2MjU2MmQ2NzQ0YzE2OWNlN2EzNmRlMDFhOGQ2MTU0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzVlOTViYjM5OWE2OTcxZDM3NjAyNjk0N2Y4OWJkZTJmMjgyYjMzODEwOTI4YmU0ZGVkMTEyYWM0ZDcwZTIwZDUnLFxuICAgICAgICAnMzlmMjNmMzY2ODA5MDg1YmVlYmZjNzExODEzMTM3NzVhOTljOWFlZDdkOGJhMzhiMTYxMzg0Yzc0NjAxMjg2NSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczNmU0NjQxYTUzOTQ4ZmQ0NzZjMzlmOGE5OWZkOTc0ZTVlYzA3NTY0YjUzMTVkOGJmOTk0NzFiY2EwZWYyZjY2JyxcbiAgICAgICAgJ2QyNDI0YjFiMWFiZTRlYjgxNjQyMjdiMDg1YzlhYTk0NTZlYTEzNDkzZmQ1NjNlMDZmZDUxY2Y1Njk0Yzc4ZmMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzM2NTgxZWE3YmZiYmIyOTBjMTkxYTJmNTA3YTQxY2Y1NjQzODQyMTcwZTkxNGZhZWFiMjdjMmM1NzlmNzI2JyxcbiAgICAgICAgJ2VhZDEyMTY4NTk1ZmUxYmU5OTI1MjEyOWI2ZTU2YjMzOTFmN2FiMTQxMGNkMWUwZWYzZGNkY2FiZDJmZGEyMjQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOGFiODk4MTZkYWRmZDZiNmExZjI2MzRmY2YwMGVjODQwMzc4MTAyNWVkNjg5MGM0ODQ5NzQyNzA2YmQ0M2VkZScsXG4gICAgICAgICc2ZmRjZWYwOWYyZjZkMGEwNDRlNjU0YWVmNjI0MTM2ZjUwM2Q0NTljM2U4OTg0NTg1OGE0N2E5MTI5Y2RkMjRlJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzFlMzNmMWE3NDZjOWM1Nzc4MTMzMzQ0ZDkyOTlmY2FhMjBiMDkzOGU4YWNmZjI1NDRiYjQwMjg0YjhjNWZiOTQnLFxuICAgICAgICAnNjA2NjAyNTdkZDExYjNhYTljOGVkNjE4ZDI0ZWRmZjIzMDZkMzIwZjFkMDMwMTBlMzNhN2QyMDU3ZjNiM2I2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzg1YjdjMWRjYjNjZWMxYjdlZTdmMzBkZWQ3OWRkMjBhMGVkMWY0Y2MxOGNiY2ZjZmE0MTAzNjFmZDhmMDhmMzEnLFxuICAgICAgICAnM2Q5OGE5Y2RkMDI2ZGQ0M2YzOTA0OGYyNWE4ODQ3ZjRmY2FmYWQxODk1ZDdhNjMzYzZmZWQzYzM1ZTk5OTUxMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyOWRmOWZiZDhkOWU0NjUwOTI3NWY0YjEyNWQ2ZDQ1ZDdmYmU5YTNiODc4YTdhZjg3MmEyODAwNjYxYWM1ZjUxJyxcbiAgICAgICAgJ2I0YzRmZTk5Yzc3NWE2MDZlMmQ4ODYyMTc5MTM5ZmZkYTYxZGM4NjFjMDE5ZTU1Y2QyODc2ZWIyYTI3ZDg0YidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhMGIxY2FlMDZiMGE4NDdhM2ZlYTZlNjcxYWFmOGFkZmRmZTU4Y2EyZjc2ODEwNWM4MDgyYjJlNDQ5ZmNlMjUyJyxcbiAgICAgICAgJ2FlNDM0MTAyZWRkZTA5NThlYzRiMTlkOTE3YTZhMjhlNmI3MmRhMTgzNGFmZjBlNjUwZjA0OTUwM2EyOTZjZjInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNGU4Y2VhZmI5YjNlOWExMzZkYzdmZjY3ZTg0MDI5NWI0OTlkZmIzYjIxMzNlNGJhMTEzZjJlNGMwZTEyMWU1JyxcbiAgICAgICAgJ2NmMjE3NDExOGM4YjZkN2E0YjQ4ZjZkNTM0Y2U1Yzc5NDIyYzA4NmE2MzQ2MDUwMmI4MjdjZTYyYTMyNjY4M2MnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDI0YTQ0ZTA0N2UxOWI2ZjVhZmI4MWM3Y2EyZjY5MDgwYTUwNzY2ODlhMDEwOTE5ZjQyNzI1YzJiNzg5YTMzYicsXG4gICAgICAgICc2ZmI4ZDU1OTFiNDY2ZjhmYzYzZGI1MGYxYzBmMWM2OTAxM2Y5OTY4ODdiODI0NGQyY2RlYzQxN2FmZWE4ZmEzJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2VhMDE2MDZhN2E2YzljZGQyNDlmZGZjZmFjYjk5NTg0MDAxZWRkMjhhYmJhYjc3YjUxMDRlOThlOGUzYjM1ZDQnLFxuICAgICAgICAnMzIyYWY0OTA4YzczMTJiMGNmYmZlMzY5ZjdhN2IzY2RiN2Q0NDk0YmMyODIzNzAwY2ZkNjUyMTg4YTNlYTk4ZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhZjhhZGRiZjJiNjYxYzhhNmM2MzI4NjU1ZWI5NjY1MTI1MjAwN2Q4YzVlYTMxYmU0YWQxOTZkZThjZTIxMzFmJyxcbiAgICAgICAgJzY3NDllNjdjMDI5Yjg1ZjUyYTAzNGVhZmQwOTY4MzZiMjUyMDgxODY4MGUyNmFjOGYzZGZiY2RiNzE3NDk3MDAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTNhZTE5NzQ1NjZjYTA2Y2M1MTZkNDdlMGZiMTY1YTY3NGEzZGFiY2ZjYTE1ZTcyMmYwZTM0NTBmNDU4ODknLFxuICAgICAgICAnMmFlYWJlN2U0NTMxNTEwMTE2MjE3ZjA3YmY0ZDA3MzAwZGU5N2U0ODc0ZjgxZjUzMzQyMGE3MmVlYjBiZDZhNCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc1OTFlZTM1NTMxM2Q5OTcyMWNmNjk5M2ZmZWQxZTNlMzAxOTkzZmYzZWQyNTg4MDIwNzVlYThjZWQzOTdlMjQ2JyxcbiAgICAgICAgJ2IwZWE1NThhMTEzYzMwYmVhNjBmYzQ3NzU0NjBjNzkwMWZmMGIwNTNkMjVjYTJiZGVlZTk4ZjFhNGJlNWQxOTYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMTEzOTZkNTVmZGE1NGM0OWYxOWFhOTczMThkOGRhNjFmYTg1ODRlNDdiMDg0OTQ1MDc3Y2YwMzI1NWI1Mjk4NCcsXG4gICAgICAgICc5OThjNzRhOGNkNDVhYzAxMjg5ZDU4MzNhN2JlYjQ3NDRmZjUzNmIwMWIyNTdiZTRjNTc2N2JlYTkzZWE1N2E0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzNjNWQyYTFiYTM5YzVhMTc5MDAwMDczOGM5ZTBjNDBiOGRjZGZkNTQ2ODc1NGI2NDA1NTQwMTU3ZTAxN2FhN2EnLFxuICAgICAgICAnYjIyODQyNzk5OTVhMzRlMmY5ZDRkZTczOTZmYzE4YjgwZjliOGI5ZmRkMjcwZjY2NjFmNzljYTRjODFiZDI1NydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdjYzg3MDRiOGE2MGEwZGVmYTNhOTlhNzI5OWYyZTljM2ZiYzM5NWFmYjA0YWMwNzg0MjVlZjhhMTc5M2NjMDMwJyxcbiAgICAgICAgJ2JkZDQ2MDM5ZmVlZDE3ODgxZDFlMDg2MmRiMzQ3ZjhjZjM5NWI3NGZjNGJjZGM0ZTk0MGI3NGUzYWMxZjFiMTMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYzUzM2U0ZjdlYTg1NTVhYWNkOTc3N2FjNWNhZDI5Yjk3ZGQ0ZGVmY2NjNTNlZTdlYTIwNDExOWIyODg5YjE5NycsXG4gICAgICAgICc2ZjBhMjU2YmM1ZWZkZjQyOWEyZmI2MjQyZjFhNDNhMmQ5YjkyNWJiNGE0YjNhMjZiYjhlMGY0NWViNTk2MDk2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2MxNGY4ZjJjY2IyN2Q2ZjEwOWY2ZDA4ZDAzY2M5NmE2OWJhOGMzNGVlYzA3YmJjZjU2NmQ0OGUzM2RhNjU5MycsXG4gICAgICAgICdjMzU5ZDY5MjNiYjM5OGY3ZmQ0NDczZTE2ZmUxYzI4NDc1Yjc0MGRkMDk4MDc1ZTZjMGU4NjQ5MTEzZGMzYTM4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2E2Y2JjMzA0NmJjNmE0NTBiYWMyNDc4OWZhMTcxMTVhNGM5NzM5ZWQ3NWY4ZjIxY2U0NDFmNzJlMGI5MGU2ZWYnLFxuICAgICAgICAnMjFhZTdmNDY4MGU4ODliYjEzMDYxOWUyYzBmOTVhMzYwY2ViNTczYzcwNjAzMTM5ODYyYWZkNjE3ZmE5YjlmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzM0N2Q2ZDlhMDJjNDg5MjdlYmZiODZjMTM1OWIxY2FmMTMwYTNjMDI2N2QxMWNlNjM0NGIzOWY5OWQ0M2NjMzgnLFxuICAgICAgICAnNjBlYTdmNjFhMzUzNTI0ZDFjOTg3ZjZlY2VjOTJmMDg2ZDU2NWFiNjg3ODcwY2IxMjY4OWZmMWUzMWM3NDQ0OCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkYTY1NDVkMjE4MWRiOGQ5ODNmN2RjYjM3NWVmNTg2NmQ0N2M2N2IxYmYzMWM4Y2Y4NTVlZjc0MzdiNzI2NTZhJyxcbiAgICAgICAgJzQ5Yjk2NzE1YWI2ODc4YTc5ZTc4ZjA3Y2U1NjgwYzVkNjY3MzA1MWI0OTM1YmQ4OTdmZWE4MjRiNzdkYzIwOGEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYzQwNzQ3Y2M5ZDAxMmNiMWExM2I4MTQ4MzA5YzZkZTdlYzI1ZDY5NDVkNjU3MTQ2YjlkNTk5NGI4ZmViMTExMScsXG4gICAgICAgICc1Y2E1NjA3NTNiZTJhMTJmYzZkZTZjYWYyY2I0ODk1NjVkYjkzNjE1NmI5NTE0ZTFiYjVlODMwMzdlMGZhMmQ0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzRlNDJjOGVjODJjOTk3OThjY2YzYTYxMGJlODcwZTc4MzM4YzdmNzEzMzQ4YmQzNGM4MjAzZWY0MDM3ZjM1MDInLFxuICAgICAgICAnNzU3MWQ3NGVlNWUwZmI5MmE3YThiMzNhMDc3ODMzNDFhNTQ5MjE0NGNjNTRiY2M0MGE5NDQ3MzY5MzYwNjQzNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczNzc1YWI3MDg5YmM2YWY4MjNhYmEyZTFhZjcwYjIzNmQyNTFjYWRiMGM4Njc0MzI4NzUyMmExYjNiMGRlZGVhJyxcbiAgICAgICAgJ2JlNTJkMTA3YmNmYTA5ZDhiY2I5NzM2YTgyOGNmYTdmYWM4ZGIxN2JmN2E3NmEyYzQyYWQ5NjE0MDkwMThjZjcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnY2VlMzFjYmY3ZTM0ZWMzNzlkOTRmYjgxNGQzZDc3NWFkOTU0NTk1ZDEzMTRiYTg4NDY5NTllM2U4MmY3NGUyNicsXG4gICAgICAgICc4ZmQ2NGExNGMwNmI1ODljMjZiOTQ3YWUyYmNmNmJmYTAxNDllZjBiZTE0ZWQ0ZDgwZjQ0OGEwMWM0M2IxYzZkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2I0ZjllYWVhMDliNjkxNzYxOWY2ZWE2YTRlYjU0NjRlZmRkYjU4ZmQ0NWIxZWJlZmNkYzFhMDFkMDhiNDc5ODYnLFxuICAgICAgICAnMzllNWM5OTI1YjVhNTRiMDc0MzNhNGYxOGM2MTcyNmY4YmIxMzFjMDEyY2E1NDJlYjI0YThhYzA3MjAwNjgyYSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkNDI2M2RmYzNkMmRmOTIzYTAxNzlhNDg5NjZkMzBjZTg0ZTI1MTVhZmMzZGNjYzFiNzc5MDc3OTJlYmNjNjBlJyxcbiAgICAgICAgJzYyZGZhZjA3YTBmNzhmZWIzMGUzMGQ2Mjk1ODUzY2UxODllMTI3NzYwYWQ2Y2Y3ZmFlMTY0ZTEyMmEyMDhkNTQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNDg0NTc1MjQ4MjBmYTY1YTRmOGQzNWViNjkzMDg1N2MwMDMyYWNjMGE0YTJkZTQyMjIzM2VlZGE4OTc2MTJjNCcsXG4gICAgICAgICcyNWE3NDhhYjM2Nzk3OWQ5ODczM2MzOGExZmExYzJlN2RjNmNjMDdkYjJkNjBhOWFlN2E3NmFhYTQ5YmQwZjc3J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2RmZWVlZjE4ODExMDFmMmNiMTE2NDRmM2EyYWZkZmMyMDQ1ZTE5OTE5MTUyOTIzZjM2N2ExNzY3YzExY2NlZGEnLFxuICAgICAgICAnZWNmYjcwNTZjZjFkZTA0MmY5NDIwYmFiMzk2NzkzYzBjMzkwYmRlNzRiNGJiZGZmMTZhODNhZTA5YTlhNzUxNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc2ZDdlZjZiMTc1NDNmODM3M2M1NzNmNDRlMWYzODk4MzVkODliY2JjNjA2MmNlZDM2YzgyZGY4M2I4ZmFlODU5JyxcbiAgICAgICAgJ2NkNDUwZWMzMzU0Mzg5ODZkZmVmYTEwYzU3ZmVhOWJjYzUyMWEwOTU5YjJkODBiYmY3NGIxOTBkY2E3MTJkMTAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTc1NjA1ZDU5MTAyYTVhMjY4NDUwMGQzYjk5MWYyZTNmM2M4OGI5MzIyNTU0NzAzNWFmMjVhZjY2ZTA0NTQxZicsXG4gICAgICAgICdmNWM1NDc1NGE4ZjcxZWU1NDBiOWI0ODcyODQ3M2UzMTRmNzI5YWM1MzA4YjA2OTM4MzYwOTkwZTJiZmFkMTI1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2ViOTg2NjBmNGM0ZGZhYTA2YTJiZTQ1M2Q1MDIwYmM5OWEwYzJlNjBhYmUzODg0NTdkZDQzZmVmYjFlZDYyMGMnLFxuICAgICAgICAnNmNiOWE4ODc2ZDljYjg1MjA2MDlhZjNhZGQyNmNkMjBhMGE3Y2Q4YTk0MTExMzFjZTg1ZjQ0MTAwMDk5MjIzZSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxM2U4N2IwMjdkODUxNGQzNTkzOWYyZTY4OTJiMTk5MjIxNTQ1OTY5NDE4ODgzMzZkYzM1NjNlM2I4ZGJhOTQyJyxcbiAgICAgICAgJ2ZlZjVhM2M2ODA1OWE2ZGVjNWQ2MjQxMTRiZjFlOTFhYWMyYjlkYTU2OGQ2YWJlYjI1NzBkNTU2NDZiOGFkZjEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZWUxNjMwMjZlOWZkNmZlMDE3YzM4ZjA2YTViZTZmYzEyNTQyNGIzNzFjZTI3MDhlN2JmNDQ5MTY5MWU1NzY0YScsXG4gICAgICAgICcxYWNiMjUwZjI1NWRkNjFjNDNkOTRjY2M2NzBkMGY1OGY0OWFlM2ZhMTViOTY2MjNlNTQzMGRhMGFkNmM2MmIyJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2IyNjhmNWVmOWFkNTFlNGQ3OGRlM2E3NTBjMmRjODliMWU2MjZkNDM1MDU4Njc5OTk5MzJlNWRiMzNhZjNkODAnLFxuICAgICAgICAnNWYzMTBkNGIzYzk5YjllYmIxOWY3N2Q0MWMxZGVlMDE4Y2YwZDM0ZmQ0MTkxNjE0MDAzZTk0NWExMjE2ZTQyMydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmZjA3ZjMxMThhOWRmMDM1ZTlmYWQ4NWViNmM3YmZlNDJiMDJmMDFjYTk5Y2VlYTNiZjdmZmRiYTkzYzQ3NTBkJyxcbiAgICAgICAgJzQzODEzNmQ2MDNlODU4YTNhNWM0NDBjMzhlY2NiYWRkYzFkMjk0MjExNGUyZWRkZDQ3NDBkMDk4Y2VkMWYwZDgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOGQ4Yjk4NTVjN2MwNTJhMzQxNDZmZDIwZmZiNjU4YmVhNGI5ZjY5ZTBkODI1ZWJlYzE2ZThjM2NlMmI1MjZhMScsXG4gICAgICAgICdjZGI1NTllZWRjMmQ3OWY5MjZiYWY0NGZiODRlYTRkNDRiY2Y1MGZlZTUxZDdjZWIzMGUyZTdmNDYzMDM2NzU4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzUyZGIwYjUzODRkZmJmMDViZmE5ZDQ3MmQ3YWUyNmRmZTRiODUxY2VjYTkxYjFlYmE1NDI2MzE4MGRhMzJiNjMnLFxuICAgICAgICAnYzNiOTk3ZDA1MGVlNWQ0MjNlYmFmNjZhNmRiOWY1N2IzMTgwYzkwMjg3NTY3OWRlOTI0YjY5ZDg0YTdiMzc1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2U2MmY5NDkwZDNkNTFkYTYzOTVlZmQyNGU4MDkxOWNjN2QwZjI5YzNmM2ZhNDhjNmZmZjU0M2JlY2JkNDMzNTInLFxuICAgICAgICAnNmQ4OWFkN2JhNDg3NmIwYjIyYzJjYTI4MGM2ODI4NjJmMzQyYzg1OTFmMWRhZjUxNzBlMDdiZmQ5Y2NhZmE3ZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3ZjMwZWEyNDc2YjM5OWI0OTU3NTA5Yzg4Zjc3ZDAxOTFhZmEyZmY1Y2I3YjE0ZmQ2ZDhlN2Q2NWFhYWIxMTkzJyxcbiAgICAgICAgJ2NhNWVmN2Q0YjIzMWM5NGMzYjE1Mzg5YTVmNjMxMWU5ZGFmZjdiYjY3YjEwM2U5ODgwZWY0YmZmNjM3YWNhZWMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNTA5OGZmMWUxZDlmMTRmYjQ2YTIxMGZhZGE2YzkwM2ZlZjBmYjdiNGExZGQxZDlhYzYwYTAzNjE4MDBiN2EwMCcsXG4gICAgICAgICc5NzMxMTQxZDgxZmM4ZjgwODRkMzdjNmU3NTQyMDA2YjNlZTFiNDBkNjBkZmU1MzYyYTViMTMyZmQxN2RkYzAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzJiNzhjN2RlOWVlNTEyYTcyODk1YmU2YjljYmVmYTZlMmYzYzRjY2NlNDQ1Yzk2YjlmMmM4MWUyNzc4YWQ1OCcsXG4gICAgICAgICdlZTE4NDlmNTEzZGY3MWUzMmVmYzM4OTZlZTI4MjYwYzczYmI4MDU0N2FlMjI3NWJhNDk3MjM3Nzk0Yzg3NTNjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2UyY2I3NGZkZGM4ZTlmYmNkMDc2ZWVmMmE3YzcyYjBjZTM3ZDUwZjA4MjY5ZGZjMDc0YjU4MTU1MDU0N2E0ZjcnLFxuICAgICAgICAnZDNhYTJlZDcxYzlkZDIyNDdhNjJkZjA2MjczNmViMGJhZGRlYTllMzYxMjJkMmJlODY0MWFiY2IwMDVjYzRhNCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4NDM4NDQ3NTY2ZDRkN2JlZGFkYzI5OTQ5NmFiMzU3NDI2MDA5YTM1ZjIzNWNiMTQxYmUwZDk5Y2QxMGFlM2E4JyxcbiAgICAgICAgJ2M0ZTEwMjA5MTY5ODBhNGRhNWQwMWFjNWU2YWQzMzA3MzRlZjBkNzkwNjYzMWM0ZjIzOTA0MjZiMmVkZDc5MWYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNDE2MmQ0ODhiODk0MDIwMzliNTg0YzZmYzZjMzA4ODcwNTg3ZDljNDZmNjYwYjg3OGFiNjVjODJjNzExZDY3ZScsXG4gICAgICAgICc2NzE2M2U5MDMyMzYyODlmNzc2ZjIyYzI1ZmI4YTNhZmMxNzMyZjJiODRiNGU5NWRiZGE0N2FlNWEwODUyNjQ5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzNmYWQzZmE4NGNhZjBmMzRmMGY4OWJmZDJkY2Y1NGZjMTc1ZDc2N2FlYzNlNTA2ODRmM2JhNGE0YmY1ZjY4M2QnLFxuICAgICAgICAnY2QxYmM3Y2I2Y2M0MDdiYjJmMGNhNjQ3YzcxOGE3MzBjZjcxODcyZTdkMGQyYTUzZmEyMGVmY2RmZTYxODI2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzY3NGYyNjAwYTMwMDdhMDA1NjhjMWE3Y2UwNWQwODE2YzFmYjg0YmYxMzcwNzk4ZjFjNjk1MzJmYWViMWE4NmInLFxuICAgICAgICAnMjk5ZDIxZjk0MTNmMzNiM2VkZjQzYjI1NzAwNDU4MGI3MGRiNTdkYTBiMTgyMjU5ZTA5ZWVjYzY5ZTBkMzhhNSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkMzJmNGRhNTRhZGU3NGFiYjgxYjgxNWFkMWZiM2IyNjNkODJkNmM2OTI3MTRiY2ZmODdkMjliZDVlZTlmMDhmJyxcbiAgICAgICAgJ2Y5NDI5ZTczOGI4ZTUzYjk2OGU5OTAxNmMwNTk3MDc3ODJlMTRmNDUzNTM1OWQ1ODJmYzQxNjkxMGIzZWVhODcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzBlNGU2NzA0MzUzODU1NTZlNTkzNjU3MTM1ODQ1ZDM2ZmJiNjkzMWY3MmIwOGNiMWVkOTU0ZjFlM2NlM2ZmNicsXG4gICAgICAgICc0NjJmOWJjZTYxOTg5ODYzODQ5OTM1MDExM2JiYzliMTBhODc4ZDM1ZGE3MDc0MGRjNjk1YTU1OWViODhkYjdiJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2JlMjA2MjAwM2M1MWNjMzAwNDY4MjkwNDMzMGU0ZGVlN2YzZGNkMTBiMDFlNTgwYmYxOTcxYjA0ZDRjYWQyOTcnLFxuICAgICAgICAnNjIxODhiYzQ5ZDYxZTU0Mjg1NzNkNDhhNzRlMWM2NTViMWM2MTA5MDkwNTY4MmEwZDU1NThlZDcyZGNjYjliYydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc5MzE0NDQyM2FjZTM0NTFlZDI5ZTBmYjlhYzJhZjIxMWNiNmU4NGE2MDFkZjU5OTNjNDE5ODU5ZmZmNWRmMDRhJyxcbiAgICAgICAgJzdjMTBkZmIxNjRjMzQyNWY1YzcxYTNmOWQ3OTkyMDM4ZjEwNjUyMjRmNzJiYjlkMWQ5MDJhNmQxMzAzN2I0N2MnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYjAxNWY4MDQ0ZjVmY2JkY2YyMWNhMjZkNmMzNGZiODE5NzgyOTIwNWM3YjdkMmE3Y2I2NjQxOGMxNTdiMTEyYycsXG4gICAgICAgICdhYjhjMWUwODZkMDRlODEzNzQ0YTY1NWIyZGY4ZDVmODNiM2NkYzZmYWEzMDg4YzFkM2FlYTE0NTRlM2ExZDVmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2Q1ZTllMWRhNjQ5ZDk3ZDg5ZTQ4NjgxMTdhNDY1YTNhNGY4YTE4ZGU1N2ExNDBkMzZiM2YyYWYzNDFhMjFiNTInLFxuICAgICAgICAnNGNiMDQ0MzdmMzkxZWQ3MzExMWExM2NjMWQ0ZGQwZGIxNjkzNDY1YzIyNDA0ODBkODk1NWU4NTkyZjI3NDQ3YSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkM2FlNDEwNDdkZDdjYTA2NWRiZjhlZDc3Yjk5MjQzOTk4MzAwNWNkNzJlMTZkNmY5OTZhNTMxNmQzNjk2NmJiJyxcbiAgICAgICAgJ2JkMWFlYjIxYWQyMmViYjIyYTEwZjAzMDM0MTdjNmQ5NjRmOGNkZDdkZjBhY2E2MTRiMTBkYzE0ZDEyNWFjNDYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNDYzZTI3NjNkODg1Zjk1OGZjNjZjZGQyMjgwMGYwYTQ4NzE5N2QwYTgyZTM3N2I0OWY4MGFmODdjODk3YjA2NScsXG4gICAgICAgICdiZmVmYWNkYjBlNWQwZmQ3ZGYzYTMxMWE5NGRlMDYyYjI2YjgwYzYxZmJjOTc1MDhiNzk5OTI2NzFlZjdjYTdmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc5ODVmZGZkMTI3YzA1NjdjNmY1M2VjMWJiNjNlYzMxNThlNTk3YzQwYmZlNzQ3YzgzY2RkZmM5MTA2NDE5MTcnLFxuICAgICAgICAnNjAzYzEyZGFmM2Q5ODYyZWYyYjI1ZmUxZGUyODlhZWQyNGVkMjkxZTBlYzY3MDg3MDNhNWJkNTY3ZjMyZWQwMydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3NGExYWQ2YjVmNzZlMzlkYjJkZDI0OTQxMGVhYzdmOTllNzRjNTljYjgzZDJkMGVkNWZmMTU0M2RhNzcwM2U5JyxcbiAgICAgICAgJ2NjNjE1N2VmMThjOWM2M2NkNjE5M2Q4MzYzMWJiZWEwMDkzZTA5Njg5NDJlOGMzM2Q1NzM3ZmQ3OTBlMGRiMDgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzA2ODJhNTA3MDMzNzVmNjAyZDQxNjY2NGJhMTliN2ZjOWJhYjQyYzcyNzQ3NDYzYTcxZDA4OTZiMjJmNmRhMycsXG4gICAgICAgICc1NTNlMDRmNmIwMThiNGZhNmM4ZjM5ZTdmMzExZDMxNzYyOTBkMGUwZjE5Y2E3M2YxNzcxNGQ5OTc3YTIyZmY4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzllMjE1OGYwZDdjMGQ1ZjI2YzM3OTFlZmVmYTc5NTk3NjU0ZTdhMmIyNDY0ZjUyYjFlZTZjMTM0Nzc2OWVmNTcnLFxuICAgICAgICAnNzEyZmNkZDFiOTA1M2YwOTAwM2EzNDgxZmE3NzYyZTlmZmQ3YzhlZjM1YTM4NTA5ZTJmYmYyNjI5MDA4MzczJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzE3NmUyNjk4OWE0M2M5Y2ZlYmE0MDI5YzIwMjUzOGMyODE3MmU1NjZlM2M0ZmNlNzMyMjg1N2YzYmUzMjdkNjYnLFxuICAgICAgICAnZWQ4Y2M5ZDA0YjI5ZWI4NzdkMjcwYjQ4NzhkYzQzYzE5YWVmZDMxZjRlZWUwOWVlN2I0NzgzNGMxZmE0YjFjMydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3NWQ0NmVmZWEzNzcxZTZlNjhhYmI4OWExM2FkNzQ3ZWNmMTg5MjM5M2RmYzRmMWI3MDA0Nzg4YzUwMzc0ZGE4JyxcbiAgICAgICAgJzk4NTIzOTBhOTk1MDc2NzlmZDBiODZmZDJiMzlhODY4ZDdlZmMyMjE1MTM0NmUxYTNjYTQ3MjY1ODZhNmJlZDgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnODA5YTIwYzY3ZDY0OTAwZmZiNjk4YzRjODI1ZjZkNWYyMzEwZmIwNDUxYzg2OTM0NWI3MzE5ZjY0NTYwNTcyMScsXG4gICAgICAgICc5ZTk5NDk4MGQ5OTE3ZTIyYjc2YjA2MTkyN2ZhMDQxNDNkMDk2Y2NjNTQ5NjNlNmE1ZWJmYTVmM2Y4ZTI4NmMxJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzFiMzg5MDNhNDNmN2YxMTRlZDQ1MDBiNGVhYzcwODNmZGVmZWNlMWNmMjljNjM1MjhkNTYzNDQ2Zjk3MmMxODAnLFxuICAgICAgICAnNDAzNmVkYzkzMWE2MGFlODg5MzUzZjc3ZmQ1M2RlNGEyNzA4YjI2YjZmNWRhNzJhZDMzOTQxMTlkYWY0MDhmOSdcbiAgICAgIF1cbiAgICBdXG4gIH1cbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IGV4cG9ydHM7XG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIG1pbkFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcbnZhciBtaW5VdGlscyA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1jcnlwdG8tdXRpbHMnKTtcblxudXRpbHMuYXNzZXJ0ID0gbWluQXNzZXJ0O1xudXRpbHMudG9BcnJheSA9IG1pblV0aWxzLnRvQXJyYXk7XG51dGlscy56ZXJvMiA9IG1pblV0aWxzLnplcm8yO1xudXRpbHMudG9IZXggPSBtaW5VdGlscy50b0hleDtcbnV0aWxzLmVuY29kZSA9IG1pblV0aWxzLmVuY29kZTtcblxuLy8gUmVwcmVzZW50IG51bSBpbiBhIHctTkFGIGZvcm1cbmZ1bmN0aW9uIGdldE5BRihudW0sIHcsIGJpdHMpIHtcbiAgdmFyIG5hZiA9IG5ldyBBcnJheShNYXRoLm1heChudW0uYml0TGVuZ3RoKCksIGJpdHMpICsgMSk7XG4gIG5hZi5maWxsKDApO1xuXG4gIHZhciB3cyA9IDEgPDwgKHcgKyAxKTtcbiAgdmFyIGsgPSBudW0uY2xvbmUoKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IG5hZi5sZW5ndGg7IGkrKykge1xuICAgIHZhciB6O1xuICAgIHZhciBtb2QgPSBrLmFuZGxuKHdzIC0gMSk7XG4gICAgaWYgKGsuaXNPZGQoKSkge1xuICAgICAgaWYgKG1vZCA+ICh3cyA+PiAxKSAtIDEpXG4gICAgICAgIHogPSAod3MgPj4gMSkgLSBtb2Q7XG4gICAgICBlbHNlXG4gICAgICAgIHogPSBtb2Q7XG4gICAgICBrLmlzdWJuKHopO1xuICAgIH0gZWxzZSB7XG4gICAgICB6ID0gMDtcbiAgICB9XG5cbiAgICBuYWZbaV0gPSB6O1xuICAgIGsuaXVzaHJuKDEpO1xuICB9XG5cbiAgcmV0dXJuIG5hZjtcbn1cbnV0aWxzLmdldE5BRiA9IGdldE5BRjtcblxuLy8gUmVwcmVzZW50IGsxLCBrMiBpbiBhIEpvaW50IFNwYXJzZSBGb3JtXG5mdW5jdGlvbiBnZXRKU0YoazEsIGsyKSB7XG4gIHZhciBqc2YgPSBbXG4gICAgW10sXG4gICAgW11cbiAgXTtcblxuICBrMSA9IGsxLmNsb25lKCk7XG4gIGsyID0gazIuY2xvbmUoKTtcbiAgdmFyIGQxID0gMDtcbiAgdmFyIGQyID0gMDtcbiAgd2hpbGUgKGsxLmNtcG4oLWQxKSA+IDAgfHwgazIuY21wbigtZDIpID4gMCkge1xuXG4gICAgLy8gRmlyc3QgcGhhc2VcbiAgICB2YXIgbTE0ID0gKGsxLmFuZGxuKDMpICsgZDEpICYgMztcbiAgICB2YXIgbTI0ID0gKGsyLmFuZGxuKDMpICsgZDIpICYgMztcbiAgICBpZiAobTE0ID09PSAzKVxuICAgICAgbTE0ID0gLTE7XG4gICAgaWYgKG0yNCA9PT0gMylcbiAgICAgIG0yNCA9IC0xO1xuICAgIHZhciB1MTtcbiAgICBpZiAoKG0xNCAmIDEpID09PSAwKSB7XG4gICAgICB1MSA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBtOCA9IChrMS5hbmRsbig3KSArIGQxKSAmIDc7XG4gICAgICBpZiAoKG04ID09PSAzIHx8IG04ID09PSA1KSAmJiBtMjQgPT09IDIpXG4gICAgICAgIHUxID0gLW0xNDtcbiAgICAgIGVsc2VcbiAgICAgICAgdTEgPSBtMTQ7XG4gICAgfVxuICAgIGpzZlswXS5wdXNoKHUxKTtcblxuICAgIHZhciB1MjtcbiAgICBpZiAoKG0yNCAmIDEpID09PSAwKSB7XG4gICAgICB1MiA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBtOCA9IChrMi5hbmRsbig3KSArIGQyKSAmIDc7XG4gICAgICBpZiAoKG04ID09PSAzIHx8IG04ID09PSA1KSAmJiBtMTQgPT09IDIpXG4gICAgICAgIHUyID0gLW0yNDtcbiAgICAgIGVsc2VcbiAgICAgICAgdTIgPSBtMjQ7XG4gICAgfVxuICAgIGpzZlsxXS5wdXNoKHUyKTtcblxuICAgIC8vIFNlY29uZCBwaGFzZVxuICAgIGlmICgyICogZDEgPT09IHUxICsgMSlcbiAgICAgIGQxID0gMSAtIGQxO1xuICAgIGlmICgyICogZDIgPT09IHUyICsgMSlcbiAgICAgIGQyID0gMSAtIGQyO1xuICAgIGsxLml1c2hybigxKTtcbiAgICBrMi5pdXNocm4oMSk7XG4gIH1cblxuICByZXR1cm4ganNmO1xufVxudXRpbHMuZ2V0SlNGID0gZ2V0SlNGO1xuXG5mdW5jdGlvbiBjYWNoZWRQcm9wZXJ0eShvYmosIG5hbWUsIGNvbXB1dGVyKSB7XG4gIHZhciBrZXkgPSAnXycgKyBuYW1lO1xuICBvYmoucHJvdG90eXBlW25hbWVdID0gZnVuY3Rpb24gY2FjaGVkUHJvcGVydHkoKSB7XG4gICAgcmV0dXJuIHRoaXNba2V5XSAhPT0gdW5kZWZpbmVkID8gdGhpc1trZXldIDpcbiAgICAgICAgICAgdGhpc1trZXldID0gY29tcHV0ZXIuY2FsbCh0aGlzKTtcbiAgfTtcbn1cbnV0aWxzLmNhY2hlZFByb3BlcnR5ID0gY2FjaGVkUHJvcGVydHk7XG5cbmZ1bmN0aW9uIHBhcnNlQnl0ZXMoYnl0ZXMpIHtcbiAgcmV0dXJuIHR5cGVvZiBieXRlcyA9PT0gJ3N0cmluZycgPyB1dGlscy50b0FycmF5KGJ5dGVzLCAnaGV4JykgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzO1xufVxudXRpbHMucGFyc2VCeXRlcyA9IHBhcnNlQnl0ZXM7XG5cbmZ1bmN0aW9uIGludEZyb21MRShieXRlcykge1xuICByZXR1cm4gbmV3IEJOKGJ5dGVzLCAnaGV4JywgJ2xlJyk7XG59XG51dGlscy5pbnRGcm9tTEUgPSBpbnRGcm9tTEU7XG5cbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSID0gdHlwZW9mIFJlZmxlY3QgPT09ICdvYmplY3QnID8gUmVmbGVjdCA6IG51bGxcbnZhciBSZWZsZWN0QXBwbHkgPSBSICYmIHR5cGVvZiBSLmFwcGx5ID09PSAnZnVuY3Rpb24nXG4gID8gUi5hcHBseVxuICA6IGZ1bmN0aW9uIFJlZmxlY3RBcHBseSh0YXJnZXQsIHJlY2VpdmVyLCBhcmdzKSB7XG4gICAgcmV0dXJuIEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseS5jYWxsKHRhcmdldCwgcmVjZWl2ZXIsIGFyZ3MpO1xuICB9XG5cbnZhciBSZWZsZWN0T3duS2V5c1xuaWYgKFIgJiYgdHlwZW9mIFIub3duS2V5cyA9PT0gJ2Z1bmN0aW9uJykge1xuICBSZWZsZWN0T3duS2V5cyA9IFIub3duS2V5c1xufSBlbHNlIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7XG4gIFJlZmxlY3RPd25LZXlzID0gZnVuY3Rpb24gUmVmbGVjdE93bktleXModGFyZ2V0KSB7XG4gICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRhcmdldClcbiAgICAgIC5jb25jYXQoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyh0YXJnZXQpKTtcbiAgfTtcbn0gZWxzZSB7XG4gIFJlZmxlY3RPd25LZXlzID0gZnVuY3Rpb24gUmVmbGVjdE93bktleXModGFyZ2V0KSB7XG4gICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRhcmdldCk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIFByb2Nlc3NFbWl0V2FybmluZyh3YXJuaW5nKSB7XG4gIGlmIChjb25zb2xlICYmIGNvbnNvbGUud2FybikgY29uc29sZS53YXJuKHdhcm5pbmcpO1xufVxuXG52YXIgTnVtYmVySXNOYU4gPSBOdW1iZXIuaXNOYU4gfHwgZnVuY3Rpb24gTnVtYmVySXNOYU4odmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9PSB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICBFdmVudEVtaXR0ZXIuaW5pdC5jYWxsKHRoaXMpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzQ291bnQgPSAwO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG52YXIgZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRXZlbnRFbWl0dGVyLCAnZGVmYXVsdE1heExpc3RlbmVycycsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZGVmYXVsdE1heExpc3RlbmVycztcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbihhcmcpIHtcbiAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicgfHwgYXJnIDwgMCB8fCBOdW1iZXJJc05hTihhcmcpKSB7XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVGhlIHZhbHVlIG9mIFwiZGVmYXVsdE1heExpc3RlbmVyc1wiIGlzIG91dCBvZiByYW5nZS4gSXQgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIuIFJlY2VpdmVkICcgKyBhcmcgKyAnLicpO1xuICAgIH1cbiAgICBkZWZhdWx0TWF4TGlzdGVuZXJzID0gYXJnO1xuICB9XG59KTtcblxuRXZlbnRFbWl0dGVyLmluaXQgPSBmdW5jdGlvbigpIHtcblxuICBpZiAodGhpcy5fZXZlbnRzID09PSB1bmRlZmluZWQgfHxcbiAgICAgIHRoaXMuX2V2ZW50cyA9PT0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpLl9ldmVudHMpIHtcbiAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgfVxuXG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59O1xuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMobikge1xuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPCAwIHx8IE51bWJlcklzTmFOKG4pKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSB2YWx1ZSBvZiBcIm5cIiBpcyBvdXQgb2YgcmFuZ2UuIEl0IG11c3QgYmUgYSBub24tbmVnYXRpdmUgbnVtYmVyLiBSZWNlaXZlZCAnICsgbiArICcuJyk7XG4gIH1cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiAkZ2V0TWF4TGlzdGVuZXJzKHRoYXQpIHtcbiAgaWYgKHRoYXQuX21heExpc3RlbmVycyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgcmV0dXJuIHRoYXQuX21heExpc3RlbmVycztcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5nZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiAkZ2V0TWF4TGlzdGVuZXJzKHRoaXMpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdCh0eXBlKSB7XG4gIHZhciBhcmdzID0gW107XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSBhcmdzLnB1c2goYXJndW1lbnRzW2ldKTtcbiAgdmFyIGRvRXJyb3IgPSAodHlwZSA9PT0gJ2Vycm9yJyk7XG5cbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgaWYgKGV2ZW50cyAhPT0gdW5kZWZpbmVkKVxuICAgIGRvRXJyb3IgPSAoZG9FcnJvciAmJiBldmVudHMuZXJyb3IgPT09IHVuZGVmaW5lZCk7XG4gIGVsc2UgaWYgKCFkb0Vycm9yKVxuICAgIHJldHVybiBmYWxzZTtcblxuICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG4gIGlmIChkb0Vycm9yKSB7XG4gICAgdmFyIGVyO1xuICAgIGlmIChhcmdzLmxlbmd0aCA+IDApXG4gICAgICBlciA9IGFyZ3NbMF07XG4gICAgaWYgKGVyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIC8vIE5vdGU6IFRoZSBjb21tZW50cyBvbiB0aGUgYHRocm93YCBsaW5lcyBhcmUgaW50ZW50aW9uYWwsIHRoZXkgc2hvd1xuICAgICAgLy8gdXAgaW4gTm9kZSdzIG91dHB1dCBpZiB0aGlzIHJlc3VsdHMgaW4gYW4gdW5oYW5kbGVkIGV4Y2VwdGlvbi5cbiAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgIH1cbiAgICAvLyBBdCBsZWFzdCBnaXZlIHNvbWUga2luZCBvZiBjb250ZXh0IHRvIHRoZSB1c2VyXG4gICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5oYW5kbGVkIGVycm9yLicgKyAoZXIgPyAnICgnICsgZXIubWVzc2FnZSArICcpJyA6ICcnKSk7XG4gICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICB0aHJvdyBlcnI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gIH1cblxuICB2YXIgaGFuZGxlciA9IGV2ZW50c1t0eXBlXTtcblxuICBpZiAoaGFuZGxlciA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICBSZWZsZWN0QXBwbHkoaGFuZGxlciwgdGhpcywgYXJncyk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIFJlZmxlY3RBcHBseShsaXN0ZW5lcnNbaV0sIHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5mdW5jdGlvbiBfYWRkTGlzdGVuZXIodGFyZ2V0LCB0eXBlLCBsaXN0ZW5lciwgcHJlcGVuZCkge1xuICB2YXIgbTtcbiAgdmFyIGV2ZW50cztcbiAgdmFyIGV4aXN0aW5nO1xuXG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBGdW5jdGlvbi4gUmVjZWl2ZWQgdHlwZSAnICsgdHlwZW9mIGxpc3RlbmVyKTtcbiAgfVxuXG4gIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpIHtcbiAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdGFyZ2V0Ll9ldmVudHNDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gICAgaWYgKGV2ZW50cy5uZXdMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0YXJnZXQuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgPyBsaXN0ZW5lci5saXN0ZW5lciA6IGxpc3RlbmVyKTtcblxuICAgICAgLy8gUmUtYXNzaWduIGBldmVudHNgIGJlY2F1c2UgYSBuZXdMaXN0ZW5lciBoYW5kbGVyIGNvdWxkIGhhdmUgY2F1c2VkIHRoZVxuICAgICAgLy8gdGhpcy5fZXZlbnRzIHRvIGJlIGFzc2lnbmVkIHRvIGEgbmV3IG9iamVjdFxuICAgICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gICAgfVxuICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdO1xuICB9XG5cbiAgaWYgKGV4aXN0aW5nID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgICsrdGFyZ2V0Ll9ldmVudHNDb3VudDtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIGV4aXN0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID1cbiAgICAgICAgcHJlcGVuZCA/IFtsaXN0ZW5lciwgZXhpc3RpbmddIDogW2V4aXN0aW5nLCBsaXN0ZW5lcl07XG4gICAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBhcnJheSwganVzdCBhcHBlbmQuXG4gICAgfSBlbHNlIGlmIChwcmVwZW5kKSB7XG4gICAgICBleGlzdGluZy51bnNoaWZ0KGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXhpc3RpbmcucHVzaChsaXN0ZW5lcik7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICBtID0gJGdldE1heExpc3RlbmVycyh0YXJnZXQpO1xuICAgIGlmIChtID4gMCAmJiBleGlzdGluZy5sZW5ndGggPiBtICYmICFleGlzdGluZy53YXJuZWQpIHtcbiAgICAgIGV4aXN0aW5nLndhcm5lZCA9IHRydWU7XG4gICAgICAvLyBObyBlcnJvciBjb2RlIGZvciB0aGlzIHNpbmNlIGl0IGlzIGEgV2FybmluZ1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG4gICAgICB2YXIgdyA9IG5ldyBFcnJvcignUG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBsZWFrIGRldGVjdGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcubGVuZ3RoICsgJyAnICsgU3RyaW5nKHR5cGUpICsgJyBsaXN0ZW5lcnMgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhZGRlZC4gVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdpbmNyZWFzZSBsaW1pdCcpO1xuICAgICAgdy5uYW1lID0gJ01heExpc3RlbmVyc0V4Y2VlZGVkV2FybmluZyc7XG4gICAgICB3LmVtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgICB3LnR5cGUgPSB0eXBlO1xuICAgICAgdy5jb3VudCA9IGV4aXN0aW5nLmxlbmd0aDtcbiAgICAgIFByb2Nlc3NFbWl0V2FybmluZyh3KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZExpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIHRydWUpO1xuICAgIH07XG5cbmZ1bmN0aW9uIG9uY2VXcmFwcGVyKCkge1xuICB2YXIgYXJncyA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgYXJncy5wdXNoKGFyZ3VtZW50c1tpXSk7XG4gIGlmICghdGhpcy5maXJlZCkge1xuICAgIHRoaXMudGFyZ2V0LnJlbW92ZUxpc3RlbmVyKHRoaXMudHlwZSwgdGhpcy53cmFwRm4pO1xuICAgIHRoaXMuZmlyZWQgPSB0cnVlO1xuICAgIFJlZmxlY3RBcHBseSh0aGlzLmxpc3RlbmVyLCB0aGlzLnRhcmdldCwgYXJncyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gX29uY2VXcmFwKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIHN0YXRlID0geyBmaXJlZDogZmFsc2UsIHdyYXBGbjogdW5kZWZpbmVkLCB0YXJnZXQ6IHRhcmdldCwgdHlwZTogdHlwZSwgbGlzdGVuZXI6IGxpc3RlbmVyIH07XG4gIHZhciB3cmFwcGVkID0gb25jZVdyYXBwZXIuYmluZChzdGF0ZSk7XG4gIHdyYXBwZWQubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgc3RhdGUud3JhcEZuID0gd3JhcHBlZDtcbiAgcmV0dXJuIHdyYXBwZWQ7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uIG9uY2UodHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBvZiB0eXBlIEZ1bmN0aW9uLiBSZWNlaXZlZCB0eXBlICcgKyB0eXBlb2YgbGlzdGVuZXIpO1xuICB9XG4gIHRoaXMub24odHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5wcmVwZW5kT25jZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kT25jZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBvZiB0eXBlIEZ1bmN0aW9uLiBSZWNlaXZlZCB0eXBlICcgKyB0eXBlb2YgbGlzdGVuZXIpO1xuICAgICAgfVxuICAgICAgdGhpcy5wcmVwZW5kTGlzdGVuZXIodHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4vLyBFbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWYgYW5kIG9ubHkgaWYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHZhciBsaXN0LCBldmVudHMsIHBvc2l0aW9uLCBpLCBvcmlnaW5hbExpc3RlbmVyO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBvZiB0eXBlIEZ1bmN0aW9uLiBSZWNlaXZlZCB0eXBlICcgKyB0eXBlb2YgbGlzdGVuZXIpO1xuICAgICAgfVxuXG4gICAgICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gICAgICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBsaXN0ID0gZXZlbnRzW3R5cGVdO1xuICAgICAgaWYgKGxpc3QgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fCBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBkZWxldGUgZXZlbnRzW3R5cGVdO1xuICAgICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdC5saXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGxpc3QgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcG9zaXRpb24gPSAtMTtcblxuICAgICAgICBmb3IgKGkgPSBsaXN0Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgaWYgKGxpc3RbaV0gPT09IGxpc3RlbmVyIHx8IGxpc3RbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICBvcmlnaW5hbExpc3RlbmVyID0gbGlzdFtpXS5saXN0ZW5lcjtcbiAgICAgICAgICAgIHBvc2l0aW9uID0gaTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwb3NpdGlvbiA8IDApXG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAwKVxuICAgICAgICAgIGxpc3Quc2hpZnQoKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgc3BsaWNlT25lKGxpc3QsIHBvc2l0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICBldmVudHNbdHlwZV0gPSBsaXN0WzBdO1xuXG4gICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgb3JpZ2luYWxMaXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub2ZmID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyh0eXBlKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzLCBldmVudHMsIGk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIC8vIG5vdCBsaXN0ZW5pbmcgZm9yIHJlbW92ZUxpc3RlbmVyLCBubyBuZWVkIHRvIGVtaXRcbiAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50c1t0eXBlXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhldmVudHMpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICAgICAgaWYgKGtleSA9PT0gJ3JlbW92ZUxpc3RlbmVyJykgY29udGludWU7XG4gICAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygncmVtb3ZlTGlzdGVuZXInKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbmVycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIExJRk8gb3JkZXJcbiAgICAgICAgZm9yIChpID0gbGlzdGVuZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbmZ1bmN0aW9uIF9saXN0ZW5lcnModGFyZ2V0LCB0eXBlLCB1bndyYXApIHtcbiAgdmFyIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gW107XG5cbiAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG4gIGlmIChldmxpc3RlbmVyID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gdW53cmFwID8gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl0gOiBbZXZsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHVud3JhcCA/XG4gICAgdW53cmFwTGlzdGVuZXJzKGV2bGlzdGVuZXIpIDogYXJyYXlDbG9uZShldmxpc3RlbmVyLCBldmxpc3RlbmVyLmxlbmd0aCk7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gbGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgdHJ1ZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJhd0xpc3RlbmVycyA9IGZ1bmN0aW9uIHJhd0xpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIubGlzdGVuZXJDb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyQ291bnQuY2FsbChlbWl0dGVyLCB0eXBlKTtcbiAgfVxufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gbGlzdGVuZXJDb3VudDtcbmZ1bmN0aW9uIGxpc3RlbmVyQ291bnQodHlwZSkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMgIT09IHVuZGVmaW5lZCkge1xuICAgIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9IGVsc2UgaWYgKGV2bGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAwO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICByZXR1cm4gdGhpcy5fZXZlbnRzQ291bnQgPiAwID8gUmVmbGVjdE93bktleXModGhpcy5fZXZlbnRzKSA6IFtdO1xufTtcblxuZnVuY3Rpb24gYXJyYXlDbG9uZShhcnIsIG4pIHtcbiAgdmFyIGNvcHkgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKVxuICAgIGNvcHlbaV0gPSBhcnJbaV07XG4gIHJldHVybiBjb3B5O1xufVxuXG5mdW5jdGlvbiBzcGxpY2VPbmUobGlzdCwgaW5kZXgpIHtcbiAgZm9yICg7IGluZGV4ICsgMSA8IGxpc3QubGVuZ3RoOyBpbmRleCsrKVxuICAgIGxpc3RbaW5kZXhdID0gbGlzdFtpbmRleCArIDFdO1xuICBsaXN0LnBvcCgpO1xufVxuXG5mdW5jdGlvbiB1bndyYXBMaXN0ZW5lcnMoYXJyKSB7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmV0W2ldID0gYXJyW2ldLmxpc3RlbmVyIHx8IGFycltpXTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuIiwidmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG52YXIgTUQ1ID0gcmVxdWlyZSgnbWQ1LmpzJylcblxuLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG5mdW5jdGlvbiBFVlBfQnl0ZXNUb0tleSAocGFzc3dvcmQsIHNhbHQsIGtleUJpdHMsIGl2TGVuKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHBhc3N3b3JkKSkgcGFzc3dvcmQgPSBCdWZmZXIuZnJvbShwYXNzd29yZCwgJ2JpbmFyeScpXG4gIGlmIChzYWx0KSB7XG4gICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoc2FsdCkpIHNhbHQgPSBCdWZmZXIuZnJvbShzYWx0LCAnYmluYXJ5JylcbiAgICBpZiAoc2FsdC5sZW5ndGggIT09IDgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzYWx0IHNob3VsZCBiZSBCdWZmZXIgd2l0aCA4IGJ5dGUgbGVuZ3RoJylcbiAgfVxuXG4gIHZhciBrZXlMZW4gPSBrZXlCaXRzIC8gOFxuICB2YXIga2V5ID0gQnVmZmVyLmFsbG9jKGtleUxlbilcbiAgdmFyIGl2ID0gQnVmZmVyLmFsbG9jKGl2TGVuIHx8IDApXG4gIHZhciB0bXAgPSBCdWZmZXIuYWxsb2MoMClcblxuICB3aGlsZSAoa2V5TGVuID4gMCB8fCBpdkxlbiA+IDApIHtcbiAgICB2YXIgaGFzaCA9IG5ldyBNRDUoKVxuICAgIGhhc2gudXBkYXRlKHRtcClcbiAgICBoYXNoLnVwZGF0ZShwYXNzd29yZClcbiAgICBpZiAoc2FsdCkgaGFzaC51cGRhdGUoc2FsdClcbiAgICB0bXAgPSBoYXNoLmRpZ2VzdCgpXG5cbiAgICB2YXIgdXNlZCA9IDBcblxuICAgIGlmIChrZXlMZW4gPiAwKSB7XG4gICAgICB2YXIga2V5U3RhcnQgPSBrZXkubGVuZ3RoIC0ga2V5TGVuXG4gICAgICB1c2VkID0gTWF0aC5taW4oa2V5TGVuLCB0bXAubGVuZ3RoKVxuICAgICAgdG1wLmNvcHkoa2V5LCBrZXlTdGFydCwgMCwgdXNlZClcbiAgICAgIGtleUxlbiAtPSB1c2VkXG4gICAgfVxuXG4gICAgaWYgKHVzZWQgPCB0bXAubGVuZ3RoICYmIGl2TGVuID4gMCkge1xuICAgICAgdmFyIGl2U3RhcnQgPSBpdi5sZW5ndGggLSBpdkxlblxuICAgICAgdmFyIGxlbmd0aCA9IE1hdGgubWluKGl2TGVuLCB0bXAubGVuZ3RoIC0gdXNlZClcbiAgICAgIHRtcC5jb3B5KGl2LCBpdlN0YXJ0LCB1c2VkLCB1c2VkICsgbGVuZ3RoKVxuICAgICAgaXZMZW4gLT0gbGVuZ3RoXG4gICAgfVxuICB9XG5cbiAgdG1wLmZpbGwoMClcbiAgcmV0dXJuIHsga2V5OiBrZXksIGl2OiBpdiB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gRVZQX0J5dGVzVG9LZXlcbiIsIid1c2Ugc3RyaWN0J1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnc3RyZWFtJykuVHJhbnNmb3JtXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG5cbmZ1bmN0aW9uIHRocm93SWZOb3RTdHJpbmdPckJ1ZmZlciAodmFsLCBwcmVmaXgpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIodmFsKSAmJiB0eXBlb2YgdmFsICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IocHJlZml4ICsgJyBtdXN0IGJlIGEgc3RyaW5nIG9yIGEgYnVmZmVyJylcbiAgfVxufVxuXG5mdW5jdGlvbiBIYXNoQmFzZSAoYmxvY2tTaXplKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG5cbiAgdGhpcy5fYmxvY2sgPSBCdWZmZXIuYWxsb2NVbnNhZmUoYmxvY2tTaXplKVxuICB0aGlzLl9ibG9ja1NpemUgPSBibG9ja1NpemVcbiAgdGhpcy5fYmxvY2tPZmZzZXQgPSAwXG4gIHRoaXMuX2xlbmd0aCA9IFswLCAwLCAwLCAwXVxuXG4gIHRoaXMuX2ZpbmFsaXplZCA9IGZhbHNlXG59XG5cbmluaGVyaXRzKEhhc2hCYXNlLCBUcmFuc2Zvcm0pXG5cbkhhc2hCYXNlLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2FsbGJhY2spIHtcbiAgdmFyIGVycm9yID0gbnVsbFxuICB0cnkge1xuICAgIHRoaXMudXBkYXRlKGNodW5rLCBlbmNvZGluZylcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgZXJyb3IgPSBlcnJcbiAgfVxuXG4gIGNhbGxiYWNrKGVycm9yKVxufVxuXG5IYXNoQmFzZS5wcm90b3R5cGUuX2ZsdXNoID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gIHZhciBlcnJvciA9IG51bGxcbiAgdHJ5IHtcbiAgICB0aGlzLnB1c2godGhpcy5kaWdlc3QoKSlcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgZXJyb3IgPSBlcnJcbiAgfVxuXG4gIGNhbGxiYWNrKGVycm9yKVxufVxuXG5IYXNoQmFzZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGVuY29kaW5nKSB7XG4gIHRocm93SWZOb3RTdHJpbmdPckJ1ZmZlcihkYXRhLCAnRGF0YScpXG4gIGlmICh0aGlzLl9maW5hbGl6ZWQpIHRocm93IG5ldyBFcnJvcignRGlnZXN0IGFscmVhZHkgY2FsbGVkJylcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoZGF0YSkpIGRhdGEgPSBCdWZmZXIuZnJvbShkYXRhLCBlbmNvZGluZylcblxuICAvLyBjb25zdW1lIGRhdGFcbiAgdmFyIGJsb2NrID0gdGhpcy5fYmxvY2tcbiAgdmFyIG9mZnNldCA9IDBcbiAgd2hpbGUgKHRoaXMuX2Jsb2NrT2Zmc2V0ICsgZGF0YS5sZW5ndGggLSBvZmZzZXQgPj0gdGhpcy5fYmxvY2tTaXplKSB7XG4gICAgZm9yICh2YXIgaSA9IHRoaXMuX2Jsb2NrT2Zmc2V0OyBpIDwgdGhpcy5fYmxvY2tTaXplOykgYmxvY2tbaSsrXSA9IGRhdGFbb2Zmc2V0KytdXG4gICAgdGhpcy5fdXBkYXRlKClcbiAgICB0aGlzLl9ibG9ja09mZnNldCA9IDBcbiAgfVxuICB3aGlsZSAob2Zmc2V0IDwgZGF0YS5sZW5ndGgpIGJsb2NrW3RoaXMuX2Jsb2NrT2Zmc2V0KytdID0gZGF0YVtvZmZzZXQrK11cblxuICAvLyB1cGRhdGUgbGVuZ3RoXG4gIGZvciAodmFyIGogPSAwLCBjYXJyeSA9IGRhdGEubGVuZ3RoICogODsgY2FycnkgPiAwOyArK2opIHtcbiAgICB0aGlzLl9sZW5ndGhbal0gKz0gY2FycnlcbiAgICBjYXJyeSA9ICh0aGlzLl9sZW5ndGhbal0gLyAweDAxMDAwMDAwMDApIHwgMFxuICAgIGlmIChjYXJyeSA+IDApIHRoaXMuX2xlbmd0aFtqXSAtPSAweDAxMDAwMDAwMDAgKiBjYXJyeVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuSGFzaEJhc2UucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcignX3VwZGF0ZSBpcyBub3QgaW1wbGVtZW50ZWQnKVxufVxuXG5IYXNoQmFzZS5wcm90b3R5cGUuZGlnZXN0ID0gZnVuY3Rpb24gKGVuY29kaW5nKSB7XG4gIGlmICh0aGlzLl9maW5hbGl6ZWQpIHRocm93IG5ldyBFcnJvcignRGlnZXN0IGFscmVhZHkgY2FsbGVkJylcbiAgdGhpcy5fZmluYWxpemVkID0gdHJ1ZVxuXG4gIHZhciBkaWdlc3QgPSB0aGlzLl9kaWdlc3QoKVxuICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCkgZGlnZXN0ID0gZGlnZXN0LnRvU3RyaW5nKGVuY29kaW5nKVxuXG4gIC8vIHJlc2V0IHN0YXRlXG4gIHRoaXMuX2Jsb2NrLmZpbGwoMClcbiAgdGhpcy5fYmxvY2tPZmZzZXQgPSAwXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgKytpKSB0aGlzLl9sZW5ndGhbaV0gPSAwXG5cbiAgcmV0dXJuIGRpZ2VzdFxufVxuXG5IYXNoQmFzZS5wcm90b3R5cGUuX2RpZ2VzdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdfZGlnZXN0IGlzIG5vdCBpbXBsZW1lbnRlZCcpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gSGFzaEJhc2VcbiIsInZhciBoYXNoID0gZXhwb3J0cztcblxuaGFzaC51dGlscyA9IHJlcXVpcmUoJy4vaGFzaC91dGlscycpO1xuaGFzaC5jb21tb24gPSByZXF1aXJlKCcuL2hhc2gvY29tbW9uJyk7XG5oYXNoLnNoYSA9IHJlcXVpcmUoJy4vaGFzaC9zaGEnKTtcbmhhc2gucmlwZW1kID0gcmVxdWlyZSgnLi9oYXNoL3JpcGVtZCcpO1xuaGFzaC5obWFjID0gcmVxdWlyZSgnLi9oYXNoL2htYWMnKTtcblxuLy8gUHJveHkgaGFzaCBmdW5jdGlvbnMgdG8gdGhlIG1haW4gb2JqZWN0XG5oYXNoLnNoYTEgPSBoYXNoLnNoYS5zaGExO1xuaGFzaC5zaGEyNTYgPSBoYXNoLnNoYS5zaGEyNTY7XG5oYXNoLnNoYTIyNCA9IGhhc2guc2hhLnNoYTIyNDtcbmhhc2guc2hhMzg0ID0gaGFzaC5zaGEuc2hhMzg0O1xuaGFzaC5zaGE1MTIgPSBoYXNoLnNoYS5zaGE1MTI7XG5oYXNoLnJpcGVtZDE2MCA9IGhhc2gucmlwZW1kLnJpcGVtZDE2MDtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcblxuZnVuY3Rpb24gQmxvY2tIYXNoKCkge1xuICB0aGlzLnBlbmRpbmcgPSBudWxsO1xuICB0aGlzLnBlbmRpbmdUb3RhbCA9IDA7XG4gIHRoaXMuYmxvY2tTaXplID0gdGhpcy5jb25zdHJ1Y3Rvci5ibG9ja1NpemU7XG4gIHRoaXMub3V0U2l6ZSA9IHRoaXMuY29uc3RydWN0b3Iub3V0U2l6ZTtcbiAgdGhpcy5obWFjU3RyZW5ndGggPSB0aGlzLmNvbnN0cnVjdG9yLmhtYWNTdHJlbmd0aDtcbiAgdGhpcy5wYWRMZW5ndGggPSB0aGlzLmNvbnN0cnVjdG9yLnBhZExlbmd0aCAvIDg7XG4gIHRoaXMuZW5kaWFuID0gJ2JpZyc7XG5cbiAgdGhpcy5fZGVsdGE4ID0gdGhpcy5ibG9ja1NpemUgLyA4O1xuICB0aGlzLl9kZWx0YTMyID0gdGhpcy5ibG9ja1NpemUgLyAzMjtcbn1cbmV4cG9ydHMuQmxvY2tIYXNoID0gQmxvY2tIYXNoO1xuXG5CbG9ja0hhc2gucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIHVwZGF0ZShtc2csIGVuYykge1xuICAvLyBDb252ZXJ0IG1lc3NhZ2UgdG8gYXJyYXksIHBhZCBpdCwgYW5kIGpvaW4gaW50byAzMmJpdCBibG9ja3NcbiAgbXNnID0gdXRpbHMudG9BcnJheShtc2csIGVuYyk7XG4gIGlmICghdGhpcy5wZW5kaW5nKVxuICAgIHRoaXMucGVuZGluZyA9IG1zZztcbiAgZWxzZVxuICAgIHRoaXMucGVuZGluZyA9IHRoaXMucGVuZGluZy5jb25jYXQobXNnKTtcbiAgdGhpcy5wZW5kaW5nVG90YWwgKz0gbXNnLmxlbmd0aDtcblxuICAvLyBFbm91Z2ggZGF0YSwgdHJ5IHVwZGF0aW5nXG4gIGlmICh0aGlzLnBlbmRpbmcubGVuZ3RoID49IHRoaXMuX2RlbHRhOCkge1xuICAgIG1zZyA9IHRoaXMucGVuZGluZztcblxuICAgIC8vIFByb2Nlc3MgcGVuZGluZyBkYXRhIGluIGJsb2Nrc1xuICAgIHZhciByID0gbXNnLmxlbmd0aCAlIHRoaXMuX2RlbHRhODtcbiAgICB0aGlzLnBlbmRpbmcgPSBtc2cuc2xpY2UobXNnLmxlbmd0aCAtIHIsIG1zZy5sZW5ndGgpO1xuICAgIGlmICh0aGlzLnBlbmRpbmcubGVuZ3RoID09PSAwKVxuICAgICAgdGhpcy5wZW5kaW5nID0gbnVsbDtcblxuICAgIG1zZyA9IHV0aWxzLmpvaW4zMihtc2csIDAsIG1zZy5sZW5ndGggLSByLCB0aGlzLmVuZGlhbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpICs9IHRoaXMuX2RlbHRhMzIpXG4gICAgICB0aGlzLl91cGRhdGUobXNnLCBpLCBpICsgdGhpcy5fZGVsdGEzMik7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbkJsb2NrSGFzaC5wcm90b3R5cGUuZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICB0aGlzLnVwZGF0ZSh0aGlzLl9wYWQoKSk7XG4gIGFzc2VydCh0aGlzLnBlbmRpbmcgPT09IG51bGwpO1xuXG4gIHJldHVybiB0aGlzLl9kaWdlc3QoZW5jKTtcbn07XG5cbkJsb2NrSGFzaC5wcm90b3R5cGUuX3BhZCA9IGZ1bmN0aW9uIHBhZCgpIHtcbiAgdmFyIGxlbiA9IHRoaXMucGVuZGluZ1RvdGFsO1xuICB2YXIgYnl0ZXMgPSB0aGlzLl9kZWx0YTg7XG4gIHZhciBrID0gYnl0ZXMgLSAoKGxlbiArIHRoaXMucGFkTGVuZ3RoKSAlIGJ5dGVzKTtcbiAgdmFyIHJlcyA9IG5ldyBBcnJheShrICsgdGhpcy5wYWRMZW5ndGgpO1xuICByZXNbMF0gPSAweDgwO1xuICBmb3IgKHZhciBpID0gMTsgaSA8IGs7IGkrKylcbiAgICByZXNbaV0gPSAwO1xuXG4gIC8vIEFwcGVuZCBsZW5ndGhcbiAgbGVuIDw8PSAzO1xuICBpZiAodGhpcy5lbmRpYW4gPT09ICdiaWcnKSB7XG4gICAgZm9yICh2YXIgdCA9IDg7IHQgPCB0aGlzLnBhZExlbmd0aDsgdCsrKVxuICAgICAgcmVzW2krK10gPSAwO1xuXG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMjQpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDE2KSAmIDB4ZmY7XG4gICAgcmVzW2krK10gPSAobGVuID4+PiA4KSAmIDB4ZmY7XG4gICAgcmVzW2krK10gPSBsZW4gJiAweGZmO1xuICB9IGVsc2Uge1xuICAgIHJlc1tpKytdID0gbGVuICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDgpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDE2KSAmIDB4ZmY7XG4gICAgcmVzW2krK10gPSAobGVuID4+PiAyNCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcblxuICAgIGZvciAodCA9IDg7IHQgPCB0aGlzLnBhZExlbmd0aDsgdCsrKVxuICAgICAgcmVzW2krK10gPSAwO1xuICB9XG5cbiAgcmV0dXJuIHJlcztcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciBhc3NlcnQgPSByZXF1aXJlKCdtaW5pbWFsaXN0aWMtYXNzZXJ0Jyk7XG5cbmZ1bmN0aW9uIEhtYWMoaGFzaCwga2V5LCBlbmMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEhtYWMpKVxuICAgIHJldHVybiBuZXcgSG1hYyhoYXNoLCBrZXksIGVuYyk7XG4gIHRoaXMuSGFzaCA9IGhhc2g7XG4gIHRoaXMuYmxvY2tTaXplID0gaGFzaC5ibG9ja1NpemUgLyA4O1xuICB0aGlzLm91dFNpemUgPSBoYXNoLm91dFNpemUgLyA4O1xuICB0aGlzLmlubmVyID0gbnVsbDtcbiAgdGhpcy5vdXRlciA9IG51bGw7XG5cbiAgdGhpcy5faW5pdCh1dGlscy50b0FycmF5KGtleSwgZW5jKSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEhtYWM7XG5cbkhtYWMucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24gaW5pdChrZXkpIHtcbiAgLy8gU2hvcnRlbiBrZXksIGlmIG5lZWRlZFxuICBpZiAoa2V5Lmxlbmd0aCA+IHRoaXMuYmxvY2tTaXplKVxuICAgIGtleSA9IG5ldyB0aGlzLkhhc2goKS51cGRhdGUoa2V5KS5kaWdlc3QoKTtcbiAgYXNzZXJ0KGtleS5sZW5ndGggPD0gdGhpcy5ibG9ja1NpemUpO1xuXG4gIC8vIEFkZCBwYWRkaW5nIHRvIGtleVxuICBmb3IgKHZhciBpID0ga2V5Lmxlbmd0aDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspXG4gICAga2V5LnB1c2goMCk7XG5cbiAgZm9yIChpID0gMDsgaSA8IGtleS5sZW5ndGg7IGkrKylcbiAgICBrZXlbaV0gXj0gMHgzNjtcbiAgdGhpcy5pbm5lciA9IG5ldyB0aGlzLkhhc2goKS51cGRhdGUoa2V5KTtcblxuICAvLyAweDM2IF4gMHg1YyA9IDB4NmFcbiAgZm9yIChpID0gMDsgaSA8IGtleS5sZW5ndGg7IGkrKylcbiAgICBrZXlbaV0gXj0gMHg2YTtcbiAgdGhpcy5vdXRlciA9IG5ldyB0aGlzLkhhc2goKS51cGRhdGUoa2V5KTtcbn07XG5cbkhtYWMucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIHVwZGF0ZShtc2csIGVuYykge1xuICB0aGlzLmlubmVyLnVwZGF0ZShtc2csIGVuYyk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuSG1hYy5wcm90b3R5cGUuZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICB0aGlzLm91dGVyLnVwZGF0ZSh0aGlzLmlubmVyLmRpZ2VzdCgpKTtcbiAgcmV0dXJuIHRoaXMub3V0ZXIuZGlnZXN0KGVuYyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxudmFyIHJvdGwzMiA9IHV0aWxzLnJvdGwzMjtcbnZhciBzdW0zMiA9IHV0aWxzLnN1bTMyO1xudmFyIHN1bTMyXzMgPSB1dGlscy5zdW0zMl8zO1xudmFyIHN1bTMyXzQgPSB1dGlscy5zdW0zMl80O1xudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbmZ1bmN0aW9uIFJJUEVNRDE2MCgpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJJUEVNRDE2MCkpXG4gICAgcmV0dXJuIG5ldyBSSVBFTUQxNjAoKTtcblxuICBCbG9ja0hhc2guY2FsbCh0aGlzKTtcblxuICB0aGlzLmggPSBbIDB4Njc0NTIzMDEsIDB4ZWZjZGFiODksIDB4OThiYWRjZmUsIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjAgXTtcbiAgdGhpcy5lbmRpYW4gPSAnbGl0dGxlJztcbn1cbnV0aWxzLmluaGVyaXRzKFJJUEVNRDE2MCwgQmxvY2tIYXNoKTtcbmV4cG9ydHMucmlwZW1kMTYwID0gUklQRU1EMTYwO1xuXG5SSVBFTUQxNjAuYmxvY2tTaXplID0gNTEyO1xuUklQRU1EMTYwLm91dFNpemUgPSAxNjA7XG5SSVBFTUQxNjAuaG1hY1N0cmVuZ3RoID0gMTkyO1xuUklQRU1EMTYwLnBhZExlbmd0aCA9IDY0O1xuXG5SSVBFTUQxNjAucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgQSA9IHRoaXMuaFswXTtcbiAgdmFyIEIgPSB0aGlzLmhbMV07XG4gIHZhciBDID0gdGhpcy5oWzJdO1xuICB2YXIgRCA9IHRoaXMuaFszXTtcbiAgdmFyIEUgPSB0aGlzLmhbNF07XG4gIHZhciBBaCA9IEE7XG4gIHZhciBCaCA9IEI7XG4gIHZhciBDaCA9IEM7XG4gIHZhciBEaCA9IEQ7XG4gIHZhciBFaCA9IEU7XG4gIGZvciAodmFyIGogPSAwOyBqIDwgODA7IGorKykge1xuICAgIHZhciBUID0gc3VtMzIoXG4gICAgICByb3RsMzIoXG4gICAgICAgIHN1bTMyXzQoQSwgZihqLCBCLCBDLCBEKSwgbXNnW3Jbal0gKyBzdGFydF0sIEsoaikpLFxuICAgICAgICBzW2pdKSxcbiAgICAgIEUpO1xuICAgIEEgPSBFO1xuICAgIEUgPSBEO1xuICAgIEQgPSByb3RsMzIoQywgMTApO1xuICAgIEMgPSBCO1xuICAgIEIgPSBUO1xuICAgIFQgPSBzdW0zMihcbiAgICAgIHJvdGwzMihcbiAgICAgICAgc3VtMzJfNChBaCwgZig3OSAtIGosIEJoLCBDaCwgRGgpLCBtc2dbcmhbal0gKyBzdGFydF0sIEtoKGopKSxcbiAgICAgICAgc2hbal0pLFxuICAgICAgRWgpO1xuICAgIEFoID0gRWg7XG4gICAgRWggPSBEaDtcbiAgICBEaCA9IHJvdGwzMihDaCwgMTApO1xuICAgIENoID0gQmg7XG4gICAgQmggPSBUO1xuICB9XG4gIFQgPSBzdW0zMl8zKHRoaXMuaFsxXSwgQywgRGgpO1xuICB0aGlzLmhbMV0gPSBzdW0zMl8zKHRoaXMuaFsyXSwgRCwgRWgpO1xuICB0aGlzLmhbMl0gPSBzdW0zMl8zKHRoaXMuaFszXSwgRSwgQWgpO1xuICB0aGlzLmhbM10gPSBzdW0zMl8zKHRoaXMuaFs0XSwgQSwgQmgpO1xuICB0aGlzLmhbNF0gPSBzdW0zMl8zKHRoaXMuaFswXSwgQiwgQ2gpO1xuICB0aGlzLmhbMF0gPSBUO1xufTtcblxuUklQRU1EMTYwLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdsaXR0bGUnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2xpdHRsZScpO1xufTtcblxuZnVuY3Rpb24gZihqLCB4LCB5LCB6KSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiB4IF4geSBeIHo7XG4gIGVsc2UgaWYgKGogPD0gMzEpXG4gICAgcmV0dXJuICh4ICYgeSkgfCAoKH54KSAmIHopO1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAoeCB8ICh+eSkpIF4gejtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gKHggJiB6KSB8ICh5ICYgKH56KSk7XG4gIGVsc2VcbiAgICByZXR1cm4geCBeICh5IHwgKH56KSk7XG59XG5cbmZ1bmN0aW9uIEsoaikge1xuICBpZiAoaiA8PSAxNSlcbiAgICByZXR1cm4gMHgwMDAwMDAwMDtcbiAgZWxzZSBpZiAoaiA8PSAzMSlcbiAgICByZXR1cm4gMHg1YTgyNzk5OTtcbiAgZWxzZSBpZiAoaiA8PSA0NylcbiAgICByZXR1cm4gMHg2ZWQ5ZWJhMTtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gMHg4ZjFiYmNkYztcbiAgZWxzZVxuICAgIHJldHVybiAweGE5NTNmZDRlO1xufVxuXG5mdW5jdGlvbiBLaChqKSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiAweDUwYTI4YmU2O1xuICBlbHNlIGlmIChqIDw9IDMxKVxuICAgIHJldHVybiAweDVjNGRkMTI0O1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAweDZkNzAzZWYzO1xuICBlbHNlIGlmIChqIDw9IDYzKVxuICAgIHJldHVybiAweDdhNmQ3NmU5O1xuICBlbHNlXG4gICAgcmV0dXJuIDB4MDAwMDAwMDA7XG59XG5cbnZhciByID0gW1xuICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LFxuICA3LCA0LCAxMywgMSwgMTAsIDYsIDE1LCAzLCAxMiwgMCwgOSwgNSwgMiwgMTQsIDExLCA4LFxuICAzLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyLFxuICAxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyLFxuICA0LCAwLCA1LCA5LCA3LCAxMiwgMiwgMTAsIDE0LCAxLCAzLCA4LCAxMSwgNiwgMTUsIDEzXG5dO1xuXG52YXIgcmggPSBbXG4gIDUsIDE0LCA3LCAwLCA5LCAyLCAxMSwgNCwgMTMsIDYsIDE1LCA4LCAxLCAxMCwgMywgMTIsXG4gIDYsIDExLCAzLCA3LCAwLCAxMywgNSwgMTAsIDE0LCAxNSwgOCwgMTIsIDQsIDksIDEsIDIsXG4gIDE1LCA1LCAxLCAzLCA3LCAxNCwgNiwgOSwgMTEsIDgsIDEyLCAyLCAxMCwgMCwgNCwgMTMsXG4gIDgsIDYsIDQsIDEsIDMsIDExLCAxNSwgMCwgNSwgMTIsIDIsIDEzLCA5LCA3LCAxMCwgMTQsXG4gIDEyLCAxNSwgMTAsIDQsIDEsIDUsIDgsIDcsIDYsIDIsIDEzLCAxNCwgMCwgMywgOSwgMTFcbl07XG5cbnZhciBzID0gW1xuICAxMSwgMTQsIDE1LCAxMiwgNSwgOCwgNywgOSwgMTEsIDEzLCAxNCwgMTUsIDYsIDcsIDksIDgsXG4gIDcsIDYsIDgsIDEzLCAxMSwgOSwgNywgMTUsIDcsIDEyLCAxNSwgOSwgMTEsIDcsIDEzLCAxMixcbiAgMTEsIDEzLCA2LCA3LCAxNCwgOSwgMTMsIDE1LCAxNCwgOCwgMTMsIDYsIDUsIDEyLCA3LCA1LFxuICAxMSwgMTIsIDE0LCAxNSwgMTQsIDE1LCA5LCA4LCA5LCAxNCwgNSwgNiwgOCwgNiwgNSwgMTIsXG4gIDksIDE1LCA1LCAxMSwgNiwgOCwgMTMsIDEyLCA1LCAxMiwgMTMsIDE0LCAxMSwgOCwgNSwgNlxuXTtcblxudmFyIHNoID0gW1xuICA4LCA5LCA5LCAxMSwgMTMsIDE1LCAxNSwgNSwgNywgNywgOCwgMTEsIDE0LCAxNCwgMTIsIDYsXG4gIDksIDEzLCAxNSwgNywgMTIsIDgsIDksIDExLCA3LCA3LCAxMiwgNywgNiwgMTUsIDEzLCAxMSxcbiAgOSwgNywgMTUsIDExLCA4LCA2LCA2LCAxNCwgMTIsIDEzLCA1LCAxNCwgMTMsIDEzLCA3LCA1LFxuICAxNSwgNSwgOCwgMTEsIDE0LCAxNCwgNiwgMTQsIDYsIDksIDEyLCA5LCAxMiwgNSwgMTUsIDgsXG4gIDgsIDUsIDEyLCA5LCAxMiwgNSwgMTQsIDYsIDgsIDEzLCA2LCA1LCAxNSwgMTMsIDExLCAxMVxuXTtcbiIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5zaGExID0gcmVxdWlyZSgnLi9zaGEvMScpO1xuZXhwb3J0cy5zaGEyMjQgPSByZXF1aXJlKCcuL3NoYS8yMjQnKTtcbmV4cG9ydHMuc2hhMjU2ID0gcmVxdWlyZSgnLi9zaGEvMjU2Jyk7XG5leHBvcnRzLnNoYTM4NCA9IHJlcXVpcmUoJy4vc2hhLzM4NCcpO1xuZXhwb3J0cy5zaGE1MTIgPSByZXF1aXJlKCcuL3NoYS81MTInKTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBjb21tb24gPSByZXF1aXJlKCcuLi9jb21tb24nKTtcbnZhciBzaGFDb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xuXG52YXIgcm90bDMyID0gdXRpbHMucm90bDMyO1xudmFyIHN1bTMyID0gdXRpbHMuc3VtMzI7XG52YXIgc3VtMzJfNSA9IHV0aWxzLnN1bTMyXzU7XG52YXIgZnRfMSA9IHNoYUNvbW1vbi5mdF8xO1xudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbnZhciBzaGExX0sgPSBbXG4gIDB4NUE4Mjc5OTksIDB4NkVEOUVCQTEsXG4gIDB4OEYxQkJDREMsIDB4Q0E2MkMxRDZcbl07XG5cbmZ1bmN0aW9uIFNIQTEoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTSEExKSlcbiAgICByZXR1cm4gbmV3IFNIQTEoKTtcblxuICBCbG9ja0hhc2guY2FsbCh0aGlzKTtcbiAgdGhpcy5oID0gW1xuICAgIDB4Njc0NTIzMDEsIDB4ZWZjZGFiODksIDB4OThiYWRjZmUsXG4gICAgMHgxMDMyNTQ3NiwgMHhjM2QyZTFmMCBdO1xuICB0aGlzLlcgPSBuZXcgQXJyYXkoODApO1xufVxuXG51dGlscy5pbmhlcml0cyhTSEExLCBCbG9ja0hhc2gpO1xubW9kdWxlLmV4cG9ydHMgPSBTSEExO1xuXG5TSEExLmJsb2NrU2l6ZSA9IDUxMjtcblNIQTEub3V0U2l6ZSA9IDE2MDtcblNIQTEuaG1hY1N0cmVuZ3RoID0gODA7XG5TSEExLnBhZExlbmd0aCA9IDY0O1xuXG5TSEExLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gX3VwZGF0ZShtc2csIHN0YXJ0KSB7XG4gIHZhciBXID0gdGhpcy5XO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKylcbiAgICBXW2ldID0gbXNnW3N0YXJ0ICsgaV07XG5cbiAgZm9yKDsgaSA8IFcubGVuZ3RoOyBpKyspXG4gICAgV1tpXSA9IHJvdGwzMihXW2kgLSAzXSBeIFdbaSAtIDhdIF4gV1tpIC0gMTRdIF4gV1tpIC0gMTZdLCAxKTtcblxuICB2YXIgYSA9IHRoaXMuaFswXTtcbiAgdmFyIGIgPSB0aGlzLmhbMV07XG4gIHZhciBjID0gdGhpcy5oWzJdO1xuICB2YXIgZCA9IHRoaXMuaFszXTtcbiAgdmFyIGUgPSB0aGlzLmhbNF07XG5cbiAgZm9yIChpID0gMDsgaSA8IFcubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcyA9IH5+KGkgLyAyMCk7XG4gICAgdmFyIHQgPSBzdW0zMl81KHJvdGwzMihhLCA1KSwgZnRfMShzLCBiLCBjLCBkKSwgZSwgV1tpXSwgc2hhMV9LW3NdKTtcbiAgICBlID0gZDtcbiAgICBkID0gYztcbiAgICBjID0gcm90bDMyKGIsIDMwKTtcbiAgICBiID0gYTtcbiAgICBhID0gdDtcbiAgfVxuXG4gIHRoaXMuaFswXSA9IHN1bTMyKHRoaXMuaFswXSwgYSk7XG4gIHRoaXMuaFsxXSA9IHN1bTMyKHRoaXMuaFsxXSwgYik7XG4gIHRoaXMuaFsyXSA9IHN1bTMyKHRoaXMuaFsyXSwgYyk7XG4gIHRoaXMuaFszXSA9IHN1bTMyKHRoaXMuaFszXSwgZCk7XG4gIHRoaXMuaFs0XSA9IHN1bTMyKHRoaXMuaFs0XSwgZSk7XG59O1xuXG5TSEExLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2JpZycpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBTSEEyNTYgPSByZXF1aXJlKCcuLzI1NicpO1xuXG5mdW5jdGlvbiBTSEEyMjQoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTSEEyMjQpKVxuICAgIHJldHVybiBuZXcgU0hBMjI0KCk7XG5cbiAgU0hBMjU2LmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFtcbiAgICAweGMxMDU5ZWQ4LCAweDM2N2NkNTA3LCAweDMwNzBkZDE3LCAweGY3MGU1OTM5LFxuICAgIDB4ZmZjMDBiMzEsIDB4Njg1ODE1MTEsIDB4NjRmOThmYTcsIDB4YmVmYTRmYTQgXTtcbn1cbnV0aWxzLmluaGVyaXRzKFNIQTIyNCwgU0hBMjU2KTtcbm1vZHVsZS5leHBvcnRzID0gU0hBMjI0O1xuXG5TSEEyMjQuYmxvY2tTaXplID0gNTEyO1xuU0hBMjI0Lm91dFNpemUgPSAyMjQ7XG5TSEEyMjQuaG1hY1N0cmVuZ3RoID0gMTkyO1xuU0hBMjI0LnBhZExlbmd0aCA9IDY0O1xuXG5TSEEyMjQucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIC8vIEp1c3QgdHJ1bmNhdGUgb3V0cHV0XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaC5zbGljZSgwLCA3KSwgJ2JpZycpO1xuICBlbHNlXG4gICAgcmV0dXJuIHV0aWxzLnNwbGl0MzIodGhpcy5oLnNsaWNlKDAsIDcpLCAnYmlnJyk7XG59O1xuXG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi4vY29tbW9uJyk7XG52YXIgc2hhQ29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBhc3NlcnQgPSByZXF1aXJlKCdtaW5pbWFsaXN0aWMtYXNzZXJ0Jyk7XG5cbnZhciBzdW0zMiA9IHV0aWxzLnN1bTMyO1xudmFyIHN1bTMyXzQgPSB1dGlscy5zdW0zMl80O1xudmFyIHN1bTMyXzUgPSB1dGlscy5zdW0zMl81O1xudmFyIGNoMzIgPSBzaGFDb21tb24uY2gzMjtcbnZhciBtYWozMiA9IHNoYUNvbW1vbi5tYWozMjtcbnZhciBzMF8yNTYgPSBzaGFDb21tb24uczBfMjU2O1xudmFyIHMxXzI1NiA9IHNoYUNvbW1vbi5zMV8yNTY7XG52YXIgZzBfMjU2ID0gc2hhQ29tbW9uLmcwXzI1NjtcbnZhciBnMV8yNTYgPSBzaGFDb21tb24uZzFfMjU2O1xuXG52YXIgQmxvY2tIYXNoID0gY29tbW9uLkJsb2NrSGFzaDtcblxudmFyIHNoYTI1Nl9LID0gW1xuICAweDQyOGEyZjk4LCAweDcxMzc0NDkxLCAweGI1YzBmYmNmLCAweGU5YjVkYmE1LFxuICAweDM5NTZjMjViLCAweDU5ZjExMWYxLCAweDkyM2Y4MmE0LCAweGFiMWM1ZWQ1LFxuICAweGQ4MDdhYTk4LCAweDEyODM1YjAxLCAweDI0MzE4NWJlLCAweDU1MGM3ZGMzLFxuICAweDcyYmU1ZDc0LCAweDgwZGViMWZlLCAweDliZGMwNmE3LCAweGMxOWJmMTc0LFxuICAweGU0OWI2OWMxLCAweGVmYmU0Nzg2LCAweDBmYzE5ZGM2LCAweDI0MGNhMWNjLFxuICAweDJkZTkyYzZmLCAweDRhNzQ4NGFhLCAweDVjYjBhOWRjLCAweDc2Zjk4OGRhLFxuICAweDk4M2U1MTUyLCAweGE4MzFjNjZkLCAweGIwMDMyN2M4LCAweGJmNTk3ZmM3LFxuICAweGM2ZTAwYmYzLCAweGQ1YTc5MTQ3LCAweDA2Y2E2MzUxLCAweDE0MjkyOTY3LFxuICAweDI3YjcwYTg1LCAweDJlMWIyMTM4LCAweDRkMmM2ZGZjLCAweDUzMzgwZDEzLFxuICAweDY1MGE3MzU0LCAweDc2NmEwYWJiLCAweDgxYzJjOTJlLCAweDkyNzIyYzg1LFxuICAweGEyYmZlOGExLCAweGE4MWE2NjRiLCAweGMyNGI4YjcwLCAweGM3NmM1MWEzLFxuICAweGQxOTJlODE5LCAweGQ2OTkwNjI0LCAweGY0MGUzNTg1LCAweDEwNmFhMDcwLFxuICAweDE5YTRjMTE2LCAweDFlMzc2YzA4LCAweDI3NDg3NzRjLCAweDM0YjBiY2I1LFxuICAweDM5MWMwY2IzLCAweDRlZDhhYTRhLCAweDViOWNjYTRmLCAweDY4MmU2ZmYzLFxuICAweDc0OGY4MmVlLCAweDc4YTU2MzZmLCAweDg0Yzg3ODE0LCAweDhjYzcwMjA4LFxuICAweDkwYmVmZmZhLCAweGE0NTA2Y2ViLCAweGJlZjlhM2Y3LCAweGM2NzE3OGYyXG5dO1xuXG5mdW5jdGlvbiBTSEEyNTYoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTSEEyNTYpKVxuICAgIHJldHVybiBuZXcgU0hBMjU2KCk7XG5cbiAgQmxvY2tIYXNoLmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFtcbiAgICAweDZhMDllNjY3LCAweGJiNjdhZTg1LCAweDNjNmVmMzcyLCAweGE1NGZmNTNhLFxuICAgIDB4NTEwZTUyN2YsIDB4OWIwNTY4OGMsIDB4MWY4M2Q5YWIsIDB4NWJlMGNkMTlcbiAgXTtcbiAgdGhpcy5rID0gc2hhMjU2X0s7XG4gIHRoaXMuVyA9IG5ldyBBcnJheSg2NCk7XG59XG51dGlscy5pbmhlcml0cyhTSEEyNTYsIEJsb2NrSGFzaCk7XG5tb2R1bGUuZXhwb3J0cyA9IFNIQTI1NjtcblxuU0hBMjU2LmJsb2NrU2l6ZSA9IDUxMjtcblNIQTI1Ni5vdXRTaXplID0gMjU2O1xuU0hBMjU2LmhtYWNTdHJlbmd0aCA9IDE5MjtcblNIQTI1Ni5wYWRMZW5ndGggPSA2NDtcblxuU0hBMjU2LnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gX3VwZGF0ZShtc2csIHN0YXJ0KSB7XG4gIHZhciBXID0gdGhpcy5XO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKylcbiAgICBXW2ldID0gbXNnW3N0YXJ0ICsgaV07XG4gIGZvciAoOyBpIDwgVy5sZW5ndGg7IGkrKylcbiAgICBXW2ldID0gc3VtMzJfNChnMV8yNTYoV1tpIC0gMl0pLCBXW2kgLSA3XSwgZzBfMjU2KFdbaSAtIDE1XSksIFdbaSAtIDE2XSk7XG5cbiAgdmFyIGEgPSB0aGlzLmhbMF07XG4gIHZhciBiID0gdGhpcy5oWzFdO1xuICB2YXIgYyA9IHRoaXMuaFsyXTtcbiAgdmFyIGQgPSB0aGlzLmhbM107XG4gIHZhciBlID0gdGhpcy5oWzRdO1xuICB2YXIgZiA9IHRoaXMuaFs1XTtcbiAgdmFyIGcgPSB0aGlzLmhbNl07XG4gIHZhciBoID0gdGhpcy5oWzddO1xuXG4gIGFzc2VydCh0aGlzLmsubGVuZ3RoID09PSBXLmxlbmd0aCk7XG4gIGZvciAoaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIFQxID0gc3VtMzJfNShoLCBzMV8yNTYoZSksIGNoMzIoZSwgZiwgZyksIHRoaXMua1tpXSwgV1tpXSk7XG4gICAgdmFyIFQyID0gc3VtMzIoczBfMjU2KGEpLCBtYWozMihhLCBiLCBjKSk7XG4gICAgaCA9IGc7XG4gICAgZyA9IGY7XG4gICAgZiA9IGU7XG4gICAgZSA9IHN1bTMyKGQsIFQxKTtcbiAgICBkID0gYztcbiAgICBjID0gYjtcbiAgICBiID0gYTtcbiAgICBhID0gc3VtMzIoVDEsIFQyKTtcbiAgfVxuXG4gIHRoaXMuaFswXSA9IHN1bTMyKHRoaXMuaFswXSwgYSk7XG4gIHRoaXMuaFsxXSA9IHN1bTMyKHRoaXMuaFsxXSwgYik7XG4gIHRoaXMuaFsyXSA9IHN1bTMyKHRoaXMuaFsyXSwgYyk7XG4gIHRoaXMuaFszXSA9IHN1bTMyKHRoaXMuaFszXSwgZCk7XG4gIHRoaXMuaFs0XSA9IHN1bTMyKHRoaXMuaFs0XSwgZSk7XG4gIHRoaXMuaFs1XSA9IHN1bTMyKHRoaXMuaFs1XSwgZik7XG4gIHRoaXMuaFs2XSA9IHN1bTMyKHRoaXMuaFs2XSwgZyk7XG4gIHRoaXMuaFs3XSA9IHN1bTMyKHRoaXMuaFs3XSwgaCk7XG59O1xuXG5TSEEyNTYucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaCwgJ2JpZycpO1xuICBlbHNlXG4gICAgcmV0dXJuIHV0aWxzLnNwbGl0MzIodGhpcy5oLCAnYmlnJyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xuXG52YXIgU0hBNTEyID0gcmVxdWlyZSgnLi81MTInKTtcblxuZnVuY3Rpb24gU0hBMzg0KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMzg0KSlcbiAgICByZXR1cm4gbmV3IFNIQTM4NCgpO1xuXG4gIFNIQTUxMi5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHhjYmJiOWQ1ZCwgMHhjMTA1OWVkOCxcbiAgICAweDYyOWEyOTJhLCAweDM2N2NkNTA3LFxuICAgIDB4OTE1OTAxNWEsIDB4MzA3MGRkMTcsXG4gICAgMHgxNTJmZWNkOCwgMHhmNzBlNTkzOSxcbiAgICAweDY3MzMyNjY3LCAweGZmYzAwYjMxLFxuICAgIDB4OGViNDRhODcsIDB4Njg1ODE1MTEsXG4gICAgMHhkYjBjMmUwZCwgMHg2NGY5OGZhNyxcbiAgICAweDQ3YjU0ODFkLCAweGJlZmE0ZmE0IF07XG59XG51dGlscy5pbmhlcml0cyhTSEEzODQsIFNIQTUxMik7XG5tb2R1bGUuZXhwb3J0cyA9IFNIQTM4NDtcblxuU0hBMzg0LmJsb2NrU2l6ZSA9IDEwMjQ7XG5TSEEzODQub3V0U2l6ZSA9IDM4NDtcblNIQTM4NC5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEEzODQucGFkTGVuZ3RoID0gMTI4O1xuXG5TSEEzODQucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaC5zbGljZSgwLCAxMiksICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaC5zbGljZSgwLCAxMiksICdiaWcnKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi4vY29tbW9uJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG52YXIgcm90cjY0X2hpID0gdXRpbHMucm90cjY0X2hpO1xudmFyIHJvdHI2NF9sbyA9IHV0aWxzLnJvdHI2NF9sbztcbnZhciBzaHI2NF9oaSA9IHV0aWxzLnNocjY0X2hpO1xudmFyIHNocjY0X2xvID0gdXRpbHMuc2hyNjRfbG87XG52YXIgc3VtNjQgPSB1dGlscy5zdW02NDtcbnZhciBzdW02NF9oaSA9IHV0aWxzLnN1bTY0X2hpO1xudmFyIHN1bTY0X2xvID0gdXRpbHMuc3VtNjRfbG87XG52YXIgc3VtNjRfNF9oaSA9IHV0aWxzLnN1bTY0XzRfaGk7XG52YXIgc3VtNjRfNF9sbyA9IHV0aWxzLnN1bTY0XzRfbG87XG52YXIgc3VtNjRfNV9oaSA9IHV0aWxzLnN1bTY0XzVfaGk7XG52YXIgc3VtNjRfNV9sbyA9IHV0aWxzLnN1bTY0XzVfbG87XG5cbnZhciBCbG9ja0hhc2ggPSBjb21tb24uQmxvY2tIYXNoO1xuXG52YXIgc2hhNTEyX0sgPSBbXG4gIDB4NDI4YTJmOTgsIDB4ZDcyOGFlMjIsIDB4NzEzNzQ0OTEsIDB4MjNlZjY1Y2QsXG4gIDB4YjVjMGZiY2YsIDB4ZWM0ZDNiMmYsIDB4ZTliNWRiYTUsIDB4ODE4OWRiYmMsXG4gIDB4Mzk1NmMyNWIsIDB4ZjM0OGI1MzgsIDB4NTlmMTExZjEsIDB4YjYwNWQwMTksXG4gIDB4OTIzZjgyYTQsIDB4YWYxOTRmOWIsIDB4YWIxYzVlZDUsIDB4ZGE2ZDgxMTgsXG4gIDB4ZDgwN2FhOTgsIDB4YTMwMzAyNDIsIDB4MTI4MzViMDEsIDB4NDU3MDZmYmUsXG4gIDB4MjQzMTg1YmUsIDB4NGVlNGIyOGMsIDB4NTUwYzdkYzMsIDB4ZDVmZmI0ZTIsXG4gIDB4NzJiZTVkNzQsIDB4ZjI3Yjg5NmYsIDB4ODBkZWIxZmUsIDB4M2IxNjk2YjEsXG4gIDB4OWJkYzA2YTcsIDB4MjVjNzEyMzUsIDB4YzE5YmYxNzQsIDB4Y2Y2OTI2OTQsXG4gIDB4ZTQ5YjY5YzEsIDB4OWVmMTRhZDIsIDB4ZWZiZTQ3ODYsIDB4Mzg0ZjI1ZTMsXG4gIDB4MGZjMTlkYzYsIDB4OGI4Y2Q1YjUsIDB4MjQwY2ExY2MsIDB4NzdhYzljNjUsXG4gIDB4MmRlOTJjNmYsIDB4NTkyYjAyNzUsIDB4NGE3NDg0YWEsIDB4NmVhNmU0ODMsXG4gIDB4NWNiMGE5ZGMsIDB4YmQ0MWZiZDQsIDB4NzZmOTg4ZGEsIDB4ODMxMTUzYjUsXG4gIDB4OTgzZTUxNTIsIDB4ZWU2NmRmYWIsIDB4YTgzMWM2NmQsIDB4MmRiNDMyMTAsXG4gIDB4YjAwMzI3YzgsIDB4OThmYjIxM2YsIDB4YmY1OTdmYzcsIDB4YmVlZjBlZTQsXG4gIDB4YzZlMDBiZjMsIDB4M2RhODhmYzIsIDB4ZDVhNzkxNDcsIDB4OTMwYWE3MjUsXG4gIDB4MDZjYTYzNTEsIDB4ZTAwMzgyNmYsIDB4MTQyOTI5NjcsIDB4MGEwZTZlNzAsXG4gIDB4MjdiNzBhODUsIDB4NDZkMjJmZmMsIDB4MmUxYjIxMzgsIDB4NWMyNmM5MjYsXG4gIDB4NGQyYzZkZmMsIDB4NWFjNDJhZWQsIDB4NTMzODBkMTMsIDB4OWQ5NWIzZGYsXG4gIDB4NjUwYTczNTQsIDB4OGJhZjYzZGUsIDB4NzY2YTBhYmIsIDB4M2M3N2IyYTgsXG4gIDB4ODFjMmM5MmUsIDB4NDdlZGFlZTYsIDB4OTI3MjJjODUsIDB4MTQ4MjM1M2IsXG4gIDB4YTJiZmU4YTEsIDB4NGNmMTAzNjQsIDB4YTgxYTY2NGIsIDB4YmM0MjMwMDEsXG4gIDB4YzI0YjhiNzAsIDB4ZDBmODk3OTEsIDB4Yzc2YzUxYTMsIDB4MDY1NGJlMzAsXG4gIDB4ZDE5MmU4MTksIDB4ZDZlZjUyMTgsIDB4ZDY5OTA2MjQsIDB4NTU2NWE5MTAsXG4gIDB4ZjQwZTM1ODUsIDB4NTc3MTIwMmEsIDB4MTA2YWEwNzAsIDB4MzJiYmQxYjgsXG4gIDB4MTlhNGMxMTYsIDB4YjhkMmQwYzgsIDB4MWUzNzZjMDgsIDB4NTE0MWFiNTMsXG4gIDB4Mjc0ODc3NGMsIDB4ZGY4ZWViOTksIDB4MzRiMGJjYjUsIDB4ZTE5YjQ4YTgsXG4gIDB4MzkxYzBjYjMsIDB4YzVjOTVhNjMsIDB4NGVkOGFhNGEsIDB4ZTM0MThhY2IsXG4gIDB4NWI5Y2NhNGYsIDB4Nzc2M2UzNzMsIDB4NjgyZTZmZjMsIDB4ZDZiMmI4YTMsXG4gIDB4NzQ4ZjgyZWUsIDB4NWRlZmIyZmMsIDB4NzhhNTYzNmYsIDB4NDMxNzJmNjAsXG4gIDB4ODRjODc4MTQsIDB4YTFmMGFiNzIsIDB4OGNjNzAyMDgsIDB4MWE2NDM5ZWMsXG4gIDB4OTBiZWZmZmEsIDB4MjM2MzFlMjgsIDB4YTQ1MDZjZWIsIDB4ZGU4MmJkZTksXG4gIDB4YmVmOWEzZjcsIDB4YjJjNjc5MTUsIDB4YzY3MTc4ZjIsIDB4ZTM3MjUzMmIsXG4gIDB4Y2EyNzNlY2UsIDB4ZWEyNjYxOWMsIDB4ZDE4NmI4YzcsIDB4MjFjMGMyMDcsXG4gIDB4ZWFkYTdkZDYsIDB4Y2RlMGViMWUsIDB4ZjU3ZDRmN2YsIDB4ZWU2ZWQxNzgsXG4gIDB4MDZmMDY3YWEsIDB4NzIxNzZmYmEsIDB4MGE2MzdkYzUsIDB4YTJjODk4YTYsXG4gIDB4MTEzZjk4MDQsIDB4YmVmOTBkYWUsIDB4MWI3MTBiMzUsIDB4MTMxYzQ3MWIsXG4gIDB4MjhkYjc3ZjUsIDB4MjMwNDdkODQsIDB4MzJjYWFiN2IsIDB4NDBjNzI0OTMsXG4gIDB4M2M5ZWJlMGEsIDB4MTVjOWJlYmMsIDB4NDMxZDY3YzQsIDB4OWMxMDBkNGMsXG4gIDB4NGNjNWQ0YmUsIDB4Y2IzZTQyYjYsIDB4NTk3ZjI5OWMsIDB4ZmM2NTdlMmEsXG4gIDB4NWZjYjZmYWIsIDB4M2FkNmZhZWMsIDB4NmM0NDE5OGMsIDB4NGE0NzU4MTdcbl07XG5cbmZ1bmN0aW9uIFNIQTUxMigpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNIQTUxMikpXG4gICAgcmV0dXJuIG5ldyBTSEE1MTIoKTtcblxuICBCbG9ja0hhc2guY2FsbCh0aGlzKTtcbiAgdGhpcy5oID0gW1xuICAgIDB4NmEwOWU2NjcsIDB4ZjNiY2M5MDgsXG4gICAgMHhiYjY3YWU4NSwgMHg4NGNhYTczYixcbiAgICAweDNjNmVmMzcyLCAweGZlOTRmODJiLFxuICAgIDB4YTU0ZmY1M2EsIDB4NWYxZDM2ZjEsXG4gICAgMHg1MTBlNTI3ZiwgMHhhZGU2ODJkMSxcbiAgICAweDliMDU2ODhjLCAweDJiM2U2YzFmLFxuICAgIDB4MWY4M2Q5YWIsIDB4ZmI0MWJkNmIsXG4gICAgMHg1YmUwY2QxOSwgMHgxMzdlMjE3OSBdO1xuICB0aGlzLmsgPSBzaGE1MTJfSztcbiAgdGhpcy5XID0gbmV3IEFycmF5KDE2MCk7XG59XG51dGlscy5pbmhlcml0cyhTSEE1MTIsIEJsb2NrSGFzaCk7XG5tb2R1bGUuZXhwb3J0cyA9IFNIQTUxMjtcblxuU0hBNTEyLmJsb2NrU2l6ZSA9IDEwMjQ7XG5TSEE1MTIub3V0U2l6ZSA9IDUxMjtcblNIQTUxMi5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEE1MTIucGFkTGVuZ3RoID0gMTI4O1xuXG5TSEE1MTIucHJvdG90eXBlLl9wcmVwYXJlQmxvY2sgPSBmdW5jdGlvbiBfcHJlcGFyZUJsb2NrKG1zZywgc3RhcnQpIHtcbiAgdmFyIFcgPSB0aGlzLlc7XG5cbiAgLy8gMzIgeCAzMmJpdCB3b3Jkc1xuICBmb3IgKHZhciBpID0gMDsgaSA8IDMyOyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuICBmb3IgKDsgaSA8IFcubGVuZ3RoOyBpICs9IDIpIHtcbiAgICB2YXIgYzBfaGkgPSBnMV81MTJfaGkoV1tpIC0gNF0sIFdbaSAtIDNdKTsgIC8vIGkgLSAyXG4gICAgdmFyIGMwX2xvID0gZzFfNTEyX2xvKFdbaSAtIDRdLCBXW2kgLSAzXSk7XG4gICAgdmFyIGMxX2hpID0gV1tpIC0gMTRdOyAgLy8gaSAtIDdcbiAgICB2YXIgYzFfbG8gPSBXW2kgLSAxM107XG4gICAgdmFyIGMyX2hpID0gZzBfNTEyX2hpKFdbaSAtIDMwXSwgV1tpIC0gMjldKTsgIC8vIGkgLSAxNVxuICAgIHZhciBjMl9sbyA9IGcwXzUxMl9sbyhXW2kgLSAzMF0sIFdbaSAtIDI5XSk7XG4gICAgdmFyIGMzX2hpID0gV1tpIC0gMzJdOyAgLy8gaSAtIDE2XG4gICAgdmFyIGMzX2xvID0gV1tpIC0gMzFdO1xuXG4gICAgV1tpXSA9IHN1bTY0XzRfaGkoXG4gICAgICBjMF9oaSwgYzBfbG8sXG4gICAgICBjMV9oaSwgYzFfbG8sXG4gICAgICBjMl9oaSwgYzJfbG8sXG4gICAgICBjM19oaSwgYzNfbG8pO1xuICAgIFdbaSArIDFdID0gc3VtNjRfNF9sbyhcbiAgICAgIGMwX2hpLCBjMF9sbyxcbiAgICAgIGMxX2hpLCBjMV9sbyxcbiAgICAgIGMyX2hpLCBjMl9sbyxcbiAgICAgIGMzX2hpLCBjM19sbyk7XG4gIH1cbn07XG5cblNIQTUxMi5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUobXNnLCBzdGFydCkge1xuICB0aGlzLl9wcmVwYXJlQmxvY2sobXNnLCBzdGFydCk7XG5cbiAgdmFyIFcgPSB0aGlzLlc7XG5cbiAgdmFyIGFoID0gdGhpcy5oWzBdO1xuICB2YXIgYWwgPSB0aGlzLmhbMV07XG4gIHZhciBiaCA9IHRoaXMuaFsyXTtcbiAgdmFyIGJsID0gdGhpcy5oWzNdO1xuICB2YXIgY2ggPSB0aGlzLmhbNF07XG4gIHZhciBjbCA9IHRoaXMuaFs1XTtcbiAgdmFyIGRoID0gdGhpcy5oWzZdO1xuICB2YXIgZGwgPSB0aGlzLmhbN107XG4gIHZhciBlaCA9IHRoaXMuaFs4XTtcbiAgdmFyIGVsID0gdGhpcy5oWzldO1xuICB2YXIgZmggPSB0aGlzLmhbMTBdO1xuICB2YXIgZmwgPSB0aGlzLmhbMTFdO1xuICB2YXIgZ2ggPSB0aGlzLmhbMTJdO1xuICB2YXIgZ2wgPSB0aGlzLmhbMTNdO1xuICB2YXIgaGggPSB0aGlzLmhbMTRdO1xuICB2YXIgaGwgPSB0aGlzLmhbMTVdO1xuXG4gIGFzc2VydCh0aGlzLmsubGVuZ3RoID09PSBXLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgVy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHZhciBjMF9oaSA9IGhoO1xuICAgIHZhciBjMF9sbyA9IGhsO1xuICAgIHZhciBjMV9oaSA9IHMxXzUxMl9oaShlaCwgZWwpO1xuICAgIHZhciBjMV9sbyA9IHMxXzUxMl9sbyhlaCwgZWwpO1xuICAgIHZhciBjMl9oaSA9IGNoNjRfaGkoZWgsIGVsLCBmaCwgZmwsIGdoLCBnbCk7XG4gICAgdmFyIGMyX2xvID0gY2g2NF9sbyhlaCwgZWwsIGZoLCBmbCwgZ2gsIGdsKTtcbiAgICB2YXIgYzNfaGkgPSB0aGlzLmtbaV07XG4gICAgdmFyIGMzX2xvID0gdGhpcy5rW2kgKyAxXTtcbiAgICB2YXIgYzRfaGkgPSBXW2ldO1xuICAgIHZhciBjNF9sbyA9IFdbaSArIDFdO1xuXG4gICAgdmFyIFQxX2hpID0gc3VtNjRfNV9oaShcbiAgICAgIGMwX2hpLCBjMF9sbyxcbiAgICAgIGMxX2hpLCBjMV9sbyxcbiAgICAgIGMyX2hpLCBjMl9sbyxcbiAgICAgIGMzX2hpLCBjM19sbyxcbiAgICAgIGM0X2hpLCBjNF9sbyk7XG4gICAgdmFyIFQxX2xvID0gc3VtNjRfNV9sbyhcbiAgICAgIGMwX2hpLCBjMF9sbyxcbiAgICAgIGMxX2hpLCBjMV9sbyxcbiAgICAgIGMyX2hpLCBjMl9sbyxcbiAgICAgIGMzX2hpLCBjM19sbyxcbiAgICAgIGM0X2hpLCBjNF9sbyk7XG5cbiAgICBjMF9oaSA9IHMwXzUxMl9oaShhaCwgYWwpO1xuICAgIGMwX2xvID0gczBfNTEyX2xvKGFoLCBhbCk7XG4gICAgYzFfaGkgPSBtYWo2NF9oaShhaCwgYWwsIGJoLCBibCwgY2gsIGNsKTtcbiAgICBjMV9sbyA9IG1hajY0X2xvKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wpO1xuXG4gICAgdmFyIFQyX2hpID0gc3VtNjRfaGkoYzBfaGksIGMwX2xvLCBjMV9oaSwgYzFfbG8pO1xuICAgIHZhciBUMl9sbyA9IHN1bTY0X2xvKGMwX2hpLCBjMF9sbywgYzFfaGksIGMxX2xvKTtcblxuICAgIGhoID0gZ2g7XG4gICAgaGwgPSBnbDtcblxuICAgIGdoID0gZmg7XG4gICAgZ2wgPSBmbDtcblxuICAgIGZoID0gZWg7XG4gICAgZmwgPSBlbDtcblxuICAgIGVoID0gc3VtNjRfaGkoZGgsIGRsLCBUMV9oaSwgVDFfbG8pO1xuICAgIGVsID0gc3VtNjRfbG8oZGwsIGRsLCBUMV9oaSwgVDFfbG8pO1xuXG4gICAgZGggPSBjaDtcbiAgICBkbCA9IGNsO1xuXG4gICAgY2ggPSBiaDtcbiAgICBjbCA9IGJsO1xuXG4gICAgYmggPSBhaDtcbiAgICBibCA9IGFsO1xuXG4gICAgYWggPSBzdW02NF9oaShUMV9oaSwgVDFfbG8sIFQyX2hpLCBUMl9sbyk7XG4gICAgYWwgPSBzdW02NF9sbyhUMV9oaSwgVDFfbG8sIFQyX2hpLCBUMl9sbyk7XG4gIH1cblxuICBzdW02NCh0aGlzLmgsIDAsIGFoLCBhbCk7XG4gIHN1bTY0KHRoaXMuaCwgMiwgYmgsIGJsKTtcbiAgc3VtNjQodGhpcy5oLCA0LCBjaCwgY2wpO1xuICBzdW02NCh0aGlzLmgsIDYsIGRoLCBkbCk7XG4gIHN1bTY0KHRoaXMuaCwgOCwgZWgsIGVsKTtcbiAgc3VtNjQodGhpcy5oLCAxMCwgZmgsIGZsKTtcbiAgc3VtNjQodGhpcy5oLCAxMiwgZ2gsIGdsKTtcbiAgc3VtNjQodGhpcy5oLCAxNCwgaGgsIGhsKTtcbn07XG5cblNIQTUxMi5wcm90b3R5cGUuX2RpZ2VzdCA9IGZ1bmN0aW9uIGRpZ2VzdChlbmMpIHtcbiAgaWYgKGVuYyA9PT0gJ2hleCcpXG4gICAgcmV0dXJuIHV0aWxzLnRvSGV4MzIodGhpcy5oLCAnYmlnJyk7XG4gIGVsc2VcbiAgICByZXR1cm4gdXRpbHMuc3BsaXQzMih0aGlzLmgsICdiaWcnKTtcbn07XG5cbmZ1bmN0aW9uIGNoNjRfaGkoeGgsIHhsLCB5aCwgeWwsIHpoKSB7XG4gIHZhciByID0gKHhoICYgeWgpIF4gKCh+eGgpICYgemgpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIGNoNjRfbG8oeGgsIHhsLCB5aCwgeWwsIHpoLCB6bCkge1xuICB2YXIgciA9ICh4bCAmIHlsKSBeICgofnhsKSAmIHpsKTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBtYWo2NF9oaSh4aCwgeGwsIHloLCB5bCwgemgpIHtcbiAgdmFyIHIgPSAoeGggJiB5aCkgXiAoeGggJiB6aCkgXiAoeWggJiB6aCk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gbWFqNjRfbG8oeGgsIHhsLCB5aCwgeWwsIHpoLCB6bCkge1xuICB2YXIgciA9ICh4bCAmIHlsKSBeICh4bCAmIHpsKSBeICh5bCAmIHpsKTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBzMF81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDI4KTtcbiAgdmFyIGMxX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgMik7ICAvLyAzNFxuICB2YXIgYzJfaGkgPSByb3RyNjRfaGkoeGwsIHhoLCA3KTsgIC8vIDM5XG5cbiAgdmFyIHIgPSBjMF9oaSBeIGMxX2hpIF4gYzJfaGk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gczBfNTEyX2xvKHhoLCB4bCkge1xuICB2YXIgYzBfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCAyOCk7XG4gIHZhciBjMV9sbyA9IHJvdHI2NF9sbyh4bCwgeGgsIDIpOyAgLy8gMzRcbiAgdmFyIGMyX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgNyk7ICAvLyAzOVxuXG4gIHZhciByID0gYzBfbG8gXiBjMV9sbyBeIGMyX2xvO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMxXzUxMl9oaSh4aCwgeGwpIHtcbiAgdmFyIGMwX2hpID0gcm90cjY0X2hpKHhoLCB4bCwgMTQpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCAxOCk7XG4gIHZhciBjMl9oaSA9IHJvdHI2NF9oaSh4bCwgeGgsIDkpOyAgLy8gNDFcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBzMV81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDE0KTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhoLCB4bCwgMTgpO1xuICB2YXIgYzJfbG8gPSByb3RyNjRfbG8oeGwsIHhoLCA5KTsgIC8vIDQxXG5cbiAgdmFyIHIgPSBjMF9sbyBeIGMxX2xvIF4gYzJfbG87XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gZzBfNTEyX2hpKHhoLCB4bCkge1xuICB2YXIgYzBfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCAxKTtcbiAgdmFyIGMxX2hpID0gcm90cjY0X2hpKHhoLCB4bCwgOCk7XG4gIHZhciBjMl9oaSA9IHNocjY0X2hpKHhoLCB4bCwgNyk7XG5cbiAgdmFyIHIgPSBjMF9oaSBeIGMxX2hpIF4gYzJfaGk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gZzBfNTEyX2xvKHhoLCB4bCkge1xuICB2YXIgYzBfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCAxKTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhoLCB4bCwgOCk7XG4gIHZhciBjMl9sbyA9IHNocjY0X2xvKHhoLCB4bCwgNyk7XG5cbiAgdmFyIHIgPSBjMF9sbyBeIGMxX2xvIF4gYzJfbG87XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gZzFfNTEyX2hpKHhoLCB4bCkge1xuICB2YXIgYzBfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCAxOSk7XG4gIHZhciBjMV9oaSA9IHJvdHI2NF9oaSh4bCwgeGgsIDI5KTsgIC8vIDYxXG4gIHZhciBjMl9oaSA9IHNocjY0X2hpKHhoLCB4bCwgNik7XG5cbiAgdmFyIHIgPSBjMF9oaSBeIGMxX2hpIF4gYzJfaGk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gZzFfNTEyX2xvKHhoLCB4bCkge1xuICB2YXIgYzBfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCAxOSk7XG4gIHZhciBjMV9sbyA9IHJvdHI2NF9sbyh4bCwgeGgsIDI5KTsgIC8vIDYxXG4gIHZhciBjMl9sbyA9IHNocjY0X2xvKHhoLCB4bCwgNik7XG5cbiAgdmFyIHIgPSBjMF9sbyBeIGMxX2xvIF4gYzJfbG87XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciByb3RyMzIgPSB1dGlscy5yb3RyMzI7XG5cbmZ1bmN0aW9uIGZ0XzEocywgeCwgeSwgeikge1xuICBpZiAocyA9PT0gMClcbiAgICByZXR1cm4gY2gzMih4LCB5LCB6KTtcbiAgaWYgKHMgPT09IDEgfHwgcyA9PT0gMylcbiAgICByZXR1cm4gcDMyKHgsIHksIHopO1xuICBpZiAocyA9PT0gMilcbiAgICByZXR1cm4gbWFqMzIoeCwgeSwgeik7XG59XG5leHBvcnRzLmZ0XzEgPSBmdF8xO1xuXG5mdW5jdGlvbiBjaDMyKHgsIHksIHopIHtcbiAgcmV0dXJuICh4ICYgeSkgXiAoKH54KSAmIHopO1xufVxuZXhwb3J0cy5jaDMyID0gY2gzMjtcblxuZnVuY3Rpb24gbWFqMzIoeCwgeSwgeikge1xuICByZXR1cm4gKHggJiB5KSBeICh4ICYgeikgXiAoeSAmIHopO1xufVxuZXhwb3J0cy5tYWozMiA9IG1hajMyO1xuXG5mdW5jdGlvbiBwMzIoeCwgeSwgeikge1xuICByZXR1cm4geCBeIHkgXiB6O1xufVxuZXhwb3J0cy5wMzIgPSBwMzI7XG5cbmZ1bmN0aW9uIHMwXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgMikgXiByb3RyMzIoeCwgMTMpIF4gcm90cjMyKHgsIDIyKTtcbn1cbmV4cG9ydHMuczBfMjU2ID0gczBfMjU2O1xuXG5mdW5jdGlvbiBzMV8yNTYoeCkge1xuICByZXR1cm4gcm90cjMyKHgsIDYpIF4gcm90cjMyKHgsIDExKSBeIHJvdHIzMih4LCAyNSk7XG59XG5leHBvcnRzLnMxXzI1NiA9IHMxXzI1NjtcblxuZnVuY3Rpb24gZzBfMjU2KHgpIHtcbiAgcmV0dXJuIHJvdHIzMih4LCA3KSBeIHJvdHIzMih4LCAxOCkgXiAoeCA+Pj4gMyk7XG59XG5leHBvcnRzLmcwXzI1NiA9IGcwXzI1NjtcblxuZnVuY3Rpb24gZzFfMjU2KHgpIHtcbiAgcmV0dXJuIHJvdHIzMih4LCAxNykgXiByb3RyMzIoeCwgMTkpIF4gKHggPj4+IDEwKTtcbn1cbmV4cG9ydHMuZzFfMjU2ID0gZzFfMjU2O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxuZXhwb3J0cy5pbmhlcml0cyA9IGluaGVyaXRzO1xuXG5mdW5jdGlvbiBpc1N1cnJvZ2F0ZVBhaXIobXNnLCBpKSB7XG4gIGlmICgobXNnLmNoYXJDb2RlQXQoaSkgJiAweEZDMDApICE9PSAweEQ4MDApIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGkgPCAwIHx8IGkgKyAxID49IG1zZy5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIChtc2cuY2hhckNvZGVBdChpICsgMSkgJiAweEZDMDApID09PSAweERDMDA7XG59XG5cbmZ1bmN0aW9uIHRvQXJyYXkobXNnLCBlbmMpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkobXNnKSlcbiAgICByZXR1cm4gbXNnLnNsaWNlKCk7XG4gIGlmICghbXNnKVxuICAgIHJldHVybiBbXTtcbiAgdmFyIHJlcyA9IFtdO1xuICBpZiAodHlwZW9mIG1zZyA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAoIWVuYykge1xuICAgICAgLy8gSW5zcGlyZWQgYnkgc3RyaW5nVG9VdGY4Qnl0ZUFycmF5KCkgaW4gY2xvc3VyZS1saWJyYXJ5IGJ5IEdvb2dsZVxuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9jbG9zdXJlLWxpYnJhcnkvYmxvYi84NTk4ZDg3MjQyYWY1OWFhYzIzMzI3MDc0MmM4OTg0ZTJiMmJkYmUwL2Nsb3N1cmUvZ29vZy9jcnlwdC9jcnlwdC5qcyNMMTE3LUwxNDNcbiAgICAgIC8vIEFwYWNoZSBMaWNlbnNlIDIuMFxuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9jbG9zdXJlLWxpYnJhcnkvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICAgICAgdmFyIHAgPSAwO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGMgPSBtc2cuY2hhckNvZGVBdChpKTtcbiAgICAgICAgaWYgKGMgPCAxMjgpIHtcbiAgICAgICAgICByZXNbcCsrXSA9IGM7XG4gICAgICAgIH0gZWxzZSBpZiAoYyA8IDIwNDgpIHtcbiAgICAgICAgICByZXNbcCsrXSA9IChjID4+IDYpIHwgMTkyO1xuICAgICAgICAgIHJlc1twKytdID0gKGMgJiA2MykgfCAxMjg7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNTdXJyb2dhdGVQYWlyKG1zZywgaSkpIHtcbiAgICAgICAgICBjID0gMHgxMDAwMCArICgoYyAmIDB4MDNGRikgPDwgMTApICsgKG1zZy5jaGFyQ29kZUF0KCsraSkgJiAweDAzRkYpO1xuICAgICAgICAgIHJlc1twKytdID0gKGMgPj4gMTgpIHwgMjQwO1xuICAgICAgICAgIHJlc1twKytdID0gKChjID4+IDEyKSAmIDYzKSB8IDEyODtcbiAgICAgICAgICByZXNbcCsrXSA9ICgoYyA+PiA2KSAmIDYzKSB8IDEyODtcbiAgICAgICAgICByZXNbcCsrXSA9IChjICYgNjMpIHwgMTI4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc1twKytdID0gKGMgPj4gMTIpIHwgMjI0O1xuICAgICAgICAgIHJlc1twKytdID0gKChjID4+IDYpICYgNjMpIHwgMTI4O1xuICAgICAgICAgIHJlc1twKytdID0gKGMgJiA2MykgfCAxMjg7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGVuYyA9PT0gJ2hleCcpIHtcbiAgICAgIG1zZyA9IG1zZy5yZXBsYWNlKC9bXmEtejAtOV0rL2lnLCAnJyk7XG4gICAgICBpZiAobXNnLmxlbmd0aCAlIDIgIT09IDApXG4gICAgICAgIG1zZyA9ICcwJyArIG1zZztcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpICs9IDIpXG4gICAgICAgIHJlcy5wdXNoKHBhcnNlSW50KG1zZ1tpXSArIG1zZ1tpICsgMV0sIDE2KSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGZvciAoaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspXG4gICAgICByZXNbaV0gPSBtc2dbaV0gfCAwO1xuICB9XG4gIHJldHVybiByZXM7XG59XG5leHBvcnRzLnRvQXJyYXkgPSB0b0FycmF5O1xuXG5mdW5jdGlvbiB0b0hleChtc2cpIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKylcbiAgICByZXMgKz0gemVybzIobXNnW2ldLnRvU3RyaW5nKDE2KSk7XG4gIHJldHVybiByZXM7XG59XG5leHBvcnRzLnRvSGV4ID0gdG9IZXg7XG5cbmZ1bmN0aW9uIGh0b25sKHcpIHtcbiAgdmFyIHJlcyA9ICh3ID4+PiAyNCkgfFxuICAgICAgICAgICAgKCh3ID4+PiA4KSAmIDB4ZmYwMCkgfFxuICAgICAgICAgICAgKCh3IDw8IDgpICYgMHhmZjAwMDApIHxcbiAgICAgICAgICAgICgodyAmIDB4ZmYpIDw8IDI0KTtcbiAgcmV0dXJuIHJlcyA+Pj4gMDtcbn1cbmV4cG9ydHMuaHRvbmwgPSBodG9ubDtcblxuZnVuY3Rpb24gdG9IZXgzMihtc2csIGVuZGlhbikge1xuICB2YXIgcmVzID0gJyc7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHcgPSBtc2dbaV07XG4gICAgaWYgKGVuZGlhbiA9PT0gJ2xpdHRsZScpXG4gICAgICB3ID0gaHRvbmwodyk7XG4gICAgcmVzICs9IHplcm84KHcudG9TdHJpbmcoMTYpKTtcbiAgfVxuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy50b0hleDMyID0gdG9IZXgzMjtcblxuZnVuY3Rpb24gemVybzIod29yZCkge1xuICBpZiAod29yZC5sZW5ndGggPT09IDEpXG4gICAgcmV0dXJuICcwJyArIHdvcmQ7XG4gIGVsc2VcbiAgICByZXR1cm4gd29yZDtcbn1cbmV4cG9ydHMuemVybzIgPSB6ZXJvMjtcblxuZnVuY3Rpb24gemVybzgod29yZCkge1xuICBpZiAod29yZC5sZW5ndGggPT09IDcpXG4gICAgcmV0dXJuICcwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSA2KVxuICAgIHJldHVybiAnMDAnICsgd29yZDtcbiAgZWxzZSBpZiAod29yZC5sZW5ndGggPT09IDUpXG4gICAgcmV0dXJuICcwMDAnICsgd29yZDtcbiAgZWxzZSBpZiAod29yZC5sZW5ndGggPT09IDQpXG4gICAgcmV0dXJuICcwMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSAzKVxuICAgIHJldHVybiAnMDAwMDAnICsgd29yZDtcbiAgZWxzZSBpZiAod29yZC5sZW5ndGggPT09IDIpXG4gICAgcmV0dXJuICcwMDAwMDAnICsgd29yZDtcbiAgZWxzZSBpZiAod29yZC5sZW5ndGggPT09IDEpXG4gICAgcmV0dXJuICcwMDAwMDAwJyArIHdvcmQ7XG4gIGVsc2VcbiAgICByZXR1cm4gd29yZDtcbn1cbmV4cG9ydHMuemVybzggPSB6ZXJvODtcblxuZnVuY3Rpb24gam9pbjMyKG1zZywgc3RhcnQsIGVuZCwgZW5kaWFuKSB7XG4gIHZhciBsZW4gPSBlbmQgLSBzdGFydDtcbiAgYXNzZXJ0KGxlbiAlIDQgPT09IDApO1xuICB2YXIgcmVzID0gbmV3IEFycmF5KGxlbiAvIDQpO1xuICBmb3IgKHZhciBpID0gMCwgayA9IHN0YXJ0OyBpIDwgcmVzLmxlbmd0aDsgaSsrLCBrICs9IDQpIHtcbiAgICB2YXIgdztcbiAgICBpZiAoZW5kaWFuID09PSAnYmlnJylcbiAgICAgIHcgPSAobXNnW2tdIDw8IDI0KSB8IChtc2dbayArIDFdIDw8IDE2KSB8IChtc2dbayArIDJdIDw8IDgpIHwgbXNnW2sgKyAzXTtcbiAgICBlbHNlXG4gICAgICB3ID0gKG1zZ1trICsgM10gPDwgMjQpIHwgKG1zZ1trICsgMl0gPDwgMTYpIHwgKG1zZ1trICsgMV0gPDwgOCkgfCBtc2dba107XG4gICAgcmVzW2ldID0gdyA+Pj4gMDtcbiAgfVxuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy5qb2luMzIgPSBqb2luMzI7XG5cbmZ1bmN0aW9uIHNwbGl0MzIobXNnLCBlbmRpYW4pIHtcbiAgdmFyIHJlcyA9IG5ldyBBcnJheShtc2cubGVuZ3RoICogNCk7XG4gIGZvciAodmFyIGkgPSAwLCBrID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKywgayArPSA0KSB7XG4gICAgdmFyIG0gPSBtc2dbaV07XG4gICAgaWYgKGVuZGlhbiA9PT0gJ2JpZycpIHtcbiAgICAgIHJlc1trXSA9IG0gPj4+IDI0O1xuICAgICAgcmVzW2sgKyAxXSA9IChtID4+PiAxNikgJiAweGZmO1xuICAgICAgcmVzW2sgKyAyXSA9IChtID4+PiA4KSAmIDB4ZmY7XG4gICAgICByZXNbayArIDNdID0gbSAmIDB4ZmY7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc1trICsgM10gPSBtID4+PiAyNDtcbiAgICAgIHJlc1trICsgMl0gPSAobSA+Pj4gMTYpICYgMHhmZjtcbiAgICAgIHJlc1trICsgMV0gPSAobSA+Pj4gOCkgJiAweGZmO1xuICAgICAgcmVzW2tdID0gbSAmIDB4ZmY7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXM7XG59XG5leHBvcnRzLnNwbGl0MzIgPSBzcGxpdDMyO1xuXG5mdW5jdGlvbiByb3RyMzIodywgYikge1xuICByZXR1cm4gKHcgPj4+IGIpIHwgKHcgPDwgKDMyIC0gYikpO1xufVxuZXhwb3J0cy5yb3RyMzIgPSByb3RyMzI7XG5cbmZ1bmN0aW9uIHJvdGwzMih3LCBiKSB7XG4gIHJldHVybiAodyA8PCBiKSB8ICh3ID4+PiAoMzIgLSBiKSk7XG59XG5leHBvcnRzLnJvdGwzMiA9IHJvdGwzMjtcblxuZnVuY3Rpb24gc3VtMzIoYSwgYikge1xuICByZXR1cm4gKGEgKyBiKSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtMzIgPSBzdW0zMjtcblxuZnVuY3Rpb24gc3VtMzJfMyhhLCBiLCBjKSB7XG4gIHJldHVybiAoYSArIGIgKyBjKSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtMzJfMyA9IHN1bTMyXzM7XG5cbmZ1bmN0aW9uIHN1bTMyXzQoYSwgYiwgYywgZCkge1xuICByZXR1cm4gKGEgKyBiICsgYyArIGQpID4+PiAwO1xufVxuZXhwb3J0cy5zdW0zMl80ID0gc3VtMzJfNDtcblxuZnVuY3Rpb24gc3VtMzJfNShhLCBiLCBjLCBkLCBlKSB7XG4gIHJldHVybiAoYSArIGIgKyBjICsgZCArIGUpID4+PiAwO1xufVxuZXhwb3J0cy5zdW0zMl81ID0gc3VtMzJfNTtcblxuZnVuY3Rpb24gc3VtNjQoYnVmLCBwb3MsIGFoLCBhbCkge1xuICB2YXIgYmggPSBidWZbcG9zXTtcbiAgdmFyIGJsID0gYnVmW3BvcyArIDFdO1xuXG4gIHZhciBsbyA9IChhbCArIGJsKSA+Pj4gMDtcbiAgdmFyIGhpID0gKGxvIDwgYWwgPyAxIDogMCkgKyBhaCArIGJoO1xuICBidWZbcG9zXSA9IGhpID4+PiAwO1xuICBidWZbcG9zICsgMV0gPSBsbztcbn1cbmV4cG9ydHMuc3VtNjQgPSBzdW02NDtcblxuZnVuY3Rpb24gc3VtNjRfaGkoYWgsIGFsLCBiaCwgYmwpIHtcbiAgdmFyIGxvID0gKGFsICsgYmwpID4+PiAwO1xuICB2YXIgaGkgPSAobG8gPCBhbCA/IDEgOiAwKSArIGFoICsgYmg7XG4gIHJldHVybiBoaSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtNjRfaGkgPSBzdW02NF9oaTtcblxuZnVuY3Rpb24gc3VtNjRfbG8oYWgsIGFsLCBiaCwgYmwpIHtcbiAgdmFyIGxvID0gYWwgKyBibDtcbiAgcmV0dXJuIGxvID4+PiAwO1xufVxuZXhwb3J0cy5zdW02NF9sbyA9IHN1bTY0X2xvO1xuXG5mdW5jdGlvbiBzdW02NF80X2hpKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wsIGRoLCBkbCkge1xuICB2YXIgY2FycnkgPSAwO1xuICB2YXIgbG8gPSBhbDtcbiAgbG8gPSAobG8gKyBibCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgYWwgPyAxIDogMDtcbiAgbG8gPSAobG8gKyBjbCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgY2wgPyAxIDogMDtcbiAgbG8gPSAobG8gKyBkbCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgZGwgPyAxIDogMDtcblxuICB2YXIgaGkgPSBhaCArIGJoICsgY2ggKyBkaCArIGNhcnJ5O1xuICByZXR1cm4gaGkgPj4+IDA7XG59XG5leHBvcnRzLnN1bTY0XzRfaGkgPSBzdW02NF80X2hpO1xuXG5mdW5jdGlvbiBzdW02NF80X2xvKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wsIGRoLCBkbCkge1xuICB2YXIgbG8gPSBhbCArIGJsICsgY2wgKyBkbDtcbiAgcmV0dXJuIGxvID4+PiAwO1xufVxuZXhwb3J0cy5zdW02NF80X2xvID0gc3VtNjRfNF9sbztcblxuZnVuY3Rpb24gc3VtNjRfNV9oaShhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwsIGVoLCBlbCkge1xuICB2YXIgY2FycnkgPSAwO1xuICB2YXIgbG8gPSBhbDtcbiAgbG8gPSAobG8gKyBibCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgYWwgPyAxIDogMDtcbiAgbG8gPSAobG8gKyBjbCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgY2wgPyAxIDogMDtcbiAgbG8gPSAobG8gKyBkbCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgZGwgPyAxIDogMDtcbiAgbG8gPSAobG8gKyBlbCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgZWwgPyAxIDogMDtcblxuICB2YXIgaGkgPSBhaCArIGJoICsgY2ggKyBkaCArIGVoICsgY2Fycnk7XG4gIHJldHVybiBoaSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtNjRfNV9oaSA9IHN1bTY0XzVfaGk7XG5cbmZ1bmN0aW9uIHN1bTY0XzVfbG8oYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCwgZGgsIGRsLCBlaCwgZWwpIHtcbiAgdmFyIGxvID0gYWwgKyBibCArIGNsICsgZGwgKyBlbDtcblxuICByZXR1cm4gbG8gPj4+IDA7XG59XG5leHBvcnRzLnN1bTY0XzVfbG8gPSBzdW02NF81X2xvO1xuXG5mdW5jdGlvbiByb3RyNjRfaGkoYWgsIGFsLCBudW0pIHtcbiAgdmFyIHIgPSAoYWwgPDwgKDMyIC0gbnVtKSkgfCAoYWggPj4+IG51bSk7XG4gIHJldHVybiByID4+PiAwO1xufVxuZXhwb3J0cy5yb3RyNjRfaGkgPSByb3RyNjRfaGk7XG5cbmZ1bmN0aW9uIHJvdHI2NF9sbyhhaCwgYWwsIG51bSkge1xuICB2YXIgciA9IChhaCA8PCAoMzIgLSBudW0pKSB8IChhbCA+Pj4gbnVtKTtcbiAgcmV0dXJuIHIgPj4+IDA7XG59XG5leHBvcnRzLnJvdHI2NF9sbyA9IHJvdHI2NF9sbztcblxuZnVuY3Rpb24gc2hyNjRfaGkoYWgsIGFsLCBudW0pIHtcbiAgcmV0dXJuIGFoID4+PiBudW07XG59XG5leHBvcnRzLnNocjY0X2hpID0gc2hyNjRfaGk7XG5cbmZ1bmN0aW9uIHNocjY0X2xvKGFoLCBhbCwgbnVtKSB7XG4gIHZhciByID0gKGFoIDw8ICgzMiAtIG51bSkpIHwgKGFsID4+PiBudW0pO1xuICByZXR1cm4gciA+Pj4gMDtcbn1cbmV4cG9ydHMuc2hyNjRfbG8gPSBzaHI2NF9sbztcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGhhc2ggPSByZXF1aXJlKCdoYXNoLmpzJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCdtaW5pbWFsaXN0aWMtY3J5cHRvLXV0aWxzJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG5mdW5jdGlvbiBIbWFjRFJCRyhvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBIbWFjRFJCRykpXG4gICAgcmV0dXJuIG5ldyBIbWFjRFJCRyhvcHRpb25zKTtcbiAgdGhpcy5oYXNoID0gb3B0aW9ucy5oYXNoO1xuICB0aGlzLnByZWRSZXNpc3QgPSAhIW9wdGlvbnMucHJlZFJlc2lzdDtcblxuICB0aGlzLm91dExlbiA9IHRoaXMuaGFzaC5vdXRTaXplO1xuICB0aGlzLm1pbkVudHJvcHkgPSBvcHRpb25zLm1pbkVudHJvcHkgfHwgdGhpcy5oYXNoLmhtYWNTdHJlbmd0aDtcblxuICB0aGlzLl9yZXNlZWQgPSBudWxsO1xuICB0aGlzLnJlc2VlZEludGVydmFsID0gbnVsbDtcbiAgdGhpcy5LID0gbnVsbDtcbiAgdGhpcy5WID0gbnVsbDtcblxuICB2YXIgZW50cm9weSA9IHV0aWxzLnRvQXJyYXkob3B0aW9ucy5lbnRyb3B5LCBvcHRpb25zLmVudHJvcHlFbmMgfHwgJ2hleCcpO1xuICB2YXIgbm9uY2UgPSB1dGlscy50b0FycmF5KG9wdGlvbnMubm9uY2UsIG9wdGlvbnMubm9uY2VFbmMgfHwgJ2hleCcpO1xuICB2YXIgcGVycyA9IHV0aWxzLnRvQXJyYXkob3B0aW9ucy5wZXJzLCBvcHRpb25zLnBlcnNFbmMgfHwgJ2hleCcpO1xuICBhc3NlcnQoZW50cm9weS5sZW5ndGggPj0gKHRoaXMubWluRW50cm9weSAvIDgpLFxuICAgICAgICAgJ05vdCBlbm91Z2ggZW50cm9weS4gTWluaW11bSBpczogJyArIHRoaXMubWluRW50cm9weSArICcgYml0cycpO1xuICB0aGlzLl9pbml0KGVudHJvcHksIG5vbmNlLCBwZXJzKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gSG1hY0RSQkc7XG5cbkhtYWNEUkJHLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uIGluaXQoZW50cm9weSwgbm9uY2UsIHBlcnMpIHtcbiAgdmFyIHNlZWQgPSBlbnRyb3B5LmNvbmNhdChub25jZSkuY29uY2F0KHBlcnMpO1xuXG4gIHRoaXMuSyA9IG5ldyBBcnJheSh0aGlzLm91dExlbiAvIDgpO1xuICB0aGlzLlYgPSBuZXcgQXJyYXkodGhpcy5vdXRMZW4gLyA4KTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLlYubGVuZ3RoOyBpKyspIHtcbiAgICB0aGlzLktbaV0gPSAweDAwO1xuICAgIHRoaXMuVltpXSA9IDB4MDE7XG4gIH1cblxuICB0aGlzLl91cGRhdGUoc2VlZCk7XG4gIHRoaXMuX3Jlc2VlZCA9IDE7XG4gIHRoaXMucmVzZWVkSW50ZXJ2YWwgPSAweDEwMDAwMDAwMDAwMDA7ICAvLyAyXjQ4XG59O1xuXG5IbWFjRFJCRy5wcm90b3R5cGUuX2htYWMgPSBmdW5jdGlvbiBobWFjKCkge1xuICByZXR1cm4gbmV3IGhhc2guaG1hYyh0aGlzLmhhc2gsIHRoaXMuSyk7XG59O1xuXG5IbWFjRFJCRy5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIHVwZGF0ZShzZWVkKSB7XG4gIHZhciBrbWFjID0gdGhpcy5faG1hYygpXG4gICAgICAgICAgICAgICAgIC51cGRhdGUodGhpcy5WKVxuICAgICAgICAgICAgICAgICAudXBkYXRlKFsgMHgwMCBdKTtcbiAgaWYgKHNlZWQpXG4gICAga21hYyA9IGttYWMudXBkYXRlKHNlZWQpO1xuICB0aGlzLksgPSBrbWFjLmRpZ2VzdCgpO1xuICB0aGlzLlYgPSB0aGlzLl9obWFjKCkudXBkYXRlKHRoaXMuVikuZGlnZXN0KCk7XG4gIGlmICghc2VlZClcbiAgICByZXR1cm47XG5cbiAgdGhpcy5LID0gdGhpcy5faG1hYygpXG4gICAgICAgICAgICAgICAudXBkYXRlKHRoaXMuVilcbiAgICAgICAgICAgICAgIC51cGRhdGUoWyAweDAxIF0pXG4gICAgICAgICAgICAgICAudXBkYXRlKHNlZWQpXG4gICAgICAgICAgICAgICAuZGlnZXN0KCk7XG4gIHRoaXMuViA9IHRoaXMuX2htYWMoKS51cGRhdGUodGhpcy5WKS5kaWdlc3QoKTtcbn07XG5cbkhtYWNEUkJHLnByb3RvdHlwZS5yZXNlZWQgPSBmdW5jdGlvbiByZXNlZWQoZW50cm9weSwgZW50cm9weUVuYywgYWRkLCBhZGRFbmMpIHtcbiAgLy8gT3B0aW9uYWwgZW50cm9weSBlbmNcbiAgaWYgKHR5cGVvZiBlbnRyb3B5RW5jICE9PSAnc3RyaW5nJykge1xuICAgIGFkZEVuYyA9IGFkZDtcbiAgICBhZGQgPSBlbnRyb3B5RW5jO1xuICAgIGVudHJvcHlFbmMgPSBudWxsO1xuICB9XG5cbiAgZW50cm9weSA9IHV0aWxzLnRvQXJyYXkoZW50cm9weSwgZW50cm9weUVuYyk7XG4gIGFkZCA9IHV0aWxzLnRvQXJyYXkoYWRkLCBhZGRFbmMpO1xuXG4gIGFzc2VydChlbnRyb3B5Lmxlbmd0aCA+PSAodGhpcy5taW5FbnRyb3B5IC8gOCksXG4gICAgICAgICAnTm90IGVub3VnaCBlbnRyb3B5LiBNaW5pbXVtIGlzOiAnICsgdGhpcy5taW5FbnRyb3B5ICsgJyBiaXRzJyk7XG5cbiAgdGhpcy5fdXBkYXRlKGVudHJvcHkuY29uY2F0KGFkZCB8fCBbXSkpO1xuICB0aGlzLl9yZXNlZWQgPSAxO1xufTtcblxuSG1hY0RSQkcucHJvdG90eXBlLmdlbmVyYXRlID0gZnVuY3Rpb24gZ2VuZXJhdGUobGVuLCBlbmMsIGFkZCwgYWRkRW5jKSB7XG4gIGlmICh0aGlzLl9yZXNlZWQgPiB0aGlzLnJlc2VlZEludGVydmFsKVxuICAgIHRocm93IG5ldyBFcnJvcignUmVzZWVkIGlzIHJlcXVpcmVkJyk7XG5cbiAgLy8gT3B0aW9uYWwgZW5jb2RpbmdcbiAgaWYgKHR5cGVvZiBlbmMgIT09ICdzdHJpbmcnKSB7XG4gICAgYWRkRW5jID0gYWRkO1xuICAgIGFkZCA9IGVuYztcbiAgICBlbmMgPSBudWxsO1xuICB9XG5cbiAgLy8gT3B0aW9uYWwgYWRkaXRpb25hbCBkYXRhXG4gIGlmIChhZGQpIHtcbiAgICBhZGQgPSB1dGlscy50b0FycmF5KGFkZCwgYWRkRW5jIHx8ICdoZXgnKTtcbiAgICB0aGlzLl91cGRhdGUoYWRkKTtcbiAgfVxuXG4gIHZhciB0ZW1wID0gW107XG4gIHdoaWxlICh0ZW1wLmxlbmd0aCA8IGxlbikge1xuICAgIHRoaXMuViA9IHRoaXMuX2htYWMoKS51cGRhdGUodGhpcy5WKS5kaWdlc3QoKTtcbiAgICB0ZW1wID0gdGVtcC5jb25jYXQodGhpcy5WKTtcbiAgfVxuXG4gIHZhciByZXMgPSB0ZW1wLnNsaWNlKDAsIGxlbik7XG4gIHRoaXMuX3VwZGF0ZShhZGQpO1xuICB0aGlzLl9yZXNlZWQrKztcbiAgcmV0dXJuIHV0aWxzLmVuY29kZShyZXMsIGVuYyk7XG59O1xuIiwiZXhwb3J0cy5yZWFkID0gZnVuY3Rpb24gKGJ1ZmZlciwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG1cbiAgdmFyIGVMZW4gPSAobkJ5dGVzICogOCkgLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSAoZSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBlID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBtTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSAobSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBpZiAoZSA9PT0gMCkge1xuICAgIGUgPSAxIC0gZUJpYXNcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiAoKHMgPyAtMSA6IDEpICogSW5maW5pdHkpXG4gIH0gZWxzZSB7XG4gICAgbSA9IG0gKyBNYXRoLnBvdygyLCBtTGVuKVxuICAgIGUgPSBlIC0gZUJpYXNcbiAgfVxuICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKVxufVxuXG5leHBvcnRzLndyaXRlID0gZnVuY3Rpb24gKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLCBjXG4gIHZhciBlTGVuID0gKG5CeXRlcyAqIDgpIC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICgodmFsdWUgKiBjKSAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSBlICsgZUJpYXNcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gMFxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbVxuICBlTGVuICs9IG1MZW5cbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyOFxufVxuIiwiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59IGVsc2Uge1xuICAvLyBvbGQgc2Nob29sIHNoaW0gZm9yIG9sZCBicm93c2Vyc1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgY3Rvci5wcm90b3R5cGUgPSBuZXcgVGVtcEN0b3IoKVxuICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICB9XG59XG4iLCJ2YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIChhcnIpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiIsIid1c2Ugc3RyaWN0J1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEhhc2hCYXNlID0gcmVxdWlyZSgnaGFzaC1iYXNlJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxuXG52YXIgQVJSQVkxNiA9IG5ldyBBcnJheSgxNilcblxuZnVuY3Rpb24gTUQ1ICgpIHtcbiAgSGFzaEJhc2UuY2FsbCh0aGlzLCA2NClcblxuICAvLyBzdGF0ZVxuICB0aGlzLl9hID0gMHg2NzQ1MjMwMVxuICB0aGlzLl9iID0gMHhlZmNkYWI4OVxuICB0aGlzLl9jID0gMHg5OGJhZGNmZVxuICB0aGlzLl9kID0gMHgxMDMyNTQ3NlxufVxuXG5pbmhlcml0cyhNRDUsIEhhc2hCYXNlKVxuXG5NRDUucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBNID0gQVJSQVkxNlxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyArK2kpIE1baV0gPSB0aGlzLl9ibG9jay5yZWFkSW50MzJMRShpICogNClcblxuICB2YXIgYSA9IHRoaXMuX2FcbiAgdmFyIGIgPSB0aGlzLl9iXG4gIHZhciBjID0gdGhpcy5fY1xuICB2YXIgZCA9IHRoaXMuX2RcblxuICBhID0gZm5GKGEsIGIsIGMsIGQsIE1bMF0sIDB4ZDc2YWE0NzgsIDcpXG4gIGQgPSBmbkYoZCwgYSwgYiwgYywgTVsxXSwgMHhlOGM3Yjc1NiwgMTIpXG4gIGMgPSBmbkYoYywgZCwgYSwgYiwgTVsyXSwgMHgyNDIwNzBkYiwgMTcpXG4gIGIgPSBmbkYoYiwgYywgZCwgYSwgTVszXSwgMHhjMWJkY2VlZSwgMjIpXG4gIGEgPSBmbkYoYSwgYiwgYywgZCwgTVs0XSwgMHhmNTdjMGZhZiwgNylcbiAgZCA9IGZuRihkLCBhLCBiLCBjLCBNWzVdLCAweDQ3ODdjNjJhLCAxMilcbiAgYyA9IGZuRihjLCBkLCBhLCBiLCBNWzZdLCAweGE4MzA0NjEzLCAxNylcbiAgYiA9IGZuRihiLCBjLCBkLCBhLCBNWzddLCAweGZkNDY5NTAxLCAyMilcbiAgYSA9IGZuRihhLCBiLCBjLCBkLCBNWzhdLCAweDY5ODA5OGQ4LCA3KVxuICBkID0gZm5GKGQsIGEsIGIsIGMsIE1bOV0sIDB4OGI0NGY3YWYsIDEyKVxuICBjID0gZm5GKGMsIGQsIGEsIGIsIE1bMTBdLCAweGZmZmY1YmIxLCAxNylcbiAgYiA9IGZuRihiLCBjLCBkLCBhLCBNWzExXSwgMHg4OTVjZDdiZSwgMjIpXG4gIGEgPSBmbkYoYSwgYiwgYywgZCwgTVsxMl0sIDB4NmI5MDExMjIsIDcpXG4gIGQgPSBmbkYoZCwgYSwgYiwgYywgTVsxM10sIDB4ZmQ5ODcxOTMsIDEyKVxuICBjID0gZm5GKGMsIGQsIGEsIGIsIE1bMTRdLCAweGE2Nzk0MzhlLCAxNylcbiAgYiA9IGZuRihiLCBjLCBkLCBhLCBNWzE1XSwgMHg0OWI0MDgyMSwgMjIpXG5cbiAgYSA9IGZuRyhhLCBiLCBjLCBkLCBNWzFdLCAweGY2MWUyNTYyLCA1KVxuICBkID0gZm5HKGQsIGEsIGIsIGMsIE1bNl0sIDB4YzA0MGIzNDAsIDkpXG4gIGMgPSBmbkcoYywgZCwgYSwgYiwgTVsxMV0sIDB4MjY1ZTVhNTEsIDE0KVxuICBiID0gZm5HKGIsIGMsIGQsIGEsIE1bMF0sIDB4ZTliNmM3YWEsIDIwKVxuICBhID0gZm5HKGEsIGIsIGMsIGQsIE1bNV0sIDB4ZDYyZjEwNWQsIDUpXG4gIGQgPSBmbkcoZCwgYSwgYiwgYywgTVsxMF0sIDB4MDI0NDE0NTMsIDkpXG4gIGMgPSBmbkcoYywgZCwgYSwgYiwgTVsxNV0sIDB4ZDhhMWU2ODEsIDE0KVxuICBiID0gZm5HKGIsIGMsIGQsIGEsIE1bNF0sIDB4ZTdkM2ZiYzgsIDIwKVxuICBhID0gZm5HKGEsIGIsIGMsIGQsIE1bOV0sIDB4MjFlMWNkZTYsIDUpXG4gIGQgPSBmbkcoZCwgYSwgYiwgYywgTVsxNF0sIDB4YzMzNzA3ZDYsIDkpXG4gIGMgPSBmbkcoYywgZCwgYSwgYiwgTVszXSwgMHhmNGQ1MGQ4NywgMTQpXG4gIGIgPSBmbkcoYiwgYywgZCwgYSwgTVs4XSwgMHg0NTVhMTRlZCwgMjApXG4gIGEgPSBmbkcoYSwgYiwgYywgZCwgTVsxM10sIDB4YTllM2U5MDUsIDUpXG4gIGQgPSBmbkcoZCwgYSwgYiwgYywgTVsyXSwgMHhmY2VmYTNmOCwgOSlcbiAgYyA9IGZuRyhjLCBkLCBhLCBiLCBNWzddLCAweDY3NmYwMmQ5LCAxNClcbiAgYiA9IGZuRyhiLCBjLCBkLCBhLCBNWzEyXSwgMHg4ZDJhNGM4YSwgMjApXG5cbiAgYSA9IGZuSChhLCBiLCBjLCBkLCBNWzVdLCAweGZmZmEzOTQyLCA0KVxuICBkID0gZm5IKGQsIGEsIGIsIGMsIE1bOF0sIDB4ODc3MWY2ODEsIDExKVxuICBjID0gZm5IKGMsIGQsIGEsIGIsIE1bMTFdLCAweDZkOWQ2MTIyLCAxNilcbiAgYiA9IGZuSChiLCBjLCBkLCBhLCBNWzE0XSwgMHhmZGU1MzgwYywgMjMpXG4gIGEgPSBmbkgoYSwgYiwgYywgZCwgTVsxXSwgMHhhNGJlZWE0NCwgNClcbiAgZCA9IGZuSChkLCBhLCBiLCBjLCBNWzRdLCAweDRiZGVjZmE5LCAxMSlcbiAgYyA9IGZuSChjLCBkLCBhLCBiLCBNWzddLCAweGY2YmI0YjYwLCAxNilcbiAgYiA9IGZuSChiLCBjLCBkLCBhLCBNWzEwXSwgMHhiZWJmYmM3MCwgMjMpXG4gIGEgPSBmbkgoYSwgYiwgYywgZCwgTVsxM10sIDB4Mjg5YjdlYzYsIDQpXG4gIGQgPSBmbkgoZCwgYSwgYiwgYywgTVswXSwgMHhlYWExMjdmYSwgMTEpXG4gIGMgPSBmbkgoYywgZCwgYSwgYiwgTVszXSwgMHhkNGVmMzA4NSwgMTYpXG4gIGIgPSBmbkgoYiwgYywgZCwgYSwgTVs2XSwgMHgwNDg4MWQwNSwgMjMpXG4gIGEgPSBmbkgoYSwgYiwgYywgZCwgTVs5XSwgMHhkOWQ0ZDAzOSwgNClcbiAgZCA9IGZuSChkLCBhLCBiLCBjLCBNWzEyXSwgMHhlNmRiOTllNSwgMTEpXG4gIGMgPSBmbkgoYywgZCwgYSwgYiwgTVsxNV0sIDB4MWZhMjdjZjgsIDE2KVxuICBiID0gZm5IKGIsIGMsIGQsIGEsIE1bMl0sIDB4YzRhYzU2NjUsIDIzKVxuXG4gIGEgPSBmbkkoYSwgYiwgYywgZCwgTVswXSwgMHhmNDI5MjI0NCwgNilcbiAgZCA9IGZuSShkLCBhLCBiLCBjLCBNWzddLCAweDQzMmFmZjk3LCAxMClcbiAgYyA9IGZuSShjLCBkLCBhLCBiLCBNWzE0XSwgMHhhYjk0MjNhNywgMTUpXG4gIGIgPSBmbkkoYiwgYywgZCwgYSwgTVs1XSwgMHhmYzkzYTAzOSwgMjEpXG4gIGEgPSBmbkkoYSwgYiwgYywgZCwgTVsxMl0sIDB4NjU1YjU5YzMsIDYpXG4gIGQgPSBmbkkoZCwgYSwgYiwgYywgTVszXSwgMHg4ZjBjY2M5MiwgMTApXG4gIGMgPSBmbkkoYywgZCwgYSwgYiwgTVsxMF0sIDB4ZmZlZmY0N2QsIDE1KVxuICBiID0gZm5JKGIsIGMsIGQsIGEsIE1bMV0sIDB4ODU4NDVkZDEsIDIxKVxuICBhID0gZm5JKGEsIGIsIGMsIGQsIE1bOF0sIDB4NmZhODdlNGYsIDYpXG4gIGQgPSBmbkkoZCwgYSwgYiwgYywgTVsxNV0sIDB4ZmUyY2U2ZTAsIDEwKVxuICBjID0gZm5JKGMsIGQsIGEsIGIsIE1bNl0sIDB4YTMwMTQzMTQsIDE1KVxuICBiID0gZm5JKGIsIGMsIGQsIGEsIE1bMTNdLCAweDRlMDgxMWExLCAyMSlcbiAgYSA9IGZuSShhLCBiLCBjLCBkLCBNWzRdLCAweGY3NTM3ZTgyLCA2KVxuICBkID0gZm5JKGQsIGEsIGIsIGMsIE1bMTFdLCAweGJkM2FmMjM1LCAxMClcbiAgYyA9IGZuSShjLCBkLCBhLCBiLCBNWzJdLCAweDJhZDdkMmJiLCAxNSlcbiAgYiA9IGZuSShiLCBjLCBkLCBhLCBNWzldLCAweGViODZkMzkxLCAyMSlcblxuICB0aGlzLl9hID0gKHRoaXMuX2EgKyBhKSB8IDBcbiAgdGhpcy5fYiA9ICh0aGlzLl9iICsgYikgfCAwXG4gIHRoaXMuX2MgPSAodGhpcy5fYyArIGMpIHwgMFxuICB0aGlzLl9kID0gKHRoaXMuX2QgKyBkKSB8IDBcbn1cblxuTUQ1LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gKCkge1xuICAvLyBjcmVhdGUgcGFkZGluZyBhbmQgaGFuZGxlIGJsb2Nrc1xuICB0aGlzLl9ibG9ja1t0aGlzLl9ibG9ja09mZnNldCsrXSA9IDB4ODBcbiAgaWYgKHRoaXMuX2Jsb2NrT2Zmc2V0ID4gNTYpIHtcbiAgICB0aGlzLl9ibG9jay5maWxsKDAsIHRoaXMuX2Jsb2NrT2Zmc2V0LCA2NClcbiAgICB0aGlzLl91cGRhdGUoKVxuICAgIHRoaXMuX2Jsb2NrT2Zmc2V0ID0gMFxuICB9XG5cbiAgdGhpcy5fYmxvY2suZmlsbCgwLCB0aGlzLl9ibG9ja09mZnNldCwgNTYpXG4gIHRoaXMuX2Jsb2NrLndyaXRlVUludDMyTEUodGhpcy5fbGVuZ3RoWzBdLCA1NilcbiAgdGhpcy5fYmxvY2sud3JpdGVVSW50MzJMRSh0aGlzLl9sZW5ndGhbMV0sIDYwKVxuICB0aGlzLl91cGRhdGUoKVxuXG4gIC8vIHByb2R1Y2UgcmVzdWx0XG4gIHZhciBidWZmZXIgPSBCdWZmZXIuYWxsb2NVbnNhZmUoMTYpXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fYSwgMClcbiAgYnVmZmVyLndyaXRlSW50MzJMRSh0aGlzLl9iLCA0KVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2MsIDgpXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fZCwgMTIpXG4gIHJldHVybiBidWZmZXJcbn1cblxuZnVuY3Rpb24gcm90bCAoeCwgbikge1xuICByZXR1cm4gKHggPDwgbikgfCAoeCA+Pj4gKDMyIC0gbikpXG59XG5cbmZ1bmN0aW9uIGZuRiAoYSwgYiwgYywgZCwgbSwgaywgcykge1xuICByZXR1cm4gKHJvdGwoKGEgKyAoKGIgJiBjKSB8ICgofmIpICYgZCkpICsgbSArIGspIHwgMCwgcykgKyBiKSB8IDBcbn1cblxuZnVuY3Rpb24gZm5HIChhLCBiLCBjLCBkLCBtLCBrLCBzKSB7XG4gIHJldHVybiAocm90bCgoYSArICgoYiAmIGQpIHwgKGMgJiAofmQpKSkgKyBtICsgaykgfCAwLCBzKSArIGIpIHwgMFxufVxuXG5mdW5jdGlvbiBmbkggKGEsIGIsIGMsIGQsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKGIgXiBjIF4gZCkgKyBtICsgaykgfCAwLCBzKSArIGIpIHwgMFxufVxuXG5mdW5jdGlvbiBmbkkgKGEsIGIsIGMsIGQsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKChjIF4gKGIgfCAofmQpKSkpICsgbSArIGspIHwgMCwgcykgKyBiKSB8IDBcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBNRDVcbiIsInZhciBibiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgYnJvcmFuZCA9IHJlcXVpcmUoJ2Jyb3JhbmQnKTtcblxuZnVuY3Rpb24gTWlsbGVyUmFiaW4ocmFuZCkge1xuICB0aGlzLnJhbmQgPSByYW5kIHx8IG5ldyBicm9yYW5kLlJhbmQoKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gTWlsbGVyUmFiaW47XG5cbk1pbGxlclJhYmluLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShyYW5kKSB7XG4gIHJldHVybiBuZXcgTWlsbGVyUmFiaW4ocmFuZCk7XG59O1xuXG5NaWxsZXJSYWJpbi5wcm90b3R5cGUuX3JhbmRiZWxvdyA9IGZ1bmN0aW9uIF9yYW5kYmVsb3cobikge1xuICB2YXIgbGVuID0gbi5iaXRMZW5ndGgoKTtcbiAgdmFyIG1pbl9ieXRlcyA9IE1hdGguY2VpbChsZW4gLyA4KTtcblxuICAvLyBHZW5lcmFnZSByYW5kb20gYnl0ZXMgdW50aWwgYSBudW1iZXIgbGVzcyB0aGFuIG4gaXMgZm91bmQuXG4gIC8vIFRoaXMgZW5zdXJlcyB0aGF0IDAuLm4tMSBoYXZlIGFuIGVxdWFsIHByb2JhYmlsaXR5IG9mIGJlaW5nIHNlbGVjdGVkLlxuICBkb1xuICAgIHZhciBhID0gbmV3IGJuKHRoaXMucmFuZC5nZW5lcmF0ZShtaW5fYnl0ZXMpKTtcbiAgd2hpbGUgKGEuY21wKG4pID49IDApO1xuXG4gIHJldHVybiBhO1xufTtcblxuTWlsbGVyUmFiaW4ucHJvdG90eXBlLl9yYW5kcmFuZ2UgPSBmdW5jdGlvbiBfcmFuZHJhbmdlKHN0YXJ0LCBzdG9wKSB7XG4gIC8vIEdlbmVyYXRlIGEgcmFuZG9tIG51bWJlciBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gc3RhcnQgYW5kIGxlc3MgdGhhbiBzdG9wLlxuICB2YXIgc2l6ZSA9IHN0b3Auc3ViKHN0YXJ0KTtcbiAgcmV0dXJuIHN0YXJ0LmFkZCh0aGlzLl9yYW5kYmVsb3coc2l6ZSkpO1xufTtcblxuTWlsbGVyUmFiaW4ucHJvdG90eXBlLnRlc3QgPSBmdW5jdGlvbiB0ZXN0KG4sIGssIGNiKSB7XG4gIHZhciBsZW4gPSBuLmJpdExlbmd0aCgpO1xuICB2YXIgcmVkID0gYm4ubW9udChuKTtcbiAgdmFyIHJvbmUgPSBuZXcgYm4oMSkudG9SZWQocmVkKTtcblxuICBpZiAoIWspXG4gICAgayA9IE1hdGgubWF4KDEsIChsZW4gLyA0OCkgfCAwKTtcblxuICAvLyBGaW5kIGQgYW5kIHMsIChuIC0gMSkgPSAoMiBeIHMpICogZDtcbiAgdmFyIG4xID0gbi5zdWJuKDEpO1xuICBmb3IgKHZhciBzID0gMDsgIW4xLnRlc3RuKHMpOyBzKyspIHt9XG4gIHZhciBkID0gbi5zaHJuKHMpO1xuXG4gIHZhciBybjEgPSBuMS50b1JlZChyZWQpO1xuXG4gIHZhciBwcmltZSA9IHRydWU7XG4gIGZvciAoOyBrID4gMDsgay0tKSB7XG4gICAgdmFyIGEgPSB0aGlzLl9yYW5kcmFuZ2UobmV3IGJuKDIpLCBuMSk7XG4gICAgaWYgKGNiKVxuICAgICAgY2IoYSk7XG5cbiAgICB2YXIgeCA9IGEudG9SZWQocmVkKS5yZWRQb3coZCk7XG4gICAgaWYgKHguY21wKHJvbmUpID09PSAwIHx8IHguY21wKHJuMSkgPT09IDApXG4gICAgICBjb250aW51ZTtcblxuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgczsgaSsrKSB7XG4gICAgICB4ID0geC5yZWRTcXIoKTtcblxuICAgICAgaWYgKHguY21wKHJvbmUpID09PSAwKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICBpZiAoeC5jbXAocm4xKSA9PT0gMClcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKGkgPT09IHMpXG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gcHJpbWU7XG59O1xuXG5NaWxsZXJSYWJpbi5wcm90b3R5cGUuZ2V0RGl2aXNvciA9IGZ1bmN0aW9uIGdldERpdmlzb3Iobiwgaykge1xuICB2YXIgbGVuID0gbi5iaXRMZW5ndGgoKTtcbiAgdmFyIHJlZCA9IGJuLm1vbnQobik7XG4gIHZhciByb25lID0gbmV3IGJuKDEpLnRvUmVkKHJlZCk7XG5cbiAgaWYgKCFrKVxuICAgIGsgPSBNYXRoLm1heCgxLCAobGVuIC8gNDgpIHwgMCk7XG5cbiAgLy8gRmluZCBkIGFuZCBzLCAobiAtIDEpID0gKDIgXiBzKSAqIGQ7XG4gIHZhciBuMSA9IG4uc3VibigxKTtcbiAgZm9yICh2YXIgcyA9IDA7ICFuMS50ZXN0bihzKTsgcysrKSB7fVxuICB2YXIgZCA9IG4uc2hybihzKTtcblxuICB2YXIgcm4xID0gbjEudG9SZWQocmVkKTtcblxuICBmb3IgKDsgayA+IDA7IGstLSkge1xuICAgIHZhciBhID0gdGhpcy5fcmFuZHJhbmdlKG5ldyBibigyKSwgbjEpO1xuXG4gICAgdmFyIGcgPSBuLmdjZChhKTtcbiAgICBpZiAoZy5jbXBuKDEpICE9PSAwKVxuICAgICAgcmV0dXJuIGc7XG5cbiAgICB2YXIgeCA9IGEudG9SZWQocmVkKS5yZWRQb3coZCk7XG4gICAgaWYgKHguY21wKHJvbmUpID09PSAwIHx8IHguY21wKHJuMSkgPT09IDApXG4gICAgICBjb250aW51ZTtcblxuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgczsgaSsrKSB7XG4gICAgICB4ID0geC5yZWRTcXIoKTtcblxuICAgICAgaWYgKHguY21wKHJvbmUpID09PSAwKVxuICAgICAgICByZXR1cm4geC5mcm9tUmVkKCkuc3VibigxKS5nY2Qobik7XG4gICAgICBpZiAoeC5jbXAocm4xKSA9PT0gMClcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKGkgPT09IHMpIHtcbiAgICAgIHggPSB4LnJlZFNxcigpO1xuICAgICAgcmV0dXJuIHguZnJvbVJlZCgpLnN1Ym4oMSkuZ2NkKG4pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGFzc2VydDtcblxuZnVuY3Rpb24gYXNzZXJ0KHZhbCwgbXNnKSB7XG4gIGlmICghdmFsKVxuICAgIHRocm93IG5ldyBFcnJvcihtc2cgfHwgJ0Fzc2VydGlvbiBmYWlsZWQnKTtcbn1cblxuYXNzZXJ0LmVxdWFsID0gZnVuY3Rpb24gYXNzZXJ0RXF1YWwobCwgciwgbXNnKSB7XG4gIGlmIChsICE9IHIpXG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZyB8fCAoJ0Fzc2VydGlvbiBmYWlsZWQ6ICcgKyBsICsgJyAhPSAnICsgcikpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gZXhwb3J0cztcblxuZnVuY3Rpb24gdG9BcnJheShtc2csIGVuYykge1xuICBpZiAoQXJyYXkuaXNBcnJheShtc2cpKVxuICAgIHJldHVybiBtc2cuc2xpY2UoKTtcbiAgaWYgKCFtc2cpXG4gICAgcmV0dXJuIFtdO1xuICB2YXIgcmVzID0gW107XG4gIGlmICh0eXBlb2YgbXNnICE9PSAnc3RyaW5nJykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKVxuICAgICAgcmVzW2ldID0gbXNnW2ldIHwgMDtcbiAgICByZXR1cm4gcmVzO1xuICB9XG4gIGlmIChlbmMgPT09ICdoZXgnKSB7XG4gICAgbXNnID0gbXNnLnJlcGxhY2UoL1teYS16MC05XSsvaWcsICcnKTtcbiAgICBpZiAobXNnLmxlbmd0aCAlIDIgIT09IDApXG4gICAgICBtc2cgPSAnMCcgKyBtc2c7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpICs9IDIpXG4gICAgICByZXMucHVzaChwYXJzZUludChtc2dbaV0gKyBtc2dbaSArIDFdLCAxNikpO1xuICB9IGVsc2Uge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgYyA9IG1zZy5jaGFyQ29kZUF0KGkpO1xuICAgICAgdmFyIGhpID0gYyA+PiA4O1xuICAgICAgdmFyIGxvID0gYyAmIDB4ZmY7XG4gICAgICBpZiAoaGkpXG4gICAgICAgIHJlcy5wdXNoKGhpLCBsbyk7XG4gICAgICBlbHNlXG4gICAgICAgIHJlcy5wdXNoKGxvKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbnV0aWxzLnRvQXJyYXkgPSB0b0FycmF5O1xuXG5mdW5jdGlvbiB6ZXJvMih3b3JkKSB7XG4gIGlmICh3b3JkLmxlbmd0aCA9PT0gMSlcbiAgICByZXR1cm4gJzAnICsgd29yZDtcbiAgZWxzZVxuICAgIHJldHVybiB3b3JkO1xufVxudXRpbHMuemVybzIgPSB6ZXJvMjtcblxuZnVuY3Rpb24gdG9IZXgobXNnKSB7XG4gIHZhciByZXMgPSAnJztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspXG4gICAgcmVzICs9IHplcm8yKG1zZ1tpXS50b1N0cmluZygxNikpO1xuICByZXR1cm4gcmVzO1xufVxudXRpbHMudG9IZXggPSB0b0hleDtcblxudXRpbHMuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKGFyciwgZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB0b0hleChhcnIpO1xuICBlbHNlXG4gICAgcmV0dXJuIGFycjtcbn07XG4iLCIvLyBUb3AgbGV2ZWwgZmlsZSBpcyBqdXN0IGEgbWl4aW4gb2Ygc3VibW9kdWxlcyAmIGNvbnN0YW50c1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzaWduICAgID0gcmVxdWlyZSgnLi9saWIvdXRpbHMvY29tbW9uJykuYXNzaWduO1xuXG52YXIgZGVmbGF0ZSAgID0gcmVxdWlyZSgnLi9saWIvZGVmbGF0ZScpO1xudmFyIGluZmxhdGUgICA9IHJlcXVpcmUoJy4vbGliL2luZmxhdGUnKTtcbnZhciBjb25zdGFudHMgPSByZXF1aXJlKCcuL2xpYi96bGliL2NvbnN0YW50cycpO1xuXG52YXIgcGFrbyA9IHt9O1xuXG5hc3NpZ24ocGFrbywgZGVmbGF0ZSwgaW5mbGF0ZSwgY29uc3RhbnRzKTtcblxubW9kdWxlLmV4cG9ydHMgPSBwYWtvO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciB6bGliX2RlZmxhdGUgPSByZXF1aXJlKCcuL3psaWIvZGVmbGF0ZScpO1xudmFyIHV0aWxzICAgICAgICA9IHJlcXVpcmUoJy4vdXRpbHMvY29tbW9uJyk7XG52YXIgc3RyaW5ncyAgICAgID0gcmVxdWlyZSgnLi91dGlscy9zdHJpbmdzJyk7XG52YXIgbXNnICAgICAgICAgID0gcmVxdWlyZSgnLi96bGliL21lc3NhZ2VzJyk7XG52YXIgWlN0cmVhbSAgICAgID0gcmVxdWlyZSgnLi96bGliL3pzdHJlYW0nKTtcblxudmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxuLyogUHVibGljIGNvbnN0YW50cyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cbnZhciBaX05PX0ZMVVNIICAgICAgPSAwO1xudmFyIFpfRklOSVNIICAgICAgICA9IDQ7XG5cbnZhciBaX09LICAgICAgICAgICAgPSAwO1xudmFyIFpfU1RSRUFNX0VORCAgICA9IDE7XG52YXIgWl9TWU5DX0ZMVVNIICAgID0gMjtcblxudmFyIFpfREVGQVVMVF9DT01QUkVTU0lPTiA9IC0xO1xuXG52YXIgWl9ERUZBVUxUX1NUUkFURUdZICAgID0gMDtcblxudmFyIFpfREVGTEFURUQgID0gODtcblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cblxuXG4vKipcbiAqIGNsYXNzIERlZmxhdGVcbiAqXG4gKiBHZW5lcmljIEpTLXN0eWxlIHdyYXBwZXIgZm9yIHpsaWIgY2FsbHMuIElmIHlvdSBkb24ndCBuZWVkXG4gKiBzdHJlYW1pbmcgYmVoYXZpb3VyIC0gdXNlIG1vcmUgc2ltcGxlIGZ1bmN0aW9uczogW1tkZWZsYXRlXV0sXG4gKiBbW2RlZmxhdGVSYXddXSBhbmQgW1tnemlwXV0uXG4gKiovXG5cbi8qIGludGVybmFsXG4gKiBEZWZsYXRlLmNodW5rcyAtPiBBcnJheVxuICpcbiAqIENodW5rcyBvZiBvdXRwdXQgZGF0YSwgaWYgW1tEZWZsYXRlI29uRGF0YV1dIG5vdCBvdmVycmlkZGVuLlxuICoqL1xuXG4vKipcbiAqIERlZmxhdGUucmVzdWx0IC0+IFVpbnQ4QXJyYXl8QXJyYXlcbiAqXG4gKiBDb21wcmVzc2VkIHJlc3VsdCwgZ2VuZXJhdGVkIGJ5IGRlZmF1bHQgW1tEZWZsYXRlI29uRGF0YV1dXG4gKiBhbmQgW1tEZWZsYXRlI29uRW5kXV0gaGFuZGxlcnMuIEZpbGxlZCBhZnRlciB5b3UgcHVzaCBsYXN0IGNodW5rXG4gKiAoY2FsbCBbW0RlZmxhdGUjcHVzaF1dIHdpdGggYFpfRklOSVNIYCAvIGB0cnVlYCBwYXJhbSkgIG9yIGlmIHlvdVxuICogcHVzaCBhIGNodW5rIHdpdGggZXhwbGljaXQgZmx1c2ggKGNhbGwgW1tEZWZsYXRlI3B1c2hdXSB3aXRoXG4gKiBgWl9TWU5DX0ZMVVNIYCBwYXJhbSkuXG4gKiovXG5cbi8qKlxuICogRGVmbGF0ZS5lcnIgLT4gTnVtYmVyXG4gKlxuICogRXJyb3IgY29kZSBhZnRlciBkZWZsYXRlIGZpbmlzaGVkLiAwIChaX09LKSBvbiBzdWNjZXNzLlxuICogWW91IHdpbGwgbm90IG5lZWQgaXQgaW4gcmVhbCBsaWZlLCBiZWNhdXNlIGRlZmxhdGUgZXJyb3JzXG4gKiBhcmUgcG9zc2libGUgb25seSBvbiB3cm9uZyBvcHRpb25zIG9yIGJhZCBgb25EYXRhYCAvIGBvbkVuZGBcbiAqIGN1c3RvbSBoYW5kbGVycy5cbiAqKi9cblxuLyoqXG4gKiBEZWZsYXRlLm1zZyAtPiBTdHJpbmdcbiAqXG4gKiBFcnJvciBtZXNzYWdlLCBpZiBbW0RlZmxhdGUuZXJyXV0gIT0gMFxuICoqL1xuXG5cbi8qKlxuICogbmV3IERlZmxhdGUob3B0aW9ucylcbiAqIC0gb3B0aW9ucyAoT2JqZWN0KTogemxpYiBkZWZsYXRlIG9wdGlvbnMuXG4gKlxuICogQ3JlYXRlcyBuZXcgZGVmbGF0b3IgaW5zdGFuY2Ugd2l0aCBzcGVjaWZpZWQgcGFyYW1zLiBUaHJvd3MgZXhjZXB0aW9uXG4gKiBvbiBiYWQgcGFyYW1zLiBTdXBwb3J0ZWQgb3B0aW9uczpcbiAqXG4gKiAtIGBsZXZlbGBcbiAqIC0gYHdpbmRvd0JpdHNgXG4gKiAtIGBtZW1MZXZlbGBcbiAqIC0gYHN0cmF0ZWd5YFxuICogLSBgZGljdGlvbmFyeWBcbiAqXG4gKiBbaHR0cDovL3psaWIubmV0L21hbnVhbC5odG1sI0FkdmFuY2VkXShodHRwOi8vemxpYi5uZXQvbWFudWFsLmh0bWwjQWR2YW5jZWQpXG4gKiBmb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiB0aGVzZS5cbiAqXG4gKiBBZGRpdGlvbmFsIG9wdGlvbnMsIGZvciBpbnRlcm5hbCBuZWVkczpcbiAqXG4gKiAtIGBjaHVua1NpemVgIC0gc2l6ZSBvZiBnZW5lcmF0ZWQgZGF0YSBjaHVua3MgKDE2SyBieSBkZWZhdWx0KVxuICogLSBgcmF3YCAoQm9vbGVhbikgLSBkbyByYXcgZGVmbGF0ZVxuICogLSBgZ3ppcGAgKEJvb2xlYW4pIC0gY3JlYXRlIGd6aXAgd3JhcHBlclxuICogLSBgdG9gIChTdHJpbmcpIC0gaWYgZXF1YWwgdG8gJ3N0cmluZycsIHRoZW4gcmVzdWx0IHdpbGwgYmUgXCJiaW5hcnkgc3RyaW5nXCJcbiAqICAgIChlYWNoIGNoYXIgY29kZSBbMC4uMjU1XSlcbiAqIC0gYGhlYWRlcmAgKE9iamVjdCkgLSBjdXN0b20gaGVhZGVyIGZvciBnemlwXG4gKiAgIC0gYHRleHRgIChCb29sZWFuKSAtIHRydWUgaWYgY29tcHJlc3NlZCBkYXRhIGJlbGlldmVkIHRvIGJlIHRleHRcbiAqICAgLSBgdGltZWAgKE51bWJlcikgLSBtb2RpZmljYXRpb24gdGltZSwgdW5peCB0aW1lc3RhbXBcbiAqICAgLSBgb3NgIChOdW1iZXIpIC0gb3BlcmF0aW9uIHN5c3RlbSBjb2RlXG4gKiAgIC0gYGV4dHJhYCAoQXJyYXkpIC0gYXJyYXkgb2YgYnl0ZXMgd2l0aCBleHRyYSBkYXRhIChtYXggNjU1MzYpXG4gKiAgIC0gYG5hbWVgIChTdHJpbmcpIC0gZmlsZSBuYW1lIChiaW5hcnkgc3RyaW5nKVxuICogICAtIGBjb21tZW50YCAoU3RyaW5nKSAtIGNvbW1lbnQgKGJpbmFyeSBzdHJpbmcpXG4gKiAgIC0gYGhjcmNgIChCb29sZWFuKSAtIHRydWUgaWYgaGVhZGVyIGNyYyBzaG91bGQgYmUgYWRkZWRcbiAqXG4gKiAjIyMjIyBFeGFtcGxlOlxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIHZhciBwYWtvID0gcmVxdWlyZSgncGFrbycpXG4gKiAgICwgY2h1bmsxID0gVWludDhBcnJheShbMSwyLDMsNCw1LDYsNyw4LDldKVxuICogICAsIGNodW5rMiA9IFVpbnQ4QXJyYXkoWzEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5XSk7XG4gKlxuICogdmFyIGRlZmxhdGUgPSBuZXcgcGFrby5EZWZsYXRlKHsgbGV2ZWw6IDN9KTtcbiAqXG4gKiBkZWZsYXRlLnB1c2goY2h1bmsxLCBmYWxzZSk7XG4gKiBkZWZsYXRlLnB1c2goY2h1bmsyLCB0cnVlKTsgIC8vIHRydWUgLT4gbGFzdCBjaHVua1xuICpcbiAqIGlmIChkZWZsYXRlLmVycikgeyB0aHJvdyBuZXcgRXJyb3IoZGVmbGF0ZS5lcnIpOyB9XG4gKlxuICogY29uc29sZS5sb2coZGVmbGF0ZS5yZXN1bHQpO1xuICogYGBgXG4gKiovXG5mdW5jdGlvbiBEZWZsYXRlKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIERlZmxhdGUpKSByZXR1cm4gbmV3IERlZmxhdGUob3B0aW9ucyk7XG5cbiAgdGhpcy5vcHRpb25zID0gdXRpbHMuYXNzaWduKHtcbiAgICBsZXZlbDogWl9ERUZBVUxUX0NPTVBSRVNTSU9OLFxuICAgIG1ldGhvZDogWl9ERUZMQVRFRCxcbiAgICBjaHVua1NpemU6IDE2Mzg0LFxuICAgIHdpbmRvd0JpdHM6IDE1LFxuICAgIG1lbUxldmVsOiA4LFxuICAgIHN0cmF0ZWd5OiBaX0RFRkFVTFRfU1RSQVRFR1ksXG4gICAgdG86ICcnXG4gIH0sIG9wdGlvbnMgfHwge30pO1xuXG4gIHZhciBvcHQgPSB0aGlzLm9wdGlvbnM7XG5cbiAgaWYgKG9wdC5yYXcgJiYgKG9wdC53aW5kb3dCaXRzID4gMCkpIHtcbiAgICBvcHQud2luZG93Qml0cyA9IC1vcHQud2luZG93Qml0cztcbiAgfVxuXG4gIGVsc2UgaWYgKG9wdC5nemlwICYmIChvcHQud2luZG93Qml0cyA+IDApICYmIChvcHQud2luZG93Qml0cyA8IDE2KSkge1xuICAgIG9wdC53aW5kb3dCaXRzICs9IDE2O1xuICB9XG5cbiAgdGhpcy5lcnIgICAgPSAwOyAgICAgIC8vIGVycm9yIGNvZGUsIGlmIGhhcHBlbnMgKDAgPSBaX09LKVxuICB0aGlzLm1zZyAgICA9ICcnOyAgICAgLy8gZXJyb3IgbWVzc2FnZVxuICB0aGlzLmVuZGVkICA9IGZhbHNlOyAgLy8gdXNlZCB0byBhdm9pZCBtdWx0aXBsZSBvbkVuZCgpIGNhbGxzXG4gIHRoaXMuY2h1bmtzID0gW107ICAgICAvLyBjaHVua3Mgb2YgY29tcHJlc3NlZCBkYXRhXG5cbiAgdGhpcy5zdHJtID0gbmV3IFpTdHJlYW0oKTtcbiAgdGhpcy5zdHJtLmF2YWlsX291dCA9IDA7XG5cbiAgdmFyIHN0YXR1cyA9IHpsaWJfZGVmbGF0ZS5kZWZsYXRlSW5pdDIoXG4gICAgdGhpcy5zdHJtLFxuICAgIG9wdC5sZXZlbCxcbiAgICBvcHQubWV0aG9kLFxuICAgIG9wdC53aW5kb3dCaXRzLFxuICAgIG9wdC5tZW1MZXZlbCxcbiAgICBvcHQuc3RyYXRlZ3lcbiAgKTtcblxuICBpZiAoc3RhdHVzICE9PSBaX09LKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZ1tzdGF0dXNdKTtcbiAgfVxuXG4gIGlmIChvcHQuaGVhZGVyKSB7XG4gICAgemxpYl9kZWZsYXRlLmRlZmxhdGVTZXRIZWFkZXIodGhpcy5zdHJtLCBvcHQuaGVhZGVyKTtcbiAgfVxuXG4gIGlmIChvcHQuZGljdGlvbmFyeSkge1xuICAgIHZhciBkaWN0O1xuICAgIC8vIENvbnZlcnQgZGF0YSBpZiBuZWVkZWRcbiAgICBpZiAodHlwZW9mIG9wdC5kaWN0aW9uYXJ5ID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gSWYgd2UgbmVlZCB0byBjb21wcmVzcyB0ZXh0LCBjaGFuZ2UgZW5jb2RpbmcgdG8gdXRmOC5cbiAgICAgIGRpY3QgPSBzdHJpbmdzLnN0cmluZzJidWYob3B0LmRpY3Rpb25hcnkpO1xuICAgIH0gZWxzZSBpZiAodG9TdHJpbmcuY2FsbChvcHQuZGljdGlvbmFyeSkgPT09ICdbb2JqZWN0IEFycmF5QnVmZmVyXScpIHtcbiAgICAgIGRpY3QgPSBuZXcgVWludDhBcnJheShvcHQuZGljdGlvbmFyeSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRpY3QgPSBvcHQuZGljdGlvbmFyeTtcbiAgICB9XG5cbiAgICBzdGF0dXMgPSB6bGliX2RlZmxhdGUuZGVmbGF0ZVNldERpY3Rpb25hcnkodGhpcy5zdHJtLCBkaWN0KTtcblxuICAgIGlmIChzdGF0dXMgIT09IFpfT0spIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihtc2dbc3RhdHVzXSk7XG4gICAgfVxuXG4gICAgdGhpcy5fZGljdF9zZXQgPSB0cnVlO1xuICB9XG59XG5cbi8qKlxuICogRGVmbGF0ZSNwdXNoKGRhdGFbLCBtb2RlXSkgLT4gQm9vbGVhblxuICogLSBkYXRhIChVaW50OEFycmF5fEFycmF5fEFycmF5QnVmZmVyfFN0cmluZyk6IGlucHV0IGRhdGEuIFN0cmluZ3Mgd2lsbCBiZVxuICogICBjb252ZXJ0ZWQgdG8gdXRmOCBieXRlIHNlcXVlbmNlLlxuICogLSBtb2RlIChOdW1iZXJ8Qm9vbGVhbik6IDAuLjYgZm9yIGNvcnJlc3BvbmRpbmcgWl9OT19GTFVTSC4uWl9UUkVFIG1vZGVzLlxuICogICBTZWUgY29uc3RhbnRzLiBTa2lwcGVkIG9yIGBmYWxzZWAgbWVhbnMgWl9OT19GTFVTSCwgYHRydWVgIG1lYW5zIFpfRklOSVNILlxuICpcbiAqIFNlbmRzIGlucHV0IGRhdGEgdG8gZGVmbGF0ZSBwaXBlLCBnZW5lcmF0aW5nIFtbRGVmbGF0ZSNvbkRhdGFdXSBjYWxscyB3aXRoXG4gKiBuZXcgY29tcHJlc3NlZCBjaHVua3MuIFJldHVybnMgYHRydWVgIG9uIHN1Y2Nlc3MuIFRoZSBsYXN0IGRhdGEgYmxvY2sgbXVzdCBoYXZlXG4gKiBtb2RlIFpfRklOSVNIIChvciBgdHJ1ZWApLiBUaGF0IHdpbGwgZmx1c2ggaW50ZXJuYWwgcGVuZGluZyBidWZmZXJzIGFuZCBjYWxsXG4gKiBbW0RlZmxhdGUjb25FbmRdXS4gRm9yIGludGVyaW0gZXhwbGljaXQgZmx1c2hlcyAod2l0aG91dCBlbmRpbmcgdGhlIHN0cmVhbSkgeW91XG4gKiBjYW4gdXNlIG1vZGUgWl9TWU5DX0ZMVVNILCBrZWVwaW5nIHRoZSBjb21wcmVzc2lvbiBjb250ZXh0LlxuICpcbiAqIE9uIGZhaWwgY2FsbCBbW0RlZmxhdGUjb25FbmRdXSB3aXRoIGVycm9yIGNvZGUgYW5kIHJldHVybiBmYWxzZS5cbiAqXG4gKiBXZSBzdHJvbmdseSByZWNvbW1lbmQgdG8gdXNlIGBVaW50OEFycmF5YCBvbiBpbnB1dCBmb3IgYmVzdCBzcGVlZCAob3V0cHV0XG4gKiBhcnJheSBmb3JtYXQgaXMgZGV0ZWN0ZWQgYXV0b21hdGljYWxseSkuIEFsc28sIGRvbid0IHNraXAgbGFzdCBwYXJhbSBhbmQgYWx3YXlzXG4gKiB1c2UgdGhlIHNhbWUgdHlwZSBpbiB5b3VyIGNvZGUgKGJvb2xlYW4gb3IgbnVtYmVyKS4gVGhhdCB3aWxsIGltcHJvdmUgSlMgc3BlZWQuXG4gKlxuICogRm9yIHJlZ3VsYXIgYEFycmF5YC1zIG1ha2Ugc3VyZSBhbGwgZWxlbWVudHMgYXJlIFswLi4yNTVdLlxuICpcbiAqICMjIyMjIEV4YW1wbGVcbiAqXG4gKiBgYGBqYXZhc2NyaXB0XG4gKiBwdXNoKGNodW5rLCBmYWxzZSk7IC8vIHB1c2ggb25lIG9mIGRhdGEgY2h1bmtzXG4gKiAuLi5cbiAqIHB1c2goY2h1bmssIHRydWUpOyAgLy8gcHVzaCBsYXN0IGNodW5rXG4gKiBgYGBcbiAqKi9cbkRlZmxhdGUucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbiAoZGF0YSwgbW9kZSkge1xuICB2YXIgc3RybSA9IHRoaXMuc3RybTtcbiAgdmFyIGNodW5rU2l6ZSA9IHRoaXMub3B0aW9ucy5jaHVua1NpemU7XG4gIHZhciBzdGF0dXMsIF9tb2RlO1xuXG4gIGlmICh0aGlzLmVuZGVkKSB7IHJldHVybiBmYWxzZTsgfVxuXG4gIF9tb2RlID0gKG1vZGUgPT09IH5+bW9kZSkgPyBtb2RlIDogKChtb2RlID09PSB0cnVlKSA/IFpfRklOSVNIIDogWl9OT19GTFVTSCk7XG5cbiAgLy8gQ29udmVydCBkYXRhIGlmIG5lZWRlZFxuICBpZiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgLy8gSWYgd2UgbmVlZCB0byBjb21wcmVzcyB0ZXh0LCBjaGFuZ2UgZW5jb2RpbmcgdG8gdXRmOC5cbiAgICBzdHJtLmlucHV0ID0gc3RyaW5ncy5zdHJpbmcyYnVmKGRhdGEpO1xuICB9IGVsc2UgaWYgKHRvU3RyaW5nLmNhbGwoZGF0YSkgPT09ICdbb2JqZWN0IEFycmF5QnVmZmVyXScpIHtcbiAgICBzdHJtLmlucHV0ID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7XG4gIH0gZWxzZSB7XG4gICAgc3RybS5pbnB1dCA9IGRhdGE7XG4gIH1cblxuICBzdHJtLm5leHRfaW4gPSAwO1xuICBzdHJtLmF2YWlsX2luID0gc3RybS5pbnB1dC5sZW5ndGg7XG5cbiAgZG8ge1xuICAgIGlmIChzdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgc3RybS5vdXRwdXQgPSBuZXcgdXRpbHMuQnVmOChjaHVua1NpemUpO1xuICAgICAgc3RybS5uZXh0X291dCA9IDA7XG4gICAgICBzdHJtLmF2YWlsX291dCA9IGNodW5rU2l6ZTtcbiAgICB9XG4gICAgc3RhdHVzID0gemxpYl9kZWZsYXRlLmRlZmxhdGUoc3RybSwgX21vZGUpOyAgICAvKiBubyBiYWQgcmV0dXJuIHZhbHVlICovXG5cbiAgICBpZiAoc3RhdHVzICE9PSBaX1NUUkVBTV9FTkQgJiYgc3RhdHVzICE9PSBaX09LKSB7XG4gICAgICB0aGlzLm9uRW5kKHN0YXR1cyk7XG4gICAgICB0aGlzLmVuZGVkID0gdHJ1ZTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHN0cm0uYXZhaWxfb3V0ID09PSAwIHx8IChzdHJtLmF2YWlsX2luID09PSAwICYmIChfbW9kZSA9PT0gWl9GSU5JU0ggfHwgX21vZGUgPT09IFpfU1lOQ19GTFVTSCkpKSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLnRvID09PSAnc3RyaW5nJykge1xuICAgICAgICB0aGlzLm9uRGF0YShzdHJpbmdzLmJ1ZjJiaW5zdHJpbmcodXRpbHMuc2hyaW5rQnVmKHN0cm0ub3V0cHV0LCBzdHJtLm5leHRfb3V0KSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5vbkRhdGEodXRpbHMuc2hyaW5rQnVmKHN0cm0ub3V0cHV0LCBzdHJtLm5leHRfb3V0KSk7XG4gICAgICB9XG4gICAgfVxuICB9IHdoaWxlICgoc3RybS5hdmFpbF9pbiA+IDAgfHwgc3RybS5hdmFpbF9vdXQgPT09IDApICYmIHN0YXR1cyAhPT0gWl9TVFJFQU1fRU5EKTtcblxuICAvLyBGaW5hbGl6ZSBvbiB0aGUgbGFzdCBjaHVuay5cbiAgaWYgKF9tb2RlID09PSBaX0ZJTklTSCkge1xuICAgIHN0YXR1cyA9IHpsaWJfZGVmbGF0ZS5kZWZsYXRlRW5kKHRoaXMuc3RybSk7XG4gICAgdGhpcy5vbkVuZChzdGF0dXMpO1xuICAgIHRoaXMuZW5kZWQgPSB0cnVlO1xuICAgIHJldHVybiBzdGF0dXMgPT09IFpfT0s7XG4gIH1cblxuICAvLyBjYWxsYmFjayBpbnRlcmltIHJlc3VsdHMgaWYgWl9TWU5DX0ZMVVNILlxuICBpZiAoX21vZGUgPT09IFpfU1lOQ19GTFVTSCkge1xuICAgIHRoaXMub25FbmQoWl9PSyk7XG4gICAgc3RybS5hdmFpbF9vdXQgPSAwO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5cbi8qKlxuICogRGVmbGF0ZSNvbkRhdGEoY2h1bmspIC0+IFZvaWRcbiAqIC0gY2h1bmsgKFVpbnQ4QXJyYXl8QXJyYXl8U3RyaW5nKTogb3V0cHV0IGRhdGEuIFR5cGUgb2YgYXJyYXkgZGVwZW5kc1xuICogICBvbiBqcyBlbmdpbmUgc3VwcG9ydC4gV2hlbiBzdHJpbmcgb3V0cHV0IHJlcXVlc3RlZCwgZWFjaCBjaHVua1xuICogICB3aWxsIGJlIHN0cmluZy5cbiAqXG4gKiBCeSBkZWZhdWx0LCBzdG9yZXMgZGF0YSBibG9ja3MgaW4gYGNodW5rc1tdYCBwcm9wZXJ0eSBhbmQgZ2x1ZVxuICogdGhvc2UgaW4gYG9uRW5kYC4gT3ZlcnJpZGUgdGhpcyBoYW5kbGVyLCBpZiB5b3UgbmVlZCBhbm90aGVyIGJlaGF2aW91ci5cbiAqKi9cbkRlZmxhdGUucHJvdG90eXBlLm9uRGF0YSA9IGZ1bmN0aW9uIChjaHVuaykge1xuICB0aGlzLmNodW5rcy5wdXNoKGNodW5rKTtcbn07XG5cblxuLyoqXG4gKiBEZWZsYXRlI29uRW5kKHN0YXR1cykgLT4gVm9pZFxuICogLSBzdGF0dXMgKE51bWJlcik6IGRlZmxhdGUgc3RhdHVzLiAwIChaX09LKSBvbiBzdWNjZXNzLFxuICogICBvdGhlciBpZiBub3QuXG4gKlxuICogQ2FsbGVkIG9uY2UgYWZ0ZXIgeW91IHRlbGwgZGVmbGF0ZSB0aGF0IHRoZSBpbnB1dCBzdHJlYW0gaXNcbiAqIGNvbXBsZXRlIChaX0ZJTklTSCkgb3Igc2hvdWxkIGJlIGZsdXNoZWQgKFpfU1lOQ19GTFVTSClcbiAqIG9yIGlmIGFuIGVycm9yIGhhcHBlbmVkLiBCeSBkZWZhdWx0IC0gam9pbiBjb2xsZWN0ZWQgY2h1bmtzLFxuICogZnJlZSBtZW1vcnkgYW5kIGZpbGwgYHJlc3VsdHNgIC8gYGVycmAgcHJvcGVydGllcy5cbiAqKi9cbkRlZmxhdGUucHJvdG90eXBlLm9uRW5kID0gZnVuY3Rpb24gKHN0YXR1cykge1xuICAvLyBPbiBzdWNjZXNzIC0gam9pblxuICBpZiAoc3RhdHVzID09PSBaX09LKSB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy50byA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRoaXMucmVzdWx0ID0gdGhpcy5jaHVua3Muam9pbignJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmVzdWx0ID0gdXRpbHMuZmxhdHRlbkNodW5rcyh0aGlzLmNodW5rcyk7XG4gICAgfVxuICB9XG4gIHRoaXMuY2h1bmtzID0gW107XG4gIHRoaXMuZXJyID0gc3RhdHVzO1xuICB0aGlzLm1zZyA9IHRoaXMuc3RybS5tc2c7XG59O1xuXG5cbi8qKlxuICogZGVmbGF0ZShkYXRhWywgb3B0aW9uc10pIC0+IFVpbnQ4QXJyYXl8QXJyYXl8U3RyaW5nXG4gKiAtIGRhdGEgKFVpbnQ4QXJyYXl8QXJyYXl8U3RyaW5nKTogaW5wdXQgZGF0YSB0byBjb21wcmVzcy5cbiAqIC0gb3B0aW9ucyAoT2JqZWN0KTogemxpYiBkZWZsYXRlIG9wdGlvbnMuXG4gKlxuICogQ29tcHJlc3MgYGRhdGFgIHdpdGggZGVmbGF0ZSBhbGdvcml0aG0gYW5kIGBvcHRpb25zYC5cbiAqXG4gKiBTdXBwb3J0ZWQgb3B0aW9ucyBhcmU6XG4gKlxuICogLSBsZXZlbFxuICogLSB3aW5kb3dCaXRzXG4gKiAtIG1lbUxldmVsXG4gKiAtIHN0cmF0ZWd5XG4gKiAtIGRpY3Rpb25hcnlcbiAqXG4gKiBbaHR0cDovL3psaWIubmV0L21hbnVhbC5odG1sI0FkdmFuY2VkXShodHRwOi8vemxpYi5uZXQvbWFudWFsLmh0bWwjQWR2YW5jZWQpXG4gKiBmb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiB0aGVzZS5cbiAqXG4gKiBTdWdhciAob3B0aW9ucyk6XG4gKlxuICogLSBgcmF3YCAoQm9vbGVhbikgLSBzYXkgdGhhdCB3ZSB3b3JrIHdpdGggcmF3IHN0cmVhbSwgaWYgeW91IGRvbid0IHdpc2ggdG8gc3BlY2lmeVxuICogICBuZWdhdGl2ZSB3aW5kb3dCaXRzIGltcGxpY2l0bHkuXG4gKiAtIGB0b2AgKFN0cmluZykgLSBpZiBlcXVhbCB0byAnc3RyaW5nJywgdGhlbiByZXN1bHQgd2lsbCBiZSBcImJpbmFyeSBzdHJpbmdcIlxuICogICAgKGVhY2ggY2hhciBjb2RlIFswLi4yNTVdKVxuICpcbiAqICMjIyMjIEV4YW1wbGU6XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogdmFyIHBha28gPSByZXF1aXJlKCdwYWtvJylcbiAqICAgLCBkYXRhID0gVWludDhBcnJheShbMSwyLDMsNCw1LDYsNyw4LDldKTtcbiAqXG4gKiBjb25zb2xlLmxvZyhwYWtvLmRlZmxhdGUoZGF0YSkpO1xuICogYGBgXG4gKiovXG5mdW5jdGlvbiBkZWZsYXRlKGlucHV0LCBvcHRpb25zKSB7XG4gIHZhciBkZWZsYXRvciA9IG5ldyBEZWZsYXRlKG9wdGlvbnMpO1xuXG4gIGRlZmxhdG9yLnB1c2goaW5wdXQsIHRydWUpO1xuXG4gIC8vIFRoYXQgd2lsbCBuZXZlciBoYXBwZW5zLCBpZiB5b3UgZG9uJ3QgY2hlYXQgd2l0aCBvcHRpb25zIDopXG4gIGlmIChkZWZsYXRvci5lcnIpIHsgdGhyb3cgZGVmbGF0b3IubXNnIHx8IG1zZ1tkZWZsYXRvci5lcnJdOyB9XG5cbiAgcmV0dXJuIGRlZmxhdG9yLnJlc3VsdDtcbn1cblxuXG4vKipcbiAqIGRlZmxhdGVSYXcoZGF0YVssIG9wdGlvbnNdKSAtPiBVaW50OEFycmF5fEFycmF5fFN0cmluZ1xuICogLSBkYXRhIChVaW50OEFycmF5fEFycmF5fFN0cmluZyk6IGlucHV0IGRhdGEgdG8gY29tcHJlc3MuXG4gKiAtIG9wdGlvbnMgKE9iamVjdCk6IHpsaWIgZGVmbGF0ZSBvcHRpb25zLlxuICpcbiAqIFRoZSBzYW1lIGFzIFtbZGVmbGF0ZV1dLCBidXQgY3JlYXRlcyByYXcgZGF0YSwgd2l0aG91dCB3cmFwcGVyXG4gKiAoaGVhZGVyIGFuZCBhZGxlcjMyIGNyYykuXG4gKiovXG5mdW5jdGlvbiBkZWZsYXRlUmF3KGlucHV0LCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBvcHRpb25zLnJhdyA9IHRydWU7XG4gIHJldHVybiBkZWZsYXRlKGlucHV0LCBvcHRpb25zKTtcbn1cblxuXG4vKipcbiAqIGd6aXAoZGF0YVssIG9wdGlvbnNdKSAtPiBVaW50OEFycmF5fEFycmF5fFN0cmluZ1xuICogLSBkYXRhIChVaW50OEFycmF5fEFycmF5fFN0cmluZyk6IGlucHV0IGRhdGEgdG8gY29tcHJlc3MuXG4gKiAtIG9wdGlvbnMgKE9iamVjdCk6IHpsaWIgZGVmbGF0ZSBvcHRpb25zLlxuICpcbiAqIFRoZSBzYW1lIGFzIFtbZGVmbGF0ZV1dLCBidXQgY3JlYXRlIGd6aXAgd3JhcHBlciBpbnN0ZWFkIG9mXG4gKiBkZWZsYXRlIG9uZS5cbiAqKi9cbmZ1bmN0aW9uIGd6aXAoaW5wdXQsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIG9wdGlvbnMuZ3ppcCA9IHRydWU7XG4gIHJldHVybiBkZWZsYXRlKGlucHV0LCBvcHRpb25zKTtcbn1cblxuXG5leHBvcnRzLkRlZmxhdGUgPSBEZWZsYXRlO1xuZXhwb3J0cy5kZWZsYXRlID0gZGVmbGF0ZTtcbmV4cG9ydHMuZGVmbGF0ZVJhdyA9IGRlZmxhdGVSYXc7XG5leHBvcnRzLmd6aXAgPSBnemlwO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciB6bGliX2luZmxhdGUgPSByZXF1aXJlKCcuL3psaWIvaW5mbGF0ZScpO1xudmFyIHV0aWxzICAgICAgICA9IHJlcXVpcmUoJy4vdXRpbHMvY29tbW9uJyk7XG52YXIgc3RyaW5ncyAgICAgID0gcmVxdWlyZSgnLi91dGlscy9zdHJpbmdzJyk7XG52YXIgYyAgICAgICAgICAgID0gcmVxdWlyZSgnLi96bGliL2NvbnN0YW50cycpO1xudmFyIG1zZyAgICAgICAgICA9IHJlcXVpcmUoJy4vemxpYi9tZXNzYWdlcycpO1xudmFyIFpTdHJlYW0gICAgICA9IHJlcXVpcmUoJy4vemxpYi96c3RyZWFtJyk7XG52YXIgR1poZWFkZXIgICAgID0gcmVxdWlyZSgnLi96bGliL2d6aGVhZGVyJyk7XG5cbnZhciB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8qKlxuICogY2xhc3MgSW5mbGF0ZVxuICpcbiAqIEdlbmVyaWMgSlMtc3R5bGUgd3JhcHBlciBmb3IgemxpYiBjYWxscy4gSWYgeW91IGRvbid0IG5lZWRcbiAqIHN0cmVhbWluZyBiZWhhdmlvdXIgLSB1c2UgbW9yZSBzaW1wbGUgZnVuY3Rpb25zOiBbW2luZmxhdGVdXVxuICogYW5kIFtbaW5mbGF0ZVJhd11dLlxuICoqL1xuXG4vKiBpbnRlcm5hbFxuICogaW5mbGF0ZS5jaHVua3MgLT4gQXJyYXlcbiAqXG4gKiBDaHVua3Mgb2Ygb3V0cHV0IGRhdGEsIGlmIFtbSW5mbGF0ZSNvbkRhdGFdXSBub3Qgb3ZlcnJpZGRlbi5cbiAqKi9cblxuLyoqXG4gKiBJbmZsYXRlLnJlc3VsdCAtPiBVaW50OEFycmF5fEFycmF5fFN0cmluZ1xuICpcbiAqIFVuY29tcHJlc3NlZCByZXN1bHQsIGdlbmVyYXRlZCBieSBkZWZhdWx0IFtbSW5mbGF0ZSNvbkRhdGFdXVxuICogYW5kIFtbSW5mbGF0ZSNvbkVuZF1dIGhhbmRsZXJzLiBGaWxsZWQgYWZ0ZXIgeW91IHB1c2ggbGFzdCBjaHVua1xuICogKGNhbGwgW1tJbmZsYXRlI3B1c2hdXSB3aXRoIGBaX0ZJTklTSGAgLyBgdHJ1ZWAgcGFyYW0pIG9yIGlmIHlvdVxuICogcHVzaCBhIGNodW5rIHdpdGggZXhwbGljaXQgZmx1c2ggKGNhbGwgW1tJbmZsYXRlI3B1c2hdXSB3aXRoXG4gKiBgWl9TWU5DX0ZMVVNIYCBwYXJhbSkuXG4gKiovXG5cbi8qKlxuICogSW5mbGF0ZS5lcnIgLT4gTnVtYmVyXG4gKlxuICogRXJyb3IgY29kZSBhZnRlciBpbmZsYXRlIGZpbmlzaGVkLiAwIChaX09LKSBvbiBzdWNjZXNzLlxuICogU2hvdWxkIGJlIGNoZWNrZWQgaWYgYnJva2VuIGRhdGEgcG9zc2libGUuXG4gKiovXG5cbi8qKlxuICogSW5mbGF0ZS5tc2cgLT4gU3RyaW5nXG4gKlxuICogRXJyb3IgbWVzc2FnZSwgaWYgW1tJbmZsYXRlLmVycl1dICE9IDBcbiAqKi9cblxuXG4vKipcbiAqIG5ldyBJbmZsYXRlKG9wdGlvbnMpXG4gKiAtIG9wdGlvbnMgKE9iamVjdCk6IHpsaWIgaW5mbGF0ZSBvcHRpb25zLlxuICpcbiAqIENyZWF0ZXMgbmV3IGluZmxhdG9yIGluc3RhbmNlIHdpdGggc3BlY2lmaWVkIHBhcmFtcy4gVGhyb3dzIGV4Y2VwdGlvblxuICogb24gYmFkIHBhcmFtcy4gU3VwcG9ydGVkIG9wdGlvbnM6XG4gKlxuICogLSBgd2luZG93Qml0c2BcbiAqIC0gYGRpY3Rpb25hcnlgXG4gKlxuICogW2h0dHA6Ly96bGliLm5ldC9tYW51YWwuaHRtbCNBZHZhbmNlZF0oaHR0cDovL3psaWIubmV0L21hbnVhbC5odG1sI0FkdmFuY2VkKVxuICogZm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhlc2UuXG4gKlxuICogQWRkaXRpb25hbCBvcHRpb25zLCBmb3IgaW50ZXJuYWwgbmVlZHM6XG4gKlxuICogLSBgY2h1bmtTaXplYCAtIHNpemUgb2YgZ2VuZXJhdGVkIGRhdGEgY2h1bmtzICgxNksgYnkgZGVmYXVsdClcbiAqIC0gYHJhd2AgKEJvb2xlYW4pIC0gZG8gcmF3IGluZmxhdGVcbiAqIC0gYHRvYCAoU3RyaW5nKSAtIGlmIGVxdWFsIHRvICdzdHJpbmcnLCB0aGVuIHJlc3VsdCB3aWxsIGJlIGNvbnZlcnRlZFxuICogICBmcm9tIHV0ZjggdG8gdXRmMTYgKGphdmFzY3JpcHQpIHN0cmluZy4gV2hlbiBzdHJpbmcgb3V0cHV0IHJlcXVlc3RlZCxcbiAqICAgY2h1bmsgbGVuZ3RoIGNhbiBkaWZmZXIgZnJvbSBgY2h1bmtTaXplYCwgZGVwZW5kaW5nIG9uIGNvbnRlbnQuXG4gKlxuICogQnkgZGVmYXVsdCwgd2hlbiBubyBvcHRpb25zIHNldCwgYXV0b2RldGVjdCBkZWZsYXRlL2d6aXAgZGF0YSBmb3JtYXQgdmlhXG4gKiB3cmFwcGVyIGhlYWRlci5cbiAqXG4gKiAjIyMjIyBFeGFtcGxlOlxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIHZhciBwYWtvID0gcmVxdWlyZSgncGFrbycpXG4gKiAgICwgY2h1bmsxID0gVWludDhBcnJheShbMSwyLDMsNCw1LDYsNyw4LDldKVxuICogICAsIGNodW5rMiA9IFVpbnQ4QXJyYXkoWzEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5XSk7XG4gKlxuICogdmFyIGluZmxhdGUgPSBuZXcgcGFrby5JbmZsYXRlKHsgbGV2ZWw6IDN9KTtcbiAqXG4gKiBpbmZsYXRlLnB1c2goY2h1bmsxLCBmYWxzZSk7XG4gKiBpbmZsYXRlLnB1c2goY2h1bmsyLCB0cnVlKTsgIC8vIHRydWUgLT4gbGFzdCBjaHVua1xuICpcbiAqIGlmIChpbmZsYXRlLmVycikgeyB0aHJvdyBuZXcgRXJyb3IoaW5mbGF0ZS5lcnIpOyB9XG4gKlxuICogY29uc29sZS5sb2coaW5mbGF0ZS5yZXN1bHQpO1xuICogYGBgXG4gKiovXG5mdW5jdGlvbiBJbmZsYXRlKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEluZmxhdGUpKSByZXR1cm4gbmV3IEluZmxhdGUob3B0aW9ucyk7XG5cbiAgdGhpcy5vcHRpb25zID0gdXRpbHMuYXNzaWduKHtcbiAgICBjaHVua1NpemU6IDE2Mzg0LFxuICAgIHdpbmRvd0JpdHM6IDAsXG4gICAgdG86ICcnXG4gIH0sIG9wdGlvbnMgfHwge30pO1xuXG4gIHZhciBvcHQgPSB0aGlzLm9wdGlvbnM7XG5cbiAgLy8gRm9yY2Ugd2luZG93IHNpemUgZm9yIGByYXdgIGRhdGEsIGlmIG5vdCBzZXQgZGlyZWN0bHksXG4gIC8vIGJlY2F1c2Ugd2UgaGF2ZSBubyBoZWFkZXIgZm9yIGF1dG9kZXRlY3QuXG4gIGlmIChvcHQucmF3ICYmIChvcHQud2luZG93Qml0cyA+PSAwKSAmJiAob3B0LndpbmRvd0JpdHMgPCAxNikpIHtcbiAgICBvcHQud2luZG93Qml0cyA9IC1vcHQud2luZG93Qml0cztcbiAgICBpZiAob3B0LndpbmRvd0JpdHMgPT09IDApIHsgb3B0LndpbmRvd0JpdHMgPSAtMTU7IH1cbiAgfVxuXG4gIC8vIElmIGB3aW5kb3dCaXRzYCBub3QgZGVmaW5lZCAoYW5kIG1vZGUgbm90IHJhdykgLSBzZXQgYXV0b2RldGVjdCBmbGFnIGZvciBnemlwL2RlZmxhdGVcbiAgaWYgKChvcHQud2luZG93Qml0cyA+PSAwKSAmJiAob3B0LndpbmRvd0JpdHMgPCAxNikgJiZcbiAgICAgICEob3B0aW9ucyAmJiBvcHRpb25zLndpbmRvd0JpdHMpKSB7XG4gICAgb3B0LndpbmRvd0JpdHMgKz0gMzI7XG4gIH1cblxuICAvLyBHemlwIGhlYWRlciBoYXMgbm8gaW5mbyBhYm91dCB3aW5kb3dzIHNpemUsIHdlIGNhbiBkbyBhdXRvZGV0ZWN0IG9ubHlcbiAgLy8gZm9yIGRlZmxhdGUuIFNvLCBpZiB3aW5kb3cgc2l6ZSBub3Qgc2V0LCBmb3JjZSBpdCB0byBtYXggd2hlbiBnemlwIHBvc3NpYmxlXG4gIGlmICgob3B0LndpbmRvd0JpdHMgPiAxNSkgJiYgKG9wdC53aW5kb3dCaXRzIDwgNDgpKSB7XG4gICAgLy8gYml0IDMgKDE2KSAtPiBnemlwcGVkIGRhdGFcbiAgICAvLyBiaXQgNCAoMzIpIC0+IGF1dG9kZXRlY3QgZ3ppcC9kZWZsYXRlXG4gICAgaWYgKChvcHQud2luZG93Qml0cyAmIDE1KSA9PT0gMCkge1xuICAgICAgb3B0LndpbmRvd0JpdHMgfD0gMTU7XG4gICAgfVxuICB9XG5cbiAgdGhpcy5lcnIgICAgPSAwOyAgICAgIC8vIGVycm9yIGNvZGUsIGlmIGhhcHBlbnMgKDAgPSBaX09LKVxuICB0aGlzLm1zZyAgICA9ICcnOyAgICAgLy8gZXJyb3IgbWVzc2FnZVxuICB0aGlzLmVuZGVkICA9IGZhbHNlOyAgLy8gdXNlZCB0byBhdm9pZCBtdWx0aXBsZSBvbkVuZCgpIGNhbGxzXG4gIHRoaXMuY2h1bmtzID0gW107ICAgICAvLyBjaHVua3Mgb2YgY29tcHJlc3NlZCBkYXRhXG5cbiAgdGhpcy5zdHJtICAgPSBuZXcgWlN0cmVhbSgpO1xuICB0aGlzLnN0cm0uYXZhaWxfb3V0ID0gMDtcblxuICB2YXIgc3RhdHVzICA9IHpsaWJfaW5mbGF0ZS5pbmZsYXRlSW5pdDIoXG4gICAgdGhpcy5zdHJtLFxuICAgIG9wdC53aW5kb3dCaXRzXG4gICk7XG5cbiAgaWYgKHN0YXR1cyAhPT0gYy5aX09LKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZ1tzdGF0dXNdKTtcbiAgfVxuXG4gIHRoaXMuaGVhZGVyID0gbmV3IEdaaGVhZGVyKCk7XG5cbiAgemxpYl9pbmZsYXRlLmluZmxhdGVHZXRIZWFkZXIodGhpcy5zdHJtLCB0aGlzLmhlYWRlcik7XG5cbiAgLy8gU2V0dXAgZGljdGlvbmFyeVxuICBpZiAob3B0LmRpY3Rpb25hcnkpIHtcbiAgICAvLyBDb252ZXJ0IGRhdGEgaWYgbmVlZGVkXG4gICAgaWYgKHR5cGVvZiBvcHQuZGljdGlvbmFyeSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG9wdC5kaWN0aW9uYXJ5ID0gc3RyaW5ncy5zdHJpbmcyYnVmKG9wdC5kaWN0aW9uYXJ5KTtcbiAgICB9IGVsc2UgaWYgKHRvU3RyaW5nLmNhbGwob3B0LmRpY3Rpb25hcnkpID09PSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nKSB7XG4gICAgICBvcHQuZGljdGlvbmFyeSA9IG5ldyBVaW50OEFycmF5KG9wdC5kaWN0aW9uYXJ5KTtcbiAgICB9XG4gICAgaWYgKG9wdC5yYXcpIHsgLy9JbiByYXcgbW9kZSB3ZSBuZWVkIHRvIHNldCB0aGUgZGljdGlvbmFyeSBlYXJseVxuICAgICAgc3RhdHVzID0gemxpYl9pbmZsYXRlLmluZmxhdGVTZXREaWN0aW9uYXJ5KHRoaXMuc3RybSwgb3B0LmRpY3Rpb25hcnkpO1xuICAgICAgaWYgKHN0YXR1cyAhPT0gYy5aX09LKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtc2dbc3RhdHVzXSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogSW5mbGF0ZSNwdXNoKGRhdGFbLCBtb2RlXSkgLT4gQm9vbGVhblxuICogLSBkYXRhIChVaW50OEFycmF5fEFycmF5fEFycmF5QnVmZmVyfFN0cmluZyk6IGlucHV0IGRhdGFcbiAqIC0gbW9kZSAoTnVtYmVyfEJvb2xlYW4pOiAwLi42IGZvciBjb3JyZXNwb25kaW5nIFpfTk9fRkxVU0guLlpfVFJFRSBtb2Rlcy5cbiAqICAgU2VlIGNvbnN0YW50cy4gU2tpcHBlZCBvciBgZmFsc2VgIG1lYW5zIFpfTk9fRkxVU0gsIGB0cnVlYCBtZWFucyBaX0ZJTklTSC5cbiAqXG4gKiBTZW5kcyBpbnB1dCBkYXRhIHRvIGluZmxhdGUgcGlwZSwgZ2VuZXJhdGluZyBbW0luZmxhdGUjb25EYXRhXV0gY2FsbHMgd2l0aFxuICogbmV3IG91dHB1dCBjaHVua3MuIFJldHVybnMgYHRydWVgIG9uIHN1Y2Nlc3MuIFRoZSBsYXN0IGRhdGEgYmxvY2sgbXVzdCBoYXZlXG4gKiBtb2RlIFpfRklOSVNIIChvciBgdHJ1ZWApLiBUaGF0IHdpbGwgZmx1c2ggaW50ZXJuYWwgcGVuZGluZyBidWZmZXJzIGFuZCBjYWxsXG4gKiBbW0luZmxhdGUjb25FbmRdXS4gRm9yIGludGVyaW0gZXhwbGljaXQgZmx1c2hlcyAod2l0aG91dCBlbmRpbmcgdGhlIHN0cmVhbSkgeW91XG4gKiBjYW4gdXNlIG1vZGUgWl9TWU5DX0ZMVVNILCBrZWVwaW5nIHRoZSBkZWNvbXByZXNzaW9uIGNvbnRleHQuXG4gKlxuICogT24gZmFpbCBjYWxsIFtbSW5mbGF0ZSNvbkVuZF1dIHdpdGggZXJyb3IgY29kZSBhbmQgcmV0dXJuIGZhbHNlLlxuICpcbiAqIFdlIHN0cm9uZ2x5IHJlY29tbWVuZCB0byB1c2UgYFVpbnQ4QXJyYXlgIG9uIGlucHV0IGZvciBiZXN0IHNwZWVkIChvdXRwdXRcbiAqIGZvcm1hdCBpcyBkZXRlY3RlZCBhdXRvbWF0aWNhbGx5KS4gQWxzbywgZG9uJ3Qgc2tpcCBsYXN0IHBhcmFtIGFuZCBhbHdheXNcbiAqIHVzZSB0aGUgc2FtZSB0eXBlIGluIHlvdXIgY29kZSAoYm9vbGVhbiBvciBudW1iZXIpLiBUaGF0IHdpbGwgaW1wcm92ZSBKUyBzcGVlZC5cbiAqXG4gKiBGb3IgcmVndWxhciBgQXJyYXlgLXMgbWFrZSBzdXJlIGFsbCBlbGVtZW50cyBhcmUgWzAuLjI1NV0uXG4gKlxuICogIyMjIyMgRXhhbXBsZVxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIHB1c2goY2h1bmssIGZhbHNlKTsgLy8gcHVzaCBvbmUgb2YgZGF0YSBjaHVua3NcbiAqIC4uLlxuICogcHVzaChjaHVuaywgdHJ1ZSk7ICAvLyBwdXNoIGxhc3QgY2h1bmtcbiAqIGBgYFxuICoqL1xuSW5mbGF0ZS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChkYXRhLCBtb2RlKSB7XG4gIHZhciBzdHJtID0gdGhpcy5zdHJtO1xuICB2YXIgY2h1bmtTaXplID0gdGhpcy5vcHRpb25zLmNodW5rU2l6ZTtcbiAgdmFyIGRpY3Rpb25hcnkgPSB0aGlzLm9wdGlvbnMuZGljdGlvbmFyeTtcbiAgdmFyIHN0YXR1cywgX21vZGU7XG4gIHZhciBuZXh0X291dF91dGY4LCB0YWlsLCB1dGY4c3RyO1xuXG4gIC8vIEZsYWcgdG8gcHJvcGVybHkgcHJvY2VzcyBaX0JVRl9FUlJPUiBvbiB0ZXN0aW5nIGluZmxhdGUgY2FsbFxuICAvLyB3aGVuIHdlIGNoZWNrIHRoYXQgYWxsIG91dHB1dCBkYXRhIHdhcyBmbHVzaGVkLlxuICB2YXIgYWxsb3dCdWZFcnJvciA9IGZhbHNlO1xuXG4gIGlmICh0aGlzLmVuZGVkKSB7IHJldHVybiBmYWxzZTsgfVxuICBfbW9kZSA9IChtb2RlID09PSB+fm1vZGUpID8gbW9kZSA6ICgobW9kZSA9PT0gdHJ1ZSkgPyBjLlpfRklOSVNIIDogYy5aX05PX0ZMVVNIKTtcblxuICAvLyBDb252ZXJ0IGRhdGEgaWYgbmVlZGVkXG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICAvLyBPbmx5IGJpbmFyeSBzdHJpbmdzIGNhbiBiZSBkZWNvbXByZXNzZWQgb24gcHJhY3RpY2VcbiAgICBzdHJtLmlucHV0ID0gc3RyaW5ncy5iaW5zdHJpbmcyYnVmKGRhdGEpO1xuICB9IGVsc2UgaWYgKHRvU3RyaW5nLmNhbGwoZGF0YSkgPT09ICdbb2JqZWN0IEFycmF5QnVmZmVyXScpIHtcbiAgICBzdHJtLmlucHV0ID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7XG4gIH0gZWxzZSB7XG4gICAgc3RybS5pbnB1dCA9IGRhdGE7XG4gIH1cblxuICBzdHJtLm5leHRfaW4gPSAwO1xuICBzdHJtLmF2YWlsX2luID0gc3RybS5pbnB1dC5sZW5ndGg7XG5cbiAgZG8ge1xuICAgIGlmIChzdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgc3RybS5vdXRwdXQgPSBuZXcgdXRpbHMuQnVmOChjaHVua1NpemUpO1xuICAgICAgc3RybS5uZXh0X291dCA9IDA7XG4gICAgICBzdHJtLmF2YWlsX291dCA9IGNodW5rU2l6ZTtcbiAgICB9XG5cbiAgICBzdGF0dXMgPSB6bGliX2luZmxhdGUuaW5mbGF0ZShzdHJtLCBjLlpfTk9fRkxVU0gpOyAgICAvKiBubyBiYWQgcmV0dXJuIHZhbHVlICovXG5cbiAgICBpZiAoc3RhdHVzID09PSBjLlpfTkVFRF9ESUNUICYmIGRpY3Rpb25hcnkpIHtcbiAgICAgIHN0YXR1cyA9IHpsaWJfaW5mbGF0ZS5pbmZsYXRlU2V0RGljdGlvbmFyeSh0aGlzLnN0cm0sIGRpY3Rpb25hcnkpO1xuICAgIH1cblxuICAgIGlmIChzdGF0dXMgPT09IGMuWl9CVUZfRVJST1IgJiYgYWxsb3dCdWZFcnJvciA9PT0gdHJ1ZSkge1xuICAgICAgc3RhdHVzID0gYy5aX09LO1xuICAgICAgYWxsb3dCdWZFcnJvciA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChzdGF0dXMgIT09IGMuWl9TVFJFQU1fRU5EICYmIHN0YXR1cyAhPT0gYy5aX09LKSB7XG4gICAgICB0aGlzLm9uRW5kKHN0YXR1cyk7XG4gICAgICB0aGlzLmVuZGVkID0gdHJ1ZTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoc3RybS5uZXh0X291dCkge1xuICAgICAgaWYgKHN0cm0uYXZhaWxfb3V0ID09PSAwIHx8IHN0YXR1cyA9PT0gYy5aX1NUUkVBTV9FTkQgfHwgKHN0cm0uYXZhaWxfaW4gPT09IDAgJiYgKF9tb2RlID09PSBjLlpfRklOSVNIIHx8IF9tb2RlID09PSBjLlpfU1lOQ19GTFVTSCkpKSB7XG5cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy50byA9PT0gJ3N0cmluZycpIHtcblxuICAgICAgICAgIG5leHRfb3V0X3V0ZjggPSBzdHJpbmdzLnV0Zjhib3JkZXIoc3RybS5vdXRwdXQsIHN0cm0ubmV4dF9vdXQpO1xuXG4gICAgICAgICAgdGFpbCA9IHN0cm0ubmV4dF9vdXQgLSBuZXh0X291dF91dGY4O1xuICAgICAgICAgIHV0ZjhzdHIgPSBzdHJpbmdzLmJ1ZjJzdHJpbmcoc3RybS5vdXRwdXQsIG5leHRfb3V0X3V0ZjgpO1xuXG4gICAgICAgICAgLy8gbW92ZSB0YWlsXG4gICAgICAgICAgc3RybS5uZXh0X291dCA9IHRhaWw7XG4gICAgICAgICAgc3RybS5hdmFpbF9vdXQgPSBjaHVua1NpemUgLSB0YWlsO1xuICAgICAgICAgIGlmICh0YWlsKSB7IHV0aWxzLmFycmF5U2V0KHN0cm0ub3V0cHV0LCBzdHJtLm91dHB1dCwgbmV4dF9vdXRfdXRmOCwgdGFpbCwgMCk7IH1cblxuICAgICAgICAgIHRoaXMub25EYXRhKHV0ZjhzdHIpO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5vbkRhdGEodXRpbHMuc2hyaW5rQnVmKHN0cm0ub3V0cHV0LCBzdHJtLm5leHRfb3V0KSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBXaGVuIG5vIG1vcmUgaW5wdXQgZGF0YSwgd2Ugc2hvdWxkIGNoZWNrIHRoYXQgaW50ZXJuYWwgaW5mbGF0ZSBidWZmZXJzXG4gICAgLy8gYXJlIGZsdXNoZWQuIFRoZSBvbmx5IHdheSB0byBkbyBpdCB3aGVuIGF2YWlsX291dCA9IDAgLSBydW4gb25lIG1vcmVcbiAgICAvLyBpbmZsYXRlIHBhc3MuIEJ1dCBpZiBvdXRwdXQgZGF0YSBub3QgZXhpc3RzLCBpbmZsYXRlIHJldHVybiBaX0JVRl9FUlJPUi5cbiAgICAvLyBIZXJlIHdlIHNldCBmbGFnIHRvIHByb2Nlc3MgdGhpcyBlcnJvciBwcm9wZXJseS5cbiAgICAvL1xuICAgIC8vIE5PVEUuIERlZmxhdGUgZG9lcyBub3QgcmV0dXJuIGVycm9yIGluIHRoaXMgY2FzZSBhbmQgZG9lcyBub3QgbmVlZHMgc3VjaFxuICAgIC8vIGxvZ2ljLlxuICAgIGlmIChzdHJtLmF2YWlsX2luID09PSAwICYmIHN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICBhbGxvd0J1ZkVycm9yID0gdHJ1ZTtcbiAgICB9XG5cbiAgfSB3aGlsZSAoKHN0cm0uYXZhaWxfaW4gPiAwIHx8IHN0cm0uYXZhaWxfb3V0ID09PSAwKSAmJiBzdGF0dXMgIT09IGMuWl9TVFJFQU1fRU5EKTtcblxuICBpZiAoc3RhdHVzID09PSBjLlpfU1RSRUFNX0VORCkge1xuICAgIF9tb2RlID0gYy5aX0ZJTklTSDtcbiAgfVxuXG4gIC8vIEZpbmFsaXplIG9uIHRoZSBsYXN0IGNodW5rLlxuICBpZiAoX21vZGUgPT09IGMuWl9GSU5JU0gpIHtcbiAgICBzdGF0dXMgPSB6bGliX2luZmxhdGUuaW5mbGF0ZUVuZCh0aGlzLnN0cm0pO1xuICAgIHRoaXMub25FbmQoc3RhdHVzKTtcbiAgICB0aGlzLmVuZGVkID0gdHJ1ZTtcbiAgICByZXR1cm4gc3RhdHVzID09PSBjLlpfT0s7XG4gIH1cblxuICAvLyBjYWxsYmFjayBpbnRlcmltIHJlc3VsdHMgaWYgWl9TWU5DX0ZMVVNILlxuICBpZiAoX21vZGUgPT09IGMuWl9TWU5DX0ZMVVNIKSB7XG4gICAgdGhpcy5vbkVuZChjLlpfT0spO1xuICAgIHN0cm0uYXZhaWxfb3V0ID0gMDtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuXG4vKipcbiAqIEluZmxhdGUjb25EYXRhKGNodW5rKSAtPiBWb2lkXG4gKiAtIGNodW5rIChVaW50OEFycmF5fEFycmF5fFN0cmluZyk6IG91dHB1dCBkYXRhLiBUeXBlIG9mIGFycmF5IGRlcGVuZHNcbiAqICAgb24ganMgZW5naW5lIHN1cHBvcnQuIFdoZW4gc3RyaW5nIG91dHB1dCByZXF1ZXN0ZWQsIGVhY2ggY2h1bmtcbiAqICAgd2lsbCBiZSBzdHJpbmcuXG4gKlxuICogQnkgZGVmYXVsdCwgc3RvcmVzIGRhdGEgYmxvY2tzIGluIGBjaHVua3NbXWAgcHJvcGVydHkgYW5kIGdsdWVcbiAqIHRob3NlIGluIGBvbkVuZGAuIE92ZXJyaWRlIHRoaXMgaGFuZGxlciwgaWYgeW91IG5lZWQgYW5vdGhlciBiZWhhdmlvdXIuXG4gKiovXG5JbmZsYXRlLnByb3RvdHlwZS5vbkRhdGEgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgdGhpcy5jaHVua3MucHVzaChjaHVuayk7XG59O1xuXG5cbi8qKlxuICogSW5mbGF0ZSNvbkVuZChzdGF0dXMpIC0+IFZvaWRcbiAqIC0gc3RhdHVzIChOdW1iZXIpOiBpbmZsYXRlIHN0YXR1cy4gMCAoWl9PSykgb24gc3VjY2VzcyxcbiAqICAgb3RoZXIgaWYgbm90LlxuICpcbiAqIENhbGxlZCBlaXRoZXIgYWZ0ZXIgeW91IHRlbGwgaW5mbGF0ZSB0aGF0IHRoZSBpbnB1dCBzdHJlYW0gaXNcbiAqIGNvbXBsZXRlIChaX0ZJTklTSCkgb3Igc2hvdWxkIGJlIGZsdXNoZWQgKFpfU1lOQ19GTFVTSClcbiAqIG9yIGlmIGFuIGVycm9yIGhhcHBlbmVkLiBCeSBkZWZhdWx0IC0gam9pbiBjb2xsZWN0ZWQgY2h1bmtzLFxuICogZnJlZSBtZW1vcnkgYW5kIGZpbGwgYHJlc3VsdHNgIC8gYGVycmAgcHJvcGVydGllcy5cbiAqKi9cbkluZmxhdGUucHJvdG90eXBlLm9uRW5kID0gZnVuY3Rpb24gKHN0YXR1cykge1xuICAvLyBPbiBzdWNjZXNzIC0gam9pblxuICBpZiAoc3RhdHVzID09PSBjLlpfT0spIHtcbiAgICBpZiAodGhpcy5vcHRpb25zLnRvID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gR2x1ZSAmIGNvbnZlcnQgaGVyZSwgdW50aWwgd2UgdGVhY2ggcGFrbyB0byBzZW5kXG4gICAgICAvLyB1dGY4IGFsaWduZWQgc3RyaW5ncyB0byBvbkRhdGFcbiAgICAgIHRoaXMucmVzdWx0ID0gdGhpcy5jaHVua3Muam9pbignJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmVzdWx0ID0gdXRpbHMuZmxhdHRlbkNodW5rcyh0aGlzLmNodW5rcyk7XG4gICAgfVxuICB9XG4gIHRoaXMuY2h1bmtzID0gW107XG4gIHRoaXMuZXJyID0gc3RhdHVzO1xuICB0aGlzLm1zZyA9IHRoaXMuc3RybS5tc2c7XG59O1xuXG5cbi8qKlxuICogaW5mbGF0ZShkYXRhWywgb3B0aW9uc10pIC0+IFVpbnQ4QXJyYXl8QXJyYXl8U3RyaW5nXG4gKiAtIGRhdGEgKFVpbnQ4QXJyYXl8QXJyYXl8U3RyaW5nKTogaW5wdXQgZGF0YSB0byBkZWNvbXByZXNzLlxuICogLSBvcHRpb25zIChPYmplY3QpOiB6bGliIGluZmxhdGUgb3B0aW9ucy5cbiAqXG4gKiBEZWNvbXByZXNzIGBkYXRhYCB3aXRoIGluZmxhdGUvdW5nemlwIGFuZCBgb3B0aW9uc2AuIEF1dG9kZXRlY3RcbiAqIGZvcm1hdCB2aWEgd3JhcHBlciBoZWFkZXIgYnkgZGVmYXVsdC4gVGhhdCdzIHdoeSB3ZSBkb24ndCBwcm92aWRlXG4gKiBzZXBhcmF0ZSBgdW5nemlwYCBtZXRob2QuXG4gKlxuICogU3VwcG9ydGVkIG9wdGlvbnMgYXJlOlxuICpcbiAqIC0gd2luZG93Qml0c1xuICpcbiAqIFtodHRwOi8vemxpYi5uZXQvbWFudWFsLmh0bWwjQWR2YW5jZWRdKGh0dHA6Ly96bGliLm5ldC9tYW51YWwuaHRtbCNBZHZhbmNlZClcbiAqIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICpcbiAqIFN1Z2FyIChvcHRpb25zKTpcbiAqXG4gKiAtIGByYXdgIChCb29sZWFuKSAtIHNheSB0aGF0IHdlIHdvcmsgd2l0aCByYXcgc3RyZWFtLCBpZiB5b3UgZG9uJ3Qgd2lzaCB0byBzcGVjaWZ5XG4gKiAgIG5lZ2F0aXZlIHdpbmRvd0JpdHMgaW1wbGljaXRseS5cbiAqIC0gYHRvYCAoU3RyaW5nKSAtIGlmIGVxdWFsIHRvICdzdHJpbmcnLCB0aGVuIHJlc3VsdCB3aWxsIGJlIGNvbnZlcnRlZFxuICogICBmcm9tIHV0ZjggdG8gdXRmMTYgKGphdmFzY3JpcHQpIHN0cmluZy4gV2hlbiBzdHJpbmcgb3V0cHV0IHJlcXVlc3RlZCxcbiAqICAgY2h1bmsgbGVuZ3RoIGNhbiBkaWZmZXIgZnJvbSBgY2h1bmtTaXplYCwgZGVwZW5kaW5nIG9uIGNvbnRlbnQuXG4gKlxuICpcbiAqICMjIyMjIEV4YW1wbGU6XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogdmFyIHBha28gPSByZXF1aXJlKCdwYWtvJylcbiAqICAgLCBpbnB1dCA9IHBha28uZGVmbGF0ZShbMSwyLDMsNCw1LDYsNyw4LDldKVxuICogICAsIG91dHB1dDtcbiAqXG4gKiB0cnkge1xuICogICBvdXRwdXQgPSBwYWtvLmluZmxhdGUoaW5wdXQpO1xuICogfSBjYXRjaCAoZXJyKVxuICogICBjb25zb2xlLmxvZyhlcnIpO1xuICogfVxuICogYGBgXG4gKiovXG5mdW5jdGlvbiBpbmZsYXRlKGlucHV0LCBvcHRpb25zKSB7XG4gIHZhciBpbmZsYXRvciA9IG5ldyBJbmZsYXRlKG9wdGlvbnMpO1xuXG4gIGluZmxhdG9yLnB1c2goaW5wdXQsIHRydWUpO1xuXG4gIC8vIFRoYXQgd2lsbCBuZXZlciBoYXBwZW5zLCBpZiB5b3UgZG9uJ3QgY2hlYXQgd2l0aCBvcHRpb25zIDopXG4gIGlmIChpbmZsYXRvci5lcnIpIHsgdGhyb3cgaW5mbGF0b3IubXNnIHx8IG1zZ1tpbmZsYXRvci5lcnJdOyB9XG5cbiAgcmV0dXJuIGluZmxhdG9yLnJlc3VsdDtcbn1cblxuXG4vKipcbiAqIGluZmxhdGVSYXcoZGF0YVssIG9wdGlvbnNdKSAtPiBVaW50OEFycmF5fEFycmF5fFN0cmluZ1xuICogLSBkYXRhIChVaW50OEFycmF5fEFycmF5fFN0cmluZyk6IGlucHV0IGRhdGEgdG8gZGVjb21wcmVzcy5cbiAqIC0gb3B0aW9ucyAoT2JqZWN0KTogemxpYiBpbmZsYXRlIG9wdGlvbnMuXG4gKlxuICogVGhlIHNhbWUgYXMgW1tpbmZsYXRlXV0sIGJ1dCBjcmVhdGVzIHJhdyBkYXRhLCB3aXRob3V0IHdyYXBwZXJcbiAqIChoZWFkZXIgYW5kIGFkbGVyMzIgY3JjKS5cbiAqKi9cbmZ1bmN0aW9uIGluZmxhdGVSYXcoaW5wdXQsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIG9wdGlvbnMucmF3ID0gdHJ1ZTtcbiAgcmV0dXJuIGluZmxhdGUoaW5wdXQsIG9wdGlvbnMpO1xufVxuXG5cbi8qKlxuICogdW5nemlwKGRhdGFbLCBvcHRpb25zXSkgLT4gVWludDhBcnJheXxBcnJheXxTdHJpbmdcbiAqIC0gZGF0YSAoVWludDhBcnJheXxBcnJheXxTdHJpbmcpOiBpbnB1dCBkYXRhIHRvIGRlY29tcHJlc3MuXG4gKiAtIG9wdGlvbnMgKE9iamVjdCk6IHpsaWIgaW5mbGF0ZSBvcHRpb25zLlxuICpcbiAqIEp1c3Qgc2hvcnRjdXQgdG8gW1tpbmZsYXRlXV0sIGJlY2F1c2UgaXQgYXV0b2RldGVjdHMgZm9ybWF0XG4gKiBieSBoZWFkZXIuY29udGVudC4gRG9uZSBmb3IgY29udmVuaWVuY2UuXG4gKiovXG5cblxuZXhwb3J0cy5JbmZsYXRlID0gSW5mbGF0ZTtcbmV4cG9ydHMuaW5mbGF0ZSA9IGluZmxhdGU7XG5leHBvcnRzLmluZmxhdGVSYXcgPSBpbmZsYXRlUmF3O1xuZXhwb3J0cy51bmd6aXAgID0gaW5mbGF0ZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgVFlQRURfT0sgPSAgKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJykgJiZcbiAgICAgICAgICAgICAgICAodHlwZW9mIFVpbnQxNkFycmF5ICE9PSAndW5kZWZpbmVkJykgJiZcbiAgICAgICAgICAgICAgICAodHlwZW9mIEludDMyQXJyYXkgIT09ICd1bmRlZmluZWQnKTtcblxuZnVuY3Rpb24gX2hhcyhvYmosIGtleSkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KTtcbn1cblxuZXhwb3J0cy5hc3NpZ24gPSBmdW5jdGlvbiAob2JqIC8qZnJvbTEsIGZyb20yLCBmcm9tMywgLi4uKi8pIHtcbiAgdmFyIHNvdXJjZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICB3aGlsZSAoc291cmNlcy5sZW5ndGgpIHtcbiAgICB2YXIgc291cmNlID0gc291cmNlcy5zaGlmdCgpO1xuICAgIGlmICghc291cmNlKSB7IGNvbnRpbnVlOyB9XG5cbiAgICBpZiAodHlwZW9mIHNvdXJjZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3Ioc291cmNlICsgJ211c3QgYmUgbm9uLW9iamVjdCcpO1xuICAgIH1cblxuICAgIGZvciAodmFyIHAgaW4gc291cmNlKSB7XG4gICAgICBpZiAoX2hhcyhzb3VyY2UsIHApKSB7XG4gICAgICAgIG9ialtwXSA9IHNvdXJjZVtwXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gb2JqO1xufTtcblxuXG4vLyByZWR1Y2UgYnVmZmVyIHNpemUsIGF2b2lkaW5nIG1lbSBjb3B5XG5leHBvcnRzLnNocmlua0J1ZiA9IGZ1bmN0aW9uIChidWYsIHNpemUpIHtcbiAgaWYgKGJ1Zi5sZW5ndGggPT09IHNpemUpIHsgcmV0dXJuIGJ1ZjsgfVxuICBpZiAoYnVmLnN1YmFycmF5KSB7IHJldHVybiBidWYuc3ViYXJyYXkoMCwgc2l6ZSk7IH1cbiAgYnVmLmxlbmd0aCA9IHNpemU7XG4gIHJldHVybiBidWY7XG59O1xuXG5cbnZhciBmblR5cGVkID0ge1xuICBhcnJheVNldDogZnVuY3Rpb24gKGRlc3QsIHNyYywgc3JjX29mZnMsIGxlbiwgZGVzdF9vZmZzKSB7XG4gICAgaWYgKHNyYy5zdWJhcnJheSAmJiBkZXN0LnN1YmFycmF5KSB7XG4gICAgICBkZXN0LnNldChzcmMuc3ViYXJyYXkoc3JjX29mZnMsIHNyY19vZmZzICsgbGVuKSwgZGVzdF9vZmZzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gRmFsbGJhY2sgdG8gb3JkaW5hcnkgYXJyYXlcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBkZXN0W2Rlc3Rfb2ZmcyArIGldID0gc3JjW3NyY19vZmZzICsgaV07XG4gICAgfVxuICB9LFxuICAvLyBKb2luIGFycmF5IG9mIGNodW5rcyB0byBzaW5nbGUgYXJyYXkuXG4gIGZsYXR0ZW5DaHVua3M6IGZ1bmN0aW9uIChjaHVua3MpIHtcbiAgICB2YXIgaSwgbCwgbGVuLCBwb3MsIGNodW5rLCByZXN1bHQ7XG5cbiAgICAvLyBjYWxjdWxhdGUgZGF0YSBsZW5ndGhcbiAgICBsZW4gPSAwO1xuICAgIGZvciAoaSA9IDAsIGwgPSBjaHVua3MubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBsZW4gKz0gY2h1bmtzW2ldLmxlbmd0aDtcbiAgICB9XG5cbiAgICAvLyBqb2luIGNodW5rc1xuICAgIHJlc3VsdCA9IG5ldyBVaW50OEFycmF5KGxlbik7XG4gICAgcG9zID0gMDtcbiAgICBmb3IgKGkgPSAwLCBsID0gY2h1bmtzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgY2h1bmsgPSBjaHVua3NbaV07XG4gICAgICByZXN1bHQuc2V0KGNodW5rLCBwb3MpO1xuICAgICAgcG9zICs9IGNodW5rLmxlbmd0aDtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59O1xuXG52YXIgZm5VbnR5cGVkID0ge1xuICBhcnJheVNldDogZnVuY3Rpb24gKGRlc3QsIHNyYywgc3JjX29mZnMsIGxlbiwgZGVzdF9vZmZzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgZGVzdFtkZXN0X29mZnMgKyBpXSA9IHNyY1tzcmNfb2ZmcyArIGldO1xuICAgIH1cbiAgfSxcbiAgLy8gSm9pbiBhcnJheSBvZiBjaHVua3MgdG8gc2luZ2xlIGFycmF5LlxuICBmbGF0dGVuQ2h1bmtzOiBmdW5jdGlvbiAoY2h1bmtzKSB7XG4gICAgcmV0dXJuIFtdLmNvbmNhdC5hcHBseShbXSwgY2h1bmtzKTtcbiAgfVxufTtcblxuXG4vLyBFbmFibGUvRGlzYWJsZSB0eXBlZCBhcnJheXMgdXNlLCBmb3IgdGVzdGluZ1xuLy9cbmV4cG9ydHMuc2V0VHlwZWQgPSBmdW5jdGlvbiAob24pIHtcbiAgaWYgKG9uKSB7XG4gICAgZXhwb3J0cy5CdWY4ICA9IFVpbnQ4QXJyYXk7XG4gICAgZXhwb3J0cy5CdWYxNiA9IFVpbnQxNkFycmF5O1xuICAgIGV4cG9ydHMuQnVmMzIgPSBJbnQzMkFycmF5O1xuICAgIGV4cG9ydHMuYXNzaWduKGV4cG9ydHMsIGZuVHlwZWQpO1xuICB9IGVsc2Uge1xuICAgIGV4cG9ydHMuQnVmOCAgPSBBcnJheTtcbiAgICBleHBvcnRzLkJ1ZjE2ID0gQXJyYXk7XG4gICAgZXhwb3J0cy5CdWYzMiA9IEFycmF5O1xuICAgIGV4cG9ydHMuYXNzaWduKGV4cG9ydHMsIGZuVW50eXBlZCk7XG4gIH1cbn07XG5cbmV4cG9ydHMuc2V0VHlwZWQoVFlQRURfT0spO1xuIiwiLy8gU3RyaW5nIGVuY29kZS9kZWNvZGUgaGVscGVyc1xuJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG5cblxuLy8gUXVpY2sgY2hlY2sgaWYgd2UgY2FuIHVzZSBmYXN0IGFycmF5IHRvIGJpbiBzdHJpbmcgY29udmVyc2lvblxuLy9cbi8vIC0gYXBwbHkoQXJyYXkpIGNhbiBmYWlsIG9uIEFuZHJvaWQgMi4yXG4vLyAtIGFwcGx5KFVpbnQ4QXJyYXkpIGNhbiBmYWlsIG9uIGlPUyA1LjEgU2FmYXJpXG4vL1xudmFyIFNUUl9BUFBMWV9PSyA9IHRydWU7XG52YXIgU1RSX0FQUExZX1VJQV9PSyA9IHRydWU7XG5cbnRyeSB7IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgWyAwIF0pOyB9IGNhdGNoIChfXykgeyBTVFJfQVBQTFlfT0sgPSBmYWxzZTsgfVxudHJ5IHsgU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBuZXcgVWludDhBcnJheSgxKSk7IH0gY2F0Y2ggKF9fKSB7IFNUUl9BUFBMWV9VSUFfT0sgPSBmYWxzZTsgfVxuXG5cbi8vIFRhYmxlIHdpdGggdXRmOCBsZW5ndGhzIChjYWxjdWxhdGVkIGJ5IGZpcnN0IGJ5dGUgb2Ygc2VxdWVuY2UpXG4vLyBOb3RlLCB0aGF0IDUgJiA2LWJ5dGUgdmFsdWVzIGFuZCBzb21lIDQtYnl0ZSB2YWx1ZXMgY2FuIG5vdCBiZSByZXByZXNlbnRlZCBpbiBKUyxcbi8vIGJlY2F1c2UgbWF4IHBvc3NpYmxlIGNvZGVwb2ludCBpcyAweDEwZmZmZlxudmFyIF91dGY4bGVuID0gbmV3IHV0aWxzLkJ1ZjgoMjU2KTtcbmZvciAodmFyIHEgPSAwOyBxIDwgMjU2OyBxKyspIHtcbiAgX3V0ZjhsZW5bcV0gPSAocSA+PSAyNTIgPyA2IDogcSA+PSAyNDggPyA1IDogcSA+PSAyNDAgPyA0IDogcSA+PSAyMjQgPyAzIDogcSA+PSAxOTIgPyAyIDogMSk7XG59XG5fdXRmOGxlblsyNTRdID0gX3V0ZjhsZW5bMjU0XSA9IDE7IC8vIEludmFsaWQgc2VxdWVuY2Ugc3RhcnRcblxuXG4vLyBjb252ZXJ0IHN0cmluZyB0byBhcnJheSAodHlwZWQsIHdoZW4gcG9zc2libGUpXG5leHBvcnRzLnN0cmluZzJidWYgPSBmdW5jdGlvbiAoc3RyKSB7XG4gIHZhciBidWYsIGMsIGMyLCBtX3BvcywgaSwgc3RyX2xlbiA9IHN0ci5sZW5ndGgsIGJ1Zl9sZW4gPSAwO1xuXG4gIC8vIGNvdW50IGJpbmFyeSBzaXplXG4gIGZvciAobV9wb3MgPSAwOyBtX3BvcyA8IHN0cl9sZW47IG1fcG9zKyspIHtcbiAgICBjID0gc3RyLmNoYXJDb2RlQXQobV9wb3MpO1xuICAgIGlmICgoYyAmIDB4ZmMwMCkgPT09IDB4ZDgwMCAmJiAobV9wb3MgKyAxIDwgc3RyX2xlbikpIHtcbiAgICAgIGMyID0gc3RyLmNoYXJDb2RlQXQobV9wb3MgKyAxKTtcbiAgICAgIGlmICgoYzIgJiAweGZjMDApID09PSAweGRjMDApIHtcbiAgICAgICAgYyA9IDB4MTAwMDAgKyAoKGMgLSAweGQ4MDApIDw8IDEwKSArIChjMiAtIDB4ZGMwMCk7XG4gICAgICAgIG1fcG9zKys7XG4gICAgICB9XG4gICAgfVxuICAgIGJ1Zl9sZW4gKz0gYyA8IDB4ODAgPyAxIDogYyA8IDB4ODAwID8gMiA6IGMgPCAweDEwMDAwID8gMyA6IDQ7XG4gIH1cblxuICAvLyBhbGxvY2F0ZSBidWZmZXJcbiAgYnVmID0gbmV3IHV0aWxzLkJ1ZjgoYnVmX2xlbik7XG5cbiAgLy8gY29udmVydFxuICBmb3IgKGkgPSAwLCBtX3BvcyA9IDA7IGkgPCBidWZfbGVuOyBtX3BvcysrKSB7XG4gICAgYyA9IHN0ci5jaGFyQ29kZUF0KG1fcG9zKTtcbiAgICBpZiAoKGMgJiAweGZjMDApID09PSAweGQ4MDAgJiYgKG1fcG9zICsgMSA8IHN0cl9sZW4pKSB7XG4gICAgICBjMiA9IHN0ci5jaGFyQ29kZUF0KG1fcG9zICsgMSk7XG4gICAgICBpZiAoKGMyICYgMHhmYzAwKSA9PT0gMHhkYzAwKSB7XG4gICAgICAgIGMgPSAweDEwMDAwICsgKChjIC0gMHhkODAwKSA8PCAxMCkgKyAoYzIgLSAweGRjMDApO1xuICAgICAgICBtX3BvcysrO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoYyA8IDB4ODApIHtcbiAgICAgIC8qIG9uZSBieXRlICovXG4gICAgICBidWZbaSsrXSA9IGM7XG4gICAgfSBlbHNlIGlmIChjIDwgMHg4MDApIHtcbiAgICAgIC8qIHR3byBieXRlcyAqL1xuICAgICAgYnVmW2krK10gPSAweEMwIHwgKGMgPj4+IDYpO1xuICAgICAgYnVmW2krK10gPSAweDgwIHwgKGMgJiAweDNmKTtcbiAgICB9IGVsc2UgaWYgKGMgPCAweDEwMDAwKSB7XG4gICAgICAvKiB0aHJlZSBieXRlcyAqL1xuICAgICAgYnVmW2krK10gPSAweEUwIHwgKGMgPj4+IDEyKTtcbiAgICAgIGJ1ZltpKytdID0gMHg4MCB8IChjID4+PiA2ICYgMHgzZik7XG4gICAgICBidWZbaSsrXSA9IDB4ODAgfCAoYyAmIDB4M2YpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvKiBmb3VyIGJ5dGVzICovXG4gICAgICBidWZbaSsrXSA9IDB4ZjAgfCAoYyA+Pj4gMTgpO1xuICAgICAgYnVmW2krK10gPSAweDgwIHwgKGMgPj4+IDEyICYgMHgzZik7XG4gICAgICBidWZbaSsrXSA9IDB4ODAgfCAoYyA+Pj4gNiAmIDB4M2YpO1xuICAgICAgYnVmW2krK10gPSAweDgwIHwgKGMgJiAweDNmKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmO1xufTtcblxuLy8gSGVscGVyICh1c2VkIGluIDIgcGxhY2VzKVxuZnVuY3Rpb24gYnVmMmJpbnN0cmluZyhidWYsIGxlbikge1xuICAvLyBPbiBDaHJvbWUsIHRoZSBhcmd1bWVudHMgaW4gYSBmdW5jdGlvbiBjYWxsIHRoYXQgYXJlIGFsbG93ZWQgaXMgYDY1NTM0YC5cbiAgLy8gSWYgdGhlIGxlbmd0aCBvZiB0aGUgYnVmZmVyIGlzIHNtYWxsZXIgdGhhbiB0aGF0LCB3ZSBjYW4gdXNlIHRoaXMgb3B0aW1pemF0aW9uLFxuICAvLyBvdGhlcndpc2Ugd2Ugd2lsbCB0YWtlIGEgc2xvd2VyIHBhdGguXG4gIGlmIChsZW4gPCA2NTUzNCkge1xuICAgIGlmICgoYnVmLnN1YmFycmF5ICYmIFNUUl9BUFBMWV9VSUFfT0spIHx8ICghYnVmLnN1YmFycmF5ICYmIFNUUl9BUFBMWV9PSykpIHtcbiAgICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIHV0aWxzLnNocmlua0J1ZihidWYsIGxlbikpO1xuICAgIH1cbiAgfVxuXG4gIHZhciByZXN1bHQgPSAnJztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuXG4vLyBDb252ZXJ0IGJ5dGUgYXJyYXkgdG8gYmluYXJ5IHN0cmluZ1xuZXhwb3J0cy5idWYyYmluc3RyaW5nID0gZnVuY3Rpb24gKGJ1Zikge1xuICByZXR1cm4gYnVmMmJpbnN0cmluZyhidWYsIGJ1Zi5sZW5ndGgpO1xufTtcblxuXG4vLyBDb252ZXJ0IGJpbmFyeSBzdHJpbmcgKHR5cGVkLCB3aGVuIHBvc3NpYmxlKVxuZXhwb3J0cy5iaW5zdHJpbmcyYnVmID0gZnVuY3Rpb24gKHN0cikge1xuICB2YXIgYnVmID0gbmV3IHV0aWxzLkJ1Zjgoc3RyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBidWYubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBidWZbaV0gPSBzdHIuY2hhckNvZGVBdChpKTtcbiAgfVxuICByZXR1cm4gYnVmO1xufTtcblxuXG4vLyBjb252ZXJ0IGFycmF5IHRvIHN0cmluZ1xuZXhwb3J0cy5idWYyc3RyaW5nID0gZnVuY3Rpb24gKGJ1ZiwgbWF4KSB7XG4gIHZhciBpLCBvdXQsIGMsIGNfbGVuO1xuICB2YXIgbGVuID0gbWF4IHx8IGJ1Zi5sZW5ndGg7XG5cbiAgLy8gUmVzZXJ2ZSBtYXggcG9zc2libGUgbGVuZ3RoICgyIHdvcmRzIHBlciBjaGFyKVxuICAvLyBOQjogYnkgdW5rbm93biByZWFzb25zLCBBcnJheSBpcyBzaWduaWZpY2FudGx5IGZhc3RlciBmb3JcbiAgLy8gICAgIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkgdGhhbiBVaW50MTZBcnJheS5cbiAgdmFyIHV0ZjE2YnVmID0gbmV3IEFycmF5KGxlbiAqIDIpO1xuXG4gIGZvciAob3V0ID0gMCwgaSA9IDA7IGkgPCBsZW47KSB7XG4gICAgYyA9IGJ1ZltpKytdO1xuICAgIC8vIHF1aWNrIHByb2Nlc3MgYXNjaWlcbiAgICBpZiAoYyA8IDB4ODApIHsgdXRmMTZidWZbb3V0KytdID0gYzsgY29udGludWU7IH1cblxuICAgIGNfbGVuID0gX3V0ZjhsZW5bY107XG4gICAgLy8gc2tpcCA1ICYgNiBieXRlIGNvZGVzXG4gICAgaWYgKGNfbGVuID4gNCkgeyB1dGYxNmJ1ZltvdXQrK10gPSAweGZmZmQ7IGkgKz0gY19sZW4gLSAxOyBjb250aW51ZTsgfVxuXG4gICAgLy8gYXBwbHkgbWFzayBvbiBmaXJzdCBieXRlXG4gICAgYyAmPSBjX2xlbiA9PT0gMiA/IDB4MWYgOiBjX2xlbiA9PT0gMyA/IDB4MGYgOiAweDA3O1xuICAgIC8vIGpvaW4gdGhlIHJlc3RcbiAgICB3aGlsZSAoY19sZW4gPiAxICYmIGkgPCBsZW4pIHtcbiAgICAgIGMgPSAoYyA8PCA2KSB8IChidWZbaSsrXSAmIDB4M2YpO1xuICAgICAgY19sZW4tLTtcbiAgICB9XG5cbiAgICAvLyB0ZXJtaW5hdGVkIGJ5IGVuZCBvZiBzdHJpbmc/XG4gICAgaWYgKGNfbGVuID4gMSkgeyB1dGYxNmJ1ZltvdXQrK10gPSAweGZmZmQ7IGNvbnRpbnVlOyB9XG5cbiAgICBpZiAoYyA8IDB4MTAwMDApIHtcbiAgICAgIHV0ZjE2YnVmW291dCsrXSA9IGM7XG4gICAgfSBlbHNlIHtcbiAgICAgIGMgLT0gMHgxMDAwMDtcbiAgICAgIHV0ZjE2YnVmW291dCsrXSA9IDB4ZDgwMCB8ICgoYyA+PiAxMCkgJiAweDNmZik7XG4gICAgICB1dGYxNmJ1ZltvdXQrK10gPSAweGRjMDAgfCAoYyAmIDB4M2ZmKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmMmJpbnN0cmluZyh1dGYxNmJ1Ziwgb3V0KTtcbn07XG5cblxuLy8gQ2FsY3VsYXRlIG1heCBwb3NzaWJsZSBwb3NpdGlvbiBpbiB1dGY4IGJ1ZmZlcixcbi8vIHRoYXQgd2lsbCBub3QgYnJlYWsgc2VxdWVuY2UuIElmIHRoYXQncyBub3QgcG9zc2libGVcbi8vIC0gKHZlcnkgc21hbGwgbGltaXRzKSByZXR1cm4gbWF4IHNpemUgYXMgaXMuXG4vL1xuLy8gYnVmW10gLSB1dGY4IGJ5dGVzIGFycmF5XG4vLyBtYXggICAtIGxlbmd0aCBsaW1pdCAobWFuZGF0b3J5KTtcbmV4cG9ydHMudXRmOGJvcmRlciA9IGZ1bmN0aW9uIChidWYsIG1heCkge1xuICB2YXIgcG9zO1xuXG4gIG1heCA9IG1heCB8fCBidWYubGVuZ3RoO1xuICBpZiAobWF4ID4gYnVmLmxlbmd0aCkgeyBtYXggPSBidWYubGVuZ3RoOyB9XG5cbiAgLy8gZ28gYmFjayBmcm9tIGxhc3QgcG9zaXRpb24sIHVudGlsIHN0YXJ0IG9mIHNlcXVlbmNlIGZvdW5kXG4gIHBvcyA9IG1heCAtIDE7XG4gIHdoaWxlIChwb3MgPj0gMCAmJiAoYnVmW3Bvc10gJiAweEMwKSA9PT0gMHg4MCkgeyBwb3MtLTsgfVxuXG4gIC8vIFZlcnkgc21hbGwgYW5kIGJyb2tlbiBzZXF1ZW5jZSxcbiAgLy8gcmV0dXJuIG1heCwgYmVjYXVzZSB3ZSBzaG91bGQgcmV0dXJuIHNvbWV0aGluZyBhbnl3YXkuXG4gIGlmIChwb3MgPCAwKSB7IHJldHVybiBtYXg7IH1cblxuICAvLyBJZiB3ZSBjYW1lIHRvIHN0YXJ0IG9mIGJ1ZmZlciAtIHRoYXQgbWVhbnMgYnVmZmVyIGlzIHRvbyBzbWFsbCxcbiAgLy8gcmV0dXJuIG1heCB0b28uXG4gIGlmIChwb3MgPT09IDApIHsgcmV0dXJuIG1heDsgfVxuXG4gIHJldHVybiAocG9zICsgX3V0ZjhsZW5bYnVmW3Bvc11dID4gbWF4KSA/IHBvcyA6IG1heDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbi8vIE5vdGU6IGFkbGVyMzIgdGFrZXMgMTIlIGZvciBsZXZlbCAwIGFuZCAyJSBmb3IgbGV2ZWwgNi5cbi8vIEl0IGlzbid0IHdvcnRoIGl0IHRvIG1ha2UgYWRkaXRpb25hbCBvcHRpbWl6YXRpb25zIGFzIGluIG9yaWdpbmFsLlxuLy8gU21hbGwgc2l6ZSBpcyBwcmVmZXJhYmxlLlxuXG4vLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXJcbi8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luXG4vL1xuLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWRcbi8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlc1xuLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSxcbi8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXRcbi8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczpcbi8vXG4vLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdFxuLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZVxuLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmVcbi8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC5cbi8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlXG4vLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS5cbi8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uXG5cbmZ1bmN0aW9uIGFkbGVyMzIoYWRsZXIsIGJ1ZiwgbGVuLCBwb3MpIHtcbiAgdmFyIHMxID0gKGFkbGVyICYgMHhmZmZmKSB8MCxcbiAgICAgIHMyID0gKChhZGxlciA+Pj4gMTYpICYgMHhmZmZmKSB8MCxcbiAgICAgIG4gPSAwO1xuXG4gIHdoaWxlIChsZW4gIT09IDApIHtcbiAgICAvLyBTZXQgbGltaXQgfiB0d2ljZSBsZXNzIHRoYW4gNTU1MiwgdG8ga2VlcFxuICAgIC8vIHMyIGluIDMxLWJpdHMsIGJlY2F1c2Ugd2UgZm9yY2Ugc2lnbmVkIGludHMuXG4gICAgLy8gaW4gb3RoZXIgY2FzZSAlPSB3aWxsIGZhaWwuXG4gICAgbiA9IGxlbiA+IDIwMDAgPyAyMDAwIDogbGVuO1xuICAgIGxlbiAtPSBuO1xuXG4gICAgZG8ge1xuICAgICAgczEgPSAoczEgKyBidWZbcG9zKytdKSB8MDtcbiAgICAgIHMyID0gKHMyICsgczEpIHwwO1xuICAgIH0gd2hpbGUgKC0tbik7XG5cbiAgICBzMSAlPSA2NTUyMTtcbiAgICBzMiAlPSA2NTUyMTtcbiAgfVxuXG4gIHJldHVybiAoczEgfCAoczIgPDwgMTYpKSB8MDtcbn1cblxuXG5tb2R1bGUuZXhwb3J0cyA9IGFkbGVyMzI7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8vIChDKSAxOTk1LTIwMTMgSmVhbi1sb3VwIEdhaWxseSBhbmQgTWFyayBBZGxlclxuLy8gKEMpIDIwMTQtMjAxNyBWaXRhbHkgUHV6cmluIGFuZCBBbmRyZXkgVHVwaXRzaW5cbi8vXG4vLyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZFxuLy8gd2FycmFudHkuIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzXG4vLyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLFxuLy8gaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdFxuLy8gZnJlZWx5LCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOlxuLy9cbi8vIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90XG4vLyAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlXG4vLyAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZVxuLy8gICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLlxuLy8gMi4gQWx0ZXJlZCBzb3VyY2UgdmVyc2lvbnMgbXVzdCBiZSBwbGFpbmx5IG1hcmtlZCBhcyBzdWNoLCBhbmQgbXVzdCBub3QgYmVcbi8vICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLlxuLy8gMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cbiAgLyogQWxsb3dlZCBmbHVzaCB2YWx1ZXM7IHNlZSBkZWZsYXRlKCkgYW5kIGluZmxhdGUoKSBiZWxvdyBmb3IgZGV0YWlscyAqL1xuICBaX05PX0ZMVVNIOiAgICAgICAgIDAsXG4gIFpfUEFSVElBTF9GTFVTSDogICAgMSxcbiAgWl9TWU5DX0ZMVVNIOiAgICAgICAyLFxuICBaX0ZVTExfRkxVU0g6ICAgICAgIDMsXG4gIFpfRklOSVNIOiAgICAgICAgICAgNCxcbiAgWl9CTE9DSzogICAgICAgICAgICA1LFxuICBaX1RSRUVTOiAgICAgICAgICAgIDYsXG5cbiAgLyogUmV0dXJuIGNvZGVzIGZvciB0aGUgY29tcHJlc3Npb24vZGVjb21wcmVzc2lvbiBmdW5jdGlvbnMuIE5lZ2F0aXZlIHZhbHVlc1xuICAqIGFyZSBlcnJvcnMsIHBvc2l0aXZlIHZhbHVlcyBhcmUgdXNlZCBmb3Igc3BlY2lhbCBidXQgbm9ybWFsIGV2ZW50cy5cbiAgKi9cbiAgWl9PSzogICAgICAgICAgICAgICAwLFxuICBaX1NUUkVBTV9FTkQ6ICAgICAgIDEsXG4gIFpfTkVFRF9ESUNUOiAgICAgICAgMixcbiAgWl9FUlJOTzogICAgICAgICAgIC0xLFxuICBaX1NUUkVBTV9FUlJPUjogICAgLTIsXG4gIFpfREFUQV9FUlJPUjogICAgICAtMyxcbiAgLy9aX01FTV9FUlJPUjogICAgIC00LFxuICBaX0JVRl9FUlJPUjogICAgICAgLTUsXG4gIC8vWl9WRVJTSU9OX0VSUk9SOiAtNixcblxuICAvKiBjb21wcmVzc2lvbiBsZXZlbHMgKi9cbiAgWl9OT19DT01QUkVTU0lPTjogICAgICAgICAwLFxuICBaX0JFU1RfU1BFRUQ6ICAgICAgICAgICAgIDEsXG4gIFpfQkVTVF9DT01QUkVTU0lPTjogICAgICAgOSxcbiAgWl9ERUZBVUxUX0NPTVBSRVNTSU9OOiAgIC0xLFxuXG5cbiAgWl9GSUxURVJFRDogICAgICAgICAgICAgICAxLFxuICBaX0hVRkZNQU5fT05MWTogICAgICAgICAgIDIsXG4gIFpfUkxFOiAgICAgICAgICAgICAgICAgICAgMyxcbiAgWl9GSVhFRDogICAgICAgICAgICAgICAgICA0LFxuICBaX0RFRkFVTFRfU1RSQVRFR1k6ICAgICAgIDAsXG5cbiAgLyogUG9zc2libGUgdmFsdWVzIG9mIHRoZSBkYXRhX3R5cGUgZmllbGQgKHRob3VnaCBzZWUgaW5mbGF0ZSgpKSAqL1xuICBaX0JJTkFSWTogICAgICAgICAgICAgICAgIDAsXG4gIFpfVEVYVDogICAgICAgICAgICAgICAgICAgMSxcbiAgLy9aX0FTQ0lJOiAgICAgICAgICAgICAgICAxLCAvLyA9IFpfVEVYVCAoZGVwcmVjYXRlZClcbiAgWl9VTktOT1dOOiAgICAgICAgICAgICAgICAyLFxuXG4gIC8qIFRoZSBkZWZsYXRlIGNvbXByZXNzaW9uIG1ldGhvZCAqL1xuICBaX0RFRkxBVEVEOiAgICAgICAgICAgICAgIDhcbiAgLy9aX05VTEw6ICAgICAgICAgICAgICAgICBudWxsIC8vIFVzZSAtMSBvciBudWxsIGlubGluZSwgZGVwZW5kaW5nIG9uIHZhciB0eXBlXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyBOb3RlOiB3ZSBjYW4ndCBnZXQgc2lnbmlmaWNhbnQgc3BlZWQgYm9vc3QgaGVyZS5cbi8vIFNvIHdyaXRlIGNvZGUgdG8gbWluaW1pemUgc2l6ZSAtIG5vIHByZWdlbmVyYXRlZCB0YWJsZXNcbi8vIGFuZCBhcnJheSB0b29scyBkZXBlbmRlbmNpZXMuXG5cbi8vIChDKSAxOTk1LTIwMTMgSmVhbi1sb3VwIEdhaWxseSBhbmQgTWFyayBBZGxlclxuLy8gKEMpIDIwMTQtMjAxNyBWaXRhbHkgUHV6cmluIGFuZCBBbmRyZXkgVHVwaXRzaW5cbi8vXG4vLyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZFxuLy8gd2FycmFudHkuIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzXG4vLyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLFxuLy8gaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdFxuLy8gZnJlZWx5LCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOlxuLy9cbi8vIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90XG4vLyAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlXG4vLyAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZVxuLy8gICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLlxuLy8gMi4gQWx0ZXJlZCBzb3VyY2UgdmVyc2lvbnMgbXVzdCBiZSBwbGFpbmx5IG1hcmtlZCBhcyBzdWNoLCBhbmQgbXVzdCBub3QgYmVcbi8vICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLlxuLy8gMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi5cblxuLy8gVXNlIG9yZGluYXJ5IGFycmF5LCBzaW5jZSB1bnR5cGVkIG1ha2VzIG5vIGJvb3N0IGhlcmVcbmZ1bmN0aW9uIG1ha2VUYWJsZSgpIHtcbiAgdmFyIGMsIHRhYmxlID0gW107XG5cbiAgZm9yICh2YXIgbiA9IDA7IG4gPCAyNTY7IG4rKykge1xuICAgIGMgPSBuO1xuICAgIGZvciAodmFyIGsgPSAwOyBrIDwgODsgaysrKSB7XG4gICAgICBjID0gKChjICYgMSkgPyAoMHhFREI4ODMyMCBeIChjID4+PiAxKSkgOiAoYyA+Pj4gMSkpO1xuICAgIH1cbiAgICB0YWJsZVtuXSA9IGM7XG4gIH1cblxuICByZXR1cm4gdGFibGU7XG59XG5cbi8vIENyZWF0ZSB0YWJsZSBvbiBsb2FkLiBKdXN0IDI1NSBzaWduZWQgbG9uZ3MuIE5vdCBhIHByb2JsZW0uXG52YXIgY3JjVGFibGUgPSBtYWtlVGFibGUoKTtcblxuXG5mdW5jdGlvbiBjcmMzMihjcmMsIGJ1ZiwgbGVuLCBwb3MpIHtcbiAgdmFyIHQgPSBjcmNUYWJsZSxcbiAgICAgIGVuZCA9IHBvcyArIGxlbjtcblxuICBjcmMgXj0gLTE7XG5cbiAgZm9yICh2YXIgaSA9IHBvczsgaSA8IGVuZDsgaSsrKSB7XG4gICAgY3JjID0gKGNyYyA+Pj4gOCkgXiB0WyhjcmMgXiBidWZbaV0pICYgMHhGRl07XG4gIH1cblxuICByZXR1cm4gKGNyYyBeICgtMSkpOyAvLyA+Pj4gMDtcbn1cblxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyYzMyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXJcbi8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luXG4vL1xuLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWRcbi8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlc1xuLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSxcbi8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXRcbi8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczpcbi8vXG4vLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdFxuLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZVxuLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmVcbi8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC5cbi8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlXG4vLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS5cbi8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uXG5cbnZhciB1dGlscyAgID0gcmVxdWlyZSgnLi4vdXRpbHMvY29tbW9uJyk7XG52YXIgdHJlZXMgICA9IHJlcXVpcmUoJy4vdHJlZXMnKTtcbnZhciBhZGxlcjMyID0gcmVxdWlyZSgnLi9hZGxlcjMyJyk7XG52YXIgY3JjMzIgICA9IHJlcXVpcmUoJy4vY3JjMzInKTtcbnZhciBtc2cgICAgID0gcmVxdWlyZSgnLi9tZXNzYWdlcycpO1xuXG4vKiBQdWJsaWMgY29uc3RhbnRzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cblxuXG4vKiBBbGxvd2VkIGZsdXNoIHZhbHVlczsgc2VlIGRlZmxhdGUoKSBhbmQgaW5mbGF0ZSgpIGJlbG93IGZvciBkZXRhaWxzICovXG52YXIgWl9OT19GTFVTSCAgICAgID0gMDtcbnZhciBaX1BBUlRJQUxfRkxVU0ggPSAxO1xuLy92YXIgWl9TWU5DX0ZMVVNIICAgID0gMjtcbnZhciBaX0ZVTExfRkxVU0ggICAgPSAzO1xudmFyIFpfRklOSVNIICAgICAgICA9IDQ7XG52YXIgWl9CTE9DSyAgICAgICAgID0gNTtcbi8vdmFyIFpfVFJFRVMgICAgICAgICA9IDY7XG5cblxuLyogUmV0dXJuIGNvZGVzIGZvciB0aGUgY29tcHJlc3Npb24vZGVjb21wcmVzc2lvbiBmdW5jdGlvbnMuIE5lZ2F0aXZlIHZhbHVlc1xuICogYXJlIGVycm9ycywgcG9zaXRpdmUgdmFsdWVzIGFyZSB1c2VkIGZvciBzcGVjaWFsIGJ1dCBub3JtYWwgZXZlbnRzLlxuICovXG52YXIgWl9PSyAgICAgICAgICAgID0gMDtcbnZhciBaX1NUUkVBTV9FTkQgICAgPSAxO1xuLy92YXIgWl9ORUVEX0RJQ1QgICAgID0gMjtcbi8vdmFyIFpfRVJSTk8gICAgICAgICA9IC0xO1xudmFyIFpfU1RSRUFNX0VSUk9SICA9IC0yO1xudmFyIFpfREFUQV9FUlJPUiAgICA9IC0zO1xuLy92YXIgWl9NRU1fRVJST1IgICAgID0gLTQ7XG52YXIgWl9CVUZfRVJST1IgICAgID0gLTU7XG4vL3ZhciBaX1ZFUlNJT05fRVJST1IgPSAtNjtcblxuXG4vKiBjb21wcmVzc2lvbiBsZXZlbHMgKi9cbi8vdmFyIFpfTk9fQ09NUFJFU1NJT04gICAgICA9IDA7XG4vL3ZhciBaX0JFU1RfU1BFRUQgICAgICAgICAgPSAxO1xuLy92YXIgWl9CRVNUX0NPTVBSRVNTSU9OICAgID0gOTtcbnZhciBaX0RFRkFVTFRfQ09NUFJFU1NJT04gPSAtMTtcblxuXG52YXIgWl9GSUxURVJFRCAgICAgICAgICAgID0gMTtcbnZhciBaX0hVRkZNQU5fT05MWSAgICAgICAgPSAyO1xudmFyIFpfUkxFICAgICAgICAgICAgICAgICA9IDM7XG52YXIgWl9GSVhFRCAgICAgICAgICAgICAgID0gNDtcbnZhciBaX0RFRkFVTFRfU1RSQVRFR1kgICAgPSAwO1xuXG4vKiBQb3NzaWJsZSB2YWx1ZXMgb2YgdGhlIGRhdGFfdHlwZSBmaWVsZCAodGhvdWdoIHNlZSBpbmZsYXRlKCkpICovXG4vL3ZhciBaX0JJTkFSWSAgICAgICAgICAgICAgPSAwO1xuLy92YXIgWl9URVhUICAgICAgICAgICAgICAgID0gMTtcbi8vdmFyIFpfQVNDSUkgICAgICAgICAgICAgICA9IDE7IC8vID0gWl9URVhUXG52YXIgWl9VTktOT1dOICAgICAgICAgICAgID0gMjtcblxuXG4vKiBUaGUgZGVmbGF0ZSBjb21wcmVzc2lvbiBtZXRob2QgKi9cbnZhciBaX0RFRkxBVEVEICA9IDg7XG5cbi8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cblxudmFyIE1BWF9NRU1fTEVWRUwgPSA5O1xuLyogTWF4aW11bSB2YWx1ZSBmb3IgbWVtTGV2ZWwgaW4gZGVmbGF0ZUluaXQyICovXG52YXIgTUFYX1dCSVRTID0gMTU7XG4vKiAzMksgTFo3NyB3aW5kb3cgKi9cbnZhciBERUZfTUVNX0xFVkVMID0gODtcblxuXG52YXIgTEVOR1RIX0NPREVTICA9IDI5O1xuLyogbnVtYmVyIG9mIGxlbmd0aCBjb2Rlcywgbm90IGNvdW50aW5nIHRoZSBzcGVjaWFsIEVORF9CTE9DSyBjb2RlICovXG52YXIgTElURVJBTFMgICAgICA9IDI1Njtcbi8qIG51bWJlciBvZiBsaXRlcmFsIGJ5dGVzIDAuLjI1NSAqL1xudmFyIExfQ09ERVMgICAgICAgPSBMSVRFUkFMUyArIDEgKyBMRU5HVEhfQ09ERVM7XG4vKiBudW1iZXIgb2YgTGl0ZXJhbCBvciBMZW5ndGggY29kZXMsIGluY2x1ZGluZyB0aGUgRU5EX0JMT0NLIGNvZGUgKi9cbnZhciBEX0NPREVTICAgICAgID0gMzA7XG4vKiBudW1iZXIgb2YgZGlzdGFuY2UgY29kZXMgKi9cbnZhciBCTF9DT0RFUyAgICAgID0gMTk7XG4vKiBudW1iZXIgb2YgY29kZXMgdXNlZCB0byB0cmFuc2ZlciB0aGUgYml0IGxlbmd0aHMgKi9cbnZhciBIRUFQX1NJWkUgICAgID0gMiAqIExfQ09ERVMgKyAxO1xuLyogbWF4aW11bSBoZWFwIHNpemUgKi9cbnZhciBNQVhfQklUUyAgPSAxNTtcbi8qIEFsbCBjb2RlcyBtdXN0IG5vdCBleGNlZWQgTUFYX0JJVFMgYml0cyAqL1xuXG52YXIgTUlOX01BVENIID0gMztcbnZhciBNQVhfTUFUQ0ggPSAyNTg7XG52YXIgTUlOX0xPT0tBSEVBRCA9IChNQVhfTUFUQ0ggKyBNSU5fTUFUQ0ggKyAxKTtcblxudmFyIFBSRVNFVF9ESUNUID0gMHgyMDtcblxudmFyIElOSVRfU1RBVEUgPSA0MjtcbnZhciBFWFRSQV9TVEFURSA9IDY5O1xudmFyIE5BTUVfU1RBVEUgPSA3MztcbnZhciBDT01NRU5UX1NUQVRFID0gOTE7XG52YXIgSENSQ19TVEFURSA9IDEwMztcbnZhciBCVVNZX1NUQVRFID0gMTEzO1xudmFyIEZJTklTSF9TVEFURSA9IDY2NjtcblxudmFyIEJTX05FRURfTU9SRSAgICAgID0gMTsgLyogYmxvY2sgbm90IGNvbXBsZXRlZCwgbmVlZCBtb3JlIGlucHV0IG9yIG1vcmUgb3V0cHV0ICovXG52YXIgQlNfQkxPQ0tfRE9ORSAgICAgPSAyOyAvKiBibG9jayBmbHVzaCBwZXJmb3JtZWQgKi9cbnZhciBCU19GSU5JU0hfU1RBUlRFRCA9IDM7IC8qIGZpbmlzaCBzdGFydGVkLCBuZWVkIG9ubHkgbW9yZSBvdXRwdXQgYXQgbmV4dCBkZWZsYXRlICovXG52YXIgQlNfRklOSVNIX0RPTkUgICAgPSA0OyAvKiBmaW5pc2ggZG9uZSwgYWNjZXB0IG5vIG1vcmUgaW5wdXQgb3Igb3V0cHV0ICovXG5cbnZhciBPU19DT0RFID0gMHgwMzsgLy8gVW5peCA6KSAuIERvbid0IGRldGVjdCwgdXNlIHRoaXMgZGVmYXVsdC5cblxuZnVuY3Rpb24gZXJyKHN0cm0sIGVycm9yQ29kZSkge1xuICBzdHJtLm1zZyA9IG1zZ1tlcnJvckNvZGVdO1xuICByZXR1cm4gZXJyb3JDb2RlO1xufVxuXG5mdW5jdGlvbiByYW5rKGYpIHtcbiAgcmV0dXJuICgoZikgPDwgMSkgLSAoKGYpID4gNCA/IDkgOiAwKTtcbn1cblxuZnVuY3Rpb24gemVybyhidWYpIHsgdmFyIGxlbiA9IGJ1Zi5sZW5ndGg7IHdoaWxlICgtLWxlbiA+PSAwKSB7IGJ1ZltsZW5dID0gMDsgfSB9XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogRmx1c2ggYXMgbXVjaCBwZW5kaW5nIG91dHB1dCBhcyBwb3NzaWJsZS4gQWxsIGRlZmxhdGUoKSBvdXRwdXQgZ29lc1xuICogdGhyb3VnaCB0aGlzIGZ1bmN0aW9uIHNvIHNvbWUgYXBwbGljYXRpb25zIG1heSB3aXNoIHRvIG1vZGlmeSBpdFxuICogdG8gYXZvaWQgYWxsb2NhdGluZyBhIGxhcmdlIHN0cm0tPm91dHB1dCBidWZmZXIgYW5kIGNvcHlpbmcgaW50byBpdC5cbiAqIChTZWUgYWxzbyByZWFkX2J1ZigpKS5cbiAqL1xuZnVuY3Rpb24gZmx1c2hfcGVuZGluZyhzdHJtKSB7XG4gIHZhciBzID0gc3RybS5zdGF0ZTtcblxuICAvL190cl9mbHVzaF9iaXRzKHMpO1xuICB2YXIgbGVuID0gcy5wZW5kaW5nO1xuICBpZiAobGVuID4gc3RybS5hdmFpbF9vdXQpIHtcbiAgICBsZW4gPSBzdHJtLmF2YWlsX291dDtcbiAgfVxuICBpZiAobGVuID09PSAwKSB7IHJldHVybjsgfVxuXG4gIHV0aWxzLmFycmF5U2V0KHN0cm0ub3V0cHV0LCBzLnBlbmRpbmdfYnVmLCBzLnBlbmRpbmdfb3V0LCBsZW4sIHN0cm0ubmV4dF9vdXQpO1xuICBzdHJtLm5leHRfb3V0ICs9IGxlbjtcbiAgcy5wZW5kaW5nX291dCArPSBsZW47XG4gIHN0cm0udG90YWxfb3V0ICs9IGxlbjtcbiAgc3RybS5hdmFpbF9vdXQgLT0gbGVuO1xuICBzLnBlbmRpbmcgLT0gbGVuO1xuICBpZiAocy5wZW5kaW5nID09PSAwKSB7XG4gICAgcy5wZW5kaW5nX291dCA9IDA7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBmbHVzaF9ibG9ja19vbmx5KHMsIGxhc3QpIHtcbiAgdHJlZXMuX3RyX2ZsdXNoX2Jsb2NrKHMsIChzLmJsb2NrX3N0YXJ0ID49IDAgPyBzLmJsb2NrX3N0YXJ0IDogLTEpLCBzLnN0cnN0YXJ0IC0gcy5ibG9ja19zdGFydCwgbGFzdCk7XG4gIHMuYmxvY2tfc3RhcnQgPSBzLnN0cnN0YXJ0O1xuICBmbHVzaF9wZW5kaW5nKHMuc3RybSk7XG59XG5cblxuZnVuY3Rpb24gcHV0X2J5dGUocywgYikge1xuICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZysrXSA9IGI7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogUHV0IGEgc2hvcnQgaW4gdGhlIHBlbmRpbmcgYnVmZmVyLiBUaGUgMTYtYml0IHZhbHVlIGlzIHB1dCBpbiBNU0Igb3JkZXIuXG4gKiBJTiBhc3NlcnRpb246IHRoZSBzdHJlYW0gc3RhdGUgaXMgY29ycmVjdCBhbmQgdGhlcmUgaXMgZW5vdWdoIHJvb20gaW5cbiAqIHBlbmRpbmdfYnVmLlxuICovXG5mdW5jdGlvbiBwdXRTaG9ydE1TQihzLCBiKSB7XG4vLyAgcHV0X2J5dGUocywgKEJ5dGUpKGIgPj4gOCkpO1xuLy8gIHB1dF9ieXRlKHMsIChCeXRlKShiICYgMHhmZikpO1xuICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZysrXSA9IChiID4+PiA4KSAmIDB4ZmY7XG4gIHMucGVuZGluZ19idWZbcy5wZW5kaW5nKytdID0gYiAmIDB4ZmY7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBSZWFkIGEgbmV3IGJ1ZmZlciBmcm9tIHRoZSBjdXJyZW50IGlucHV0IHN0cmVhbSwgdXBkYXRlIHRoZSBhZGxlcjMyXG4gKiBhbmQgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuICBBbGwgZGVmbGF0ZSgpIGlucHV0IGdvZXMgdGhyb3VnaFxuICogdGhpcyBmdW5jdGlvbiBzbyBzb21lIGFwcGxpY2F0aW9ucyBtYXkgd2lzaCB0byBtb2RpZnkgaXQgdG8gYXZvaWRcbiAqIGFsbG9jYXRpbmcgYSBsYXJnZSBzdHJtLT5pbnB1dCBidWZmZXIgYW5kIGNvcHlpbmcgZnJvbSBpdC5cbiAqIChTZWUgYWxzbyBmbHVzaF9wZW5kaW5nKCkpLlxuICovXG5mdW5jdGlvbiByZWFkX2J1ZihzdHJtLCBidWYsIHN0YXJ0LCBzaXplKSB7XG4gIHZhciBsZW4gPSBzdHJtLmF2YWlsX2luO1xuXG4gIGlmIChsZW4gPiBzaXplKSB7IGxlbiA9IHNpemU7IH1cbiAgaWYgKGxlbiA9PT0gMCkgeyByZXR1cm4gMDsgfVxuXG4gIHN0cm0uYXZhaWxfaW4gLT0gbGVuO1xuXG4gIC8vIHptZW1jcHkoYnVmLCBzdHJtLT5uZXh0X2luLCBsZW4pO1xuICB1dGlscy5hcnJheVNldChidWYsIHN0cm0uaW5wdXQsIHN0cm0ubmV4dF9pbiwgbGVuLCBzdGFydCk7XG4gIGlmIChzdHJtLnN0YXRlLndyYXAgPT09IDEpIHtcbiAgICBzdHJtLmFkbGVyID0gYWRsZXIzMihzdHJtLmFkbGVyLCBidWYsIGxlbiwgc3RhcnQpO1xuICB9XG5cbiAgZWxzZSBpZiAoc3RybS5zdGF0ZS53cmFwID09PSAyKSB7XG4gICAgc3RybS5hZGxlciA9IGNyYzMyKHN0cm0uYWRsZXIsIGJ1ZiwgbGVuLCBzdGFydCk7XG4gIH1cblxuICBzdHJtLm5leHRfaW4gKz0gbGVuO1xuICBzdHJtLnRvdGFsX2luICs9IGxlbjtcblxuICByZXR1cm4gbGVuO1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogU2V0IG1hdGNoX3N0YXJ0IHRvIHRoZSBsb25nZXN0IG1hdGNoIHN0YXJ0aW5nIGF0IHRoZSBnaXZlbiBzdHJpbmcgYW5kXG4gKiByZXR1cm4gaXRzIGxlbmd0aC4gTWF0Y2hlcyBzaG9ydGVyIG9yIGVxdWFsIHRvIHByZXZfbGVuZ3RoIGFyZSBkaXNjYXJkZWQsXG4gKiBpbiB3aGljaCBjYXNlIHRoZSByZXN1bHQgaXMgZXF1YWwgdG8gcHJldl9sZW5ndGggYW5kIG1hdGNoX3N0YXJ0IGlzXG4gKiBnYXJiYWdlLlxuICogSU4gYXNzZXJ0aW9uczogY3VyX21hdGNoIGlzIHRoZSBoZWFkIG9mIHRoZSBoYXNoIGNoYWluIGZvciB0aGUgY3VycmVudFxuICogICBzdHJpbmcgKHN0cnN0YXJ0KSBhbmQgaXRzIGRpc3RhbmNlIGlzIDw9IE1BWF9ESVNULCBhbmQgcHJldl9sZW5ndGggPj0gMVxuICogT1VUIGFzc2VydGlvbjogdGhlIG1hdGNoIGxlbmd0aCBpcyBub3QgZ3JlYXRlciB0aGFuIHMtPmxvb2thaGVhZC5cbiAqL1xuZnVuY3Rpb24gbG9uZ2VzdF9tYXRjaChzLCBjdXJfbWF0Y2gpIHtcbiAgdmFyIGNoYWluX2xlbmd0aCA9IHMubWF4X2NoYWluX2xlbmd0aDsgICAgICAvKiBtYXggaGFzaCBjaGFpbiBsZW5ndGggKi9cbiAgdmFyIHNjYW4gPSBzLnN0cnN0YXJ0OyAvKiBjdXJyZW50IHN0cmluZyAqL1xuICB2YXIgbWF0Y2g7ICAgICAgICAgICAgICAgICAgICAgICAvKiBtYXRjaGVkIHN0cmluZyAqL1xuICB2YXIgbGVuOyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGxlbmd0aCBvZiBjdXJyZW50IG1hdGNoICovXG4gIHZhciBiZXN0X2xlbiA9IHMucHJldl9sZW5ndGg7ICAgICAgICAgICAgICAvKiBiZXN0IG1hdGNoIGxlbmd0aCBzbyBmYXIgKi9cbiAgdmFyIG5pY2VfbWF0Y2ggPSBzLm5pY2VfbWF0Y2g7ICAgICAgICAgICAgIC8qIHN0b3AgaWYgbWF0Y2ggbG9uZyBlbm91Z2ggKi9cbiAgdmFyIGxpbWl0ID0gKHMuc3Ryc3RhcnQgPiAocy53X3NpemUgLSBNSU5fTE9PS0FIRUFEKSkgP1xuICAgICAgcy5zdHJzdGFydCAtIChzLndfc2l6ZSAtIE1JTl9MT09LQUhFQUQpIDogMC8qTklMKi87XG5cbiAgdmFyIF93aW4gPSBzLndpbmRvdzsgLy8gc2hvcnRjdXRcblxuICB2YXIgd21hc2sgPSBzLndfbWFzaztcbiAgdmFyIHByZXYgID0gcy5wcmV2O1xuXG4gIC8qIFN0b3Agd2hlbiBjdXJfbWF0Y2ggYmVjb21lcyA8PSBsaW1pdC4gVG8gc2ltcGxpZnkgdGhlIGNvZGUsXG4gICAqIHdlIHByZXZlbnQgbWF0Y2hlcyB3aXRoIHRoZSBzdHJpbmcgb2Ygd2luZG93IGluZGV4IDAuXG4gICAqL1xuXG4gIHZhciBzdHJlbmQgPSBzLnN0cnN0YXJ0ICsgTUFYX01BVENIO1xuICB2YXIgc2Nhbl9lbmQxICA9IF93aW5bc2NhbiArIGJlc3RfbGVuIC0gMV07XG4gIHZhciBzY2FuX2VuZCAgID0gX3dpbltzY2FuICsgYmVzdF9sZW5dO1xuXG4gIC8qIFRoZSBjb2RlIGlzIG9wdGltaXplZCBmb3IgSEFTSF9CSVRTID49IDggYW5kIE1BWF9NQVRDSC0yIG11bHRpcGxlIG9mIDE2LlxuICAgKiBJdCBpcyBlYXN5IHRvIGdldCByaWQgb2YgdGhpcyBvcHRpbWl6YXRpb24gaWYgbmVjZXNzYXJ5LlxuICAgKi9cbiAgLy8gQXNzZXJ0KHMtPmhhc2hfYml0cyA+PSA4ICYmIE1BWF9NQVRDSCA9PSAyNTgsIFwiQ29kZSB0b28gY2xldmVyXCIpO1xuXG4gIC8qIERvIG5vdCB3YXN0ZSB0b28gbXVjaCB0aW1lIGlmIHdlIGFscmVhZHkgaGF2ZSBhIGdvb2QgbWF0Y2g6ICovXG4gIGlmIChzLnByZXZfbGVuZ3RoID49IHMuZ29vZF9tYXRjaCkge1xuICAgIGNoYWluX2xlbmd0aCA+Pj0gMjtcbiAgfVxuICAvKiBEbyBub3QgbG9vayBmb3IgbWF0Y2hlcyBiZXlvbmQgdGhlIGVuZCBvZiB0aGUgaW5wdXQuIFRoaXMgaXMgbmVjZXNzYXJ5XG4gICAqIHRvIG1ha2UgZGVmbGF0ZSBkZXRlcm1pbmlzdGljLlxuICAgKi9cbiAgaWYgKG5pY2VfbWF0Y2ggPiBzLmxvb2thaGVhZCkgeyBuaWNlX21hdGNoID0gcy5sb29rYWhlYWQ7IH1cblxuICAvLyBBc3NlcnQoKHVsZylzLT5zdHJzdGFydCA8PSBzLT53aW5kb3dfc2l6ZS1NSU5fTE9PS0FIRUFELCBcIm5lZWQgbG9va2FoZWFkXCIpO1xuXG4gIGRvIHtcbiAgICAvLyBBc3NlcnQoY3VyX21hdGNoIDwgcy0+c3Ryc3RhcnQsIFwibm8gZnV0dXJlXCIpO1xuICAgIG1hdGNoID0gY3VyX21hdGNoO1xuXG4gICAgLyogU2tpcCB0byBuZXh0IG1hdGNoIGlmIHRoZSBtYXRjaCBsZW5ndGggY2Fubm90IGluY3JlYXNlXG4gICAgICogb3IgaWYgdGhlIG1hdGNoIGxlbmd0aCBpcyBsZXNzIHRoYW4gMi4gIE5vdGUgdGhhdCB0aGUgY2hlY2tzIGJlbG93XG4gICAgICogZm9yIGluc3VmZmljaWVudCBsb29rYWhlYWQgb25seSBvY2N1ciBvY2Nhc2lvbmFsbHkgZm9yIHBlcmZvcm1hbmNlXG4gICAgICogcmVhc29ucy4gIFRoZXJlZm9yZSB1bmluaXRpYWxpemVkIG1lbW9yeSB3aWxsIGJlIGFjY2Vzc2VkLCBhbmRcbiAgICAgKiBjb25kaXRpb25hbCBqdW1wcyB3aWxsIGJlIG1hZGUgdGhhdCBkZXBlbmQgb24gdGhvc2UgdmFsdWVzLlxuICAgICAqIEhvd2V2ZXIgdGhlIGxlbmd0aCBvZiB0aGUgbWF0Y2ggaXMgbGltaXRlZCB0byB0aGUgbG9va2FoZWFkLCBzb1xuICAgICAqIHRoZSBvdXRwdXQgb2YgZGVmbGF0ZSBpcyBub3QgYWZmZWN0ZWQgYnkgdGhlIHVuaW5pdGlhbGl6ZWQgdmFsdWVzLlxuICAgICAqL1xuXG4gICAgaWYgKF93aW5bbWF0Y2ggKyBiZXN0X2xlbl0gICAgICE9PSBzY2FuX2VuZCAgfHxcbiAgICAgICAgX3dpblttYXRjaCArIGJlc3RfbGVuIC0gMV0gIT09IHNjYW5fZW5kMSB8fFxuICAgICAgICBfd2luW21hdGNoXSAgICAgICAgICAgICAgICAhPT0gX3dpbltzY2FuXSB8fFxuICAgICAgICBfd2luWysrbWF0Y2hdICAgICAgICAgICAgICAhPT0gX3dpbltzY2FuICsgMV0pIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8qIFRoZSBjaGVjayBhdCBiZXN0X2xlbi0xIGNhbiBiZSByZW1vdmVkIGJlY2F1c2UgaXQgd2lsbCBiZSBtYWRlXG4gICAgICogYWdhaW4gbGF0ZXIuIChUaGlzIGhldXJpc3RpYyBpcyBub3QgYWx3YXlzIGEgd2luLilcbiAgICAgKiBJdCBpcyBub3QgbmVjZXNzYXJ5IHRvIGNvbXBhcmUgc2NhblsyXSBhbmQgbWF0Y2hbMl0gc2luY2UgdGhleVxuICAgICAqIGFyZSBhbHdheXMgZXF1YWwgd2hlbiB0aGUgb3RoZXIgYnl0ZXMgbWF0Y2gsIGdpdmVuIHRoYXRcbiAgICAgKiB0aGUgaGFzaCBrZXlzIGFyZSBlcXVhbCBhbmQgdGhhdCBIQVNIX0JJVFMgPj0gOC5cbiAgICAgKi9cbiAgICBzY2FuICs9IDI7XG4gICAgbWF0Y2grKztcbiAgICAvLyBBc3NlcnQoKnNjYW4gPT0gKm1hdGNoLCBcIm1hdGNoWzJdP1wiKTtcblxuICAgIC8qIFdlIGNoZWNrIGZvciBpbnN1ZmZpY2llbnQgbG9va2FoZWFkIG9ubHkgZXZlcnkgOHRoIGNvbXBhcmlzb247XG4gICAgICogdGhlIDI1NnRoIGNoZWNrIHdpbGwgYmUgbWFkZSBhdCBzdHJzdGFydCsyNTguXG4gICAgICovXG4gICAgZG8ge1xuICAgICAgLypqc2hpbnQgbm9lbXB0eTpmYWxzZSovXG4gICAgfSB3aGlsZSAoX3dpblsrK3NjYW5dID09PSBfd2luWysrbWF0Y2hdICYmIF93aW5bKytzY2FuXSA9PT0gX3dpblsrK21hdGNoXSAmJlxuICAgICAgICAgICAgIF93aW5bKytzY2FuXSA9PT0gX3dpblsrK21hdGNoXSAmJiBfd2luWysrc2Nhbl0gPT09IF93aW5bKyttYXRjaF0gJiZcbiAgICAgICAgICAgICBfd2luWysrc2Nhbl0gPT09IF93aW5bKyttYXRjaF0gJiYgX3dpblsrK3NjYW5dID09PSBfd2luWysrbWF0Y2hdICYmXG4gICAgICAgICAgICAgX3dpblsrK3NjYW5dID09PSBfd2luWysrbWF0Y2hdICYmIF93aW5bKytzY2FuXSA9PT0gX3dpblsrK21hdGNoXSAmJlxuICAgICAgICAgICAgIHNjYW4gPCBzdHJlbmQpO1xuXG4gICAgLy8gQXNzZXJ0KHNjYW4gPD0gcy0+d2luZG93Kyh1bnNpZ25lZCkocy0+d2luZG93X3NpemUtMSksIFwid2lsZCBzY2FuXCIpO1xuXG4gICAgbGVuID0gTUFYX01BVENIIC0gKHN0cmVuZCAtIHNjYW4pO1xuICAgIHNjYW4gPSBzdHJlbmQgLSBNQVhfTUFUQ0g7XG5cbiAgICBpZiAobGVuID4gYmVzdF9sZW4pIHtcbiAgICAgIHMubWF0Y2hfc3RhcnQgPSBjdXJfbWF0Y2g7XG4gICAgICBiZXN0X2xlbiA9IGxlbjtcbiAgICAgIGlmIChsZW4gPj0gbmljZV9tYXRjaCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIHNjYW5fZW5kMSAgPSBfd2luW3NjYW4gKyBiZXN0X2xlbiAtIDFdO1xuICAgICAgc2Nhbl9lbmQgICA9IF93aW5bc2NhbiArIGJlc3RfbGVuXTtcbiAgICB9XG4gIH0gd2hpbGUgKChjdXJfbWF0Y2ggPSBwcmV2W2N1cl9tYXRjaCAmIHdtYXNrXSkgPiBsaW1pdCAmJiAtLWNoYWluX2xlbmd0aCAhPT0gMCk7XG5cbiAgaWYgKGJlc3RfbGVuIDw9IHMubG9va2FoZWFkKSB7XG4gICAgcmV0dXJuIGJlc3RfbGVuO1xuICB9XG4gIHJldHVybiBzLmxvb2thaGVhZDtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEZpbGwgdGhlIHdpbmRvdyB3aGVuIHRoZSBsb29rYWhlYWQgYmVjb21lcyBpbnN1ZmZpY2llbnQuXG4gKiBVcGRhdGVzIHN0cnN0YXJ0IGFuZCBsb29rYWhlYWQuXG4gKlxuICogSU4gYXNzZXJ0aW9uOiBsb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFEXG4gKiBPVVQgYXNzZXJ0aW9uczogc3Ryc3RhcnQgPD0gd2luZG93X3NpemUtTUlOX0xPT0tBSEVBRFxuICogICAgQXQgbGVhc3Qgb25lIGJ5dGUgaGFzIGJlZW4gcmVhZCwgb3IgYXZhaWxfaW4gPT0gMDsgcmVhZHMgYXJlXG4gKiAgICBwZXJmb3JtZWQgZm9yIGF0IGxlYXN0IHR3byBieXRlcyAocmVxdWlyZWQgZm9yIHRoZSB6aXAgdHJhbnNsYXRlX2VvbFxuICogICAgb3B0aW9uIC0tIG5vdCBzdXBwb3J0ZWQgaGVyZSkuXG4gKi9cbmZ1bmN0aW9uIGZpbGxfd2luZG93KHMpIHtcbiAgdmFyIF93X3NpemUgPSBzLndfc2l6ZTtcbiAgdmFyIHAsIG4sIG0sIG1vcmUsIHN0cjtcblxuICAvL0Fzc2VydChzLT5sb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFELCBcImFscmVhZHkgZW5vdWdoIGxvb2thaGVhZFwiKTtcblxuICBkbyB7XG4gICAgbW9yZSA9IHMud2luZG93X3NpemUgLSBzLmxvb2thaGVhZCAtIHMuc3Ryc3RhcnQ7XG5cbiAgICAvLyBKUyBpbnRzIGhhdmUgMzIgYml0LCBibG9jayBiZWxvdyBub3QgbmVlZGVkXG4gICAgLyogRGVhbCB3aXRoICFAIyQlIDY0SyBsaW1pdDogKi9cbiAgICAvL2lmIChzaXplb2YoaW50KSA8PSAyKSB7XG4gICAgLy8gICAgaWYgKG1vcmUgPT0gMCAmJiBzLT5zdHJzdGFydCA9PSAwICYmIHMtPmxvb2thaGVhZCA9PSAwKSB7XG4gICAgLy8gICAgICAgIG1vcmUgPSB3c2l6ZTtcbiAgICAvL1xuICAgIC8vICB9IGVsc2UgaWYgKG1vcmUgPT0gKHVuc2lnbmVkKSgtMSkpIHtcbiAgICAvLyAgICAgICAgLyogVmVyeSB1bmxpa2VseSwgYnV0IHBvc3NpYmxlIG9uIDE2IGJpdCBtYWNoaW5lIGlmXG4gICAgLy8gICAgICAgICAqIHN0cnN0YXJ0ID09IDAgJiYgbG9va2FoZWFkID09IDEgKGlucHV0IGRvbmUgYSBieXRlIGF0IHRpbWUpXG4gICAgLy8gICAgICAgICAqL1xuICAgIC8vICAgICAgICBtb3JlLS07XG4gICAgLy8gICAgfVxuICAgIC8vfVxuXG5cbiAgICAvKiBJZiB0aGUgd2luZG93IGlzIGFsbW9zdCBmdWxsIGFuZCB0aGVyZSBpcyBpbnN1ZmZpY2llbnQgbG9va2FoZWFkLFxuICAgICAqIG1vdmUgdGhlIHVwcGVyIGhhbGYgdG8gdGhlIGxvd2VyIG9uZSB0byBtYWtlIHJvb20gaW4gdGhlIHVwcGVyIGhhbGYuXG4gICAgICovXG4gICAgaWYgKHMuc3Ryc3RhcnQgPj0gX3dfc2l6ZSArIChfd19zaXplIC0gTUlOX0xPT0tBSEVBRCkpIHtcblxuICAgICAgdXRpbHMuYXJyYXlTZXQocy53aW5kb3csIHMud2luZG93LCBfd19zaXplLCBfd19zaXplLCAwKTtcbiAgICAgIHMubWF0Y2hfc3RhcnQgLT0gX3dfc2l6ZTtcbiAgICAgIHMuc3Ryc3RhcnQgLT0gX3dfc2l6ZTtcbiAgICAgIC8qIHdlIG5vdyBoYXZlIHN0cnN0YXJ0ID49IE1BWF9ESVNUICovXG4gICAgICBzLmJsb2NrX3N0YXJ0IC09IF93X3NpemU7XG5cbiAgICAgIC8qIFNsaWRlIHRoZSBoYXNoIHRhYmxlIChjb3VsZCBiZSBhdm9pZGVkIHdpdGggMzIgYml0IHZhbHVlc1xuICAgICAgIGF0IHRoZSBleHBlbnNlIG9mIG1lbW9yeSB1c2FnZSkuIFdlIHNsaWRlIGV2ZW4gd2hlbiBsZXZlbCA9PSAwXG4gICAgICAgdG8ga2VlcCB0aGUgaGFzaCB0YWJsZSBjb25zaXN0ZW50IGlmIHdlIHN3aXRjaCBiYWNrIHRvIGxldmVsID4gMFxuICAgICAgIGxhdGVyLiAoVXNpbmcgbGV2ZWwgMCBwZXJtYW5lbnRseSBpcyBub3QgYW4gb3B0aW1hbCB1c2FnZSBvZlxuICAgICAgIHpsaWIsIHNvIHdlIGRvbid0IGNhcmUgYWJvdXQgdGhpcyBwYXRob2xvZ2ljYWwgY2FzZS4pXG4gICAgICAgKi9cblxuICAgICAgbiA9IHMuaGFzaF9zaXplO1xuICAgICAgcCA9IG47XG4gICAgICBkbyB7XG4gICAgICAgIG0gPSBzLmhlYWRbLS1wXTtcbiAgICAgICAgcy5oZWFkW3BdID0gKG0gPj0gX3dfc2l6ZSA/IG0gLSBfd19zaXplIDogMCk7XG4gICAgICB9IHdoaWxlICgtLW4pO1xuXG4gICAgICBuID0gX3dfc2l6ZTtcbiAgICAgIHAgPSBuO1xuICAgICAgZG8ge1xuICAgICAgICBtID0gcy5wcmV2Wy0tcF07XG4gICAgICAgIHMucHJldltwXSA9IChtID49IF93X3NpemUgPyBtIC0gX3dfc2l6ZSA6IDApO1xuICAgICAgICAvKiBJZiBuIGlzIG5vdCBvbiBhbnkgaGFzaCBjaGFpbiwgcHJldltuXSBpcyBnYXJiYWdlIGJ1dFxuICAgICAgICAgKiBpdHMgdmFsdWUgd2lsbCBuZXZlciBiZSB1c2VkLlxuICAgICAgICAgKi9cbiAgICAgIH0gd2hpbGUgKC0tbik7XG5cbiAgICAgIG1vcmUgKz0gX3dfc2l6ZTtcbiAgICB9XG4gICAgaWYgKHMuc3RybS5hdmFpbF9pbiA9PT0gMCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLyogSWYgdGhlcmUgd2FzIG5vIHNsaWRpbmc6XG4gICAgICogICAgc3Ryc3RhcnQgPD0gV1NJWkUrTUFYX0RJU1QtMSAmJiBsb29rYWhlYWQgPD0gTUlOX0xPT0tBSEVBRCAtIDEgJiZcbiAgICAgKiAgICBtb3JlID09IHdpbmRvd19zaXplIC0gbG9va2FoZWFkIC0gc3Ryc3RhcnRcbiAgICAgKiA9PiBtb3JlID49IHdpbmRvd19zaXplIC0gKE1JTl9MT09LQUhFQUQtMSArIFdTSVpFICsgTUFYX0RJU1QtMSlcbiAgICAgKiA9PiBtb3JlID49IHdpbmRvd19zaXplIC0gMipXU0laRSArIDJcbiAgICAgKiBJbiB0aGUgQklHX01FTSBvciBNTUFQIGNhc2UgKG5vdCB5ZXQgc3VwcG9ydGVkKSxcbiAgICAgKiAgIHdpbmRvd19zaXplID09IGlucHV0X3NpemUgKyBNSU5fTE9PS0FIRUFEICAmJlxuICAgICAqICAgc3Ryc3RhcnQgKyBzLT5sb29rYWhlYWQgPD0gaW5wdXRfc2l6ZSA9PiBtb3JlID49IE1JTl9MT09LQUhFQUQuXG4gICAgICogT3RoZXJ3aXNlLCB3aW5kb3dfc2l6ZSA9PSAyKldTSVpFIHNvIG1vcmUgPj0gMi5cbiAgICAgKiBJZiB0aGVyZSB3YXMgc2xpZGluZywgbW9yZSA+PSBXU0laRS4gU28gaW4gYWxsIGNhc2VzLCBtb3JlID49IDIuXG4gICAgICovXG4gICAgLy9Bc3NlcnQobW9yZSA+PSAyLCBcIm1vcmUgPCAyXCIpO1xuICAgIG4gPSByZWFkX2J1ZihzLnN0cm0sIHMud2luZG93LCBzLnN0cnN0YXJ0ICsgcy5sb29rYWhlYWQsIG1vcmUpO1xuICAgIHMubG9va2FoZWFkICs9IG47XG5cbiAgICAvKiBJbml0aWFsaXplIHRoZSBoYXNoIHZhbHVlIG5vdyB0aGF0IHdlIGhhdmUgc29tZSBpbnB1dDogKi9cbiAgICBpZiAocy5sb29rYWhlYWQgKyBzLmluc2VydCA+PSBNSU5fTUFUQ0gpIHtcbiAgICAgIHN0ciA9IHMuc3Ryc3RhcnQgLSBzLmluc2VydDtcbiAgICAgIHMuaW5zX2ggPSBzLndpbmRvd1tzdHJdO1xuXG4gICAgICAvKiBVUERBVEVfSEFTSChzLCBzLT5pbnNfaCwgcy0+d2luZG93W3N0ciArIDFdKTsgKi9cbiAgICAgIHMuaW5zX2ggPSAoKHMuaW5zX2ggPDwgcy5oYXNoX3NoaWZ0KSBeIHMud2luZG93W3N0ciArIDFdKSAmIHMuaGFzaF9tYXNrO1xuLy8jaWYgTUlOX01BVENIICE9IDNcbi8vICAgICAgICBDYWxsIHVwZGF0ZV9oYXNoKCkgTUlOX01BVENILTMgbW9yZSB0aW1lc1xuLy8jZW5kaWZcbiAgICAgIHdoaWxlIChzLmluc2VydCkge1xuICAgICAgICAvKiBVUERBVEVfSEFTSChzLCBzLT5pbnNfaCwgcy0+d2luZG93W3N0ciArIE1JTl9NQVRDSC0xXSk7ICovXG4gICAgICAgIHMuaW5zX2ggPSAoKHMuaW5zX2ggPDwgcy5oYXNoX3NoaWZ0KSBeIHMud2luZG93W3N0ciArIE1JTl9NQVRDSCAtIDFdKSAmIHMuaGFzaF9tYXNrO1xuXG4gICAgICAgIHMucHJldltzdHIgJiBzLndfbWFza10gPSBzLmhlYWRbcy5pbnNfaF07XG4gICAgICAgIHMuaGVhZFtzLmluc19oXSA9IHN0cjtcbiAgICAgICAgc3RyKys7XG4gICAgICAgIHMuaW5zZXJ0LS07XG4gICAgICAgIGlmIChzLmxvb2thaGVhZCArIHMuaW5zZXJ0IDwgTUlOX01BVENIKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLyogSWYgdGhlIHdob2xlIGlucHV0IGhhcyBsZXNzIHRoYW4gTUlOX01BVENIIGJ5dGVzLCBpbnNfaCBpcyBnYXJiYWdlLFxuICAgICAqIGJ1dCB0aGlzIGlzIG5vdCBpbXBvcnRhbnQgc2luY2Ugb25seSBsaXRlcmFsIGJ5dGVzIHdpbGwgYmUgZW1pdHRlZC5cbiAgICAgKi9cblxuICB9IHdoaWxlIChzLmxvb2thaGVhZCA8IE1JTl9MT09LQUhFQUQgJiYgcy5zdHJtLmF2YWlsX2luICE9PSAwKTtcblxuICAvKiBJZiB0aGUgV0lOX0lOSVQgYnl0ZXMgYWZ0ZXIgdGhlIGVuZCBvZiB0aGUgY3VycmVudCBkYXRhIGhhdmUgbmV2ZXIgYmVlblxuICAgKiB3cml0dGVuLCB0aGVuIHplcm8gdGhvc2UgYnl0ZXMgaW4gb3JkZXIgdG8gYXZvaWQgbWVtb3J5IGNoZWNrIHJlcG9ydHMgb2ZcbiAgICogdGhlIHVzZSBvZiB1bmluaXRpYWxpemVkIChvciB1bmluaXRpYWxpc2VkIGFzIEp1bGlhbiB3cml0ZXMpIGJ5dGVzIGJ5XG4gICAqIHRoZSBsb25nZXN0IG1hdGNoIHJvdXRpbmVzLiAgVXBkYXRlIHRoZSBoaWdoIHdhdGVyIG1hcmsgZm9yIHRoZSBuZXh0XG4gICAqIHRpbWUgdGhyb3VnaCBoZXJlLiAgV0lOX0lOSVQgaXMgc2V0IHRvIE1BWF9NQVRDSCBzaW5jZSB0aGUgbG9uZ2VzdCBtYXRjaFxuICAgKiByb3V0aW5lcyBhbGxvdyBzY2FubmluZyB0byBzdHJzdGFydCArIE1BWF9NQVRDSCwgaWdub3JpbmcgbG9va2FoZWFkLlxuICAgKi9cbi8vICBpZiAocy5oaWdoX3dhdGVyIDwgcy53aW5kb3dfc2l6ZSkge1xuLy8gICAgdmFyIGN1cnIgPSBzLnN0cnN0YXJ0ICsgcy5sb29rYWhlYWQ7XG4vLyAgICB2YXIgaW5pdCA9IDA7XG4vL1xuLy8gICAgaWYgKHMuaGlnaF93YXRlciA8IGN1cnIpIHtcbi8vICAgICAgLyogUHJldmlvdXMgaGlnaCB3YXRlciBtYXJrIGJlbG93IGN1cnJlbnQgZGF0YSAtLSB6ZXJvIFdJTl9JTklUXG4vLyAgICAgICAqIGJ5dGVzIG9yIHVwIHRvIGVuZCBvZiB3aW5kb3csIHdoaWNoZXZlciBpcyBsZXNzLlxuLy8gICAgICAgKi9cbi8vICAgICAgaW5pdCA9IHMud2luZG93X3NpemUgLSBjdXJyO1xuLy8gICAgICBpZiAoaW5pdCA+IFdJTl9JTklUKVxuLy8gICAgICAgIGluaXQgPSBXSU5fSU5JVDtcbi8vICAgICAgem1lbXplcm8ocy0+d2luZG93ICsgY3VyciwgKHVuc2lnbmVkKWluaXQpO1xuLy8gICAgICBzLT5oaWdoX3dhdGVyID0gY3VyciArIGluaXQ7XG4vLyAgICB9XG4vLyAgICBlbHNlIGlmIChzLT5oaWdoX3dhdGVyIDwgKHVsZyljdXJyICsgV0lOX0lOSVQpIHtcbi8vICAgICAgLyogSGlnaCB3YXRlciBtYXJrIGF0IG9yIGFib3ZlIGN1cnJlbnQgZGF0YSwgYnV0IGJlbG93IGN1cnJlbnQgZGF0YVxuLy8gICAgICAgKiBwbHVzIFdJTl9JTklUIC0tIHplcm8gb3V0IHRvIGN1cnJlbnQgZGF0YSBwbHVzIFdJTl9JTklULCBvciB1cFxuLy8gICAgICAgKiB0byBlbmQgb2Ygd2luZG93LCB3aGljaGV2ZXIgaXMgbGVzcy5cbi8vICAgICAgICovXG4vLyAgICAgIGluaXQgPSAodWxnKWN1cnIgKyBXSU5fSU5JVCAtIHMtPmhpZ2hfd2F0ZXI7XG4vLyAgICAgIGlmIChpbml0ID4gcy0+d2luZG93X3NpemUgLSBzLT5oaWdoX3dhdGVyKVxuLy8gICAgICAgIGluaXQgPSBzLT53aW5kb3dfc2l6ZSAtIHMtPmhpZ2hfd2F0ZXI7XG4vLyAgICAgIHptZW16ZXJvKHMtPndpbmRvdyArIHMtPmhpZ2hfd2F0ZXIsICh1bnNpZ25lZClpbml0KTtcbi8vICAgICAgcy0+aGlnaF93YXRlciArPSBpbml0O1xuLy8gICAgfVxuLy8gIH1cbi8vXG4vLyAgQXNzZXJ0KCh1bGcpcy0+c3Ryc3RhcnQgPD0gcy0+d2luZG93X3NpemUgLSBNSU5fTE9PS0FIRUFELFxuLy8gICAgXCJub3QgZW5vdWdoIHJvb20gZm9yIHNlYXJjaFwiKTtcbn1cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb3B5IHdpdGhvdXQgY29tcHJlc3Npb24gYXMgbXVjaCBhcyBwb3NzaWJsZSBmcm9tIHRoZSBpbnB1dCBzdHJlYW0sIHJldHVyblxuICogdGhlIGN1cnJlbnQgYmxvY2sgc3RhdGUuXG4gKiBUaGlzIGZ1bmN0aW9uIGRvZXMgbm90IGluc2VydCBuZXcgc3RyaW5ncyBpbiB0aGUgZGljdGlvbmFyeSBzaW5jZVxuICogdW5jb21wcmVzc2libGUgZGF0YSBpcyBwcm9iYWJseSBub3QgdXNlZnVsLiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWRcbiAqIG9ubHkgZm9yIHRoZSBsZXZlbD0wIGNvbXByZXNzaW9uIG9wdGlvbi5cbiAqIE5PVEU6IHRoaXMgZnVuY3Rpb24gc2hvdWxkIGJlIG9wdGltaXplZCB0byBhdm9pZCBleHRyYSBjb3B5aW5nIGZyb21cbiAqIHdpbmRvdyB0byBwZW5kaW5nX2J1Zi5cbiAqL1xuZnVuY3Rpb24gZGVmbGF0ZV9zdG9yZWQocywgZmx1c2gpIHtcbiAgLyogU3RvcmVkIGJsb2NrcyBhcmUgbGltaXRlZCB0byAweGZmZmYgYnl0ZXMsIHBlbmRpbmdfYnVmIGlzIGxpbWl0ZWRcbiAgICogdG8gcGVuZGluZ19idWZfc2l6ZSwgYW5kIGVhY2ggc3RvcmVkIGJsb2NrIGhhcyBhIDUgYnl0ZSBoZWFkZXI6XG4gICAqL1xuICB2YXIgbWF4X2Jsb2NrX3NpemUgPSAweGZmZmY7XG5cbiAgaWYgKG1heF9ibG9ja19zaXplID4gcy5wZW5kaW5nX2J1Zl9zaXplIC0gNSkge1xuICAgIG1heF9ibG9ja19zaXplID0gcy5wZW5kaW5nX2J1Zl9zaXplIC0gNTtcbiAgfVxuXG4gIC8qIENvcHkgYXMgbXVjaCBhcyBwb3NzaWJsZSBmcm9tIGlucHV0IHRvIG91dHB1dDogKi9cbiAgZm9yICg7Oykge1xuICAgIC8qIEZpbGwgdGhlIHdpbmRvdyBhcyBtdWNoIGFzIHBvc3NpYmxlOiAqL1xuICAgIGlmIChzLmxvb2thaGVhZCA8PSAxKSB7XG5cbiAgICAgIC8vQXNzZXJ0KHMtPnN0cnN0YXJ0IDwgcy0+d19zaXplK01BWF9ESVNUKHMpIHx8XG4gICAgICAvLyAgcy0+YmxvY2tfc3RhcnQgPj0gKGxvbmcpcy0+d19zaXplLCBcInNsaWRlIHRvbyBsYXRlXCIpO1xuLy8gICAgICBpZiAoIShzLnN0cnN0YXJ0IDwgcy53X3NpemUgKyAocy53X3NpemUgLSBNSU5fTE9PS0FIRUFEKSB8fFxuLy8gICAgICAgIHMuYmxvY2tfc3RhcnQgPj0gcy53X3NpemUpKSB7XG4vLyAgICAgICAgdGhyb3cgIG5ldyBFcnJvcihcInNsaWRlIHRvbyBsYXRlXCIpO1xuLy8gICAgICB9XG5cbiAgICAgIGZpbGxfd2luZG93KHMpO1xuICAgICAgaWYgKHMubG9va2FoZWFkID09PSAwICYmIGZsdXNoID09PSBaX05PX0ZMVVNIKSB7XG4gICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICB9XG5cbiAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIC8qIGZsdXNoIHRoZSBjdXJyZW50IGJsb2NrICovXG4gICAgfVxuICAgIC8vQXNzZXJ0KHMtPmJsb2NrX3N0YXJ0ID49IDBMLCBcImJsb2NrIGdvbmVcIik7XG4vLyAgICBpZiAocy5ibG9ja19zdGFydCA8IDApIHRocm93IG5ldyBFcnJvcihcImJsb2NrIGdvbmVcIik7XG5cbiAgICBzLnN0cnN0YXJ0ICs9IHMubG9va2FoZWFkO1xuICAgIHMubG9va2FoZWFkID0gMDtcblxuICAgIC8qIEVtaXQgYSBzdG9yZWQgYmxvY2sgaWYgcGVuZGluZ19idWYgd2lsbCBiZSBmdWxsOiAqL1xuICAgIHZhciBtYXhfc3RhcnQgPSBzLmJsb2NrX3N0YXJ0ICsgbWF4X2Jsb2NrX3NpemU7XG5cbiAgICBpZiAocy5zdHJzdGFydCA9PT0gMCB8fCBzLnN0cnN0YXJ0ID49IG1heF9zdGFydCkge1xuICAgICAgLyogc3Ryc3RhcnQgPT0gMCBpcyBwb3NzaWJsZSB3aGVuIHdyYXBhcm91bmQgb24gMTYtYml0IG1hY2hpbmUgKi9cbiAgICAgIHMubG9va2FoZWFkID0gcy5zdHJzdGFydCAtIG1heF9zdGFydDtcbiAgICAgIHMuc3Ryc3RhcnQgPSBtYXhfc3RhcnQ7XG4gICAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICB9XG4gICAgICAvKioqL1xuXG5cbiAgICB9XG4gICAgLyogRmx1c2ggaWYgd2UgbWF5IGhhdmUgdG8gc2xpZGUsIG90aGVyd2lzZSBibG9ja19zdGFydCBtYXkgYmVjb21lXG4gICAgICogbmVnYXRpdmUgYW5kIHRoZSBkYXRhIHdpbGwgYmUgZ29uZTpcbiAgICAgKi9cbiAgICBpZiAocy5zdHJzdGFydCAtIHMuYmxvY2tfc3RhcnQgPj0gKHMud19zaXplIC0gTUlOX0xPT0tBSEVBRCkpIHtcbiAgICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICAgIC8qKiovXG4gICAgfVxuICB9XG5cbiAgcy5pbnNlcnQgPSAwO1xuXG4gIGlmIChmbHVzaCA9PT0gWl9GSU5JU0gpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDEpOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCB0cnVlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX0ZJTklTSF9TVEFSVEVEO1xuICAgIH1cbiAgICAvKioqL1xuICAgIHJldHVybiBCU19GSU5JU0hfRE9ORTtcbiAgfVxuXG4gIGlmIChzLnN0cnN0YXJ0ID4gcy5ibG9ja19zdGFydCkge1xuICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICB9XG4gICAgLyoqKi9cbiAgfVxuXG4gIHJldHVybiBCU19ORUVEX01PUkU7XG59XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29tcHJlc3MgYXMgbXVjaCBhcyBwb3NzaWJsZSBmcm9tIHRoZSBpbnB1dCBzdHJlYW0sIHJldHVybiB0aGUgY3VycmVudFxuICogYmxvY2sgc3RhdGUuXG4gKiBUaGlzIGZ1bmN0aW9uIGRvZXMgbm90IHBlcmZvcm0gbGF6eSBldmFsdWF0aW9uIG9mIG1hdGNoZXMgYW5kIGluc2VydHNcbiAqIG5ldyBzdHJpbmdzIGluIHRoZSBkaWN0aW9uYXJ5IG9ubHkgZm9yIHVubWF0Y2hlZCBzdHJpbmdzIG9yIGZvciBzaG9ydFxuICogbWF0Y2hlcy4gSXQgaXMgdXNlZCBvbmx5IGZvciB0aGUgZmFzdCBjb21wcmVzc2lvbiBvcHRpb25zLlxuICovXG5mdW5jdGlvbiBkZWZsYXRlX2Zhc3QocywgZmx1c2gpIHtcbiAgdmFyIGhhc2hfaGVhZDsgICAgICAgIC8qIGhlYWQgb2YgdGhlIGhhc2ggY2hhaW4gKi9cbiAgdmFyIGJmbHVzaDsgICAgICAgICAgIC8qIHNldCBpZiBjdXJyZW50IGJsb2NrIG11c3QgYmUgZmx1c2hlZCAqL1xuXG4gIGZvciAoOzspIHtcbiAgICAvKiBNYWtlIHN1cmUgdGhhdCB3ZSBhbHdheXMgaGF2ZSBlbm91Z2ggbG9va2FoZWFkLCBleGNlcHRcbiAgICAgKiBhdCB0aGUgZW5kIG9mIHRoZSBpbnB1dCBmaWxlLiBXZSBuZWVkIE1BWF9NQVRDSCBieXRlc1xuICAgICAqIGZvciB0aGUgbmV4dCBtYXRjaCwgcGx1cyBNSU5fTUFUQ0ggYnl0ZXMgdG8gaW5zZXJ0IHRoZVxuICAgICAqIHN0cmluZyBmb2xsb3dpbmcgdGhlIG5leHQgbWF0Y2guXG4gICAgICovXG4gICAgaWYgKHMubG9va2FoZWFkIDwgTUlOX0xPT0tBSEVBRCkge1xuICAgICAgZmlsbF93aW5kb3cocyk7XG4gICAgICBpZiAocy5sb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFEICYmIGZsdXNoID09PSBaX05PX0ZMVVNIKSB7XG4gICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICB9XG4gICAgICBpZiAocy5sb29rYWhlYWQgPT09IDApIHtcbiAgICAgICAgYnJlYWs7IC8qIGZsdXNoIHRoZSBjdXJyZW50IGJsb2NrICovXG4gICAgICB9XG4gICAgfVxuXG4gICAgLyogSW5zZXJ0IHRoZSBzdHJpbmcgd2luZG93W3N0cnN0YXJ0IC4uIHN0cnN0YXJ0KzJdIGluIHRoZVxuICAgICAqIGRpY3Rpb25hcnksIGFuZCBzZXQgaGFzaF9oZWFkIHRvIHRoZSBoZWFkIG9mIHRoZSBoYXNoIGNoYWluOlxuICAgICAqL1xuICAgIGhhc2hfaGVhZCA9IDAvKk5JTCovO1xuICAgIGlmIChzLmxvb2thaGVhZCA+PSBNSU5fTUFUQ0gpIHtcbiAgICAgIC8qKiogSU5TRVJUX1NUUklORyhzLCBzLnN0cnN0YXJ0LCBoYXNoX2hlYWQpOyAqKiovXG4gICAgICBzLmluc19oID0gKChzLmluc19oIDw8IHMuaGFzaF9zaGlmdCkgXiBzLndpbmRvd1tzLnN0cnN0YXJ0ICsgTUlOX01BVENIIC0gMV0pICYgcy5oYXNoX21hc2s7XG4gICAgICBoYXNoX2hlYWQgPSBzLnByZXZbcy5zdHJzdGFydCAmIHMud19tYXNrXSA9IHMuaGVhZFtzLmluc19oXTtcbiAgICAgIHMuaGVhZFtzLmluc19oXSA9IHMuc3Ryc3RhcnQ7XG4gICAgICAvKioqL1xuICAgIH1cblxuICAgIC8qIEZpbmQgdGhlIGxvbmdlc3QgbWF0Y2gsIGRpc2NhcmRpbmcgdGhvc2UgPD0gcHJldl9sZW5ndGguXG4gICAgICogQXQgdGhpcyBwb2ludCB3ZSBoYXZlIGFsd2F5cyBtYXRjaF9sZW5ndGggPCBNSU5fTUFUQ0hcbiAgICAgKi9cbiAgICBpZiAoaGFzaF9oZWFkICE9PSAwLypOSUwqLyAmJiAoKHMuc3Ryc3RhcnQgLSBoYXNoX2hlYWQpIDw9IChzLndfc2l6ZSAtIE1JTl9MT09LQUhFQUQpKSkge1xuICAgICAgLyogVG8gc2ltcGxpZnkgdGhlIGNvZGUsIHdlIHByZXZlbnQgbWF0Y2hlcyB3aXRoIHRoZSBzdHJpbmdcbiAgICAgICAqIG9mIHdpbmRvdyBpbmRleCAwIChpbiBwYXJ0aWN1bGFyIHdlIGhhdmUgdG8gYXZvaWQgYSBtYXRjaFxuICAgICAgICogb2YgdGhlIHN0cmluZyB3aXRoIGl0c2VsZiBhdCB0aGUgc3RhcnQgb2YgdGhlIGlucHV0IGZpbGUpLlxuICAgICAgICovXG4gICAgICBzLm1hdGNoX2xlbmd0aCA9IGxvbmdlc3RfbWF0Y2gocywgaGFzaF9oZWFkKTtcbiAgICAgIC8qIGxvbmdlc3RfbWF0Y2goKSBzZXRzIG1hdGNoX3N0YXJ0ICovXG4gICAgfVxuICAgIGlmIChzLm1hdGNoX2xlbmd0aCA+PSBNSU5fTUFUQ0gpIHtcbiAgICAgIC8vIGNoZWNrX21hdGNoKHMsIHMuc3Ryc3RhcnQsIHMubWF0Y2hfc3RhcnQsIHMubWF0Y2hfbGVuZ3RoKTsgLy8gZm9yIGRlYnVnIG9ubHlcblxuICAgICAgLyoqKiBfdHJfdGFsbHlfZGlzdChzLCBzLnN0cnN0YXJ0IC0gcy5tYXRjaF9zdGFydCxcbiAgICAgICAgICAgICAgICAgICAgIHMubWF0Y2hfbGVuZ3RoIC0gTUlOX01BVENILCBiZmx1c2gpOyAqKiovXG4gICAgICBiZmx1c2ggPSB0cmVlcy5fdHJfdGFsbHkocywgcy5zdHJzdGFydCAtIHMubWF0Y2hfc3RhcnQsIHMubWF0Y2hfbGVuZ3RoIC0gTUlOX01BVENIKTtcblxuICAgICAgcy5sb29rYWhlYWQgLT0gcy5tYXRjaF9sZW5ndGg7XG5cbiAgICAgIC8qIEluc2VydCBuZXcgc3RyaW5ncyBpbiB0aGUgaGFzaCB0YWJsZSBvbmx5IGlmIHRoZSBtYXRjaCBsZW5ndGhcbiAgICAgICAqIGlzIG5vdCB0b28gbGFyZ2UuIFRoaXMgc2F2ZXMgdGltZSBidXQgZGVncmFkZXMgY29tcHJlc3Npb24uXG4gICAgICAgKi9cbiAgICAgIGlmIChzLm1hdGNoX2xlbmd0aCA8PSBzLm1heF9sYXp5X21hdGNoLyptYXhfaW5zZXJ0X2xlbmd0aCovICYmIHMubG9va2FoZWFkID49IE1JTl9NQVRDSCkge1xuICAgICAgICBzLm1hdGNoX2xlbmd0aC0tOyAvKiBzdHJpbmcgYXQgc3Ryc3RhcnQgYWxyZWFkeSBpbiB0YWJsZSAqL1xuICAgICAgICBkbyB7XG4gICAgICAgICAgcy5zdHJzdGFydCsrO1xuICAgICAgICAgIC8qKiogSU5TRVJUX1NUUklORyhzLCBzLnN0cnN0YXJ0LCBoYXNoX2hlYWQpOyAqKiovXG4gICAgICAgICAgcy5pbnNfaCA9ICgocy5pbnNfaCA8PCBzLmhhc2hfc2hpZnQpIF4gcy53aW5kb3dbcy5zdHJzdGFydCArIE1JTl9NQVRDSCAtIDFdKSAmIHMuaGFzaF9tYXNrO1xuICAgICAgICAgIGhhc2hfaGVhZCA9IHMucHJldltzLnN0cnN0YXJ0ICYgcy53X21hc2tdID0gcy5oZWFkW3MuaW5zX2hdO1xuICAgICAgICAgIHMuaGVhZFtzLmluc19oXSA9IHMuc3Ryc3RhcnQ7XG4gICAgICAgICAgLyoqKi9cbiAgICAgICAgICAvKiBzdHJzdGFydCBuZXZlciBleGNlZWRzIFdTSVpFLU1BWF9NQVRDSCwgc28gdGhlcmUgYXJlXG4gICAgICAgICAgICogYWx3YXlzIE1JTl9NQVRDSCBieXRlcyBhaGVhZC5cbiAgICAgICAgICAgKi9cbiAgICAgICAgfSB3aGlsZSAoLS1zLm1hdGNoX2xlbmd0aCAhPT0gMCk7XG4gICAgICAgIHMuc3Ryc3RhcnQrKztcbiAgICAgIH0gZWxzZVxuICAgICAge1xuICAgICAgICBzLnN0cnN0YXJ0ICs9IHMubWF0Y2hfbGVuZ3RoO1xuICAgICAgICBzLm1hdGNoX2xlbmd0aCA9IDA7XG4gICAgICAgIHMuaW5zX2ggPSBzLndpbmRvd1tzLnN0cnN0YXJ0XTtcbiAgICAgICAgLyogVVBEQVRFX0hBU0gocywgcy5pbnNfaCwgcy53aW5kb3dbcy5zdHJzdGFydCsxXSk7ICovXG4gICAgICAgIHMuaW5zX2ggPSAoKHMuaW5zX2ggPDwgcy5oYXNoX3NoaWZ0KSBeIHMud2luZG93W3Muc3Ryc3RhcnQgKyAxXSkgJiBzLmhhc2hfbWFzaztcblxuLy8jaWYgTUlOX01BVENIICE9IDNcbi8vICAgICAgICAgICAgICAgIENhbGwgVVBEQVRFX0hBU0goKSBNSU5fTUFUQ0gtMyBtb3JlIHRpbWVzXG4vLyNlbmRpZlxuICAgICAgICAvKiBJZiBsb29rYWhlYWQgPCBNSU5fTUFUQ0gsIGluc19oIGlzIGdhcmJhZ2UsIGJ1dCBpdCBkb2VzIG5vdFxuICAgICAgICAgKiBtYXR0ZXIgc2luY2UgaXQgd2lsbCBiZSByZWNvbXB1dGVkIGF0IG5leHQgZGVmbGF0ZSBjYWxsLlxuICAgICAgICAgKi9cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLyogTm8gbWF0Y2gsIG91dHB1dCBhIGxpdGVyYWwgYnl0ZSAqL1xuICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsXCIlY1wiLCBzLndpbmRvd1tzLnN0cnN0YXJ0XSkpO1xuICAgICAgLyoqKiBfdHJfdGFsbHlfbGl0KHMsIHMud2luZG93W3Muc3Ryc3RhcnRdLCBiZmx1c2gpOyAqKiovXG4gICAgICBiZmx1c2ggPSB0cmVlcy5fdHJfdGFsbHkocywgMCwgcy53aW5kb3dbcy5zdHJzdGFydF0pO1xuXG4gICAgICBzLmxvb2thaGVhZC0tO1xuICAgICAgcy5zdHJzdGFydCsrO1xuICAgIH1cbiAgICBpZiAoYmZsdXNoKSB7XG4gICAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICB9XG4gICAgICAvKioqL1xuICAgIH1cbiAgfVxuICBzLmluc2VydCA9ICgocy5zdHJzdGFydCA8IChNSU5fTUFUQ0ggLSAxKSkgPyBzLnN0cnN0YXJ0IDogTUlOX01BVENIIC0gMSk7XG4gIGlmIChmbHVzaCA9PT0gWl9GSU5JU0gpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDEpOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCB0cnVlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX0ZJTklTSF9TVEFSVEVEO1xuICAgIH1cbiAgICAvKioqL1xuICAgIHJldHVybiBCU19GSU5JU0hfRE9ORTtcbiAgfVxuICBpZiAocy5sYXN0X2xpdCkge1xuICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICB9XG4gICAgLyoqKi9cbiAgfVxuICByZXR1cm4gQlNfQkxPQ0tfRE9ORTtcbn1cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTYW1lIGFzIGFib3ZlLCBidXQgYWNoaWV2ZXMgYmV0dGVyIGNvbXByZXNzaW9uLiBXZSB1c2UgYSBsYXp5XG4gKiBldmFsdWF0aW9uIGZvciBtYXRjaGVzOiBhIG1hdGNoIGlzIGZpbmFsbHkgYWRvcHRlZCBvbmx5IGlmIHRoZXJlIGlzXG4gKiBubyBiZXR0ZXIgbWF0Y2ggYXQgdGhlIG5leHQgd2luZG93IHBvc2l0aW9uLlxuICovXG5mdW5jdGlvbiBkZWZsYXRlX3Nsb3cocywgZmx1c2gpIHtcbiAgdmFyIGhhc2hfaGVhZDsgICAgICAgICAgLyogaGVhZCBvZiBoYXNoIGNoYWluICovXG4gIHZhciBiZmx1c2g7ICAgICAgICAgICAgICAvKiBzZXQgaWYgY3VycmVudCBibG9jayBtdXN0IGJlIGZsdXNoZWQgKi9cblxuICB2YXIgbWF4X2luc2VydDtcblxuICAvKiBQcm9jZXNzIHRoZSBpbnB1dCBibG9jay4gKi9cbiAgZm9yICg7Oykge1xuICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHdlIGFsd2F5cyBoYXZlIGVub3VnaCBsb29rYWhlYWQsIGV4Y2VwdFxuICAgICAqIGF0IHRoZSBlbmQgb2YgdGhlIGlucHV0IGZpbGUuIFdlIG5lZWQgTUFYX01BVENIIGJ5dGVzXG4gICAgICogZm9yIHRoZSBuZXh0IG1hdGNoLCBwbHVzIE1JTl9NQVRDSCBieXRlcyB0byBpbnNlcnQgdGhlXG4gICAgICogc3RyaW5nIGZvbGxvd2luZyB0aGUgbmV4dCBtYXRjaC5cbiAgICAgKi9cbiAgICBpZiAocy5sb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFEKSB7XG4gICAgICBmaWxsX3dpbmRvdyhzKTtcbiAgICAgIGlmIChzLmxvb2thaGVhZCA8IE1JTl9MT09LQUhFQUQgJiYgZmx1c2ggPT09IFpfTk9fRkxVU0gpIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkgeyBicmVhazsgfSAvKiBmbHVzaCB0aGUgY3VycmVudCBibG9jayAqL1xuICAgIH1cblxuICAgIC8qIEluc2VydCB0aGUgc3RyaW5nIHdpbmRvd1tzdHJzdGFydCAuLiBzdHJzdGFydCsyXSBpbiB0aGVcbiAgICAgKiBkaWN0aW9uYXJ5LCBhbmQgc2V0IGhhc2hfaGVhZCB0byB0aGUgaGVhZCBvZiB0aGUgaGFzaCBjaGFpbjpcbiAgICAgKi9cbiAgICBoYXNoX2hlYWQgPSAwLypOSUwqLztcbiAgICBpZiAocy5sb29rYWhlYWQgPj0gTUlOX01BVENIKSB7XG4gICAgICAvKioqIElOU0VSVF9TVFJJTkcocywgcy5zdHJzdGFydCwgaGFzaF9oZWFkKTsgKioqL1xuICAgICAgcy5pbnNfaCA9ICgocy5pbnNfaCA8PCBzLmhhc2hfc2hpZnQpIF4gcy53aW5kb3dbcy5zdHJzdGFydCArIE1JTl9NQVRDSCAtIDFdKSAmIHMuaGFzaF9tYXNrO1xuICAgICAgaGFzaF9oZWFkID0gcy5wcmV2W3Muc3Ryc3RhcnQgJiBzLndfbWFza10gPSBzLmhlYWRbcy5pbnNfaF07XG4gICAgICBzLmhlYWRbcy5pbnNfaF0gPSBzLnN0cnN0YXJ0O1xuICAgICAgLyoqKi9cbiAgICB9XG5cbiAgICAvKiBGaW5kIHRoZSBsb25nZXN0IG1hdGNoLCBkaXNjYXJkaW5nIHRob3NlIDw9IHByZXZfbGVuZ3RoLlxuICAgICAqL1xuICAgIHMucHJldl9sZW5ndGggPSBzLm1hdGNoX2xlbmd0aDtcbiAgICBzLnByZXZfbWF0Y2ggPSBzLm1hdGNoX3N0YXJ0O1xuICAgIHMubWF0Y2hfbGVuZ3RoID0gTUlOX01BVENIIC0gMTtcblxuICAgIGlmIChoYXNoX2hlYWQgIT09IDAvKk5JTCovICYmIHMucHJldl9sZW5ndGggPCBzLm1heF9sYXp5X21hdGNoICYmXG4gICAgICAgIHMuc3Ryc3RhcnQgLSBoYXNoX2hlYWQgPD0gKHMud19zaXplIC0gTUlOX0xPT0tBSEVBRCkvKk1BWF9ESVNUKHMpKi8pIHtcbiAgICAgIC8qIFRvIHNpbXBsaWZ5IHRoZSBjb2RlLCB3ZSBwcmV2ZW50IG1hdGNoZXMgd2l0aCB0aGUgc3RyaW5nXG4gICAgICAgKiBvZiB3aW5kb3cgaW5kZXggMCAoaW4gcGFydGljdWxhciB3ZSBoYXZlIHRvIGF2b2lkIGEgbWF0Y2hcbiAgICAgICAqIG9mIHRoZSBzdHJpbmcgd2l0aCBpdHNlbGYgYXQgdGhlIHN0YXJ0IG9mIHRoZSBpbnB1dCBmaWxlKS5cbiAgICAgICAqL1xuICAgICAgcy5tYXRjaF9sZW5ndGggPSBsb25nZXN0X21hdGNoKHMsIGhhc2hfaGVhZCk7XG4gICAgICAvKiBsb25nZXN0X21hdGNoKCkgc2V0cyBtYXRjaF9zdGFydCAqL1xuXG4gICAgICBpZiAocy5tYXRjaF9sZW5ndGggPD0gNSAmJlxuICAgICAgICAgKHMuc3RyYXRlZ3kgPT09IFpfRklMVEVSRUQgfHwgKHMubWF0Y2hfbGVuZ3RoID09PSBNSU5fTUFUQ0ggJiYgcy5zdHJzdGFydCAtIHMubWF0Y2hfc3RhcnQgPiA0MDk2LypUT09fRkFSKi8pKSkge1xuXG4gICAgICAgIC8qIElmIHByZXZfbWF0Y2ggaXMgYWxzbyBNSU5fTUFUQ0gsIG1hdGNoX3N0YXJ0IGlzIGdhcmJhZ2VcbiAgICAgICAgICogYnV0IHdlIHdpbGwgaWdub3JlIHRoZSBjdXJyZW50IG1hdGNoIGFueXdheS5cbiAgICAgICAgICovXG4gICAgICAgIHMubWF0Y2hfbGVuZ3RoID0gTUlOX01BVENIIC0gMTtcbiAgICAgIH1cbiAgICB9XG4gICAgLyogSWYgdGhlcmUgd2FzIGEgbWF0Y2ggYXQgdGhlIHByZXZpb3VzIHN0ZXAgYW5kIHRoZSBjdXJyZW50XG4gICAgICogbWF0Y2ggaXMgbm90IGJldHRlciwgb3V0cHV0IHRoZSBwcmV2aW91cyBtYXRjaDpcbiAgICAgKi9cbiAgICBpZiAocy5wcmV2X2xlbmd0aCA+PSBNSU5fTUFUQ0ggJiYgcy5tYXRjaF9sZW5ndGggPD0gcy5wcmV2X2xlbmd0aCkge1xuICAgICAgbWF4X2luc2VydCA9IHMuc3Ryc3RhcnQgKyBzLmxvb2thaGVhZCAtIE1JTl9NQVRDSDtcbiAgICAgIC8qIERvIG5vdCBpbnNlcnQgc3RyaW5ncyBpbiBoYXNoIHRhYmxlIGJleW9uZCB0aGlzLiAqL1xuXG4gICAgICAvL2NoZWNrX21hdGNoKHMsIHMuc3Ryc3RhcnQtMSwgcy5wcmV2X21hdGNoLCBzLnByZXZfbGVuZ3RoKTtcblxuICAgICAgLyoqKl90cl90YWxseV9kaXN0KHMsIHMuc3Ryc3RhcnQgLSAxIC0gcy5wcmV2X21hdGNoLFxuICAgICAgICAgICAgICAgICAgICAgcy5wcmV2X2xlbmd0aCAtIE1JTl9NQVRDSCwgYmZsdXNoKTsqKiovXG4gICAgICBiZmx1c2ggPSB0cmVlcy5fdHJfdGFsbHkocywgcy5zdHJzdGFydCAtIDEgLSBzLnByZXZfbWF0Y2gsIHMucHJldl9sZW5ndGggLSBNSU5fTUFUQ0gpO1xuICAgICAgLyogSW5zZXJ0IGluIGhhc2ggdGFibGUgYWxsIHN0cmluZ3MgdXAgdG8gdGhlIGVuZCBvZiB0aGUgbWF0Y2guXG4gICAgICAgKiBzdHJzdGFydC0xIGFuZCBzdHJzdGFydCBhcmUgYWxyZWFkeSBpbnNlcnRlZC4gSWYgdGhlcmUgaXMgbm90XG4gICAgICAgKiBlbm91Z2ggbG9va2FoZWFkLCB0aGUgbGFzdCB0d28gc3RyaW5ncyBhcmUgbm90IGluc2VydGVkIGluXG4gICAgICAgKiB0aGUgaGFzaCB0YWJsZS5cbiAgICAgICAqL1xuICAgICAgcy5sb29rYWhlYWQgLT0gcy5wcmV2X2xlbmd0aCAtIDE7XG4gICAgICBzLnByZXZfbGVuZ3RoIC09IDI7XG4gICAgICBkbyB7XG4gICAgICAgIGlmICgrK3Muc3Ryc3RhcnQgPD0gbWF4X2luc2VydCkge1xuICAgICAgICAgIC8qKiogSU5TRVJUX1NUUklORyhzLCBzLnN0cnN0YXJ0LCBoYXNoX2hlYWQpOyAqKiovXG4gICAgICAgICAgcy5pbnNfaCA9ICgocy5pbnNfaCA8PCBzLmhhc2hfc2hpZnQpIF4gcy53aW5kb3dbcy5zdHJzdGFydCArIE1JTl9NQVRDSCAtIDFdKSAmIHMuaGFzaF9tYXNrO1xuICAgICAgICAgIGhhc2hfaGVhZCA9IHMucHJldltzLnN0cnN0YXJ0ICYgcy53X21hc2tdID0gcy5oZWFkW3MuaW5zX2hdO1xuICAgICAgICAgIHMuaGVhZFtzLmluc19oXSA9IHMuc3Ryc3RhcnQ7XG4gICAgICAgICAgLyoqKi9cbiAgICAgICAgfVxuICAgICAgfSB3aGlsZSAoLS1zLnByZXZfbGVuZ3RoICE9PSAwKTtcbiAgICAgIHMubWF0Y2hfYXZhaWxhYmxlID0gMDtcbiAgICAgIHMubWF0Y2hfbGVuZ3RoID0gTUlOX01BVENIIC0gMTtcbiAgICAgIHMuc3Ryc3RhcnQrKztcblxuICAgICAgaWYgKGJmbHVzaCkge1xuICAgICAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgICAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICAgIH1cbiAgICAgICAgLyoqKi9cbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAocy5tYXRjaF9hdmFpbGFibGUpIHtcbiAgICAgIC8qIElmIHRoZXJlIHdhcyBubyBtYXRjaCBhdCB0aGUgcHJldmlvdXMgcG9zaXRpb24sIG91dHB1dCBhXG4gICAgICAgKiBzaW5nbGUgbGl0ZXJhbC4gSWYgdGhlcmUgd2FzIGEgbWF0Y2ggYnV0IHRoZSBjdXJyZW50IG1hdGNoXG4gICAgICAgKiBpcyBsb25nZXIsIHRydW5jYXRlIHRoZSBwcmV2aW91cyBtYXRjaCB0byBhIHNpbmdsZSBsaXRlcmFsLlxuICAgICAgICovXG4gICAgICAvL1RyYWNldnYoKHN0ZGVycixcIiVjXCIsIHMtPndpbmRvd1tzLT5zdHJzdGFydC0xXSkpO1xuICAgICAgLyoqKiBfdHJfdGFsbHlfbGl0KHMsIHMud2luZG93W3Muc3Ryc3RhcnQtMV0sIGJmbHVzaCk7ICoqKi9cbiAgICAgIGJmbHVzaCA9IHRyZWVzLl90cl90YWxseShzLCAwLCBzLndpbmRvd1tzLnN0cnN0YXJ0IC0gMV0pO1xuXG4gICAgICBpZiAoYmZsdXNoKSB7XG4gICAgICAgIC8qKiogRkxVU0hfQkxPQ0tfT05MWShzLCAwKSAqKiovXG4gICAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgICAgICAvKioqL1xuICAgICAgfVxuICAgICAgcy5zdHJzdGFydCsrO1xuICAgICAgcy5sb29rYWhlYWQtLTtcbiAgICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8qIFRoZXJlIGlzIG5vIHByZXZpb3VzIG1hdGNoIHRvIGNvbXBhcmUgd2l0aCwgd2FpdCBmb3JcbiAgICAgICAqIHRoZSBuZXh0IHN0ZXAgdG8gZGVjaWRlLlxuICAgICAgICovXG4gICAgICBzLm1hdGNoX2F2YWlsYWJsZSA9IDE7XG4gICAgICBzLnN0cnN0YXJ0Kys7XG4gICAgICBzLmxvb2thaGVhZC0tO1xuICAgIH1cbiAgfVxuICAvL0Fzc2VydCAoZmx1c2ggIT0gWl9OT19GTFVTSCwgXCJubyBmbHVzaD9cIik7XG4gIGlmIChzLm1hdGNoX2F2YWlsYWJsZSkge1xuICAgIC8vVHJhY2V2digoc3RkZXJyLFwiJWNcIiwgcy0+d2luZG93W3MtPnN0cnN0YXJ0LTFdKSk7XG4gICAgLyoqKiBfdHJfdGFsbHlfbGl0KHMsIHMud2luZG93W3Muc3Ryc3RhcnQtMV0sIGJmbHVzaCk7ICoqKi9cbiAgICBiZmx1c2ggPSB0cmVlcy5fdHJfdGFsbHkocywgMCwgcy53aW5kb3dbcy5zdHJzdGFydCAtIDFdKTtcblxuICAgIHMubWF0Y2hfYXZhaWxhYmxlID0gMDtcbiAgfVxuICBzLmluc2VydCA9IHMuc3Ryc3RhcnQgPCBNSU5fTUFUQ0ggLSAxID8gcy5zdHJzdGFydCA6IE1JTl9NQVRDSCAtIDE7XG4gIGlmIChmbHVzaCA9PT0gWl9GSU5JU0gpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDEpOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCB0cnVlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX0ZJTklTSF9TVEFSVEVEO1xuICAgIH1cbiAgICAvKioqL1xuICAgIHJldHVybiBCU19GSU5JU0hfRE9ORTtcbiAgfVxuICBpZiAocy5sYXN0X2xpdCkge1xuICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICB9XG4gICAgLyoqKi9cbiAgfVxuXG4gIHJldHVybiBCU19CTE9DS19ET05FO1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogRm9yIFpfUkxFLCBzaW1wbHkgbG9vayBmb3IgcnVucyBvZiBieXRlcywgZ2VuZXJhdGUgbWF0Y2hlcyBvbmx5IG9mIGRpc3RhbmNlXG4gKiBvbmUuICBEbyBub3QgbWFpbnRhaW4gYSBoYXNoIHRhYmxlLiAgKEl0IHdpbGwgYmUgcmVnZW5lcmF0ZWQgaWYgdGhpcyBydW4gb2ZcbiAqIGRlZmxhdGUgc3dpdGNoZXMgYXdheSBmcm9tIFpfUkxFLilcbiAqL1xuZnVuY3Rpb24gZGVmbGF0ZV9ybGUocywgZmx1c2gpIHtcbiAgdmFyIGJmbHVzaDsgICAgICAgICAgICAvKiBzZXQgaWYgY3VycmVudCBibG9jayBtdXN0IGJlIGZsdXNoZWQgKi9cbiAgdmFyIHByZXY7ICAgICAgICAgICAgICAvKiBieXRlIGF0IGRpc3RhbmNlIG9uZSB0byBtYXRjaCAqL1xuICB2YXIgc2Nhbiwgc3RyZW5kOyAgICAgIC8qIHNjYW4gZ29lcyB1cCB0byBzdHJlbmQgZm9yIGxlbmd0aCBvZiBydW4gKi9cblxuICB2YXIgX3dpbiA9IHMud2luZG93O1xuXG4gIGZvciAoOzspIHtcbiAgICAvKiBNYWtlIHN1cmUgdGhhdCB3ZSBhbHdheXMgaGF2ZSBlbm91Z2ggbG9va2FoZWFkLCBleGNlcHRcbiAgICAgKiBhdCB0aGUgZW5kIG9mIHRoZSBpbnB1dCBmaWxlLiBXZSBuZWVkIE1BWF9NQVRDSCBieXRlc1xuICAgICAqIGZvciB0aGUgbG9uZ2VzdCBydW4sIHBsdXMgb25lIGZvciB0aGUgdW5yb2xsZWQgbG9vcC5cbiAgICAgKi9cbiAgICBpZiAocy5sb29rYWhlYWQgPD0gTUFYX01BVENIKSB7XG4gICAgICBmaWxsX3dpbmRvdyhzKTtcbiAgICAgIGlmIChzLmxvb2thaGVhZCA8PSBNQVhfTUFUQ0ggJiYgZmx1c2ggPT09IFpfTk9fRkxVU0gpIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkgeyBicmVhazsgfSAvKiBmbHVzaCB0aGUgY3VycmVudCBibG9jayAqL1xuICAgIH1cblxuICAgIC8qIFNlZSBob3cgbWFueSB0aW1lcyB0aGUgcHJldmlvdXMgYnl0ZSByZXBlYXRzICovXG4gICAgcy5tYXRjaF9sZW5ndGggPSAwO1xuICAgIGlmIChzLmxvb2thaGVhZCA+PSBNSU5fTUFUQ0ggJiYgcy5zdHJzdGFydCA+IDApIHtcbiAgICAgIHNjYW4gPSBzLnN0cnN0YXJ0IC0gMTtcbiAgICAgIHByZXYgPSBfd2luW3NjYW5dO1xuICAgICAgaWYgKHByZXYgPT09IF93aW5bKytzY2FuXSAmJiBwcmV2ID09PSBfd2luWysrc2Nhbl0gJiYgcHJldiA9PT0gX3dpblsrK3NjYW5dKSB7XG4gICAgICAgIHN0cmVuZCA9IHMuc3Ryc3RhcnQgKyBNQVhfTUFUQ0g7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICAvKmpzaGludCBub2VtcHR5OmZhbHNlKi9cbiAgICAgICAgfSB3aGlsZSAocHJldiA9PT0gX3dpblsrK3NjYW5dICYmIHByZXYgPT09IF93aW5bKytzY2FuXSAmJlxuICAgICAgICAgICAgICAgICBwcmV2ID09PSBfd2luWysrc2Nhbl0gJiYgcHJldiA9PT0gX3dpblsrK3NjYW5dICYmXG4gICAgICAgICAgICAgICAgIHByZXYgPT09IF93aW5bKytzY2FuXSAmJiBwcmV2ID09PSBfd2luWysrc2Nhbl0gJiZcbiAgICAgICAgICAgICAgICAgcHJldiA9PT0gX3dpblsrK3NjYW5dICYmIHByZXYgPT09IF93aW5bKytzY2FuXSAmJlxuICAgICAgICAgICAgICAgICBzY2FuIDwgc3RyZW5kKTtcbiAgICAgICAgcy5tYXRjaF9sZW5ndGggPSBNQVhfTUFUQ0ggLSAoc3RyZW5kIC0gc2Nhbik7XG4gICAgICAgIGlmIChzLm1hdGNoX2xlbmd0aCA+IHMubG9va2FoZWFkKSB7XG4gICAgICAgICAgcy5tYXRjaF9sZW5ndGggPSBzLmxvb2thaGVhZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy9Bc3NlcnQoc2NhbiA8PSBzLT53aW5kb3crKHVJbnQpKHMtPndpbmRvd19zaXplLTEpLCBcIndpbGQgc2NhblwiKTtcbiAgICB9XG5cbiAgICAvKiBFbWl0IG1hdGNoIGlmIGhhdmUgcnVuIG9mIE1JTl9NQVRDSCBvciBsb25nZXIsIGVsc2UgZW1pdCBsaXRlcmFsICovXG4gICAgaWYgKHMubWF0Y2hfbGVuZ3RoID49IE1JTl9NQVRDSCkge1xuICAgICAgLy9jaGVja19tYXRjaChzLCBzLnN0cnN0YXJ0LCBzLnN0cnN0YXJ0IC0gMSwgcy5tYXRjaF9sZW5ndGgpO1xuXG4gICAgICAvKioqIF90cl90YWxseV9kaXN0KHMsIDEsIHMubWF0Y2hfbGVuZ3RoIC0gTUlOX01BVENILCBiZmx1c2gpOyAqKiovXG4gICAgICBiZmx1c2ggPSB0cmVlcy5fdHJfdGFsbHkocywgMSwgcy5tYXRjaF9sZW5ndGggLSBNSU5fTUFUQ0gpO1xuXG4gICAgICBzLmxvb2thaGVhZCAtPSBzLm1hdGNoX2xlbmd0aDtcbiAgICAgIHMuc3Ryc3RhcnQgKz0gcy5tYXRjaF9sZW5ndGg7XG4gICAgICBzLm1hdGNoX2xlbmd0aCA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8qIE5vIG1hdGNoLCBvdXRwdXQgYSBsaXRlcmFsIGJ5dGUgKi9cbiAgICAgIC8vVHJhY2V2digoc3RkZXJyLFwiJWNcIiwgcy0+d2luZG93W3MtPnN0cnN0YXJ0XSkpO1xuICAgICAgLyoqKiBfdHJfdGFsbHlfbGl0KHMsIHMud2luZG93W3Muc3Ryc3RhcnRdLCBiZmx1c2gpOyAqKiovXG4gICAgICBiZmx1c2ggPSB0cmVlcy5fdHJfdGFsbHkocywgMCwgcy53aW5kb3dbcy5zdHJzdGFydF0pO1xuXG4gICAgICBzLmxvb2thaGVhZC0tO1xuICAgICAgcy5zdHJzdGFydCsrO1xuICAgIH1cbiAgICBpZiAoYmZsdXNoKSB7XG4gICAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICB9XG4gICAgICAvKioqL1xuICAgIH1cbiAgfVxuICBzLmluc2VydCA9IDA7XG4gIGlmIChmbHVzaCA9PT0gWl9GSU5JU0gpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDEpOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCB0cnVlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX0ZJTklTSF9TVEFSVEVEO1xuICAgIH1cbiAgICAvKioqL1xuICAgIHJldHVybiBCU19GSU5JU0hfRE9ORTtcbiAgfVxuICBpZiAocy5sYXN0X2xpdCkge1xuICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICB9XG4gICAgLyoqKi9cbiAgfVxuICByZXR1cm4gQlNfQkxPQ0tfRE9ORTtcbn1cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBGb3IgWl9IVUZGTUFOX09OTFksIGRvIG5vdCBsb29rIGZvciBtYXRjaGVzLiAgRG8gbm90IG1haW50YWluIGEgaGFzaCB0YWJsZS5cbiAqIChJdCB3aWxsIGJlIHJlZ2VuZXJhdGVkIGlmIHRoaXMgcnVuIG9mIGRlZmxhdGUgc3dpdGNoZXMgYXdheSBmcm9tIEh1ZmZtYW4uKVxuICovXG5mdW5jdGlvbiBkZWZsYXRlX2h1ZmYocywgZmx1c2gpIHtcbiAgdmFyIGJmbHVzaDsgICAgICAgICAgICAgLyogc2V0IGlmIGN1cnJlbnQgYmxvY2sgbXVzdCBiZSBmbHVzaGVkICovXG5cbiAgZm9yICg7Oykge1xuICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHdlIGhhdmUgYSBsaXRlcmFsIHRvIHdyaXRlLiAqL1xuICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkge1xuICAgICAgZmlsbF93aW5kb3cocyk7XG4gICAgICBpZiAocy5sb29rYWhlYWQgPT09IDApIHtcbiAgICAgICAgaWYgKGZsdXNoID09PSBaX05PX0ZMVVNIKSB7XG4gICAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgICAgfVxuICAgICAgICBicmVhazsgICAgICAvKiBmbHVzaCB0aGUgY3VycmVudCBibG9jayAqL1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qIE91dHB1dCBhIGxpdGVyYWwgYnl0ZSAqL1xuICAgIHMubWF0Y2hfbGVuZ3RoID0gMDtcbiAgICAvL1RyYWNldnYoKHN0ZGVycixcIiVjXCIsIHMtPndpbmRvd1tzLT5zdHJzdGFydF0pKTtcbiAgICAvKioqIF90cl90YWxseV9saXQocywgcy53aW5kb3dbcy5zdHJzdGFydF0sIGJmbHVzaCk7ICoqKi9cbiAgICBiZmx1c2ggPSB0cmVlcy5fdHJfdGFsbHkocywgMCwgcy53aW5kb3dbcy5zdHJzdGFydF0pO1xuICAgIHMubG9va2FoZWFkLS07XG4gICAgcy5zdHJzdGFydCsrO1xuICAgIGlmIChiZmx1c2gpIHtcbiAgICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICAgIC8qKiovXG4gICAgfVxuICB9XG4gIHMuaW5zZXJ0ID0gMDtcbiAgaWYgKGZsdXNoID09PSBaX0ZJTklTSCkge1xuICAgIC8qKiogRkxVU0hfQkxPQ0socywgMSk7ICoqKi9cbiAgICBmbHVzaF9ibG9ja19vbmx5KHMsIHRydWUpO1xuICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICByZXR1cm4gQlNfRklOSVNIX1NUQVJURUQ7XG4gICAgfVxuICAgIC8qKiovXG4gICAgcmV0dXJuIEJTX0ZJTklTSF9ET05FO1xuICB9XG4gIGlmIChzLmxhc3RfbGl0KSB7XG4gICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAwKTsgKioqL1xuICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgIH1cbiAgICAvKioqL1xuICB9XG4gIHJldHVybiBCU19CTE9DS19ET05FO1xufVxuXG4vKiBWYWx1ZXMgZm9yIG1heF9sYXp5X21hdGNoLCBnb29kX21hdGNoIGFuZCBtYXhfY2hhaW5fbGVuZ3RoLCBkZXBlbmRpbmcgb25cbiAqIHRoZSBkZXNpcmVkIHBhY2sgbGV2ZWwgKDAuLjkpLiBUaGUgdmFsdWVzIGdpdmVuIGJlbG93IGhhdmUgYmVlbiB0dW5lZCB0b1xuICogZXhjbHVkZSB3b3JzdCBjYXNlIHBlcmZvcm1hbmNlIGZvciBwYXRob2xvZ2ljYWwgZmlsZXMuIEJldHRlciB2YWx1ZXMgbWF5IGJlXG4gKiBmb3VuZCBmb3Igc3BlY2lmaWMgZmlsZXMuXG4gKi9cbmZ1bmN0aW9uIENvbmZpZyhnb29kX2xlbmd0aCwgbWF4X2xhenksIG5pY2VfbGVuZ3RoLCBtYXhfY2hhaW4sIGZ1bmMpIHtcbiAgdGhpcy5nb29kX2xlbmd0aCA9IGdvb2RfbGVuZ3RoO1xuICB0aGlzLm1heF9sYXp5ID0gbWF4X2xhenk7XG4gIHRoaXMubmljZV9sZW5ndGggPSBuaWNlX2xlbmd0aDtcbiAgdGhpcy5tYXhfY2hhaW4gPSBtYXhfY2hhaW47XG4gIHRoaXMuZnVuYyA9IGZ1bmM7XG59XG5cbnZhciBjb25maWd1cmF0aW9uX3RhYmxlO1xuXG5jb25maWd1cmF0aW9uX3RhYmxlID0gW1xuICAvKiAgICAgIGdvb2QgbGF6eSBuaWNlIGNoYWluICovXG4gIG5ldyBDb25maWcoMCwgMCwgMCwgMCwgZGVmbGF0ZV9zdG9yZWQpLCAgICAgICAgICAvKiAwIHN0b3JlIG9ubHkgKi9cbiAgbmV3IENvbmZpZyg0LCA0LCA4LCA0LCBkZWZsYXRlX2Zhc3QpLCAgICAgICAgICAgIC8qIDEgbWF4IHNwZWVkLCBubyBsYXp5IG1hdGNoZXMgKi9cbiAgbmV3IENvbmZpZyg0LCA1LCAxNiwgOCwgZGVmbGF0ZV9mYXN0KSwgICAgICAgICAgIC8qIDIgKi9cbiAgbmV3IENvbmZpZyg0LCA2LCAzMiwgMzIsIGRlZmxhdGVfZmFzdCksICAgICAgICAgIC8qIDMgKi9cblxuICBuZXcgQ29uZmlnKDQsIDQsIDE2LCAxNiwgZGVmbGF0ZV9zbG93KSwgICAgICAgICAgLyogNCBsYXp5IG1hdGNoZXMgKi9cbiAgbmV3IENvbmZpZyg4LCAxNiwgMzIsIDMyLCBkZWZsYXRlX3Nsb3cpLCAgICAgICAgIC8qIDUgKi9cbiAgbmV3IENvbmZpZyg4LCAxNiwgMTI4LCAxMjgsIGRlZmxhdGVfc2xvdyksICAgICAgIC8qIDYgKi9cbiAgbmV3IENvbmZpZyg4LCAzMiwgMTI4LCAyNTYsIGRlZmxhdGVfc2xvdyksICAgICAgIC8qIDcgKi9cbiAgbmV3IENvbmZpZygzMiwgMTI4LCAyNTgsIDEwMjQsIGRlZmxhdGVfc2xvdyksICAgIC8qIDggKi9cbiAgbmV3IENvbmZpZygzMiwgMjU4LCAyNTgsIDQwOTYsIGRlZmxhdGVfc2xvdykgICAgIC8qIDkgbWF4IGNvbXByZXNzaW9uICovXG5dO1xuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogSW5pdGlhbGl6ZSB0aGUgXCJsb25nZXN0IG1hdGNoXCIgcm91dGluZXMgZm9yIGEgbmV3IHpsaWIgc3RyZWFtXG4gKi9cbmZ1bmN0aW9uIGxtX2luaXQocykge1xuICBzLndpbmRvd19zaXplID0gMiAqIHMud19zaXplO1xuXG4gIC8qKiogQ0xFQVJfSEFTSChzKTsgKioqL1xuICB6ZXJvKHMuaGVhZCk7IC8vIEZpbGwgd2l0aCBOSUwgKD0gMCk7XG5cbiAgLyogU2V0IHRoZSBkZWZhdWx0IGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyczpcbiAgICovXG4gIHMubWF4X2xhenlfbWF0Y2ggPSBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLm1heF9sYXp5O1xuICBzLmdvb2RfbWF0Y2ggPSBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLmdvb2RfbGVuZ3RoO1xuICBzLm5pY2VfbWF0Y2ggPSBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLm5pY2VfbGVuZ3RoO1xuICBzLm1heF9jaGFpbl9sZW5ndGggPSBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLm1heF9jaGFpbjtcblxuICBzLnN0cnN0YXJ0ID0gMDtcbiAgcy5ibG9ja19zdGFydCA9IDA7XG4gIHMubG9va2FoZWFkID0gMDtcbiAgcy5pbnNlcnQgPSAwO1xuICBzLm1hdGNoX2xlbmd0aCA9IHMucHJldl9sZW5ndGggPSBNSU5fTUFUQ0ggLSAxO1xuICBzLm1hdGNoX2F2YWlsYWJsZSA9IDA7XG4gIHMuaW5zX2ggPSAwO1xufVxuXG5cbmZ1bmN0aW9uIERlZmxhdGVTdGF0ZSgpIHtcbiAgdGhpcy5zdHJtID0gbnVsbDsgICAgICAgICAgICAvKiBwb2ludGVyIGJhY2sgdG8gdGhpcyB6bGliIHN0cmVhbSAqL1xuICB0aGlzLnN0YXR1cyA9IDA7ICAgICAgICAgICAgLyogYXMgdGhlIG5hbWUgaW1wbGllcyAqL1xuICB0aGlzLnBlbmRpbmdfYnVmID0gbnVsbDsgICAgICAvKiBvdXRwdXQgc3RpbGwgcGVuZGluZyAqL1xuICB0aGlzLnBlbmRpbmdfYnVmX3NpemUgPSAwOyAgLyogc2l6ZSBvZiBwZW5kaW5nX2J1ZiAqL1xuICB0aGlzLnBlbmRpbmdfb3V0ID0gMDsgICAgICAgLyogbmV4dCBwZW5kaW5nIGJ5dGUgdG8gb3V0cHV0IHRvIHRoZSBzdHJlYW0gKi9cbiAgdGhpcy5wZW5kaW5nID0gMDsgICAgICAgICAgIC8qIG5iIG9mIGJ5dGVzIGluIHRoZSBwZW5kaW5nIGJ1ZmZlciAqL1xuICB0aGlzLndyYXAgPSAwOyAgICAgICAgICAgICAgLyogYml0IDAgdHJ1ZSBmb3IgemxpYiwgYml0IDEgdHJ1ZSBmb3IgZ3ppcCAqL1xuICB0aGlzLmd6aGVhZCA9IG51bGw7ICAgICAgICAgLyogZ3ppcCBoZWFkZXIgaW5mb3JtYXRpb24gdG8gd3JpdGUgKi9cbiAgdGhpcy5nemluZGV4ID0gMDsgICAgICAgICAgIC8qIHdoZXJlIGluIGV4dHJhLCBuYW1lLCBvciBjb21tZW50ICovXG4gIHRoaXMubWV0aG9kID0gWl9ERUZMQVRFRDsgLyogY2FuIG9ubHkgYmUgREVGTEFURUQgKi9cbiAgdGhpcy5sYXN0X2ZsdXNoID0gLTE7ICAgLyogdmFsdWUgb2YgZmx1c2ggcGFyYW0gZm9yIHByZXZpb3VzIGRlZmxhdGUgY2FsbCAqL1xuXG4gIHRoaXMud19zaXplID0gMDsgIC8qIExaNzcgd2luZG93IHNpemUgKDMySyBieSBkZWZhdWx0KSAqL1xuICB0aGlzLndfYml0cyA9IDA7ICAvKiBsb2cyKHdfc2l6ZSkgICg4Li4xNikgKi9cbiAgdGhpcy53X21hc2sgPSAwOyAgLyogd19zaXplIC0gMSAqL1xuXG4gIHRoaXMud2luZG93ID0gbnVsbDtcbiAgLyogU2xpZGluZyB3aW5kb3cuIElucHV0IGJ5dGVzIGFyZSByZWFkIGludG8gdGhlIHNlY29uZCBoYWxmIG9mIHRoZSB3aW5kb3csXG4gICAqIGFuZCBtb3ZlIHRvIHRoZSBmaXJzdCBoYWxmIGxhdGVyIHRvIGtlZXAgYSBkaWN0aW9uYXJ5IG9mIGF0IGxlYXN0IHdTaXplXG4gICAqIGJ5dGVzLiBXaXRoIHRoaXMgb3JnYW5pemF0aW9uLCBtYXRjaGVzIGFyZSBsaW1pdGVkIHRvIGEgZGlzdGFuY2Ugb2ZcbiAgICogd1NpemUtTUFYX01BVENIIGJ5dGVzLCBidXQgdGhpcyBlbnN1cmVzIHRoYXQgSU8gaXMgYWx3YXlzXG4gICAqIHBlcmZvcm1lZCB3aXRoIGEgbGVuZ3RoIG11bHRpcGxlIG9mIHRoZSBibG9jayBzaXplLlxuICAgKi9cblxuICB0aGlzLndpbmRvd19zaXplID0gMDtcbiAgLyogQWN0dWFsIHNpemUgb2Ygd2luZG93OiAyKndTaXplLCBleGNlcHQgd2hlbiB0aGUgdXNlciBpbnB1dCBidWZmZXJcbiAgICogaXMgZGlyZWN0bHkgdXNlZCBhcyBzbGlkaW5nIHdpbmRvdy5cbiAgICovXG5cbiAgdGhpcy5wcmV2ID0gbnVsbDtcbiAgLyogTGluayB0byBvbGRlciBzdHJpbmcgd2l0aCBzYW1lIGhhc2ggaW5kZXguIFRvIGxpbWl0IHRoZSBzaXplIG9mIHRoaXNcbiAgICogYXJyYXkgdG8gNjRLLCB0aGlzIGxpbmsgaXMgbWFpbnRhaW5lZCBvbmx5IGZvciB0aGUgbGFzdCAzMksgc3RyaW5ncy5cbiAgICogQW4gaW5kZXggaW4gdGhpcyBhcnJheSBpcyB0aHVzIGEgd2luZG93IGluZGV4IG1vZHVsbyAzMksuXG4gICAqL1xuXG4gIHRoaXMuaGVhZCA9IG51bGw7ICAgLyogSGVhZHMgb2YgdGhlIGhhc2ggY2hhaW5zIG9yIE5JTC4gKi9cblxuICB0aGlzLmluc19oID0gMDsgICAgICAgLyogaGFzaCBpbmRleCBvZiBzdHJpbmcgdG8gYmUgaW5zZXJ0ZWQgKi9cbiAgdGhpcy5oYXNoX3NpemUgPSAwOyAgIC8qIG51bWJlciBvZiBlbGVtZW50cyBpbiBoYXNoIHRhYmxlICovXG4gIHRoaXMuaGFzaF9iaXRzID0gMDsgICAvKiBsb2cyKGhhc2hfc2l6ZSkgKi9cbiAgdGhpcy5oYXNoX21hc2sgPSAwOyAgIC8qIGhhc2hfc2l6ZS0xICovXG5cbiAgdGhpcy5oYXNoX3NoaWZ0ID0gMDtcbiAgLyogTnVtYmVyIG9mIGJpdHMgYnkgd2hpY2ggaW5zX2ggbXVzdCBiZSBzaGlmdGVkIGF0IGVhY2ggaW5wdXRcbiAgICogc3RlcC4gSXQgbXVzdCBiZSBzdWNoIHRoYXQgYWZ0ZXIgTUlOX01BVENIIHN0ZXBzLCB0aGUgb2xkZXN0XG4gICAqIGJ5dGUgbm8gbG9uZ2VyIHRha2VzIHBhcnQgaW4gdGhlIGhhc2gga2V5LCB0aGF0IGlzOlxuICAgKiAgIGhhc2hfc2hpZnQgKiBNSU5fTUFUQ0ggPj0gaGFzaF9iaXRzXG4gICAqL1xuXG4gIHRoaXMuYmxvY2tfc3RhcnQgPSAwO1xuICAvKiBXaW5kb3cgcG9zaXRpb24gYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgY3VycmVudCBvdXRwdXQgYmxvY2suIEdldHNcbiAgICogbmVnYXRpdmUgd2hlbiB0aGUgd2luZG93IGlzIG1vdmVkIGJhY2t3YXJkcy5cbiAgICovXG5cbiAgdGhpcy5tYXRjaF9sZW5ndGggPSAwOyAgICAgIC8qIGxlbmd0aCBvZiBiZXN0IG1hdGNoICovXG4gIHRoaXMucHJldl9tYXRjaCA9IDA7ICAgICAgICAvKiBwcmV2aW91cyBtYXRjaCAqL1xuICB0aGlzLm1hdGNoX2F2YWlsYWJsZSA9IDA7ICAgLyogc2V0IGlmIHByZXZpb3VzIG1hdGNoIGV4aXN0cyAqL1xuICB0aGlzLnN0cnN0YXJ0ID0gMDsgICAgICAgICAgLyogc3RhcnQgb2Ygc3RyaW5nIHRvIGluc2VydCAqL1xuICB0aGlzLm1hdGNoX3N0YXJ0ID0gMDsgICAgICAgLyogc3RhcnQgb2YgbWF0Y2hpbmcgc3RyaW5nICovXG4gIHRoaXMubG9va2FoZWFkID0gMDsgICAgICAgICAvKiBudW1iZXIgb2YgdmFsaWQgYnl0ZXMgYWhlYWQgaW4gd2luZG93ICovXG5cbiAgdGhpcy5wcmV2X2xlbmd0aCA9IDA7XG4gIC8qIExlbmd0aCBvZiB0aGUgYmVzdCBtYXRjaCBhdCBwcmV2aW91cyBzdGVwLiBNYXRjaGVzIG5vdCBncmVhdGVyIHRoYW4gdGhpc1xuICAgKiBhcmUgZGlzY2FyZGVkLiBUaGlzIGlzIHVzZWQgaW4gdGhlIGxhenkgbWF0Y2ggZXZhbHVhdGlvbi5cbiAgICovXG5cbiAgdGhpcy5tYXhfY2hhaW5fbGVuZ3RoID0gMDtcbiAgLyogVG8gc3BlZWQgdXAgZGVmbGF0aW9uLCBoYXNoIGNoYWlucyBhcmUgbmV2ZXIgc2VhcmNoZWQgYmV5b25kIHRoaXNcbiAgICogbGVuZ3RoLiAgQSBoaWdoZXIgbGltaXQgaW1wcm92ZXMgY29tcHJlc3Npb24gcmF0aW8gYnV0IGRlZ3JhZGVzIHRoZVxuICAgKiBzcGVlZC5cbiAgICovXG5cbiAgdGhpcy5tYXhfbGF6eV9tYXRjaCA9IDA7XG4gIC8qIEF0dGVtcHQgdG8gZmluZCBhIGJldHRlciBtYXRjaCBvbmx5IHdoZW4gdGhlIGN1cnJlbnQgbWF0Y2ggaXMgc3RyaWN0bHlcbiAgICogc21hbGxlciB0aGFuIHRoaXMgdmFsdWUuIFRoaXMgbWVjaGFuaXNtIGlzIHVzZWQgb25seSBmb3IgY29tcHJlc3Npb25cbiAgICogbGV2ZWxzID49IDQuXG4gICAqL1xuICAvLyBUaGF0J3MgYWxpYXMgdG8gbWF4X2xhenlfbWF0Y2gsIGRvbid0IHVzZSBkaXJlY3RseVxuICAvL3RoaXMubWF4X2luc2VydF9sZW5ndGggPSAwO1xuICAvKiBJbnNlcnQgbmV3IHN0cmluZ3MgaW4gdGhlIGhhc2ggdGFibGUgb25seSBpZiB0aGUgbWF0Y2ggbGVuZ3RoIGlzIG5vdFxuICAgKiBncmVhdGVyIHRoYW4gdGhpcyBsZW5ndGguIFRoaXMgc2F2ZXMgdGltZSBidXQgZGVncmFkZXMgY29tcHJlc3Npb24uXG4gICAqIG1heF9pbnNlcnRfbGVuZ3RoIGlzIHVzZWQgb25seSBmb3IgY29tcHJlc3Npb24gbGV2ZWxzIDw9IDMuXG4gICAqL1xuXG4gIHRoaXMubGV2ZWwgPSAwOyAgICAgLyogY29tcHJlc3Npb24gbGV2ZWwgKDEuLjkpICovXG4gIHRoaXMuc3RyYXRlZ3kgPSAwOyAgLyogZmF2b3Igb3IgZm9yY2UgSHVmZm1hbiBjb2RpbmcqL1xuXG4gIHRoaXMuZ29vZF9tYXRjaCA9IDA7XG4gIC8qIFVzZSBhIGZhc3RlciBzZWFyY2ggd2hlbiB0aGUgcHJldmlvdXMgbWF0Y2ggaXMgbG9uZ2VyIHRoYW4gdGhpcyAqL1xuXG4gIHRoaXMubmljZV9tYXRjaCA9IDA7IC8qIFN0b3Agc2VhcmNoaW5nIHdoZW4gY3VycmVudCBtYXRjaCBleGNlZWRzIHRoaXMgKi9cblxuICAgICAgICAgICAgICAvKiB1c2VkIGJ5IHRyZWVzLmM6ICovXG5cbiAgLyogRGlkbid0IHVzZSBjdF9kYXRhIHR5cGVkZWYgYmVsb3cgdG8gc3VwcHJlc3MgY29tcGlsZXIgd2FybmluZyAqL1xuXG4gIC8vIHN0cnVjdCBjdF9kYXRhX3MgZHluX2x0cmVlW0hFQVBfU0laRV07ICAgLyogbGl0ZXJhbCBhbmQgbGVuZ3RoIHRyZWUgKi9cbiAgLy8gc3RydWN0IGN0X2RhdGFfcyBkeW5fZHRyZWVbMipEX0NPREVTKzFdOyAvKiBkaXN0YW5jZSB0cmVlICovXG4gIC8vIHN0cnVjdCBjdF9kYXRhX3MgYmxfdHJlZVsyKkJMX0NPREVTKzFdOyAgLyogSHVmZm1hbiB0cmVlIGZvciBiaXQgbGVuZ3RocyAqL1xuXG4gIC8vIFVzZSBmbGF0IGFycmF5IG9mIERPVUJMRSBzaXplLCB3aXRoIGludGVybGVhdmVkIGZhdGEsXG4gIC8vIGJlY2F1c2UgSlMgZG9lcyBub3Qgc3VwcG9ydCBlZmZlY3RpdmVcbiAgdGhpcy5keW5fbHRyZWUgID0gbmV3IHV0aWxzLkJ1ZjE2KEhFQVBfU0laRSAqIDIpO1xuICB0aGlzLmR5bl9kdHJlZSAgPSBuZXcgdXRpbHMuQnVmMTYoKDIgKiBEX0NPREVTICsgMSkgKiAyKTtcbiAgdGhpcy5ibF90cmVlICAgID0gbmV3IHV0aWxzLkJ1ZjE2KCgyICogQkxfQ09ERVMgKyAxKSAqIDIpO1xuICB6ZXJvKHRoaXMuZHluX2x0cmVlKTtcbiAgemVybyh0aGlzLmR5bl9kdHJlZSk7XG4gIHplcm8odGhpcy5ibF90cmVlKTtcblxuICB0aGlzLmxfZGVzYyAgID0gbnVsbDsgICAgICAgICAvKiBkZXNjLiBmb3IgbGl0ZXJhbCB0cmVlICovXG4gIHRoaXMuZF9kZXNjICAgPSBudWxsOyAgICAgICAgIC8qIGRlc2MuIGZvciBkaXN0YW5jZSB0cmVlICovXG4gIHRoaXMuYmxfZGVzYyAgPSBudWxsOyAgICAgICAgIC8qIGRlc2MuIGZvciBiaXQgbGVuZ3RoIHRyZWUgKi9cblxuICAvL3VzaCBibF9jb3VudFtNQVhfQklUUysxXTtcbiAgdGhpcy5ibF9jb3VudCA9IG5ldyB1dGlscy5CdWYxNihNQVhfQklUUyArIDEpO1xuICAvKiBudW1iZXIgb2YgY29kZXMgYXQgZWFjaCBiaXQgbGVuZ3RoIGZvciBhbiBvcHRpbWFsIHRyZWUgKi9cblxuICAvL2ludCBoZWFwWzIqTF9DT0RFUysxXTsgICAgICAvKiBoZWFwIHVzZWQgdG8gYnVpbGQgdGhlIEh1ZmZtYW4gdHJlZXMgKi9cbiAgdGhpcy5oZWFwID0gbmV3IHV0aWxzLkJ1ZjE2KDIgKiBMX0NPREVTICsgMSk7ICAvKiBoZWFwIHVzZWQgdG8gYnVpbGQgdGhlIEh1ZmZtYW4gdHJlZXMgKi9cbiAgemVybyh0aGlzLmhlYXApO1xuXG4gIHRoaXMuaGVhcF9sZW4gPSAwOyAgICAgICAgICAgICAgIC8qIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgaGVhcCAqL1xuICB0aGlzLmhlYXBfbWF4ID0gMDsgICAgICAgICAgICAgICAvKiBlbGVtZW50IG9mIGxhcmdlc3QgZnJlcXVlbmN5ICovXG4gIC8qIFRoZSBzb25zIG9mIGhlYXBbbl0gYXJlIGhlYXBbMipuXSBhbmQgaGVhcFsyKm4rMV0uIGhlYXBbMF0gaXMgbm90IHVzZWQuXG4gICAqIFRoZSBzYW1lIGhlYXAgYXJyYXkgaXMgdXNlZCB0byBidWlsZCBhbGwgdHJlZXMuXG4gICAqL1xuXG4gIHRoaXMuZGVwdGggPSBuZXcgdXRpbHMuQnVmMTYoMiAqIExfQ09ERVMgKyAxKTsgLy91Y2ggZGVwdGhbMipMX0NPREVTKzFdO1xuICB6ZXJvKHRoaXMuZGVwdGgpO1xuICAvKiBEZXB0aCBvZiBlYWNoIHN1YnRyZWUgdXNlZCBhcyB0aWUgYnJlYWtlciBmb3IgdHJlZXMgb2YgZXF1YWwgZnJlcXVlbmN5XG4gICAqL1xuXG4gIHRoaXMubF9idWYgPSAwOyAgICAgICAgICAvKiBidWZmZXIgaW5kZXggZm9yIGxpdGVyYWxzIG9yIGxlbmd0aHMgKi9cblxuICB0aGlzLmxpdF9idWZzaXplID0gMDtcbiAgLyogU2l6ZSBvZiBtYXRjaCBidWZmZXIgZm9yIGxpdGVyYWxzL2xlbmd0aHMuICBUaGVyZSBhcmUgNCByZWFzb25zIGZvclxuICAgKiBsaW1pdGluZyBsaXRfYnVmc2l6ZSB0byA2NEs6XG4gICAqICAgLSBmcmVxdWVuY2llcyBjYW4gYmUga2VwdCBpbiAxNiBiaXQgY291bnRlcnNcbiAgICogICAtIGlmIGNvbXByZXNzaW9uIGlzIG5vdCBzdWNjZXNzZnVsIGZvciB0aGUgZmlyc3QgYmxvY2ssIGFsbCBpbnB1dFxuICAgKiAgICAgZGF0YSBpcyBzdGlsbCBpbiB0aGUgd2luZG93IHNvIHdlIGNhbiBzdGlsbCBlbWl0IGEgc3RvcmVkIGJsb2NrIGV2ZW5cbiAgICogICAgIHdoZW4gaW5wdXQgY29tZXMgZnJvbSBzdGFuZGFyZCBpbnB1dC4gIChUaGlzIGNhbiBhbHNvIGJlIGRvbmUgZm9yXG4gICAqICAgICBhbGwgYmxvY2tzIGlmIGxpdF9idWZzaXplIGlzIG5vdCBncmVhdGVyIHRoYW4gMzJLLilcbiAgICogICAtIGlmIGNvbXByZXNzaW9uIGlzIG5vdCBzdWNjZXNzZnVsIGZvciBhIGZpbGUgc21hbGxlciB0aGFuIDY0Sywgd2UgY2FuXG4gICAqICAgICBldmVuIGVtaXQgYSBzdG9yZWQgZmlsZSBpbnN0ZWFkIG9mIGEgc3RvcmVkIGJsb2NrIChzYXZpbmcgNSBieXRlcykuXG4gICAqICAgICBUaGlzIGlzIGFwcGxpY2FibGUgb25seSBmb3IgemlwIChub3QgZ3ppcCBvciB6bGliKS5cbiAgICogICAtIGNyZWF0aW5nIG5ldyBIdWZmbWFuIHRyZWVzIGxlc3MgZnJlcXVlbnRseSBtYXkgbm90IHByb3ZpZGUgZmFzdFxuICAgKiAgICAgYWRhcHRhdGlvbiB0byBjaGFuZ2VzIGluIHRoZSBpbnB1dCBkYXRhIHN0YXRpc3RpY3MuIChUYWtlIGZvclxuICAgKiAgICAgZXhhbXBsZSBhIGJpbmFyeSBmaWxlIHdpdGggcG9vcmx5IGNvbXByZXNzaWJsZSBjb2RlIGZvbGxvd2VkIGJ5XG4gICAqICAgICBhIGhpZ2hseSBjb21wcmVzc2libGUgc3RyaW5nIHRhYmxlLikgU21hbGxlciBidWZmZXIgc2l6ZXMgZ2l2ZVxuICAgKiAgICAgZmFzdCBhZGFwdGF0aW9uIGJ1dCBoYXZlIG9mIGNvdXJzZSB0aGUgb3ZlcmhlYWQgb2YgdHJhbnNtaXR0aW5nXG4gICAqICAgICB0cmVlcyBtb3JlIGZyZXF1ZW50bHkuXG4gICAqICAgLSBJIGNhbid0IGNvdW50IGFib3ZlIDRcbiAgICovXG5cbiAgdGhpcy5sYXN0X2xpdCA9IDA7ICAgICAgLyogcnVubmluZyBpbmRleCBpbiBsX2J1ZiAqL1xuXG4gIHRoaXMuZF9idWYgPSAwO1xuICAvKiBCdWZmZXIgaW5kZXggZm9yIGRpc3RhbmNlcy4gVG8gc2ltcGxpZnkgdGhlIGNvZGUsIGRfYnVmIGFuZCBsX2J1ZiBoYXZlXG4gICAqIHRoZSBzYW1lIG51bWJlciBvZiBlbGVtZW50cy4gVG8gdXNlIGRpZmZlcmVudCBsZW5ndGhzLCBhbiBleHRyYSBmbGFnXG4gICAqIGFycmF5IHdvdWxkIGJlIG5lY2Vzc2FyeS5cbiAgICovXG5cbiAgdGhpcy5vcHRfbGVuID0gMDsgICAgICAgLyogYml0IGxlbmd0aCBvZiBjdXJyZW50IGJsb2NrIHdpdGggb3B0aW1hbCB0cmVlcyAqL1xuICB0aGlzLnN0YXRpY19sZW4gPSAwOyAgICAvKiBiaXQgbGVuZ3RoIG9mIGN1cnJlbnQgYmxvY2sgd2l0aCBzdGF0aWMgdHJlZXMgKi9cbiAgdGhpcy5tYXRjaGVzID0gMDsgICAgICAgLyogbnVtYmVyIG9mIHN0cmluZyBtYXRjaGVzIGluIGN1cnJlbnQgYmxvY2sgKi9cbiAgdGhpcy5pbnNlcnQgPSAwOyAgICAgICAgLyogYnl0ZXMgYXQgZW5kIG9mIHdpbmRvdyBsZWZ0IHRvIGluc2VydCAqL1xuXG5cbiAgdGhpcy5iaV9idWYgPSAwO1xuICAvKiBPdXRwdXQgYnVmZmVyLiBiaXRzIGFyZSBpbnNlcnRlZCBzdGFydGluZyBhdCB0aGUgYm90dG9tIChsZWFzdFxuICAgKiBzaWduaWZpY2FudCBiaXRzKS5cbiAgICovXG4gIHRoaXMuYmlfdmFsaWQgPSAwO1xuICAvKiBOdW1iZXIgb2YgdmFsaWQgYml0cyBpbiBiaV9idWYuICBBbGwgYml0cyBhYm92ZSB0aGUgbGFzdCB2YWxpZCBiaXRcbiAgICogYXJlIGFsd2F5cyB6ZXJvLlxuICAgKi9cblxuICAvLyBVc2VkIGZvciB3aW5kb3cgbWVtb3J5IGluaXQuIFdlIHNhZmVseSBpZ25vcmUgaXQgZm9yIEpTLiBUaGF0IG1ha2VzXG4gIC8vIHNlbnNlIG9ubHkgZm9yIHBvaW50ZXJzIGFuZCBtZW1vcnkgY2hlY2sgdG9vbHMuXG4gIC8vdGhpcy5oaWdoX3dhdGVyID0gMDtcbiAgLyogSGlnaCB3YXRlciBtYXJrIG9mZnNldCBpbiB3aW5kb3cgZm9yIGluaXRpYWxpemVkIGJ5dGVzIC0tIGJ5dGVzIGFib3ZlXG4gICAqIHRoaXMgYXJlIHNldCB0byB6ZXJvIGluIG9yZGVyIHRvIGF2b2lkIG1lbW9yeSBjaGVjayB3YXJuaW5ncyB3aGVuXG4gICAqIGxvbmdlc3QgbWF0Y2ggcm91dGluZXMgYWNjZXNzIGJ5dGVzIHBhc3QgdGhlIGlucHV0LiAgVGhpcyBpcyB0aGVuXG4gICAqIHVwZGF0ZWQgdG8gdGhlIG5ldyBoaWdoIHdhdGVyIG1hcmsuXG4gICAqL1xufVxuXG5cbmZ1bmN0aW9uIGRlZmxhdGVSZXNldEtlZXAoc3RybSkge1xuICB2YXIgcztcblxuICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUpIHtcbiAgICByZXR1cm4gZXJyKHN0cm0sIFpfU1RSRUFNX0VSUk9SKTtcbiAgfVxuXG4gIHN0cm0udG90YWxfaW4gPSBzdHJtLnRvdGFsX291dCA9IDA7XG4gIHN0cm0uZGF0YV90eXBlID0gWl9VTktOT1dOO1xuXG4gIHMgPSBzdHJtLnN0YXRlO1xuICBzLnBlbmRpbmcgPSAwO1xuICBzLnBlbmRpbmdfb3V0ID0gMDtcblxuICBpZiAocy53cmFwIDwgMCkge1xuICAgIHMud3JhcCA9IC1zLndyYXA7XG4gICAgLyogd2FzIG1hZGUgbmVnYXRpdmUgYnkgZGVmbGF0ZSguLi4sIFpfRklOSVNIKTsgKi9cbiAgfVxuICBzLnN0YXR1cyA9IChzLndyYXAgPyBJTklUX1NUQVRFIDogQlVTWV9TVEFURSk7XG4gIHN0cm0uYWRsZXIgPSAocy53cmFwID09PSAyKSA/XG4gICAgMCAgLy8gY3JjMzIoMCwgWl9OVUxMLCAwKVxuICA6XG4gICAgMTsgLy8gYWRsZXIzMigwLCBaX05VTEwsIDApXG4gIHMubGFzdF9mbHVzaCA9IFpfTk9fRkxVU0g7XG4gIHRyZWVzLl90cl9pbml0KHMpO1xuICByZXR1cm4gWl9PSztcbn1cblxuXG5mdW5jdGlvbiBkZWZsYXRlUmVzZXQoc3RybSkge1xuICB2YXIgcmV0ID0gZGVmbGF0ZVJlc2V0S2VlcChzdHJtKTtcbiAgaWYgKHJldCA9PT0gWl9PSykge1xuICAgIGxtX2luaXQoc3RybS5zdGF0ZSk7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuXG5mdW5jdGlvbiBkZWZsYXRlU2V0SGVhZGVyKHN0cm0sIGhlYWQpIHtcbiAgaWYgKCFzdHJtIHx8ICFzdHJtLnN0YXRlKSB7IHJldHVybiBaX1NUUkVBTV9FUlJPUjsgfVxuICBpZiAoc3RybS5zdGF0ZS53cmFwICE9PSAyKSB7IHJldHVybiBaX1NUUkVBTV9FUlJPUjsgfVxuICBzdHJtLnN0YXRlLmd6aGVhZCA9IGhlYWQ7XG4gIHJldHVybiBaX09LO1xufVxuXG5cbmZ1bmN0aW9uIGRlZmxhdGVJbml0MihzdHJtLCBsZXZlbCwgbWV0aG9kLCB3aW5kb3dCaXRzLCBtZW1MZXZlbCwgc3RyYXRlZ3kpIHtcbiAgaWYgKCFzdHJtKSB7IC8vID09PSBaX05VTExcbiAgICByZXR1cm4gWl9TVFJFQU1fRVJST1I7XG4gIH1cbiAgdmFyIHdyYXAgPSAxO1xuXG4gIGlmIChsZXZlbCA9PT0gWl9ERUZBVUxUX0NPTVBSRVNTSU9OKSB7XG4gICAgbGV2ZWwgPSA2O1xuICB9XG5cbiAgaWYgKHdpbmRvd0JpdHMgPCAwKSB7IC8qIHN1cHByZXNzIHpsaWIgd3JhcHBlciAqL1xuICAgIHdyYXAgPSAwO1xuICAgIHdpbmRvd0JpdHMgPSAtd2luZG93Qml0cztcbiAgfVxuXG4gIGVsc2UgaWYgKHdpbmRvd0JpdHMgPiAxNSkge1xuICAgIHdyYXAgPSAyOyAgICAgICAgICAgLyogd3JpdGUgZ3ppcCB3cmFwcGVyIGluc3RlYWQgKi9cbiAgICB3aW5kb3dCaXRzIC09IDE2O1xuICB9XG5cblxuICBpZiAobWVtTGV2ZWwgPCAxIHx8IG1lbUxldmVsID4gTUFYX01FTV9MRVZFTCB8fCBtZXRob2QgIT09IFpfREVGTEFURUQgfHxcbiAgICB3aW5kb3dCaXRzIDwgOCB8fCB3aW5kb3dCaXRzID4gMTUgfHwgbGV2ZWwgPCAwIHx8IGxldmVsID4gOSB8fFxuICAgIHN0cmF0ZWd5IDwgMCB8fCBzdHJhdGVneSA+IFpfRklYRUQpIHtcbiAgICByZXR1cm4gZXJyKHN0cm0sIFpfU1RSRUFNX0VSUk9SKTtcbiAgfVxuXG5cbiAgaWYgKHdpbmRvd0JpdHMgPT09IDgpIHtcbiAgICB3aW5kb3dCaXRzID0gOTtcbiAgfVxuICAvKiB1bnRpbCAyNTYtYnl0ZSB3aW5kb3cgYnVnIGZpeGVkICovXG5cbiAgdmFyIHMgPSBuZXcgRGVmbGF0ZVN0YXRlKCk7XG5cbiAgc3RybS5zdGF0ZSA9IHM7XG4gIHMuc3RybSA9IHN0cm07XG5cbiAgcy53cmFwID0gd3JhcDtcbiAgcy5nemhlYWQgPSBudWxsO1xuICBzLndfYml0cyA9IHdpbmRvd0JpdHM7XG4gIHMud19zaXplID0gMSA8PCBzLndfYml0cztcbiAgcy53X21hc2sgPSBzLndfc2l6ZSAtIDE7XG5cbiAgcy5oYXNoX2JpdHMgPSBtZW1MZXZlbCArIDc7XG4gIHMuaGFzaF9zaXplID0gMSA8PCBzLmhhc2hfYml0cztcbiAgcy5oYXNoX21hc2sgPSBzLmhhc2hfc2l6ZSAtIDE7XG4gIHMuaGFzaF9zaGlmdCA9IH5+KChzLmhhc2hfYml0cyArIE1JTl9NQVRDSCAtIDEpIC8gTUlOX01BVENIKTtcblxuICBzLndpbmRvdyA9IG5ldyB1dGlscy5CdWY4KHMud19zaXplICogMik7XG4gIHMuaGVhZCA9IG5ldyB1dGlscy5CdWYxNihzLmhhc2hfc2l6ZSk7XG4gIHMucHJldiA9IG5ldyB1dGlscy5CdWYxNihzLndfc2l6ZSk7XG5cbiAgLy8gRG9uJ3QgbmVlZCBtZW0gaW5pdCBtYWdpYyBmb3IgSlMuXG4gIC8vcy5oaWdoX3dhdGVyID0gMDsgIC8qIG5vdGhpbmcgd3JpdHRlbiB0byBzLT53aW5kb3cgeWV0ICovXG5cbiAgcy5saXRfYnVmc2l6ZSA9IDEgPDwgKG1lbUxldmVsICsgNik7IC8qIDE2SyBlbGVtZW50cyBieSBkZWZhdWx0ICovXG5cbiAgcy5wZW5kaW5nX2J1Zl9zaXplID0gcy5saXRfYnVmc2l6ZSAqIDQ7XG5cbiAgLy9vdmVybGF5ID0gKHVzaGYgKikgWkFMTE9DKHN0cm0sIHMtPmxpdF9idWZzaXplLCBzaXplb2YodXNoKSsyKTtcbiAgLy9zLT5wZW5kaW5nX2J1ZiA9ICh1Y2hmICopIG92ZXJsYXk7XG4gIHMucGVuZGluZ19idWYgPSBuZXcgdXRpbHMuQnVmOChzLnBlbmRpbmdfYnVmX3NpemUpO1xuXG4gIC8vIEl0IGlzIG9mZnNldCBmcm9tIGBzLnBlbmRpbmdfYnVmYCAoc2l6ZSBpcyBgcy5saXRfYnVmc2l6ZSAqIDJgKVxuICAvL3MtPmRfYnVmID0gb3ZlcmxheSArIHMtPmxpdF9idWZzaXplL3NpemVvZih1c2gpO1xuICBzLmRfYnVmID0gMSAqIHMubGl0X2J1ZnNpemU7XG5cbiAgLy9zLT5sX2J1ZiA9IHMtPnBlbmRpbmdfYnVmICsgKDErc2l6ZW9mKHVzaCkpKnMtPmxpdF9idWZzaXplO1xuICBzLmxfYnVmID0gKDEgKyAyKSAqIHMubGl0X2J1ZnNpemU7XG5cbiAgcy5sZXZlbCA9IGxldmVsO1xuICBzLnN0cmF0ZWd5ID0gc3RyYXRlZ3k7XG4gIHMubWV0aG9kID0gbWV0aG9kO1xuXG4gIHJldHVybiBkZWZsYXRlUmVzZXQoc3RybSk7XG59XG5cbmZ1bmN0aW9uIGRlZmxhdGVJbml0KHN0cm0sIGxldmVsKSB7XG4gIHJldHVybiBkZWZsYXRlSW5pdDIoc3RybSwgbGV2ZWwsIFpfREVGTEFURUQsIE1BWF9XQklUUywgREVGX01FTV9MRVZFTCwgWl9ERUZBVUxUX1NUUkFURUdZKTtcbn1cblxuXG5mdW5jdGlvbiBkZWZsYXRlKHN0cm0sIGZsdXNoKSB7XG4gIHZhciBvbGRfZmx1c2gsIHM7XG4gIHZhciBiZWcsIHZhbDsgLy8gZm9yIGd6aXAgaGVhZGVyIHdyaXRlIG9ubHlcblxuICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUgfHxcbiAgICBmbHVzaCA+IFpfQkxPQ0sgfHwgZmx1c2ggPCAwKSB7XG4gICAgcmV0dXJuIHN0cm0gPyBlcnIoc3RybSwgWl9TVFJFQU1fRVJST1IpIDogWl9TVFJFQU1fRVJST1I7XG4gIH1cblxuICBzID0gc3RybS5zdGF0ZTtcblxuICBpZiAoIXN0cm0ub3V0cHV0IHx8XG4gICAgICAoIXN0cm0uaW5wdXQgJiYgc3RybS5hdmFpbF9pbiAhPT0gMCkgfHxcbiAgICAgIChzLnN0YXR1cyA9PT0gRklOSVNIX1NUQVRFICYmIGZsdXNoICE9PSBaX0ZJTklTSCkpIHtcbiAgICByZXR1cm4gZXJyKHN0cm0sIChzdHJtLmF2YWlsX291dCA9PT0gMCkgPyBaX0JVRl9FUlJPUiA6IFpfU1RSRUFNX0VSUk9SKTtcbiAgfVxuXG4gIHMuc3RybSA9IHN0cm07IC8qIGp1c3QgaW4gY2FzZSAqL1xuICBvbGRfZmx1c2ggPSBzLmxhc3RfZmx1c2g7XG4gIHMubGFzdF9mbHVzaCA9IGZsdXNoO1xuXG4gIC8qIFdyaXRlIHRoZSBoZWFkZXIgKi9cbiAgaWYgKHMuc3RhdHVzID09PSBJTklUX1NUQVRFKSB7XG5cbiAgICBpZiAocy53cmFwID09PSAyKSB7IC8vIEdaSVAgaGVhZGVyXG4gICAgICBzdHJtLmFkbGVyID0gMDsgIC8vY3JjMzIoMEwsIFpfTlVMTCwgMCk7XG4gICAgICBwdXRfYnl0ZShzLCAzMSk7XG4gICAgICBwdXRfYnl0ZShzLCAxMzkpO1xuICAgICAgcHV0X2J5dGUocywgOCk7XG4gICAgICBpZiAoIXMuZ3poZWFkKSB7IC8vIHMtPmd6aGVhZCA9PSBaX05VTExcbiAgICAgICAgcHV0X2J5dGUocywgMCk7XG4gICAgICAgIHB1dF9ieXRlKHMsIDApO1xuICAgICAgICBwdXRfYnl0ZShzLCAwKTtcbiAgICAgICAgcHV0X2J5dGUocywgMCk7XG4gICAgICAgIHB1dF9ieXRlKHMsIDApO1xuICAgICAgICBwdXRfYnl0ZShzLCBzLmxldmVsID09PSA5ID8gMiA6XG4gICAgICAgICAgICAgICAgICAgIChzLnN0cmF0ZWd5ID49IFpfSFVGRk1BTl9PTkxZIHx8IHMubGV2ZWwgPCAyID9cbiAgICAgICAgICAgICAgICAgICAgIDQgOiAwKSk7XG4gICAgICAgIHB1dF9ieXRlKHMsIE9TX0NPREUpO1xuICAgICAgICBzLnN0YXR1cyA9IEJVU1lfU1RBVEU7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgcHV0X2J5dGUocywgKHMuZ3poZWFkLnRleHQgPyAxIDogMCkgK1xuICAgICAgICAgICAgICAgICAgICAocy5nemhlYWQuaGNyYyA/IDIgOiAwKSArXG4gICAgICAgICAgICAgICAgICAgICghcy5nemhlYWQuZXh0cmEgPyAwIDogNCkgK1xuICAgICAgICAgICAgICAgICAgICAoIXMuZ3poZWFkLm5hbWUgPyAwIDogOCkgK1xuICAgICAgICAgICAgICAgICAgICAoIXMuZ3poZWFkLmNvbW1lbnQgPyAwIDogMTYpXG4gICAgICAgICk7XG4gICAgICAgIHB1dF9ieXRlKHMsIHMuZ3poZWFkLnRpbWUgJiAweGZmKTtcbiAgICAgICAgcHV0X2J5dGUocywgKHMuZ3poZWFkLnRpbWUgPj4gOCkgJiAweGZmKTtcbiAgICAgICAgcHV0X2J5dGUocywgKHMuZ3poZWFkLnRpbWUgPj4gMTYpICYgMHhmZik7XG4gICAgICAgIHB1dF9ieXRlKHMsIChzLmd6aGVhZC50aW1lID4+IDI0KSAmIDB4ZmYpO1xuICAgICAgICBwdXRfYnl0ZShzLCBzLmxldmVsID09PSA5ID8gMiA6XG4gICAgICAgICAgICAgICAgICAgIChzLnN0cmF0ZWd5ID49IFpfSFVGRk1BTl9PTkxZIHx8IHMubGV2ZWwgPCAyID9cbiAgICAgICAgICAgICAgICAgICAgIDQgOiAwKSk7XG4gICAgICAgIHB1dF9ieXRlKHMsIHMuZ3poZWFkLm9zICYgMHhmZik7XG4gICAgICAgIGlmIChzLmd6aGVhZC5leHRyYSAmJiBzLmd6aGVhZC5leHRyYS5sZW5ndGgpIHtcbiAgICAgICAgICBwdXRfYnl0ZShzLCBzLmd6aGVhZC5leHRyYS5sZW5ndGggJiAweGZmKTtcbiAgICAgICAgICBwdXRfYnl0ZShzLCAocy5nemhlYWQuZXh0cmEubGVuZ3RoID4+IDgpICYgMHhmZik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHMuZ3poZWFkLmhjcmMpIHtcbiAgICAgICAgICBzdHJtLmFkbGVyID0gY3JjMzIoc3RybS5hZGxlciwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nLCAwKTtcbiAgICAgICAgfVxuICAgICAgICBzLmd6aW5kZXggPSAwO1xuICAgICAgICBzLnN0YXR1cyA9IEVYVFJBX1NUQVRFO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIC8vIERFRkxBVEUgaGVhZGVyXG4gICAge1xuICAgICAgdmFyIGhlYWRlciA9IChaX0RFRkxBVEVEICsgKChzLndfYml0cyAtIDgpIDw8IDQpKSA8PCA4O1xuICAgICAgdmFyIGxldmVsX2ZsYWdzID0gLTE7XG5cbiAgICAgIGlmIChzLnN0cmF0ZWd5ID49IFpfSFVGRk1BTl9PTkxZIHx8IHMubGV2ZWwgPCAyKSB7XG4gICAgICAgIGxldmVsX2ZsYWdzID0gMDtcbiAgICAgIH0gZWxzZSBpZiAocy5sZXZlbCA8IDYpIHtcbiAgICAgICAgbGV2ZWxfZmxhZ3MgPSAxO1xuICAgICAgfSBlbHNlIGlmIChzLmxldmVsID09PSA2KSB7XG4gICAgICAgIGxldmVsX2ZsYWdzID0gMjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxldmVsX2ZsYWdzID0gMztcbiAgICAgIH1cbiAgICAgIGhlYWRlciB8PSAobGV2ZWxfZmxhZ3MgPDwgNik7XG4gICAgICBpZiAocy5zdHJzdGFydCAhPT0gMCkgeyBoZWFkZXIgfD0gUFJFU0VUX0RJQ1Q7IH1cbiAgICAgIGhlYWRlciArPSAzMSAtIChoZWFkZXIgJSAzMSk7XG5cbiAgICAgIHMuc3RhdHVzID0gQlVTWV9TVEFURTtcbiAgICAgIHB1dFNob3J0TVNCKHMsIGhlYWRlcik7XG5cbiAgICAgIC8qIFNhdmUgdGhlIGFkbGVyMzIgb2YgdGhlIHByZXNldCBkaWN0aW9uYXJ5OiAqL1xuICAgICAgaWYgKHMuc3Ryc3RhcnQgIT09IDApIHtcbiAgICAgICAgcHV0U2hvcnRNU0Iocywgc3RybS5hZGxlciA+Pj4gMTYpO1xuICAgICAgICBwdXRTaG9ydE1TQihzLCBzdHJtLmFkbGVyICYgMHhmZmZmKTtcbiAgICAgIH1cbiAgICAgIHN0cm0uYWRsZXIgPSAxOyAvLyBhZGxlcjMyKDBMLCBaX05VTEwsIDApO1xuICAgIH1cbiAgfVxuXG4vLyNpZmRlZiBHWklQXG4gIGlmIChzLnN0YXR1cyA9PT0gRVhUUkFfU1RBVEUpIHtcbiAgICBpZiAocy5nemhlYWQuZXh0cmEvKiAhPSBaX05VTEwqLykge1xuICAgICAgYmVnID0gcy5wZW5kaW5nOyAgLyogc3RhcnQgb2YgYnl0ZXMgdG8gdXBkYXRlIGNyYyAqL1xuXG4gICAgICB3aGlsZSAocy5nemluZGV4IDwgKHMuZ3poZWFkLmV4dHJhLmxlbmd0aCAmIDB4ZmZmZikpIHtcbiAgICAgICAgaWYgKHMucGVuZGluZyA9PT0gcy5wZW5kaW5nX2J1Zl9zaXplKSB7XG4gICAgICAgICAgaWYgKHMuZ3poZWFkLmhjcmMgJiYgcy5wZW5kaW5nID4gYmVnKSB7XG4gICAgICAgICAgICBzdHJtLmFkbGVyID0gY3JjMzIoc3RybS5hZGxlciwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nIC0gYmVnLCBiZWcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmbHVzaF9wZW5kaW5nKHN0cm0pO1xuICAgICAgICAgIGJlZyA9IHMucGVuZGluZztcbiAgICAgICAgICBpZiAocy5wZW5kaW5nID09PSBzLnBlbmRpbmdfYnVmX3NpemUpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBwdXRfYnl0ZShzLCBzLmd6aGVhZC5leHRyYVtzLmd6aW5kZXhdICYgMHhmZik7XG4gICAgICAgIHMuZ3ppbmRleCsrO1xuICAgICAgfVxuICAgICAgaWYgKHMuZ3poZWFkLmhjcmMgJiYgcy5wZW5kaW5nID4gYmVnKSB7XG4gICAgICAgIHN0cm0uYWRsZXIgPSBjcmMzMihzdHJtLmFkbGVyLCBzLnBlbmRpbmdfYnVmLCBzLnBlbmRpbmcgLSBiZWcsIGJlZyk7XG4gICAgICB9XG4gICAgICBpZiAocy5nemluZGV4ID09PSBzLmd6aGVhZC5leHRyYS5sZW5ndGgpIHtcbiAgICAgICAgcy5nemluZGV4ID0gMDtcbiAgICAgICAgcy5zdGF0dXMgPSBOQU1FX1NUQVRFO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHMuc3RhdHVzID0gTkFNRV9TVEFURTtcbiAgICB9XG4gIH1cbiAgaWYgKHMuc3RhdHVzID09PSBOQU1FX1NUQVRFKSB7XG4gICAgaWYgKHMuZ3poZWFkLm5hbWUvKiAhPSBaX05VTEwqLykge1xuICAgICAgYmVnID0gcy5wZW5kaW5nOyAgLyogc3RhcnQgb2YgYnl0ZXMgdG8gdXBkYXRlIGNyYyAqL1xuICAgICAgLy9pbnQgdmFsO1xuXG4gICAgICBkbyB7XG4gICAgICAgIGlmIChzLnBlbmRpbmcgPT09IHMucGVuZGluZ19idWZfc2l6ZSkge1xuICAgICAgICAgIGlmIChzLmd6aGVhZC5oY3JjICYmIHMucGVuZGluZyA+IGJlZykge1xuICAgICAgICAgICAgc3RybS5hZGxlciA9IGNyYzMyKHN0cm0uYWRsZXIsIHMucGVuZGluZ19idWYsIHMucGVuZGluZyAtIGJlZywgYmVnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZmx1c2hfcGVuZGluZyhzdHJtKTtcbiAgICAgICAgICBiZWcgPSBzLnBlbmRpbmc7XG4gICAgICAgICAgaWYgKHMucGVuZGluZyA9PT0gcy5wZW5kaW5nX2J1Zl9zaXplKSB7XG4gICAgICAgICAgICB2YWwgPSAxO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIEpTIHNwZWNpZmljOiBsaXR0bGUgbWFnaWMgdG8gYWRkIHplcm8gdGVybWluYXRvciB0byBlbmQgb2Ygc3RyaW5nXG4gICAgICAgIGlmIChzLmd6aW5kZXggPCBzLmd6aGVhZC5uYW1lLmxlbmd0aCkge1xuICAgICAgICAgIHZhbCA9IHMuZ3poZWFkLm5hbWUuY2hhckNvZGVBdChzLmd6aW5kZXgrKykgJiAweGZmO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbCA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgcHV0X2J5dGUocywgdmFsKTtcbiAgICAgIH0gd2hpbGUgKHZhbCAhPT0gMCk7XG5cbiAgICAgIGlmIChzLmd6aGVhZC5oY3JjICYmIHMucGVuZGluZyA+IGJlZykge1xuICAgICAgICBzdHJtLmFkbGVyID0gY3JjMzIoc3RybS5hZGxlciwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nIC0gYmVnLCBiZWcpO1xuICAgICAgfVxuICAgICAgaWYgKHZhbCA9PT0gMCkge1xuICAgICAgICBzLmd6aW5kZXggPSAwO1xuICAgICAgICBzLnN0YXR1cyA9IENPTU1FTlRfU1RBVEU7XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcy5zdGF0dXMgPSBDT01NRU5UX1NUQVRFO1xuICAgIH1cbiAgfVxuICBpZiAocy5zdGF0dXMgPT09IENPTU1FTlRfU1RBVEUpIHtcbiAgICBpZiAocy5nemhlYWQuY29tbWVudC8qICE9IFpfTlVMTCovKSB7XG4gICAgICBiZWcgPSBzLnBlbmRpbmc7ICAvKiBzdGFydCBvZiBieXRlcyB0byB1cGRhdGUgY3JjICovXG4gICAgICAvL2ludCB2YWw7XG5cbiAgICAgIGRvIHtcbiAgICAgICAgaWYgKHMucGVuZGluZyA9PT0gcy5wZW5kaW5nX2J1Zl9zaXplKSB7XG4gICAgICAgICAgaWYgKHMuZ3poZWFkLmhjcmMgJiYgcy5wZW5kaW5nID4gYmVnKSB7XG4gICAgICAgICAgICBzdHJtLmFkbGVyID0gY3JjMzIoc3RybS5hZGxlciwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nIC0gYmVnLCBiZWcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmbHVzaF9wZW5kaW5nKHN0cm0pO1xuICAgICAgICAgIGJlZyA9IHMucGVuZGluZztcbiAgICAgICAgICBpZiAocy5wZW5kaW5nID09PSBzLnBlbmRpbmdfYnVmX3NpemUpIHtcbiAgICAgICAgICAgIHZhbCA9IDE7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gSlMgc3BlY2lmaWM6IGxpdHRsZSBtYWdpYyB0byBhZGQgemVybyB0ZXJtaW5hdG9yIHRvIGVuZCBvZiBzdHJpbmdcbiAgICAgICAgaWYgKHMuZ3ppbmRleCA8IHMuZ3poZWFkLmNvbW1lbnQubGVuZ3RoKSB7XG4gICAgICAgICAgdmFsID0gcy5nemhlYWQuY29tbWVudC5jaGFyQ29kZUF0KHMuZ3ppbmRleCsrKSAmIDB4ZmY7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsID0gMDtcbiAgICAgICAgfVxuICAgICAgICBwdXRfYnl0ZShzLCB2YWwpO1xuICAgICAgfSB3aGlsZSAodmFsICE9PSAwKTtcblxuICAgICAgaWYgKHMuZ3poZWFkLmhjcmMgJiYgcy5wZW5kaW5nID4gYmVnKSB7XG4gICAgICAgIHN0cm0uYWRsZXIgPSBjcmMzMihzdHJtLmFkbGVyLCBzLnBlbmRpbmdfYnVmLCBzLnBlbmRpbmcgLSBiZWcsIGJlZyk7XG4gICAgICB9XG4gICAgICBpZiAodmFsID09PSAwKSB7XG4gICAgICAgIHMuc3RhdHVzID0gSENSQ19TVEFURTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBzLnN0YXR1cyA9IEhDUkNfU1RBVEU7XG4gICAgfVxuICB9XG4gIGlmIChzLnN0YXR1cyA9PT0gSENSQ19TVEFURSkge1xuICAgIGlmIChzLmd6aGVhZC5oY3JjKSB7XG4gICAgICBpZiAocy5wZW5kaW5nICsgMiA+IHMucGVuZGluZ19idWZfc2l6ZSkge1xuICAgICAgICBmbHVzaF9wZW5kaW5nKHN0cm0pO1xuICAgICAgfVxuICAgICAgaWYgKHMucGVuZGluZyArIDIgPD0gcy5wZW5kaW5nX2J1Zl9zaXplKSB7XG4gICAgICAgIHB1dF9ieXRlKHMsIHN0cm0uYWRsZXIgJiAweGZmKTtcbiAgICAgICAgcHV0X2J5dGUocywgKHN0cm0uYWRsZXIgPj4gOCkgJiAweGZmKTtcbiAgICAgICAgc3RybS5hZGxlciA9IDA7IC8vY3JjMzIoMEwsIFpfTlVMTCwgMCk7XG4gICAgICAgIHMuc3RhdHVzID0gQlVTWV9TVEFURTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBzLnN0YXR1cyA9IEJVU1lfU1RBVEU7XG4gICAgfVxuICB9XG4vLyNlbmRpZlxuXG4gIC8qIEZsdXNoIGFzIG11Y2ggcGVuZGluZyBvdXRwdXQgYXMgcG9zc2libGUgKi9cbiAgaWYgKHMucGVuZGluZyAhPT0gMCkge1xuICAgIGZsdXNoX3BlbmRpbmcoc3RybSk7XG4gICAgaWYgKHN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAvKiBTaW5jZSBhdmFpbF9vdXQgaXMgMCwgZGVmbGF0ZSB3aWxsIGJlIGNhbGxlZCBhZ2FpbiB3aXRoXG4gICAgICAgKiBtb3JlIG91dHB1dCBzcGFjZSwgYnV0IHBvc3NpYmx5IHdpdGggYm90aCBwZW5kaW5nIGFuZFxuICAgICAgICogYXZhaWxfaW4gZXF1YWwgdG8gemVyby4gVGhlcmUgd29uJ3QgYmUgYW55dGhpbmcgdG8gZG8sXG4gICAgICAgKiBidXQgdGhpcyBpcyBub3QgYW4gZXJyb3Igc2l0dWF0aW9uIHNvIG1ha2Ugc3VyZSB3ZVxuICAgICAgICogcmV0dXJuIE9LIGluc3RlYWQgb2YgQlVGX0VSUk9SIGF0IG5leHQgY2FsbCBvZiBkZWZsYXRlOlxuICAgICAgICovXG4gICAgICBzLmxhc3RfZmx1c2ggPSAtMTtcbiAgICAgIHJldHVybiBaX09LO1xuICAgIH1cblxuICAgIC8qIE1ha2Ugc3VyZSB0aGVyZSBpcyBzb21ldGhpbmcgdG8gZG8gYW5kIGF2b2lkIGR1cGxpY2F0ZSBjb25zZWN1dGl2ZVxuICAgICAqIGZsdXNoZXMuIEZvciByZXBlYXRlZCBhbmQgdXNlbGVzcyBjYWxscyB3aXRoIFpfRklOSVNILCB3ZSBrZWVwXG4gICAgICogcmV0dXJuaW5nIFpfU1RSRUFNX0VORCBpbnN0ZWFkIG9mIFpfQlVGX0VSUk9SLlxuICAgICAqL1xuICB9IGVsc2UgaWYgKHN0cm0uYXZhaWxfaW4gPT09IDAgJiYgcmFuayhmbHVzaCkgPD0gcmFuayhvbGRfZmx1c2gpICYmXG4gICAgZmx1c2ggIT09IFpfRklOSVNIKSB7XG4gICAgcmV0dXJuIGVycihzdHJtLCBaX0JVRl9FUlJPUik7XG4gIH1cblxuICAvKiBVc2VyIG11c3Qgbm90IHByb3ZpZGUgbW9yZSBpbnB1dCBhZnRlciB0aGUgZmlyc3QgRklOSVNIOiAqL1xuICBpZiAocy5zdGF0dXMgPT09IEZJTklTSF9TVEFURSAmJiBzdHJtLmF2YWlsX2luICE9PSAwKSB7XG4gICAgcmV0dXJuIGVycihzdHJtLCBaX0JVRl9FUlJPUik7XG4gIH1cblxuICAvKiBTdGFydCBhIG5ldyBibG9jayBvciBjb250aW51ZSB0aGUgY3VycmVudCBvbmUuXG4gICAqL1xuICBpZiAoc3RybS5hdmFpbF9pbiAhPT0gMCB8fCBzLmxvb2thaGVhZCAhPT0gMCB8fFxuICAgIChmbHVzaCAhPT0gWl9OT19GTFVTSCAmJiBzLnN0YXR1cyAhPT0gRklOSVNIX1NUQVRFKSkge1xuICAgIHZhciBic3RhdGUgPSAocy5zdHJhdGVneSA9PT0gWl9IVUZGTUFOX09OTFkpID8gZGVmbGF0ZV9odWZmKHMsIGZsdXNoKSA6XG4gICAgICAocy5zdHJhdGVneSA9PT0gWl9STEUgPyBkZWZsYXRlX3JsZShzLCBmbHVzaCkgOlxuICAgICAgICBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLmZ1bmMocywgZmx1c2gpKTtcblxuICAgIGlmIChic3RhdGUgPT09IEJTX0ZJTklTSF9TVEFSVEVEIHx8IGJzdGF0ZSA9PT0gQlNfRklOSVNIX0RPTkUpIHtcbiAgICAgIHMuc3RhdHVzID0gRklOSVNIX1NUQVRFO1xuICAgIH1cbiAgICBpZiAoYnN0YXRlID09PSBCU19ORUVEX01PUkUgfHwgYnN0YXRlID09PSBCU19GSU5JU0hfU1RBUlRFRCkge1xuICAgICAgaWYgKHN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAgIHMubGFzdF9mbHVzaCA9IC0xO1xuICAgICAgICAvKiBhdm9pZCBCVUZfRVJST1IgbmV4dCBjYWxsLCBzZWUgYWJvdmUgKi9cbiAgICAgIH1cbiAgICAgIHJldHVybiBaX09LO1xuICAgICAgLyogSWYgZmx1c2ggIT0gWl9OT19GTFVTSCAmJiBhdmFpbF9vdXQgPT0gMCwgdGhlIG5leHQgY2FsbFxuICAgICAgICogb2YgZGVmbGF0ZSBzaG91bGQgdXNlIHRoZSBzYW1lIGZsdXNoIHBhcmFtZXRlciB0byBtYWtlIHN1cmVcbiAgICAgICAqIHRoYXQgdGhlIGZsdXNoIGlzIGNvbXBsZXRlLiBTbyB3ZSBkb24ndCBoYXZlIHRvIG91dHB1dCBhblxuICAgICAgICogZW1wdHkgYmxvY2sgaGVyZSwgdGhpcyB3aWxsIGJlIGRvbmUgYXQgbmV4dCBjYWxsLiBUaGlzIGFsc29cbiAgICAgICAqIGVuc3VyZXMgdGhhdCBmb3IgYSB2ZXJ5IHNtYWxsIG91dHB1dCBidWZmZXIsIHdlIGVtaXQgYXQgbW9zdFxuICAgICAgICogb25lIGVtcHR5IGJsb2NrLlxuICAgICAgICovXG4gICAgfVxuICAgIGlmIChic3RhdGUgPT09IEJTX0JMT0NLX0RPTkUpIHtcbiAgICAgIGlmIChmbHVzaCA9PT0gWl9QQVJUSUFMX0ZMVVNIKSB7XG4gICAgICAgIHRyZWVzLl90cl9hbGlnbihzKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGZsdXNoICE9PSBaX0JMT0NLKSB7IC8qIEZVTExfRkxVU0ggb3IgU1lOQ19GTFVTSCAqL1xuXG4gICAgICAgIHRyZWVzLl90cl9zdG9yZWRfYmxvY2socywgMCwgMCwgZmFsc2UpO1xuICAgICAgICAvKiBGb3IgYSBmdWxsIGZsdXNoLCB0aGlzIGVtcHR5IGJsb2NrIHdpbGwgYmUgcmVjb2duaXplZFxuICAgICAgICAgKiBhcyBhIHNwZWNpYWwgbWFya2VyIGJ5IGluZmxhdGVfc3luYygpLlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKGZsdXNoID09PSBaX0ZVTExfRkxVU0gpIHtcbiAgICAgICAgICAvKioqIENMRUFSX0hBU0gocyk7ICoqKi8gICAgICAgICAgICAgLyogZm9yZ2V0IGhpc3RvcnkgKi9cbiAgICAgICAgICB6ZXJvKHMuaGVhZCk7IC8vIEZpbGwgd2l0aCBOSUwgKD0gMCk7XG5cbiAgICAgICAgICBpZiAocy5sb29rYWhlYWQgPT09IDApIHtcbiAgICAgICAgICAgIHMuc3Ryc3RhcnQgPSAwO1xuICAgICAgICAgICAgcy5ibG9ja19zdGFydCA9IDA7XG4gICAgICAgICAgICBzLmluc2VydCA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBmbHVzaF9wZW5kaW5nKHN0cm0pO1xuICAgICAgaWYgKHN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAgIHMubGFzdF9mbHVzaCA9IC0xOyAvKiBhdm9pZCBCVUZfRVJST1IgYXQgbmV4dCBjYWxsLCBzZWUgYWJvdmUgKi9cbiAgICAgICAgcmV0dXJuIFpfT0s7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIC8vQXNzZXJ0KHN0cm0tPmF2YWlsX291dCA+IDAsIFwiYnVnMlwiKTtcbiAgLy9pZiAoc3RybS5hdmFpbF9vdXQgPD0gMCkgeyB0aHJvdyBuZXcgRXJyb3IoXCJidWcyXCIpO31cblxuICBpZiAoZmx1c2ggIT09IFpfRklOSVNIKSB7IHJldHVybiBaX09LOyB9XG4gIGlmIChzLndyYXAgPD0gMCkgeyByZXR1cm4gWl9TVFJFQU1fRU5EOyB9XG5cbiAgLyogV3JpdGUgdGhlIHRyYWlsZXIgKi9cbiAgaWYgKHMud3JhcCA9PT0gMikge1xuICAgIHB1dF9ieXRlKHMsIHN0cm0uYWRsZXIgJiAweGZmKTtcbiAgICBwdXRfYnl0ZShzLCAoc3RybS5hZGxlciA+PiA4KSAmIDB4ZmYpO1xuICAgIHB1dF9ieXRlKHMsIChzdHJtLmFkbGVyID4+IDE2KSAmIDB4ZmYpO1xuICAgIHB1dF9ieXRlKHMsIChzdHJtLmFkbGVyID4+IDI0KSAmIDB4ZmYpO1xuICAgIHB1dF9ieXRlKHMsIHN0cm0udG90YWxfaW4gJiAweGZmKTtcbiAgICBwdXRfYnl0ZShzLCAoc3RybS50b3RhbF9pbiA+PiA4KSAmIDB4ZmYpO1xuICAgIHB1dF9ieXRlKHMsIChzdHJtLnRvdGFsX2luID4+IDE2KSAmIDB4ZmYpO1xuICAgIHB1dF9ieXRlKHMsIChzdHJtLnRvdGFsX2luID4+IDI0KSAmIDB4ZmYpO1xuICB9XG4gIGVsc2VcbiAge1xuICAgIHB1dFNob3J0TVNCKHMsIHN0cm0uYWRsZXIgPj4+IDE2KTtcbiAgICBwdXRTaG9ydE1TQihzLCBzdHJtLmFkbGVyICYgMHhmZmZmKTtcbiAgfVxuXG4gIGZsdXNoX3BlbmRpbmcoc3RybSk7XG4gIC8qIElmIGF2YWlsX291dCBpcyB6ZXJvLCB0aGUgYXBwbGljYXRpb24gd2lsbCBjYWxsIGRlZmxhdGUgYWdhaW5cbiAgICogdG8gZmx1c2ggdGhlIHJlc3QuXG4gICAqL1xuICBpZiAocy53cmFwID4gMCkgeyBzLndyYXAgPSAtcy53cmFwOyB9XG4gIC8qIHdyaXRlIHRoZSB0cmFpbGVyIG9ubHkgb25jZSEgKi9cbiAgcmV0dXJuIHMucGVuZGluZyAhPT0gMCA/IFpfT0sgOiBaX1NUUkVBTV9FTkQ7XG59XG5cbmZ1bmN0aW9uIGRlZmxhdGVFbmQoc3RybSkge1xuICB2YXIgc3RhdHVzO1xuXG4gIGlmICghc3RybS8qPT0gWl9OVUxMKi8gfHwgIXN0cm0uc3RhdGUvKj09IFpfTlVMTCovKSB7XG4gICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SO1xuICB9XG5cbiAgc3RhdHVzID0gc3RybS5zdGF0ZS5zdGF0dXM7XG4gIGlmIChzdGF0dXMgIT09IElOSVRfU1RBVEUgJiZcbiAgICBzdGF0dXMgIT09IEVYVFJBX1NUQVRFICYmXG4gICAgc3RhdHVzICE9PSBOQU1FX1NUQVRFICYmXG4gICAgc3RhdHVzICE9PSBDT01NRU5UX1NUQVRFICYmXG4gICAgc3RhdHVzICE9PSBIQ1JDX1NUQVRFICYmXG4gICAgc3RhdHVzICE9PSBCVVNZX1NUQVRFICYmXG4gICAgc3RhdHVzICE9PSBGSU5JU0hfU1RBVEVcbiAgKSB7XG4gICAgcmV0dXJuIGVycihzdHJtLCBaX1NUUkVBTV9FUlJPUik7XG4gIH1cblxuICBzdHJtLnN0YXRlID0gbnVsbDtcblxuICByZXR1cm4gc3RhdHVzID09PSBCVVNZX1NUQVRFID8gZXJyKHN0cm0sIFpfREFUQV9FUlJPUikgOiBaX09LO1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEluaXRpYWxpemVzIHRoZSBjb21wcmVzc2lvbiBkaWN0aW9uYXJ5IGZyb20gdGhlIGdpdmVuIGJ5dGVcbiAqIHNlcXVlbmNlIHdpdGhvdXQgcHJvZHVjaW5nIGFueSBjb21wcmVzc2VkIG91dHB1dC5cbiAqL1xuZnVuY3Rpb24gZGVmbGF0ZVNldERpY3Rpb25hcnkoc3RybSwgZGljdGlvbmFyeSkge1xuICB2YXIgZGljdExlbmd0aCA9IGRpY3Rpb25hcnkubGVuZ3RoO1xuXG4gIHZhciBzO1xuICB2YXIgc3RyLCBuO1xuICB2YXIgd3JhcDtcbiAgdmFyIGF2YWlsO1xuICB2YXIgbmV4dDtcbiAgdmFyIGlucHV0O1xuICB2YXIgdG1wRGljdDtcblxuICBpZiAoIXN0cm0vKj09IFpfTlVMTCovIHx8ICFzdHJtLnN0YXRlLyo9PSBaX05VTEwqLykge1xuICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUjtcbiAgfVxuXG4gIHMgPSBzdHJtLnN0YXRlO1xuICB3cmFwID0gcy53cmFwO1xuXG4gIGlmICh3cmFwID09PSAyIHx8ICh3cmFwID09PSAxICYmIHMuc3RhdHVzICE9PSBJTklUX1NUQVRFKSB8fCBzLmxvb2thaGVhZCkge1xuICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUjtcbiAgfVxuXG4gIC8qIHdoZW4gdXNpbmcgemxpYiB3cmFwcGVycywgY29tcHV0ZSBBZGxlci0zMiBmb3IgcHJvdmlkZWQgZGljdGlvbmFyeSAqL1xuICBpZiAod3JhcCA9PT0gMSkge1xuICAgIC8qIGFkbGVyMzIoc3RybS0+YWRsZXIsIGRpY3Rpb25hcnksIGRpY3RMZW5ndGgpOyAqL1xuICAgIHN0cm0uYWRsZXIgPSBhZGxlcjMyKHN0cm0uYWRsZXIsIGRpY3Rpb25hcnksIGRpY3RMZW5ndGgsIDApO1xuICB9XG5cbiAgcy53cmFwID0gMDsgICAvKiBhdm9pZCBjb21wdXRpbmcgQWRsZXItMzIgaW4gcmVhZF9idWYgKi9cblxuICAvKiBpZiBkaWN0aW9uYXJ5IHdvdWxkIGZpbGwgd2luZG93LCBqdXN0IHJlcGxhY2UgdGhlIGhpc3RvcnkgKi9cbiAgaWYgKGRpY3RMZW5ndGggPj0gcy53X3NpemUpIHtcbiAgICBpZiAod3JhcCA9PT0gMCkgeyAgICAgICAgICAgIC8qIGFscmVhZHkgZW1wdHkgb3RoZXJ3aXNlICovXG4gICAgICAvKioqIENMRUFSX0hBU0gocyk7ICoqKi9cbiAgICAgIHplcm8ocy5oZWFkKTsgLy8gRmlsbCB3aXRoIE5JTCAoPSAwKTtcbiAgICAgIHMuc3Ryc3RhcnQgPSAwO1xuICAgICAgcy5ibG9ja19zdGFydCA9IDA7XG4gICAgICBzLmluc2VydCA9IDA7XG4gICAgfVxuICAgIC8qIHVzZSB0aGUgdGFpbCAqL1xuICAgIC8vIGRpY3Rpb25hcnkgPSBkaWN0aW9uYXJ5LnNsaWNlKGRpY3RMZW5ndGggLSBzLndfc2l6ZSk7XG4gICAgdG1wRGljdCA9IG5ldyB1dGlscy5CdWY4KHMud19zaXplKTtcbiAgICB1dGlscy5hcnJheVNldCh0bXBEaWN0LCBkaWN0aW9uYXJ5LCBkaWN0TGVuZ3RoIC0gcy53X3NpemUsIHMud19zaXplLCAwKTtcbiAgICBkaWN0aW9uYXJ5ID0gdG1wRGljdDtcbiAgICBkaWN0TGVuZ3RoID0gcy53X3NpemU7XG4gIH1cbiAgLyogaW5zZXJ0IGRpY3Rpb25hcnkgaW50byB3aW5kb3cgYW5kIGhhc2ggKi9cbiAgYXZhaWwgPSBzdHJtLmF2YWlsX2luO1xuICBuZXh0ID0gc3RybS5uZXh0X2luO1xuICBpbnB1dCA9IHN0cm0uaW5wdXQ7XG4gIHN0cm0uYXZhaWxfaW4gPSBkaWN0TGVuZ3RoO1xuICBzdHJtLm5leHRfaW4gPSAwO1xuICBzdHJtLmlucHV0ID0gZGljdGlvbmFyeTtcbiAgZmlsbF93aW5kb3cocyk7XG4gIHdoaWxlIChzLmxvb2thaGVhZCA+PSBNSU5fTUFUQ0gpIHtcbiAgICBzdHIgPSBzLnN0cnN0YXJ0O1xuICAgIG4gPSBzLmxvb2thaGVhZCAtIChNSU5fTUFUQ0ggLSAxKTtcbiAgICBkbyB7XG4gICAgICAvKiBVUERBVEVfSEFTSChzLCBzLT5pbnNfaCwgcy0+d2luZG93W3N0ciArIE1JTl9NQVRDSC0xXSk7ICovXG4gICAgICBzLmluc19oID0gKChzLmluc19oIDw8IHMuaGFzaF9zaGlmdCkgXiBzLndpbmRvd1tzdHIgKyBNSU5fTUFUQ0ggLSAxXSkgJiBzLmhhc2hfbWFzaztcblxuICAgICAgcy5wcmV2W3N0ciAmIHMud19tYXNrXSA9IHMuaGVhZFtzLmluc19oXTtcblxuICAgICAgcy5oZWFkW3MuaW5zX2hdID0gc3RyO1xuICAgICAgc3RyKys7XG4gICAgfSB3aGlsZSAoLS1uKTtcbiAgICBzLnN0cnN0YXJ0ID0gc3RyO1xuICAgIHMubG9va2FoZWFkID0gTUlOX01BVENIIC0gMTtcbiAgICBmaWxsX3dpbmRvdyhzKTtcbiAgfVxuICBzLnN0cnN0YXJ0ICs9IHMubG9va2FoZWFkO1xuICBzLmJsb2NrX3N0YXJ0ID0gcy5zdHJzdGFydDtcbiAgcy5pbnNlcnQgPSBzLmxvb2thaGVhZDtcbiAgcy5sb29rYWhlYWQgPSAwO1xuICBzLm1hdGNoX2xlbmd0aCA9IHMucHJldl9sZW5ndGggPSBNSU5fTUFUQ0ggLSAxO1xuICBzLm1hdGNoX2F2YWlsYWJsZSA9IDA7XG4gIHN0cm0ubmV4dF9pbiA9IG5leHQ7XG4gIHN0cm0uaW5wdXQgPSBpbnB1dDtcbiAgc3RybS5hdmFpbF9pbiA9IGF2YWlsO1xuICBzLndyYXAgPSB3cmFwO1xuICByZXR1cm4gWl9PSztcbn1cblxuXG5leHBvcnRzLmRlZmxhdGVJbml0ID0gZGVmbGF0ZUluaXQ7XG5leHBvcnRzLmRlZmxhdGVJbml0MiA9IGRlZmxhdGVJbml0MjtcbmV4cG9ydHMuZGVmbGF0ZVJlc2V0ID0gZGVmbGF0ZVJlc2V0O1xuZXhwb3J0cy5kZWZsYXRlUmVzZXRLZWVwID0gZGVmbGF0ZVJlc2V0S2VlcDtcbmV4cG9ydHMuZGVmbGF0ZVNldEhlYWRlciA9IGRlZmxhdGVTZXRIZWFkZXI7XG5leHBvcnRzLmRlZmxhdGUgPSBkZWZsYXRlO1xuZXhwb3J0cy5kZWZsYXRlRW5kID0gZGVmbGF0ZUVuZDtcbmV4cG9ydHMuZGVmbGF0ZVNldERpY3Rpb25hcnkgPSBkZWZsYXRlU2V0RGljdGlvbmFyeTtcbmV4cG9ydHMuZGVmbGF0ZUluZm8gPSAncGFrbyBkZWZsYXRlIChmcm9tIE5vZGVjYSBwcm9qZWN0KSc7XG5cbi8qIE5vdCBpbXBsZW1lbnRlZFxuZXhwb3J0cy5kZWZsYXRlQm91bmQgPSBkZWZsYXRlQm91bmQ7XG5leHBvcnRzLmRlZmxhdGVDb3B5ID0gZGVmbGF0ZUNvcHk7XG5leHBvcnRzLmRlZmxhdGVQYXJhbXMgPSBkZWZsYXRlUGFyYW1zO1xuZXhwb3J0cy5kZWZsYXRlUGVuZGluZyA9IGRlZmxhdGVQZW5kaW5nO1xuZXhwb3J0cy5kZWZsYXRlUHJpbWUgPSBkZWZsYXRlUHJpbWU7XG5leHBvcnRzLmRlZmxhdGVUdW5lID0gZGVmbGF0ZVR1bmU7XG4qL1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXJcbi8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luXG4vL1xuLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWRcbi8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlc1xuLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSxcbi8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXRcbi8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczpcbi8vXG4vLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdFxuLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZVxuLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmVcbi8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC5cbi8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlXG4vLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS5cbi8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uXG5cbmZ1bmN0aW9uIEdaaGVhZGVyKCkge1xuICAvKiB0cnVlIGlmIGNvbXByZXNzZWQgZGF0YSBiZWxpZXZlZCB0byBiZSB0ZXh0ICovXG4gIHRoaXMudGV4dCAgICAgICA9IDA7XG4gIC8qIG1vZGlmaWNhdGlvbiB0aW1lICovXG4gIHRoaXMudGltZSAgICAgICA9IDA7XG4gIC8qIGV4dHJhIGZsYWdzIChub3QgdXNlZCB3aGVuIHdyaXRpbmcgYSBnemlwIGZpbGUpICovXG4gIHRoaXMueGZsYWdzICAgICA9IDA7XG4gIC8qIG9wZXJhdGluZyBzeXN0ZW0gKi9cbiAgdGhpcy5vcyAgICAgICAgID0gMDtcbiAgLyogcG9pbnRlciB0byBleHRyYSBmaWVsZCBvciBaX05VTEwgaWYgbm9uZSAqL1xuICB0aGlzLmV4dHJhICAgICAgPSBudWxsO1xuICAvKiBleHRyYSBmaWVsZCBsZW5ndGggKHZhbGlkIGlmIGV4dHJhICE9IFpfTlVMTCkgKi9cbiAgdGhpcy5leHRyYV9sZW4gID0gMDsgLy8gQWN0dWFsbHksIHdlIGRvbid0IG5lZWQgaXQgaW4gSlMsXG4gICAgICAgICAgICAgICAgICAgICAgIC8vIGJ1dCBsZWF2ZSBmb3IgZmV3IGNvZGUgbW9kaWZpY2F0aW9uc1xuXG4gIC8vXG4gIC8vIFNldHVwIGxpbWl0cyBpcyBub3QgbmVjZXNzYXJ5IGJlY2F1c2UgaW4ganMgd2Ugc2hvdWxkIG5vdCBwcmVhbGxvY2F0ZSBtZW1vcnlcbiAgLy8gZm9yIGluZmxhdGUgdXNlIGNvbnN0YW50IGxpbWl0IGluIDY1NTM2IGJ5dGVzXG4gIC8vXG5cbiAgLyogc3BhY2UgYXQgZXh0cmEgKG9ubHkgd2hlbiByZWFkaW5nIGhlYWRlcikgKi9cbiAgLy8gdGhpcy5leHRyYV9tYXggID0gMDtcbiAgLyogcG9pbnRlciB0byB6ZXJvLXRlcm1pbmF0ZWQgZmlsZSBuYW1lIG9yIFpfTlVMTCAqL1xuICB0aGlzLm5hbWUgICAgICAgPSAnJztcbiAgLyogc3BhY2UgYXQgbmFtZSAob25seSB3aGVuIHJlYWRpbmcgaGVhZGVyKSAqL1xuICAvLyB0aGlzLm5hbWVfbWF4ICAgPSAwO1xuICAvKiBwb2ludGVyIHRvIHplcm8tdGVybWluYXRlZCBjb21tZW50IG9yIFpfTlVMTCAqL1xuICB0aGlzLmNvbW1lbnQgICAgPSAnJztcbiAgLyogc3BhY2UgYXQgY29tbWVudCAob25seSB3aGVuIHJlYWRpbmcgaGVhZGVyKSAqL1xuICAvLyB0aGlzLmNvbW1fbWF4ICAgPSAwO1xuICAvKiB0cnVlIGlmIHRoZXJlIHdhcyBvciB3aWxsIGJlIGEgaGVhZGVyIGNyYyAqL1xuICB0aGlzLmhjcmMgICAgICAgPSAwO1xuICAvKiB0cnVlIHdoZW4gZG9uZSByZWFkaW5nIGd6aXAgaGVhZGVyIChub3QgdXNlZCB3aGVuIHdyaXRpbmcgYSBnemlwIGZpbGUpICovXG4gIHRoaXMuZG9uZSAgICAgICA9IGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEdaaGVhZGVyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXJcbi8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luXG4vL1xuLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWRcbi8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlc1xuLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSxcbi8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXRcbi8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczpcbi8vXG4vLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdFxuLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZVxuLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmVcbi8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC5cbi8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlXG4vLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS5cbi8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uXG5cbi8vIFNlZSBzdGF0ZSBkZWZzIGZyb20gaW5mbGF0ZS5qc1xudmFyIEJBRCA9IDMwOyAgICAgICAvKiBnb3QgYSBkYXRhIGVycm9yIC0tIHJlbWFpbiBoZXJlIHVudGlsIHJlc2V0ICovXG52YXIgVFlQRSA9IDEyOyAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIHR5cGUgYml0cywgaW5jbHVkaW5nIGxhc3QtZmxhZyBiaXQgKi9cblxuLypcbiAgIERlY29kZSBsaXRlcmFsLCBsZW5ndGgsIGFuZCBkaXN0YW5jZSBjb2RlcyBhbmQgd3JpdGUgb3V0IHRoZSByZXN1bHRpbmdcbiAgIGxpdGVyYWwgYW5kIG1hdGNoIGJ5dGVzIHVudGlsIGVpdGhlciBub3QgZW5vdWdoIGlucHV0IG9yIG91dHB1dCBpc1xuICAgYXZhaWxhYmxlLCBhbiBlbmQtb2YtYmxvY2sgaXMgZW5jb3VudGVyZWQsIG9yIGEgZGF0YSBlcnJvciBpcyBlbmNvdW50ZXJlZC5cbiAgIFdoZW4gbGFyZ2UgZW5vdWdoIGlucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBhcmUgc3VwcGxpZWQgdG8gaW5mbGF0ZSgpLCBmb3JcbiAgIGV4YW1wbGUsIGEgMTZLIGlucHV0IGJ1ZmZlciBhbmQgYSA2NEsgb3V0cHV0IGJ1ZmZlciwgbW9yZSB0aGFuIDk1JSBvZiB0aGVcbiAgIGluZmxhdGUgZXhlY3V0aW9uIHRpbWUgaXMgc3BlbnQgaW4gdGhpcyByb3V0aW5lLlxuXG4gICBFbnRyeSBhc3N1bXB0aW9uczpcblxuICAgICAgICBzdGF0ZS5tb2RlID09PSBMRU5cbiAgICAgICAgc3RybS5hdmFpbF9pbiA+PSA2XG4gICAgICAgIHN0cm0uYXZhaWxfb3V0ID49IDI1OFxuICAgICAgICBzdGFydCA+PSBzdHJtLmF2YWlsX291dFxuICAgICAgICBzdGF0ZS5iaXRzIDwgOFxuXG4gICBPbiByZXR1cm4sIHN0YXRlLm1vZGUgaXMgb25lIG9mOlxuXG4gICAgICAgIExFTiAtLSByYW4gb3V0IG9mIGVub3VnaCBvdXRwdXQgc3BhY2Ugb3IgZW5vdWdoIGF2YWlsYWJsZSBpbnB1dFxuICAgICAgICBUWVBFIC0tIHJlYWNoZWQgZW5kIG9mIGJsb2NrIGNvZGUsIGluZmxhdGUoKSB0byBpbnRlcnByZXQgbmV4dCBibG9ja1xuICAgICAgICBCQUQgLS0gZXJyb3IgaW4gYmxvY2sgZGF0YVxuXG4gICBOb3RlczpcblxuICAgIC0gVGhlIG1heGltdW0gaW5wdXQgYml0cyB1c2VkIGJ5IGEgbGVuZ3RoL2Rpc3RhbmNlIHBhaXIgaXMgMTUgYml0cyBmb3IgdGhlXG4gICAgICBsZW5ndGggY29kZSwgNSBiaXRzIGZvciB0aGUgbGVuZ3RoIGV4dHJhLCAxNSBiaXRzIGZvciB0aGUgZGlzdGFuY2UgY29kZSxcbiAgICAgIGFuZCAxMyBiaXRzIGZvciB0aGUgZGlzdGFuY2UgZXh0cmEuICBUaGlzIHRvdGFscyA0OCBiaXRzLCBvciBzaXggYnl0ZXMuXG4gICAgICBUaGVyZWZvcmUgaWYgc3RybS5hdmFpbF9pbiA+PSA2LCB0aGVuIHRoZXJlIGlzIGVub3VnaCBpbnB1dCB0byBhdm9pZFxuICAgICAgY2hlY2tpbmcgZm9yIGF2YWlsYWJsZSBpbnB1dCB3aGlsZSBkZWNvZGluZy5cblxuICAgIC0gVGhlIG1heGltdW0gYnl0ZXMgdGhhdCBhIHNpbmdsZSBsZW5ndGgvZGlzdGFuY2UgcGFpciBjYW4gb3V0cHV0IGlzIDI1OFxuICAgICAgYnl0ZXMsIHdoaWNoIGlzIHRoZSBtYXhpbXVtIGxlbmd0aCB0aGF0IGNhbiBiZSBjb2RlZC4gIGluZmxhdGVfZmFzdCgpXG4gICAgICByZXF1aXJlcyBzdHJtLmF2YWlsX291dCA+PSAyNTggZm9yIGVhY2ggbG9vcCB0byBhdm9pZCBjaGVja2luZyBmb3JcbiAgICAgIG91dHB1dCBzcGFjZS5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmZsYXRlX2Zhc3Qoc3RybSwgc3RhcnQpIHtcbiAgdmFyIHN0YXRlO1xuICB2YXIgX2luOyAgICAgICAgICAgICAgICAgICAgLyogbG9jYWwgc3RybS5pbnB1dCAqL1xuICB2YXIgbGFzdDsgICAgICAgICAgICAgICAgICAgLyogaGF2ZSBlbm91Z2ggaW5wdXQgd2hpbGUgaW4gPCBsYXN0ICovXG4gIHZhciBfb3V0OyAgICAgICAgICAgICAgICAgICAvKiBsb2NhbCBzdHJtLm91dHB1dCAqL1xuICB2YXIgYmVnOyAgICAgICAgICAgICAgICAgICAgLyogaW5mbGF0ZSgpJ3MgaW5pdGlhbCBzdHJtLm91dHB1dCAqL1xuICB2YXIgZW5kOyAgICAgICAgICAgICAgICAgICAgLyogd2hpbGUgb3V0IDwgZW5kLCBlbm91Z2ggc3BhY2UgYXZhaWxhYmxlICovXG4vLyNpZmRlZiBJTkZMQVRFX1NUUklDVFxuICB2YXIgZG1heDsgICAgICAgICAgICAgICAgICAgLyogbWF4aW11bSBkaXN0YW5jZSBmcm9tIHpsaWIgaGVhZGVyICovXG4vLyNlbmRpZlxuICB2YXIgd3NpemU7ICAgICAgICAgICAgICAgICAgLyogd2luZG93IHNpemUgb3IgemVybyBpZiBub3QgdXNpbmcgd2luZG93ICovXG4gIHZhciB3aGF2ZTsgICAgICAgICAgICAgICAgICAvKiB2YWxpZCBieXRlcyBpbiB0aGUgd2luZG93ICovXG4gIHZhciB3bmV4dDsgICAgICAgICAgICAgICAgICAvKiB3aW5kb3cgd3JpdGUgaW5kZXggKi9cbiAgLy8gVXNlIGBzX3dpbmRvd2AgaW5zdGVhZCBgd2luZG93YCwgYXZvaWQgY29uZmxpY3Qgd2l0aCBpbnN0cnVtZW50YXRpb24gdG9vbHNcbiAgdmFyIHNfd2luZG93OyAgICAgICAgICAgICAgIC8qIGFsbG9jYXRlZCBzbGlkaW5nIHdpbmRvdywgaWYgd3NpemUgIT0gMCAqL1xuICB2YXIgaG9sZDsgICAgICAgICAgICAgICAgICAgLyogbG9jYWwgc3RybS5ob2xkICovXG4gIHZhciBiaXRzOyAgICAgICAgICAgICAgICAgICAvKiBsb2NhbCBzdHJtLmJpdHMgKi9cbiAgdmFyIGxjb2RlOyAgICAgICAgICAgICAgICAgIC8qIGxvY2FsIHN0cm0ubGVuY29kZSAqL1xuICB2YXIgZGNvZGU7ICAgICAgICAgICAgICAgICAgLyogbG9jYWwgc3RybS5kaXN0Y29kZSAqL1xuICB2YXIgbG1hc2s7ICAgICAgICAgICAgICAgICAgLyogbWFzayBmb3IgZmlyc3QgbGV2ZWwgb2YgbGVuZ3RoIGNvZGVzICovXG4gIHZhciBkbWFzazsgICAgICAgICAgICAgICAgICAvKiBtYXNrIGZvciBmaXJzdCBsZXZlbCBvZiBkaXN0YW5jZSBjb2RlcyAqL1xuICB2YXIgaGVyZTsgICAgICAgICAgICAgICAgICAgLyogcmV0cmlldmVkIHRhYmxlIGVudHJ5ICovXG4gIHZhciBvcDsgICAgICAgICAgICAgICAgICAgICAvKiBjb2RlIGJpdHMsIG9wZXJhdGlvbiwgZXh0cmEgYml0cywgb3IgKi9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qICB3aW5kb3cgcG9zaXRpb24sIHdpbmRvdyBieXRlcyB0byBjb3B5ICovXG4gIHZhciBsZW47ICAgICAgICAgICAgICAgICAgICAvKiBtYXRjaCBsZW5ndGgsIHVudXNlZCBieXRlcyAqL1xuICB2YXIgZGlzdDsgICAgICAgICAgICAgICAgICAgLyogbWF0Y2ggZGlzdGFuY2UgKi9cbiAgdmFyIGZyb207ICAgICAgICAgICAgICAgICAgIC8qIHdoZXJlIHRvIGNvcHkgbWF0Y2ggZnJvbSAqL1xuICB2YXIgZnJvbV9zb3VyY2U7XG5cblxuICB2YXIgaW5wdXQsIG91dHB1dDsgLy8gSlMgc3BlY2lmaWMsIGJlY2F1c2Ugd2UgaGF2ZSBubyBwb2ludGVyc1xuXG4gIC8qIGNvcHkgc3RhdGUgdG8gbG9jYWwgdmFyaWFibGVzICovXG4gIHN0YXRlID0gc3RybS5zdGF0ZTtcbiAgLy9oZXJlID0gc3RhdGUuaGVyZTtcbiAgX2luID0gc3RybS5uZXh0X2luO1xuICBpbnB1dCA9IHN0cm0uaW5wdXQ7XG4gIGxhc3QgPSBfaW4gKyAoc3RybS5hdmFpbF9pbiAtIDUpO1xuICBfb3V0ID0gc3RybS5uZXh0X291dDtcbiAgb3V0cHV0ID0gc3RybS5vdXRwdXQ7XG4gIGJlZyA9IF9vdXQgLSAoc3RhcnQgLSBzdHJtLmF2YWlsX291dCk7XG4gIGVuZCA9IF9vdXQgKyAoc3RybS5hdmFpbF9vdXQgLSAyNTcpO1xuLy8jaWZkZWYgSU5GTEFURV9TVFJJQ1RcbiAgZG1heCA9IHN0YXRlLmRtYXg7XG4vLyNlbmRpZlxuICB3c2l6ZSA9IHN0YXRlLndzaXplO1xuICB3aGF2ZSA9IHN0YXRlLndoYXZlO1xuICB3bmV4dCA9IHN0YXRlLnduZXh0O1xuICBzX3dpbmRvdyA9IHN0YXRlLndpbmRvdztcbiAgaG9sZCA9IHN0YXRlLmhvbGQ7XG4gIGJpdHMgPSBzdGF0ZS5iaXRzO1xuICBsY29kZSA9IHN0YXRlLmxlbmNvZGU7XG4gIGRjb2RlID0gc3RhdGUuZGlzdGNvZGU7XG4gIGxtYXNrID0gKDEgPDwgc3RhdGUubGVuYml0cykgLSAxO1xuICBkbWFzayA9ICgxIDw8IHN0YXRlLmRpc3RiaXRzKSAtIDE7XG5cblxuICAvKiBkZWNvZGUgbGl0ZXJhbHMgYW5kIGxlbmd0aC9kaXN0YW5jZXMgdW50aWwgZW5kLW9mLWJsb2NrIG9yIG5vdCBlbm91Z2hcbiAgICAgaW5wdXQgZGF0YSBvciBvdXRwdXQgc3BhY2UgKi9cblxuICB0b3A6XG4gIGRvIHtcbiAgICBpZiAoYml0cyA8IDE1KSB7XG4gICAgICBob2xkICs9IGlucHV0W19pbisrXSA8PCBiaXRzO1xuICAgICAgYml0cyArPSA4O1xuICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgIGJpdHMgKz0gODtcbiAgICB9XG5cbiAgICBoZXJlID0gbGNvZGVbaG9sZCAmIGxtYXNrXTtcblxuICAgIGRvbGVuOlxuICAgIGZvciAoOzspIHsgLy8gR290byBlbXVsYXRpb25cbiAgICAgIG9wID0gaGVyZSA+Pj4gMjQvKmhlcmUuYml0cyovO1xuICAgICAgaG9sZCA+Pj49IG9wO1xuICAgICAgYml0cyAtPSBvcDtcbiAgICAgIG9wID0gKGhlcmUgPj4+IDE2KSAmIDB4ZmYvKmhlcmUub3AqLztcbiAgICAgIGlmIChvcCA9PT0gMCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbGl0ZXJhbCAqL1xuICAgICAgICAvL1RyYWNldnYoKHN0ZGVyciwgaGVyZS52YWwgPj0gMHgyMCAmJiBoZXJlLnZhbCA8IDB4N2YgP1xuICAgICAgICAvLyAgICAgICAgXCJpbmZsYXRlOiAgICAgICAgIGxpdGVyYWwgJyVjJ1xcblwiIDpcbiAgICAgICAgLy8gICAgICAgIFwiaW5mbGF0ZTogICAgICAgICBsaXRlcmFsIDB4JTAyeFxcblwiLCBoZXJlLnZhbCkpO1xuICAgICAgICBvdXRwdXRbX291dCsrXSA9IGhlcmUgJiAweGZmZmYvKmhlcmUudmFsKi87XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChvcCAmIDE2KSB7ICAgICAgICAgICAgICAgICAgICAgLyogbGVuZ3RoIGJhc2UgKi9cbiAgICAgICAgbGVuID0gaGVyZSAmIDB4ZmZmZi8qaGVyZS52YWwqLztcbiAgICAgICAgb3AgJj0gMTU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGV4dHJhIGJpdHMgKi9cbiAgICAgICAgaWYgKG9wKSB7XG4gICAgICAgICAgaWYgKGJpdHMgPCBvcCkge1xuICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICB9XG4gICAgICAgICAgbGVuICs9IGhvbGQgJiAoKDEgPDwgb3ApIC0gMSk7XG4gICAgICAgICAgaG9sZCA+Pj49IG9wO1xuICAgICAgICAgIGJpdHMgLT0gb3A7XG4gICAgICAgIH1cbiAgICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgICBsZW5ndGggJXVcXG5cIiwgbGVuKSk7XG4gICAgICAgIGlmIChiaXRzIDwgMTUpIHtcbiAgICAgICAgICBob2xkICs9IGlucHV0W19pbisrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICBob2xkICs9IGlucHV0W19pbisrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgfVxuICAgICAgICBoZXJlID0gZGNvZGVbaG9sZCAmIGRtYXNrXTtcblxuICAgICAgICBkb2Rpc3Q6XG4gICAgICAgIGZvciAoOzspIHsgLy8gZ290byBlbXVsYXRpb25cbiAgICAgICAgICBvcCA9IGhlcmUgPj4+IDI0LypoZXJlLmJpdHMqLztcbiAgICAgICAgICBob2xkID4+Pj0gb3A7XG4gICAgICAgICAgYml0cyAtPSBvcDtcbiAgICAgICAgICBvcCA9IChoZXJlID4+PiAxNikgJiAweGZmLypoZXJlLm9wKi87XG5cbiAgICAgICAgICBpZiAob3AgJiAxNikgeyAgICAgICAgICAgICAgICAgICAgICAvKiBkaXN0YW5jZSBiYXNlICovXG4gICAgICAgICAgICBkaXN0ID0gaGVyZSAmIDB4ZmZmZi8qaGVyZS52YWwqLztcbiAgICAgICAgICAgIG9wICY9IDE1OyAgICAgICAgICAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGV4dHJhIGJpdHMgKi9cbiAgICAgICAgICAgIGlmIChiaXRzIDwgb3ApIHtcbiAgICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgICAgICBpZiAoYml0cyA8IG9wKSB7XG4gICAgICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgICAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRpc3QgKz0gaG9sZCAmICgoMSA8PCBvcCkgLSAxKTtcbi8vI2lmZGVmIElORkxBVEVfU1RSSUNUXG4gICAgICAgICAgICBpZiAoZGlzdCA+IGRtYXgpIHtcbiAgICAgICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBkaXN0YW5jZSB0b28gZmFyIGJhY2snO1xuICAgICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgICAgICBicmVhayB0b3A7XG4gICAgICAgICAgICB9XG4vLyNlbmRpZlxuICAgICAgICAgICAgaG9sZCA+Pj49IG9wO1xuICAgICAgICAgICAgYml0cyAtPSBvcDtcbiAgICAgICAgICAgIC8vVHJhY2V2digoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgICAgZGlzdGFuY2UgJXVcXG5cIiwgZGlzdCkpO1xuICAgICAgICAgICAgb3AgPSBfb3V0IC0gYmVnOyAgICAgICAgICAgICAgICAvKiBtYXggZGlzdGFuY2UgaW4gb3V0cHV0ICovXG4gICAgICAgICAgICBpZiAoZGlzdCA+IG9wKSB7ICAgICAgICAgICAgICAgIC8qIHNlZSBpZiBjb3B5IGZyb20gd2luZG93ICovXG4gICAgICAgICAgICAgIG9wID0gZGlzdCAtIG9wOyAgICAgICAgICAgICAgIC8qIGRpc3RhbmNlIGJhY2sgaW4gd2luZG93ICovXG4gICAgICAgICAgICAgIGlmIChvcCA+IHdoYXZlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlLnNhbmUpIHtcbiAgICAgICAgICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgZGlzdGFuY2UgdG9vIGZhciBiYWNrJztcbiAgICAgICAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgICAgICAgICBicmVhayB0b3A7XG4gICAgICAgICAgICAgICAgfVxuXG4vLyAoISkgVGhpcyBibG9jayBpcyBkaXNhYmxlZCBpbiB6bGliIGRlZmF1bHRzLFxuLy8gZG9uJ3QgZW5hYmxlIGl0IGZvciBiaW5hcnkgY29tcGF0aWJpbGl0eVxuLy8jaWZkZWYgSU5GTEFURV9BTExPV19JTlZBTElEX0RJU1RBTkNFX1RPT0ZBUl9BUlJSXG4vLyAgICAgICAgICAgICAgICBpZiAobGVuIDw9IG9wIC0gd2hhdmUpIHtcbi8vICAgICAgICAgICAgICAgICAgZG8ge1xuLy8gICAgICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gMDtcbi8vICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoLS1sZW4pO1xuLy8gICAgICAgICAgICAgICAgICBjb250aW51ZSB0b3A7XG4vLyAgICAgICAgICAgICAgICB9XG4vLyAgICAgICAgICAgICAgICBsZW4gLT0gb3AgLSB3aGF2ZTtcbi8vICAgICAgICAgICAgICAgIGRvIHtcbi8vICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSAwO1xuLy8gICAgICAgICAgICAgICAgfSB3aGlsZSAoLS1vcCA+IHdoYXZlKTtcbi8vICAgICAgICAgICAgICAgIGlmIChvcCA9PT0gMCkge1xuLy8gICAgICAgICAgICAgICAgICBmcm9tID0gX291dCAtIGRpc3Q7XG4vLyAgICAgICAgICAgICAgICAgIGRvIHtcbi8vICAgICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdO1xuLy8gICAgICAgICAgICAgICAgICB9IHdoaWxlICgtLWxlbik7XG4vLyAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIHRvcDtcbi8vICAgICAgICAgICAgICAgIH1cbi8vI2VuZGlmXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZnJvbSA9IDA7IC8vIHdpbmRvdyBpbmRleFxuICAgICAgICAgICAgICBmcm9tX3NvdXJjZSA9IHNfd2luZG93O1xuICAgICAgICAgICAgICBpZiAod25leHQgPT09IDApIHsgICAgICAgICAgIC8qIHZlcnkgY29tbW9uIGNhc2UgKi9cbiAgICAgICAgICAgICAgICBmcm9tICs9IHdzaXplIC0gb3A7XG4gICAgICAgICAgICAgICAgaWYgKG9wIDwgbGVuKSB7ICAgICAgICAgLyogc29tZSBmcm9tIHdpbmRvdyAqL1xuICAgICAgICAgICAgICAgICAgbGVuIC09IG9wO1xuICAgICAgICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IHNfd2luZG93W2Zyb20rK107XG4gICAgICAgICAgICAgICAgICB9IHdoaWxlICgtLW9wKTtcbiAgICAgICAgICAgICAgICAgIGZyb20gPSBfb3V0IC0gZGlzdDsgIC8qIHJlc3QgZnJvbSBvdXRwdXQgKi9cbiAgICAgICAgICAgICAgICAgIGZyb21fc291cmNlID0gb3V0cHV0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIGlmICh3bmV4dCA8IG9wKSB7ICAgICAgLyogd3JhcCBhcm91bmQgd2luZG93ICovXG4gICAgICAgICAgICAgICAgZnJvbSArPSB3c2l6ZSArIHduZXh0IC0gb3A7XG4gICAgICAgICAgICAgICAgb3AgLT0gd25leHQ7XG4gICAgICAgICAgICAgICAgaWYgKG9wIDwgbGVuKSB7ICAgICAgICAgLyogc29tZSBmcm9tIGVuZCBvZiB3aW5kb3cgKi9cbiAgICAgICAgICAgICAgICAgIGxlbiAtPSBvcDtcbiAgICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBzX3dpbmRvd1tmcm9tKytdO1xuICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoLS1vcCk7XG4gICAgICAgICAgICAgICAgICBmcm9tID0gMDtcbiAgICAgICAgICAgICAgICAgIGlmICh3bmV4dCA8IGxlbikgeyAgLyogc29tZSBmcm9tIHN0YXJ0IG9mIHdpbmRvdyAqL1xuICAgICAgICAgICAgICAgICAgICBvcCA9IHduZXh0O1xuICAgICAgICAgICAgICAgICAgICBsZW4gLT0gb3A7XG4gICAgICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IHNfd2luZG93W2Zyb20rK107XG4gICAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKC0tb3ApO1xuICAgICAgICAgICAgICAgICAgICBmcm9tID0gX291dCAtIGRpc3Q7ICAgICAgLyogcmVzdCBmcm9tIG91dHB1dCAqL1xuICAgICAgICAgICAgICAgICAgICBmcm9tX3NvdXJjZSA9IG91dHB1dDtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgIC8qIGNvbnRpZ3VvdXMgaW4gd2luZG93ICovXG4gICAgICAgICAgICAgICAgZnJvbSArPSB3bmV4dCAtIG9wO1xuICAgICAgICAgICAgICAgIGlmIChvcCA8IGxlbikgeyAgICAgICAgIC8qIHNvbWUgZnJvbSB3aW5kb3cgKi9cbiAgICAgICAgICAgICAgICAgIGxlbiAtPSBvcDtcbiAgICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBzX3dpbmRvd1tmcm9tKytdO1xuICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoLS1vcCk7XG4gICAgICAgICAgICAgICAgICBmcm9tID0gX291dCAtIGRpc3Q7ICAvKiByZXN0IGZyb20gb3V0cHV0ICovXG4gICAgICAgICAgICAgICAgICBmcm9tX3NvdXJjZSA9IG91dHB1dDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgd2hpbGUgKGxlbiA+IDIpIHtcbiAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IGZyb21fc291cmNlW2Zyb20rK107XG4gICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBmcm9tX3NvdXJjZVtmcm9tKytdO1xuICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gZnJvbV9zb3VyY2VbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICBsZW4gLT0gMztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAobGVuKSB7XG4gICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBmcm9tX3NvdXJjZVtmcm9tKytdO1xuICAgICAgICAgICAgICAgIGlmIChsZW4gPiAxKSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IGZyb21fc291cmNlW2Zyb20rK107XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgZnJvbSA9IF9vdXQgLSBkaXN0OyAgICAgICAgICAvKiBjb3B5IGRpcmVjdCBmcm9tIG91dHB1dCAqL1xuICAgICAgICAgICAgICBkbyB7ICAgICAgICAgICAgICAgICAgICAgICAgLyogbWluaW11bSBsZW5ndGggaXMgdGhyZWUgKi9cbiAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdO1xuICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gb3V0cHV0W2Zyb20rK107XG4gICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBvdXRwdXRbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICBsZW4gLT0gMztcbiAgICAgICAgICAgICAgfSB3aGlsZSAobGVuID4gMik7XG4gICAgICAgICAgICAgIGlmIChsZW4pIHtcbiAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdO1xuICAgICAgICAgICAgICAgIGlmIChsZW4gPiAxKSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmICgob3AgJiA2NCkgPT09IDApIHsgICAgICAgICAgLyogMm5kIGxldmVsIGRpc3RhbmNlIGNvZGUgKi9cbiAgICAgICAgICAgIGhlcmUgPSBkY29kZVsoaGVyZSAmIDB4ZmZmZikvKmhlcmUudmFsKi8gKyAoaG9sZCAmICgoMSA8PCBvcCkgLSAxKSldO1xuICAgICAgICAgICAgY29udGludWUgZG9kaXN0O1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgZGlzdGFuY2UgY29kZSc7XG4gICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgICAgYnJlYWsgdG9wO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrOyAvLyBuZWVkIHRvIGVtdWxhdGUgZ290byB2aWEgXCJjb250aW51ZVwiXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKChvcCAmIDY0KSA9PT0gMCkgeyAgICAgICAgICAgICAgLyogMm5kIGxldmVsIGxlbmd0aCBjb2RlICovXG4gICAgICAgIGhlcmUgPSBsY29kZVsoaGVyZSAmIDB4ZmZmZikvKmhlcmUudmFsKi8gKyAoaG9sZCAmICgoMSA8PCBvcCkgLSAxKSldO1xuICAgICAgICBjb250aW51ZSBkb2xlbjtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKG9wICYgMzIpIHsgICAgICAgICAgICAgICAgICAgICAvKiBlbmQtb2YtYmxvY2sgKi9cbiAgICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgICBlbmQgb2YgYmxvY2tcXG5cIikpO1xuICAgICAgICBzdGF0ZS5tb2RlID0gVFlQRTtcbiAgICAgICAgYnJlYWsgdG9wO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgbGl0ZXJhbC9sZW5ndGggY29kZSc7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgIGJyZWFrIHRvcDtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7IC8vIG5lZWQgdG8gZW11bGF0ZSBnb3RvIHZpYSBcImNvbnRpbnVlXCJcbiAgICB9XG4gIH0gd2hpbGUgKF9pbiA8IGxhc3QgJiYgX291dCA8IGVuZCk7XG5cbiAgLyogcmV0dXJuIHVudXNlZCBieXRlcyAob24gZW50cnksIGJpdHMgPCA4LCBzbyBpbiB3b24ndCBnbyB0b28gZmFyIGJhY2spICovXG4gIGxlbiA9IGJpdHMgPj4gMztcbiAgX2luIC09IGxlbjtcbiAgYml0cyAtPSBsZW4gPDwgMztcbiAgaG9sZCAmPSAoMSA8PCBiaXRzKSAtIDE7XG5cbiAgLyogdXBkYXRlIHN0YXRlIGFuZCByZXR1cm4gKi9cbiAgc3RybS5uZXh0X2luID0gX2luO1xuICBzdHJtLm5leHRfb3V0ID0gX291dDtcbiAgc3RybS5hdmFpbF9pbiA9IChfaW4gPCBsYXN0ID8gNSArIChsYXN0IC0gX2luKSA6IDUgLSAoX2luIC0gbGFzdCkpO1xuICBzdHJtLmF2YWlsX291dCA9IChfb3V0IDwgZW5kID8gMjU3ICsgKGVuZCAtIF9vdXQpIDogMjU3IC0gKF9vdXQgLSBlbmQpKTtcbiAgc3RhdGUuaG9sZCA9IGhvbGQ7XG4gIHN0YXRlLmJpdHMgPSBiaXRzO1xuICByZXR1cm47XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXJcbi8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luXG4vL1xuLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWRcbi8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlc1xuLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSxcbi8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXRcbi8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczpcbi8vXG4vLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdFxuLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZVxuLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmVcbi8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC5cbi8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlXG4vLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS5cbi8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uXG5cbnZhciB1dGlscyAgICAgICAgID0gcmVxdWlyZSgnLi4vdXRpbHMvY29tbW9uJyk7XG52YXIgYWRsZXIzMiAgICAgICA9IHJlcXVpcmUoJy4vYWRsZXIzMicpO1xudmFyIGNyYzMyICAgICAgICAgPSByZXF1aXJlKCcuL2NyYzMyJyk7XG52YXIgaW5mbGF0ZV9mYXN0ICA9IHJlcXVpcmUoJy4vaW5mZmFzdCcpO1xudmFyIGluZmxhdGVfdGFibGUgPSByZXF1aXJlKCcuL2luZnRyZWVzJyk7XG5cbnZhciBDT0RFUyA9IDA7XG52YXIgTEVOUyA9IDE7XG52YXIgRElTVFMgPSAyO1xuXG4vKiBQdWJsaWMgY29uc3RhbnRzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cblxuXG4vKiBBbGxvd2VkIGZsdXNoIHZhbHVlczsgc2VlIGRlZmxhdGUoKSBhbmQgaW5mbGF0ZSgpIGJlbG93IGZvciBkZXRhaWxzICovXG4vL3ZhciBaX05PX0ZMVVNIICAgICAgPSAwO1xuLy92YXIgWl9QQVJUSUFMX0ZMVVNIID0gMTtcbi8vdmFyIFpfU1lOQ19GTFVTSCAgICA9IDI7XG4vL3ZhciBaX0ZVTExfRkxVU0ggICAgPSAzO1xudmFyIFpfRklOSVNIICAgICAgICA9IDQ7XG52YXIgWl9CTE9DSyAgICAgICAgID0gNTtcbnZhciBaX1RSRUVTICAgICAgICAgPSA2O1xuXG5cbi8qIFJldHVybiBjb2RlcyBmb3IgdGhlIGNvbXByZXNzaW9uL2RlY29tcHJlc3Npb24gZnVuY3Rpb25zLiBOZWdhdGl2ZSB2YWx1ZXNcbiAqIGFyZSBlcnJvcnMsIHBvc2l0aXZlIHZhbHVlcyBhcmUgdXNlZCBmb3Igc3BlY2lhbCBidXQgbm9ybWFsIGV2ZW50cy5cbiAqL1xudmFyIFpfT0sgICAgICAgICAgICA9IDA7XG52YXIgWl9TVFJFQU1fRU5EICAgID0gMTtcbnZhciBaX05FRURfRElDVCAgICAgPSAyO1xuLy92YXIgWl9FUlJOTyAgICAgICAgID0gLTE7XG52YXIgWl9TVFJFQU1fRVJST1IgID0gLTI7XG52YXIgWl9EQVRBX0VSUk9SICAgID0gLTM7XG52YXIgWl9NRU1fRVJST1IgICAgID0gLTQ7XG52YXIgWl9CVUZfRVJST1IgICAgID0gLTU7XG4vL3ZhciBaX1ZFUlNJT05fRVJST1IgPSAtNjtcblxuLyogVGhlIGRlZmxhdGUgY29tcHJlc3Npb24gbWV0aG9kICovXG52YXIgWl9ERUZMQVRFRCAgPSA4O1xuXG5cbi8qIFNUQVRFUyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuXG5cbnZhciAgICBIRUFEID0gMTsgICAgICAgLyogaTogd2FpdGluZyBmb3IgbWFnaWMgaGVhZGVyICovXG52YXIgICAgRkxBR1MgPSAyOyAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIG1ldGhvZCBhbmQgZmxhZ3MgKGd6aXApICovXG52YXIgICAgVElNRSA9IDM7ICAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIG1vZGlmaWNhdGlvbiB0aW1lIChnemlwKSAqL1xudmFyICAgIE9TID0gNDsgICAgICAgICAvKiBpOiB3YWl0aW5nIGZvciBleHRyYSBmbGFncyBhbmQgb3BlcmF0aW5nIHN5c3RlbSAoZ3ppcCkgKi9cbnZhciAgICBFWExFTiA9IDU7ICAgICAgLyogaTogd2FpdGluZyBmb3IgZXh0cmEgbGVuZ3RoIChnemlwKSAqL1xudmFyICAgIEVYVFJBID0gNjsgICAgICAvKiBpOiB3YWl0aW5nIGZvciBleHRyYSBieXRlcyAoZ3ppcCkgKi9cbnZhciAgICBOQU1FID0gNzsgICAgICAgLyogaTogd2FpdGluZyBmb3IgZW5kIG9mIGZpbGUgbmFtZSAoZ3ppcCkgKi9cbnZhciAgICBDT01NRU5UID0gODsgICAgLyogaTogd2FpdGluZyBmb3IgZW5kIG9mIGNvbW1lbnQgKGd6aXApICovXG52YXIgICAgSENSQyA9IDk7ICAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIGhlYWRlciBjcmMgKGd6aXApICovXG52YXIgICAgRElDVElEID0gMTA7ICAgIC8qIGk6IHdhaXRpbmcgZm9yIGRpY3Rpb25hcnkgY2hlY2sgdmFsdWUgKi9cbnZhciAgICBESUNUID0gMTE7ICAgICAgLyogd2FpdGluZyBmb3IgaW5mbGF0ZVNldERpY3Rpb25hcnkoKSBjYWxsICovXG52YXIgICAgICAgIFRZUEUgPSAxMjsgICAgICAvKiBpOiB3YWl0aW5nIGZvciB0eXBlIGJpdHMsIGluY2x1ZGluZyBsYXN0LWZsYWcgYml0ICovXG52YXIgICAgICAgIFRZUEVETyA9IDEzOyAgICAvKiBpOiBzYW1lLCBidXQgc2tpcCBjaGVjayB0byBleGl0IGluZmxhdGUgb24gbmV3IGJsb2NrICovXG52YXIgICAgICAgIFNUT1JFRCA9IDE0OyAgICAvKiBpOiB3YWl0aW5nIGZvciBzdG9yZWQgc2l6ZSAobGVuZ3RoIGFuZCBjb21wbGVtZW50KSAqL1xudmFyICAgICAgICBDT1BZXyA9IDE1OyAgICAgLyogaS9vOiBzYW1lIGFzIENPUFkgYmVsb3csIGJ1dCBvbmx5IGZpcnN0IHRpbWUgaW4gKi9cbnZhciAgICAgICAgQ09QWSA9IDE2OyAgICAgIC8qIGkvbzogd2FpdGluZyBmb3IgaW5wdXQgb3Igb3V0cHV0IHRvIGNvcHkgc3RvcmVkIGJsb2NrICovXG52YXIgICAgICAgIFRBQkxFID0gMTc7ICAgICAvKiBpOiB3YWl0aW5nIGZvciBkeW5hbWljIGJsb2NrIHRhYmxlIGxlbmd0aHMgKi9cbnZhciAgICAgICAgTEVOTEVOUyA9IDE4OyAgIC8qIGk6IHdhaXRpbmcgZm9yIGNvZGUgbGVuZ3RoIGNvZGUgbGVuZ3RocyAqL1xudmFyICAgICAgICBDT0RFTEVOUyA9IDE5OyAgLyogaTogd2FpdGluZyBmb3IgbGVuZ3RoL2xpdCBhbmQgZGlzdGFuY2UgY29kZSBsZW5ndGhzICovXG52YXIgICAgICAgICAgICBMRU5fID0gMjA7ICAgICAgLyogaTogc2FtZSBhcyBMRU4gYmVsb3csIGJ1dCBvbmx5IGZpcnN0IHRpbWUgaW4gKi9cbnZhciAgICAgICAgICAgIExFTiA9IDIxOyAgICAgICAvKiBpOiB3YWl0aW5nIGZvciBsZW5ndGgvbGl0L2VvYiBjb2RlICovXG52YXIgICAgICAgICAgICBMRU5FWFQgPSAyMjsgICAgLyogaTogd2FpdGluZyBmb3IgbGVuZ3RoIGV4dHJhIGJpdHMgKi9cbnZhciAgICAgICAgICAgIERJU1QgPSAyMzsgICAgICAvKiBpOiB3YWl0aW5nIGZvciBkaXN0YW5jZSBjb2RlICovXG52YXIgICAgICAgICAgICBESVNURVhUID0gMjQ7ICAgLyogaTogd2FpdGluZyBmb3IgZGlzdGFuY2UgZXh0cmEgYml0cyAqL1xudmFyICAgICAgICAgICAgTUFUQ0ggPSAyNTsgICAgIC8qIG86IHdhaXRpbmcgZm9yIG91dHB1dCBzcGFjZSB0byBjb3B5IHN0cmluZyAqL1xudmFyICAgICAgICAgICAgTElUID0gMjY7ICAgICAgIC8qIG86IHdhaXRpbmcgZm9yIG91dHB1dCBzcGFjZSB0byB3cml0ZSBsaXRlcmFsICovXG52YXIgICAgQ0hFQ0sgPSAyNzsgICAgIC8qIGk6IHdhaXRpbmcgZm9yIDMyLWJpdCBjaGVjayB2YWx1ZSAqL1xudmFyICAgIExFTkdUSCA9IDI4OyAgICAvKiBpOiB3YWl0aW5nIGZvciAzMi1iaXQgbGVuZ3RoIChnemlwKSAqL1xudmFyICAgIERPTkUgPSAyOTsgICAgICAvKiBmaW5pc2hlZCBjaGVjaywgZG9uZSAtLSByZW1haW4gaGVyZSB1bnRpbCByZXNldCAqL1xudmFyICAgIEJBRCA9IDMwOyAgICAgICAvKiBnb3QgYSBkYXRhIGVycm9yIC0tIHJlbWFpbiBoZXJlIHVudGlsIHJlc2V0ICovXG52YXIgICAgTUVNID0gMzE7ICAgICAgIC8qIGdvdCBhbiBpbmZsYXRlKCkgbWVtb3J5IGVycm9yIC0tIHJlbWFpbiBoZXJlIHVudGlsIHJlc2V0ICovXG52YXIgICAgU1lOQyA9IDMyOyAgICAgIC8qIGxvb2tpbmcgZm9yIHN5bmNocm9uaXphdGlvbiBieXRlcyB0byByZXN0YXJ0IGluZmxhdGUoKSAqL1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuXG5cblxudmFyIEVOT1VHSF9MRU5TID0gODUyO1xudmFyIEVOT1VHSF9ESVNUUyA9IDU5Mjtcbi8vdmFyIEVOT1VHSCA9ICAoRU5PVUdIX0xFTlMrRU5PVUdIX0RJU1RTKTtcblxudmFyIE1BWF9XQklUUyA9IDE1O1xuLyogMzJLIExaNzcgd2luZG93ICovXG52YXIgREVGX1dCSVRTID0gTUFYX1dCSVRTO1xuXG5cbmZ1bmN0aW9uIHpzd2FwMzIocSkge1xuICByZXR1cm4gICgoKHEgPj4+IDI0KSAmIDB4ZmYpICtcbiAgICAgICAgICAoKHEgPj4+IDgpICYgMHhmZjAwKSArXG4gICAgICAgICAgKChxICYgMHhmZjAwKSA8PCA4KSArXG4gICAgICAgICAgKChxICYgMHhmZikgPDwgMjQpKTtcbn1cblxuXG5mdW5jdGlvbiBJbmZsYXRlU3RhdGUoKSB7XG4gIHRoaXMubW9kZSA9IDA7ICAgICAgICAgICAgIC8qIGN1cnJlbnQgaW5mbGF0ZSBtb2RlICovXG4gIHRoaXMubGFzdCA9IGZhbHNlOyAgICAgICAgICAvKiB0cnVlIGlmIHByb2Nlc3NpbmcgbGFzdCBibG9jayAqL1xuICB0aGlzLndyYXAgPSAwOyAgICAgICAgICAgICAgLyogYml0IDAgdHJ1ZSBmb3IgemxpYiwgYml0IDEgdHJ1ZSBmb3IgZ3ppcCAqL1xuICB0aGlzLmhhdmVkaWN0ID0gZmFsc2U7ICAgICAgLyogdHJ1ZSBpZiBkaWN0aW9uYXJ5IHByb3ZpZGVkICovXG4gIHRoaXMuZmxhZ3MgPSAwOyAgICAgICAgICAgICAvKiBnemlwIGhlYWRlciBtZXRob2QgYW5kIGZsYWdzICgwIGlmIHpsaWIpICovXG4gIHRoaXMuZG1heCA9IDA7ICAgICAgICAgICAgICAvKiB6bGliIGhlYWRlciBtYXggZGlzdGFuY2UgKElORkxBVEVfU1RSSUNUKSAqL1xuICB0aGlzLmNoZWNrID0gMDsgICAgICAgICAgICAgLyogcHJvdGVjdGVkIGNvcHkgb2YgY2hlY2sgdmFsdWUgKi9cbiAgdGhpcy50b3RhbCA9IDA7ICAgICAgICAgICAgIC8qIHByb3RlY3RlZCBjb3B5IG9mIG91dHB1dCBjb3VudCAqL1xuICAvLyBUT0RPOiBtYXkgYmUge31cbiAgdGhpcy5oZWFkID0gbnVsbDsgICAgICAgICAgIC8qIHdoZXJlIHRvIHNhdmUgZ3ppcCBoZWFkZXIgaW5mb3JtYXRpb24gKi9cblxuICAvKiBzbGlkaW5nIHdpbmRvdyAqL1xuICB0aGlzLndiaXRzID0gMDsgICAgICAgICAgICAgLyogbG9nIGJhc2UgMiBvZiByZXF1ZXN0ZWQgd2luZG93IHNpemUgKi9cbiAgdGhpcy53c2l6ZSA9IDA7ICAgICAgICAgICAgIC8qIHdpbmRvdyBzaXplIG9yIHplcm8gaWYgbm90IHVzaW5nIHdpbmRvdyAqL1xuICB0aGlzLndoYXZlID0gMDsgICAgICAgICAgICAgLyogdmFsaWQgYnl0ZXMgaW4gdGhlIHdpbmRvdyAqL1xuICB0aGlzLnduZXh0ID0gMDsgICAgICAgICAgICAgLyogd2luZG93IHdyaXRlIGluZGV4ICovXG4gIHRoaXMud2luZG93ID0gbnVsbDsgICAgICAgICAvKiBhbGxvY2F0ZWQgc2xpZGluZyB3aW5kb3csIGlmIG5lZWRlZCAqL1xuXG4gIC8qIGJpdCBhY2N1bXVsYXRvciAqL1xuICB0aGlzLmhvbGQgPSAwOyAgICAgICAgICAgICAgLyogaW5wdXQgYml0IGFjY3VtdWxhdG9yICovXG4gIHRoaXMuYml0cyA9IDA7ICAgICAgICAgICAgICAvKiBudW1iZXIgb2YgYml0cyBpbiBcImluXCIgKi9cblxuICAvKiBmb3Igc3RyaW5nIGFuZCBzdG9yZWQgYmxvY2sgY29weWluZyAqL1xuICB0aGlzLmxlbmd0aCA9IDA7ICAgICAgICAgICAgLyogbGl0ZXJhbCBvciBsZW5ndGggb2YgZGF0YSB0byBjb3B5ICovXG4gIHRoaXMub2Zmc2V0ID0gMDsgICAgICAgICAgICAvKiBkaXN0YW5jZSBiYWNrIHRvIGNvcHkgc3RyaW5nIGZyb20gKi9cblxuICAvKiBmb3IgdGFibGUgYW5kIGNvZGUgZGVjb2RpbmcgKi9cbiAgdGhpcy5leHRyYSA9IDA7ICAgICAgICAgICAgIC8qIGV4dHJhIGJpdHMgbmVlZGVkICovXG5cbiAgLyogZml4ZWQgYW5kIGR5bmFtaWMgY29kZSB0YWJsZXMgKi9cbiAgdGhpcy5sZW5jb2RlID0gbnVsbDsgICAgICAgICAgLyogc3RhcnRpbmcgdGFibGUgZm9yIGxlbmd0aC9saXRlcmFsIGNvZGVzICovXG4gIHRoaXMuZGlzdGNvZGUgPSBudWxsOyAgICAgICAgIC8qIHN0YXJ0aW5nIHRhYmxlIGZvciBkaXN0YW5jZSBjb2RlcyAqL1xuICB0aGlzLmxlbmJpdHMgPSAwOyAgICAgICAgICAgLyogaW5kZXggYml0cyBmb3IgbGVuY29kZSAqL1xuICB0aGlzLmRpc3RiaXRzID0gMDsgICAgICAgICAgLyogaW5kZXggYml0cyBmb3IgZGlzdGNvZGUgKi9cblxuICAvKiBkeW5hbWljIHRhYmxlIGJ1aWxkaW5nICovXG4gIHRoaXMubmNvZGUgPSAwOyAgICAgICAgICAgICAvKiBudW1iZXIgb2YgY29kZSBsZW5ndGggY29kZSBsZW5ndGhzICovXG4gIHRoaXMubmxlbiA9IDA7ICAgICAgICAgICAgICAvKiBudW1iZXIgb2YgbGVuZ3RoIGNvZGUgbGVuZ3RocyAqL1xuICB0aGlzLm5kaXN0ID0gMDsgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGRpc3RhbmNlIGNvZGUgbGVuZ3RocyAqL1xuICB0aGlzLmhhdmUgPSAwOyAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGNvZGUgbGVuZ3RocyBpbiBsZW5zW10gKi9cbiAgdGhpcy5uZXh0ID0gbnVsbDsgICAgICAgICAgICAgIC8qIG5leHQgYXZhaWxhYmxlIHNwYWNlIGluIGNvZGVzW10gKi9cblxuICB0aGlzLmxlbnMgPSBuZXcgdXRpbHMuQnVmMTYoMzIwKTsgLyogdGVtcG9yYXJ5IHN0b3JhZ2UgZm9yIGNvZGUgbGVuZ3RocyAqL1xuICB0aGlzLndvcmsgPSBuZXcgdXRpbHMuQnVmMTYoMjg4KTsgLyogd29yayBhcmVhIGZvciBjb2RlIHRhYmxlIGJ1aWxkaW5nICovXG5cbiAgLypcbiAgIGJlY2F1c2Ugd2UgZG9uJ3QgaGF2ZSBwb2ludGVycyBpbiBqcywgd2UgdXNlIGxlbmNvZGUgYW5kIGRpc3Rjb2RlIGRpcmVjdGx5XG4gICBhcyBidWZmZXJzIHNvIHdlIGRvbid0IG5lZWQgY29kZXNcbiAgKi9cbiAgLy90aGlzLmNvZGVzID0gbmV3IHV0aWxzLkJ1ZjMyKEVOT1VHSCk7ICAgICAgIC8qIHNwYWNlIGZvciBjb2RlIHRhYmxlcyAqL1xuICB0aGlzLmxlbmR5biA9IG51bGw7ICAgICAgICAgICAgICAvKiBkeW5hbWljIHRhYmxlIGZvciBsZW5ndGgvbGl0ZXJhbCBjb2RlcyAoSlMgc3BlY2lmaWMpICovXG4gIHRoaXMuZGlzdGR5biA9IG51bGw7ICAgICAgICAgICAgIC8qIGR5bmFtaWMgdGFibGUgZm9yIGRpc3RhbmNlIGNvZGVzIChKUyBzcGVjaWZpYykgKi9cbiAgdGhpcy5zYW5lID0gMDsgICAgICAgICAgICAgICAgICAgLyogaWYgZmFsc2UsIGFsbG93IGludmFsaWQgZGlzdGFuY2UgdG9vIGZhciAqL1xuICB0aGlzLmJhY2sgPSAwOyAgICAgICAgICAgICAgICAgICAvKiBiaXRzIGJhY2sgb2YgbGFzdCB1bnByb2Nlc3NlZCBsZW5ndGgvbGl0ICovXG4gIHRoaXMud2FzID0gMDsgICAgICAgICAgICAgICAgICAgIC8qIGluaXRpYWwgbGVuZ3RoIG9mIG1hdGNoICovXG59XG5cbmZ1bmN0aW9uIGluZmxhdGVSZXNldEtlZXAoc3RybSkge1xuICB2YXIgc3RhdGU7XG5cbiAgaWYgKCFzdHJtIHx8ICFzdHJtLnN0YXRlKSB7IHJldHVybiBaX1NUUkVBTV9FUlJPUjsgfVxuICBzdGF0ZSA9IHN0cm0uc3RhdGU7XG4gIHN0cm0udG90YWxfaW4gPSBzdHJtLnRvdGFsX291dCA9IHN0YXRlLnRvdGFsID0gMDtcbiAgc3RybS5tc2cgPSAnJzsgLypaX05VTEwqL1xuICBpZiAoc3RhdGUud3JhcCkgeyAgICAgICAvKiB0byBzdXBwb3J0IGlsbC1jb25jZWl2ZWQgSmF2YSB0ZXN0IHN1aXRlICovXG4gICAgc3RybS5hZGxlciA9IHN0YXRlLndyYXAgJiAxO1xuICB9XG4gIHN0YXRlLm1vZGUgPSBIRUFEO1xuICBzdGF0ZS5sYXN0ID0gMDtcbiAgc3RhdGUuaGF2ZWRpY3QgPSAwO1xuICBzdGF0ZS5kbWF4ID0gMzI3Njg7XG4gIHN0YXRlLmhlYWQgPSBudWxsLypaX05VTEwqLztcbiAgc3RhdGUuaG9sZCA9IDA7XG4gIHN0YXRlLmJpdHMgPSAwO1xuICAvL3N0YXRlLmxlbmNvZGUgPSBzdGF0ZS5kaXN0Y29kZSA9IHN0YXRlLm5leHQgPSBzdGF0ZS5jb2RlcztcbiAgc3RhdGUubGVuY29kZSA9IHN0YXRlLmxlbmR5biA9IG5ldyB1dGlscy5CdWYzMihFTk9VR0hfTEVOUyk7XG4gIHN0YXRlLmRpc3Rjb2RlID0gc3RhdGUuZGlzdGR5biA9IG5ldyB1dGlscy5CdWYzMihFTk9VR0hfRElTVFMpO1xuXG4gIHN0YXRlLnNhbmUgPSAxO1xuICBzdGF0ZS5iYWNrID0gLTE7XG4gIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogcmVzZXRcXG5cIikpO1xuICByZXR1cm4gWl9PSztcbn1cblxuZnVuY3Rpb24gaW5mbGF0ZVJlc2V0KHN0cm0pIHtcbiAgdmFyIHN0YXRlO1xuXG4gIGlmICghc3RybSB8fCAhc3RybS5zdGF0ZSkgeyByZXR1cm4gWl9TVFJFQU1fRVJST1I7IH1cbiAgc3RhdGUgPSBzdHJtLnN0YXRlO1xuICBzdGF0ZS53c2l6ZSA9IDA7XG4gIHN0YXRlLndoYXZlID0gMDtcbiAgc3RhdGUud25leHQgPSAwO1xuICByZXR1cm4gaW5mbGF0ZVJlc2V0S2VlcChzdHJtKTtcblxufVxuXG5mdW5jdGlvbiBpbmZsYXRlUmVzZXQyKHN0cm0sIHdpbmRvd0JpdHMpIHtcbiAgdmFyIHdyYXA7XG4gIHZhciBzdGF0ZTtcblxuICAvKiBnZXQgdGhlIHN0YXRlICovXG4gIGlmICghc3RybSB8fCAhc3RybS5zdGF0ZSkgeyByZXR1cm4gWl9TVFJFQU1fRVJST1I7IH1cbiAgc3RhdGUgPSBzdHJtLnN0YXRlO1xuXG4gIC8qIGV4dHJhY3Qgd3JhcCByZXF1ZXN0IGZyb20gd2luZG93Qml0cyBwYXJhbWV0ZXIgKi9cbiAgaWYgKHdpbmRvd0JpdHMgPCAwKSB7XG4gICAgd3JhcCA9IDA7XG4gICAgd2luZG93Qml0cyA9IC13aW5kb3dCaXRzO1xuICB9XG4gIGVsc2Uge1xuICAgIHdyYXAgPSAod2luZG93Qml0cyA+PiA0KSArIDE7XG4gICAgaWYgKHdpbmRvd0JpdHMgPCA0OCkge1xuICAgICAgd2luZG93Qml0cyAmPSAxNTtcbiAgICB9XG4gIH1cblxuICAvKiBzZXQgbnVtYmVyIG9mIHdpbmRvdyBiaXRzLCBmcmVlIHdpbmRvdyBpZiBkaWZmZXJlbnQgKi9cbiAgaWYgKHdpbmRvd0JpdHMgJiYgKHdpbmRvd0JpdHMgPCA4IHx8IHdpbmRvd0JpdHMgPiAxNSkpIHtcbiAgICByZXR1cm4gWl9TVFJFQU1fRVJST1I7XG4gIH1cbiAgaWYgKHN0YXRlLndpbmRvdyAhPT0gbnVsbCAmJiBzdGF0ZS53Yml0cyAhPT0gd2luZG93Qml0cykge1xuICAgIHN0YXRlLndpbmRvdyA9IG51bGw7XG4gIH1cblxuICAvKiB1cGRhdGUgc3RhdGUgYW5kIHJlc2V0IHRoZSByZXN0IG9mIGl0ICovXG4gIHN0YXRlLndyYXAgPSB3cmFwO1xuICBzdGF0ZS53Yml0cyA9IHdpbmRvd0JpdHM7XG4gIHJldHVybiBpbmZsYXRlUmVzZXQoc3RybSk7XG59XG5cbmZ1bmN0aW9uIGluZmxhdGVJbml0MihzdHJtLCB3aW5kb3dCaXRzKSB7XG4gIHZhciByZXQ7XG4gIHZhciBzdGF0ZTtcblxuICBpZiAoIXN0cm0pIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SOyB9XG4gIC8vc3RybS5tc2cgPSBaX05VTEw7ICAgICAgICAgICAgICAgICAvKiBpbiBjYXNlIHdlIHJldHVybiBhbiBlcnJvciAqL1xuXG4gIHN0YXRlID0gbmV3IEluZmxhdGVTdGF0ZSgpO1xuXG4gIC8vaWYgKHN0YXRlID09PSBaX05VTEwpIHJldHVybiBaX01FTV9FUlJPUjtcbiAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiBhbGxvY2F0ZWRcXG5cIikpO1xuICBzdHJtLnN0YXRlID0gc3RhdGU7XG4gIHN0YXRlLndpbmRvdyA9IG51bGwvKlpfTlVMTCovO1xuICByZXQgPSBpbmZsYXRlUmVzZXQyKHN0cm0sIHdpbmRvd0JpdHMpO1xuICBpZiAocmV0ICE9PSBaX09LKSB7XG4gICAgc3RybS5zdGF0ZSA9IG51bGwvKlpfTlVMTCovO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGluZmxhdGVJbml0KHN0cm0pIHtcbiAgcmV0dXJuIGluZmxhdGVJbml0MihzdHJtLCBERUZfV0JJVFMpO1xufVxuXG5cbi8qXG4gUmV0dXJuIHN0YXRlIHdpdGggbGVuZ3RoIGFuZCBkaXN0YW5jZSBkZWNvZGluZyB0YWJsZXMgYW5kIGluZGV4IHNpemVzIHNldCB0b1xuIGZpeGVkIGNvZGUgZGVjb2RpbmcuICBOb3JtYWxseSB0aGlzIHJldHVybnMgZml4ZWQgdGFibGVzIGZyb20gaW5mZml4ZWQuaC5cbiBJZiBCVUlMREZJWEVEIGlzIGRlZmluZWQsIHRoZW4gaW5zdGVhZCB0aGlzIHJvdXRpbmUgYnVpbGRzIHRoZSB0YWJsZXMgdGhlXG4gZmlyc3QgdGltZSBpdCdzIGNhbGxlZCwgYW5kIHJldHVybnMgdGhvc2UgdGFibGVzIHRoZSBmaXJzdCB0aW1lIGFuZFxuIHRoZXJlYWZ0ZXIuICBUaGlzIHJlZHVjZXMgdGhlIHNpemUgb2YgdGhlIGNvZGUgYnkgYWJvdXQgMksgYnl0ZXMsIGluXG4gZXhjaGFuZ2UgZm9yIGEgbGl0dGxlIGV4ZWN1dGlvbiB0aW1lLiAgSG93ZXZlciwgQlVJTERGSVhFRCBzaG91bGQgbm90IGJlXG4gdXNlZCBmb3IgdGhyZWFkZWQgYXBwbGljYXRpb25zLCBzaW5jZSB0aGUgcmV3cml0aW5nIG9mIHRoZSB0YWJsZXMgYW5kIHZpcmdpblxuIG1heSBub3QgYmUgdGhyZWFkLXNhZmUuXG4gKi9cbnZhciB2aXJnaW4gPSB0cnVlO1xuXG52YXIgbGVuZml4LCBkaXN0Zml4OyAvLyBXZSBoYXZlIG5vIHBvaW50ZXJzIGluIEpTLCBzbyBrZWVwIHRhYmxlcyBzZXBhcmF0ZVxuXG5mdW5jdGlvbiBmaXhlZHRhYmxlcyhzdGF0ZSkge1xuICAvKiBidWlsZCBmaXhlZCBodWZmbWFuIHRhYmxlcyBpZiBmaXJzdCBjYWxsIChtYXkgbm90IGJlIHRocmVhZCBzYWZlKSAqL1xuICBpZiAodmlyZ2luKSB7XG4gICAgdmFyIHN5bTtcblxuICAgIGxlbmZpeCA9IG5ldyB1dGlscy5CdWYzMig1MTIpO1xuICAgIGRpc3RmaXggPSBuZXcgdXRpbHMuQnVmMzIoMzIpO1xuXG4gICAgLyogbGl0ZXJhbC9sZW5ndGggdGFibGUgKi9cbiAgICBzeW0gPSAwO1xuICAgIHdoaWxlIChzeW0gPCAxNDQpIHsgc3RhdGUubGVuc1tzeW0rK10gPSA4OyB9XG4gICAgd2hpbGUgKHN5bSA8IDI1NikgeyBzdGF0ZS5sZW5zW3N5bSsrXSA9IDk7IH1cbiAgICB3aGlsZSAoc3ltIDwgMjgwKSB7IHN0YXRlLmxlbnNbc3ltKytdID0gNzsgfVxuICAgIHdoaWxlIChzeW0gPCAyODgpIHsgc3RhdGUubGVuc1tzeW0rK10gPSA4OyB9XG5cbiAgICBpbmZsYXRlX3RhYmxlKExFTlMsICBzdGF0ZS5sZW5zLCAwLCAyODgsIGxlbmZpeCwgICAwLCBzdGF0ZS53b3JrLCB7IGJpdHM6IDkgfSk7XG5cbiAgICAvKiBkaXN0YW5jZSB0YWJsZSAqL1xuICAgIHN5bSA9IDA7XG4gICAgd2hpbGUgKHN5bSA8IDMyKSB7IHN0YXRlLmxlbnNbc3ltKytdID0gNTsgfVxuXG4gICAgaW5mbGF0ZV90YWJsZShESVNUUywgc3RhdGUubGVucywgMCwgMzIsICAgZGlzdGZpeCwgMCwgc3RhdGUud29yaywgeyBiaXRzOiA1IH0pO1xuXG4gICAgLyogZG8gdGhpcyBqdXN0IG9uY2UgKi9cbiAgICB2aXJnaW4gPSBmYWxzZTtcbiAgfVxuXG4gIHN0YXRlLmxlbmNvZGUgPSBsZW5maXg7XG4gIHN0YXRlLmxlbmJpdHMgPSA5O1xuICBzdGF0ZS5kaXN0Y29kZSA9IGRpc3RmaXg7XG4gIHN0YXRlLmRpc3RiaXRzID0gNTtcbn1cblxuXG4vKlxuIFVwZGF0ZSB0aGUgd2luZG93IHdpdGggdGhlIGxhc3Qgd3NpemUgKG5vcm1hbGx5IDMySykgYnl0ZXMgd3JpdHRlbiBiZWZvcmVcbiByZXR1cm5pbmcuICBJZiB3aW5kb3cgZG9lcyBub3QgZXhpc3QgeWV0LCBjcmVhdGUgaXQuICBUaGlzIGlzIG9ubHkgY2FsbGVkXG4gd2hlbiBhIHdpbmRvdyBpcyBhbHJlYWR5IGluIHVzZSwgb3Igd2hlbiBvdXRwdXQgaGFzIGJlZW4gd3JpdHRlbiBkdXJpbmcgdGhpc1xuIGluZmxhdGUgY2FsbCwgYnV0IHRoZSBlbmQgb2YgdGhlIGRlZmxhdGUgc3RyZWFtIGhhcyBub3QgYmVlbiByZWFjaGVkIHlldC5cbiBJdCBpcyBhbHNvIGNhbGxlZCB0byBjcmVhdGUgYSB3aW5kb3cgZm9yIGRpY3Rpb25hcnkgZGF0YSB3aGVuIGEgZGljdGlvbmFyeVxuIGlzIGxvYWRlZC5cblxuIFByb3ZpZGluZyBvdXRwdXQgYnVmZmVycyBsYXJnZXIgdGhhbiAzMksgdG8gaW5mbGF0ZSgpIHNob3VsZCBwcm92aWRlIGEgc3BlZWRcbiBhZHZhbnRhZ2UsIHNpbmNlIG9ubHkgdGhlIGxhc3QgMzJLIG9mIG91dHB1dCBpcyBjb3BpZWQgdG8gdGhlIHNsaWRpbmcgd2luZG93XG4gdXBvbiByZXR1cm4gZnJvbSBpbmZsYXRlKCksIGFuZCBzaW5jZSBhbGwgZGlzdGFuY2VzIGFmdGVyIHRoZSBmaXJzdCAzMksgb2ZcbiBvdXRwdXQgd2lsbCBmYWxsIGluIHRoZSBvdXRwdXQgZGF0YSwgbWFraW5nIG1hdGNoIGNvcGllcyBzaW1wbGVyIGFuZCBmYXN0ZXIuXG4gVGhlIGFkdmFudGFnZSBtYXkgYmUgZGVwZW5kZW50IG9uIHRoZSBzaXplIG9mIHRoZSBwcm9jZXNzb3IncyBkYXRhIGNhY2hlcy5cbiAqL1xuZnVuY3Rpb24gdXBkYXRld2luZG93KHN0cm0sIHNyYywgZW5kLCBjb3B5KSB7XG4gIHZhciBkaXN0O1xuICB2YXIgc3RhdGUgPSBzdHJtLnN0YXRlO1xuXG4gIC8qIGlmIGl0IGhhc24ndCBiZWVuIGRvbmUgYWxyZWFkeSwgYWxsb2NhdGUgc3BhY2UgZm9yIHRoZSB3aW5kb3cgKi9cbiAgaWYgKHN0YXRlLndpbmRvdyA9PT0gbnVsbCkge1xuICAgIHN0YXRlLndzaXplID0gMSA8PCBzdGF0ZS53Yml0cztcbiAgICBzdGF0ZS53bmV4dCA9IDA7XG4gICAgc3RhdGUud2hhdmUgPSAwO1xuXG4gICAgc3RhdGUud2luZG93ID0gbmV3IHV0aWxzLkJ1Zjgoc3RhdGUud3NpemUpO1xuICB9XG5cbiAgLyogY29weSBzdGF0ZS0+d3NpemUgb3IgbGVzcyBvdXRwdXQgYnl0ZXMgaW50byB0aGUgY2lyY3VsYXIgd2luZG93ICovXG4gIGlmIChjb3B5ID49IHN0YXRlLndzaXplKSB7XG4gICAgdXRpbHMuYXJyYXlTZXQoc3RhdGUud2luZG93LCBzcmMsIGVuZCAtIHN0YXRlLndzaXplLCBzdGF0ZS53c2l6ZSwgMCk7XG4gICAgc3RhdGUud25leHQgPSAwO1xuICAgIHN0YXRlLndoYXZlID0gc3RhdGUud3NpemU7XG4gIH1cbiAgZWxzZSB7XG4gICAgZGlzdCA9IHN0YXRlLndzaXplIC0gc3RhdGUud25leHQ7XG4gICAgaWYgKGRpc3QgPiBjb3B5KSB7XG4gICAgICBkaXN0ID0gY29weTtcbiAgICB9XG4gICAgLy96bWVtY3B5KHN0YXRlLT53aW5kb3cgKyBzdGF0ZS0+d25leHQsIGVuZCAtIGNvcHksIGRpc3QpO1xuICAgIHV0aWxzLmFycmF5U2V0KHN0YXRlLndpbmRvdywgc3JjLCBlbmQgLSBjb3B5LCBkaXN0LCBzdGF0ZS53bmV4dCk7XG4gICAgY29weSAtPSBkaXN0O1xuICAgIGlmIChjb3B5KSB7XG4gICAgICAvL3ptZW1jcHkoc3RhdGUtPndpbmRvdywgZW5kIC0gY29weSwgY29weSk7XG4gICAgICB1dGlscy5hcnJheVNldChzdGF0ZS53aW5kb3csIHNyYywgZW5kIC0gY29weSwgY29weSwgMCk7XG4gICAgICBzdGF0ZS53bmV4dCA9IGNvcHk7XG4gICAgICBzdGF0ZS53aGF2ZSA9IHN0YXRlLndzaXplO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHN0YXRlLnduZXh0ICs9IGRpc3Q7XG4gICAgICBpZiAoc3RhdGUud25leHQgPT09IHN0YXRlLndzaXplKSB7IHN0YXRlLnduZXh0ID0gMDsgfVxuICAgICAgaWYgKHN0YXRlLndoYXZlIDwgc3RhdGUud3NpemUpIHsgc3RhdGUud2hhdmUgKz0gZGlzdDsgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gMDtcbn1cblxuZnVuY3Rpb24gaW5mbGF0ZShzdHJtLCBmbHVzaCkge1xuICB2YXIgc3RhdGU7XG4gIHZhciBpbnB1dCwgb3V0cHV0OyAgICAgICAgICAvLyBpbnB1dC9vdXRwdXQgYnVmZmVyc1xuICB2YXIgbmV4dDsgICAgICAgICAgICAgICAgICAgLyogbmV4dCBpbnB1dCBJTkRFWCAqL1xuICB2YXIgcHV0OyAgICAgICAgICAgICAgICAgICAgLyogbmV4dCBvdXRwdXQgSU5ERVggKi9cbiAgdmFyIGhhdmUsIGxlZnQ7ICAgICAgICAgICAgIC8qIGF2YWlsYWJsZSBpbnB1dCBhbmQgb3V0cHV0ICovXG4gIHZhciBob2xkOyAgICAgICAgICAgICAgICAgICAvKiBiaXQgYnVmZmVyICovXG4gIHZhciBiaXRzOyAgICAgICAgICAgICAgICAgICAvKiBiaXRzIGluIGJpdCBidWZmZXIgKi9cbiAgdmFyIF9pbiwgX291dDsgICAgICAgICAgICAgIC8qIHNhdmUgc3RhcnRpbmcgYXZhaWxhYmxlIGlucHV0IGFuZCBvdXRwdXQgKi9cbiAgdmFyIGNvcHk7ICAgICAgICAgICAgICAgICAgIC8qIG51bWJlciBvZiBzdG9yZWQgb3IgbWF0Y2ggYnl0ZXMgdG8gY29weSAqL1xuICB2YXIgZnJvbTsgICAgICAgICAgICAgICAgICAgLyogd2hlcmUgdG8gY29weSBtYXRjaCBieXRlcyBmcm9tICovXG4gIHZhciBmcm9tX3NvdXJjZTtcbiAgdmFyIGhlcmUgPSAwOyAgICAgICAgICAgICAgIC8qIGN1cnJlbnQgZGVjb2RpbmcgdGFibGUgZW50cnkgKi9cbiAgdmFyIGhlcmVfYml0cywgaGVyZV9vcCwgaGVyZV92YWw7IC8vIHBha2VkIFwiaGVyZVwiIGRlbm9ybWFsaXplZCAoSlMgc3BlY2lmaWMpXG4gIC8vdmFyIGxhc3Q7ICAgICAgICAgICAgICAgICAgIC8qIHBhcmVudCB0YWJsZSBlbnRyeSAqL1xuICB2YXIgbGFzdF9iaXRzLCBsYXN0X29wLCBsYXN0X3ZhbDsgLy8gcGFrZWQgXCJsYXN0XCIgZGVub3JtYWxpemVkIChKUyBzcGVjaWZpYylcbiAgdmFyIGxlbjsgICAgICAgICAgICAgICAgICAgIC8qIGxlbmd0aCB0byBjb3B5IGZvciByZXBlYXRzLCBiaXRzIHRvIGRyb3AgKi9cbiAgdmFyIHJldDsgICAgICAgICAgICAgICAgICAgIC8qIHJldHVybiBjb2RlICovXG4gIHZhciBoYnVmID0gbmV3IHV0aWxzLkJ1ZjgoNCk7ICAgIC8qIGJ1ZmZlciBmb3IgZ3ppcCBoZWFkZXIgY3JjIGNhbGN1bGF0aW9uICovXG4gIHZhciBvcHRzO1xuXG4gIHZhciBuOyAvLyB0ZW1wb3JhcnkgdmFyIGZvciBORUVEX0JJVFNcblxuICB2YXIgb3JkZXIgPSAvKiBwZXJtdXRhdGlvbiBvZiBjb2RlIGxlbmd0aHMgKi9cbiAgICBbIDE2LCAxNywgMTgsIDAsIDgsIDcsIDksIDYsIDEwLCA1LCAxMSwgNCwgMTIsIDMsIDEzLCAyLCAxNCwgMSwgMTUgXTtcblxuXG4gIGlmICghc3RybSB8fCAhc3RybS5zdGF0ZSB8fCAhc3RybS5vdXRwdXQgfHxcbiAgICAgICghc3RybS5pbnB1dCAmJiBzdHJtLmF2YWlsX2luICE9PSAwKSkge1xuICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUjtcbiAgfVxuXG4gIHN0YXRlID0gc3RybS5zdGF0ZTtcbiAgaWYgKHN0YXRlLm1vZGUgPT09IFRZUEUpIHsgc3RhdGUubW9kZSA9IFRZUEVETzsgfSAgICAvKiBza2lwIGNoZWNrICovXG5cblxuICAvLy0tLSBMT0FEKCkgLS0tXG4gIHB1dCA9IHN0cm0ubmV4dF9vdXQ7XG4gIG91dHB1dCA9IHN0cm0ub3V0cHV0O1xuICBsZWZ0ID0gc3RybS5hdmFpbF9vdXQ7XG4gIG5leHQgPSBzdHJtLm5leHRfaW47XG4gIGlucHV0ID0gc3RybS5pbnB1dDtcbiAgaGF2ZSA9IHN0cm0uYXZhaWxfaW47XG4gIGhvbGQgPSBzdGF0ZS5ob2xkO1xuICBiaXRzID0gc3RhdGUuYml0cztcbiAgLy8tLS1cblxuICBfaW4gPSBoYXZlO1xuICBfb3V0ID0gbGVmdDtcbiAgcmV0ID0gWl9PSztcblxuICBpbmZfbGVhdmU6IC8vIGdvdG8gZW11bGF0aW9uXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKHN0YXRlLm1vZGUpIHtcbiAgICAgIGNhc2UgSEVBRDpcbiAgICAgICAgaWYgKHN0YXRlLndyYXAgPT09IDApIHtcbiAgICAgICAgICBzdGF0ZS5tb2RlID0gVFlQRURPO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDE2KTtcbiAgICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBpZiAoKHN0YXRlLndyYXAgJiAyKSAmJiBob2xkID09PSAweDhiMWYpIHsgIC8qIGd6aXAgaGVhZGVyICovXG4gICAgICAgICAgc3RhdGUuY2hlY2sgPSAwLypjcmMzMigwTCwgWl9OVUxMLCAwKSovO1xuICAgICAgICAgIC8vPT09IENSQzIoc3RhdGUuY2hlY2ssIGhvbGQpO1xuICAgICAgICAgIGhidWZbMF0gPSBob2xkICYgMHhmZjtcbiAgICAgICAgICBoYnVmWzFdID0gKGhvbGQgPj4+IDgpICYgMHhmZjtcbiAgICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyKHN0YXRlLmNoZWNrLCBoYnVmLCAyLCAwKTtcbiAgICAgICAgICAvLz09PS8vXG5cbiAgICAgICAgICAvLz09PSBJTklUQklUUygpO1xuICAgICAgICAgIGhvbGQgPSAwO1xuICAgICAgICAgIGJpdHMgPSAwO1xuICAgICAgICAgIC8vPT09Ly9cbiAgICAgICAgICBzdGF0ZS5tb2RlID0gRkxBR1M7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUuZmxhZ3MgPSAwOyAgICAgICAgICAgLyogZXhwZWN0IHpsaWIgaGVhZGVyICovXG4gICAgICAgIGlmIChzdGF0ZS5oZWFkKSB7XG4gICAgICAgICAgc3RhdGUuaGVhZC5kb25lID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEoc3RhdGUud3JhcCAmIDEpIHx8ICAgLyogY2hlY2sgaWYgemxpYiBoZWFkZXIgYWxsb3dlZCAqL1xuICAgICAgICAgICgoKGhvbGQgJiAweGZmKS8qQklUUyg4KSovIDw8IDgpICsgKGhvbGQgPj4gOCkpICUgMzEpIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICdpbmNvcnJlY3QgaGVhZGVyIGNoZWNrJztcbiAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoaG9sZCAmIDB4MGYpLypCSVRTKDQpKi8gIT09IFpfREVGTEFURUQpIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICd1bmtub3duIGNvbXByZXNzaW9uIG1ldGhvZCc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvLy0tLSBEUk9QQklUUyg0KSAtLS0vL1xuICAgICAgICBob2xkID4+Pj0gNDtcbiAgICAgICAgYml0cyAtPSA0O1xuICAgICAgICAvLy0tLS8vXG4gICAgICAgIGxlbiA9IChob2xkICYgMHgwZikvKkJJVFMoNCkqLyArIDg7XG4gICAgICAgIGlmIChzdGF0ZS53Yml0cyA9PT0gMCkge1xuICAgICAgICAgIHN0YXRlLndiaXRzID0gbGVuO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGxlbiA+IHN0YXRlLndiaXRzKSB7XG4gICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCB3aW5kb3cgc2l6ZSc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBzdGF0ZS5kbWF4ID0gMSA8PCBsZW47XG4gICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICB6bGliIGhlYWRlciBva1xcblwiKSk7XG4gICAgICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS5jaGVjayA9IDEvKmFkbGVyMzIoMEwsIFpfTlVMTCwgMCkqLztcbiAgICAgICAgc3RhdGUubW9kZSA9IGhvbGQgJiAweDIwMCA/IERJQ1RJRCA6IFRZUEU7XG4gICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgIGhvbGQgPSAwO1xuICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgLy89PT0vL1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgRkxBR1M6XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDE2KTsgKi9cbiAgICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5mbGFncyA9IGhvbGQ7XG4gICAgICAgIGlmICgoc3RhdGUuZmxhZ3MgJiAweGZmKSAhPT0gWl9ERUZMQVRFRCkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ3Vua25vd24gY29tcHJlc3Npb24gbWV0aG9kJztcbiAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4ZTAwMCkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ3Vua25vd24gaGVhZGVyIGZsYWdzIHNldCc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICAgIHN0YXRlLmhlYWQudGV4dCA9ICgoaG9sZCA+PiA4KSAmIDEpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDIwMCkge1xuICAgICAgICAgIC8vPT09IENSQzIoc3RhdGUuY2hlY2ssIGhvbGQpO1xuICAgICAgICAgIGhidWZbMF0gPSBob2xkICYgMHhmZjtcbiAgICAgICAgICBoYnVmWzFdID0gKGhvbGQgPj4+IDgpICYgMHhmZjtcbiAgICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyKHN0YXRlLmNoZWNrLCBoYnVmLCAyLCAwKTtcbiAgICAgICAgICAvLz09PS8vXG4gICAgICAgIH1cbiAgICAgICAgLy89PT0gSU5JVEJJVFMoKTtcbiAgICAgICAgaG9sZCA9IDA7XG4gICAgICAgIGJpdHMgPSAwO1xuICAgICAgICAvLz09PS8vXG4gICAgICAgIHN0YXRlLm1vZGUgPSBUSU1FO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIFRJTUU6XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDMyKTsgKi9cbiAgICAgICAgd2hpbGUgKGJpdHMgPCAzMikge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICAgIHN0YXRlLmhlYWQudGltZSA9IGhvbGQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwMjAwKSB7XG4gICAgICAgICAgLy89PT0gQ1JDNChzdGF0ZS5jaGVjaywgaG9sZClcbiAgICAgICAgICBoYnVmWzBdID0gaG9sZCAmIDB4ZmY7XG4gICAgICAgICAgaGJ1ZlsxXSA9IChob2xkID4+PiA4KSAmIDB4ZmY7XG4gICAgICAgICAgaGJ1ZlsyXSA9IChob2xkID4+PiAxNikgJiAweGZmO1xuICAgICAgICAgIGhidWZbM10gPSAoaG9sZCA+Pj4gMjQpICYgMHhmZjtcbiAgICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyKHN0YXRlLmNoZWNrLCBoYnVmLCA0LCAwKTtcbiAgICAgICAgICAvLz09PVxuICAgICAgICB9XG4gICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgIGhvbGQgPSAwO1xuICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5tb2RlID0gT1M7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgT1M6XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDE2KTsgKi9cbiAgICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICAgIHN0YXRlLmhlYWQueGZsYWdzID0gKGhvbGQgJiAweGZmKTtcbiAgICAgICAgICBzdGF0ZS5oZWFkLm9zID0gKGhvbGQgPj4gOCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwMjAwKSB7XG4gICAgICAgICAgLy89PT0gQ1JDMihzdGF0ZS5jaGVjaywgaG9sZCk7XG4gICAgICAgICAgaGJ1ZlswXSA9IGhvbGQgJiAweGZmO1xuICAgICAgICAgIGhidWZbMV0gPSAoaG9sZCA+Pj4gOCkgJiAweGZmO1xuICAgICAgICAgIHN0YXRlLmNoZWNrID0gY3JjMzIoc3RhdGUuY2hlY2ssIGhidWYsIDIsIDApO1xuICAgICAgICAgIC8vPT09Ly9cbiAgICAgICAgfVxuICAgICAgICAvLz09PSBJTklUQklUUygpO1xuICAgICAgICBob2xkID0gMDtcbiAgICAgICAgYml0cyA9IDA7XG4gICAgICAgIC8vPT09Ly9cbiAgICAgICAgc3RhdGUubW9kZSA9IEVYTEVOO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIEVYTEVOOlxuICAgICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDA0MDApIHtcbiAgICAgICAgICAvLz09PSBORUVEQklUUygxNik7ICovXG4gICAgICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICAgIHN0YXRlLmxlbmd0aCA9IGhvbGQ7XG4gICAgICAgICAgaWYgKHN0YXRlLmhlYWQpIHtcbiAgICAgICAgICAgIHN0YXRlLmhlYWQuZXh0cmFfbGVuID0gaG9sZDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwMjAwKSB7XG4gICAgICAgICAgICAvLz09PSBDUkMyKHN0YXRlLmNoZWNrLCBob2xkKTtcbiAgICAgICAgICAgIGhidWZbMF0gPSBob2xkICYgMHhmZjtcbiAgICAgICAgICAgIGhidWZbMV0gPSAoaG9sZCA+Pj4gOCkgJiAweGZmO1xuICAgICAgICAgICAgc3RhdGUuY2hlY2sgPSBjcmMzMihzdGF0ZS5jaGVjaywgaGJ1ZiwgMiwgMCk7XG4gICAgICAgICAgICAvLz09PS8vXG4gICAgICAgICAgfVxuICAgICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgICAgaG9sZCA9IDA7XG4gICAgICAgICAgYml0cyA9IDA7XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHN0YXRlLmhlYWQpIHtcbiAgICAgICAgICBzdGF0ZS5oZWFkLmV4dHJhID0gbnVsbC8qWl9OVUxMKi87XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUubW9kZSA9IEVYVFJBO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIEVYVFJBOlxuICAgICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDA0MDApIHtcbiAgICAgICAgICBjb3B5ID0gc3RhdGUubGVuZ3RoO1xuICAgICAgICAgIGlmIChjb3B5ID4gaGF2ZSkgeyBjb3B5ID0gaGF2ZTsgfVxuICAgICAgICAgIGlmIChjb3B5KSB7XG4gICAgICAgICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICAgICAgICBsZW4gPSBzdGF0ZS5oZWFkLmV4dHJhX2xlbiAtIHN0YXRlLmxlbmd0aDtcbiAgICAgICAgICAgICAgaWYgKCFzdGF0ZS5oZWFkLmV4dHJhKSB7XG4gICAgICAgICAgICAgICAgLy8gVXNlIHVudHlwZWQgYXJyYXkgZm9yIG1vcmUgY29udmVuaWVudCBwcm9jZXNzaW5nIGxhdGVyXG4gICAgICAgICAgICAgICAgc3RhdGUuaGVhZC5leHRyYSA9IG5ldyBBcnJheShzdGF0ZS5oZWFkLmV4dHJhX2xlbik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdXRpbHMuYXJyYXlTZXQoXG4gICAgICAgICAgICAgICAgc3RhdGUuaGVhZC5leHRyYSxcbiAgICAgICAgICAgICAgICBpbnB1dCxcbiAgICAgICAgICAgICAgICBuZXh0LFxuICAgICAgICAgICAgICAgIC8vIGV4dHJhIGZpZWxkIGlzIGxpbWl0ZWQgdG8gNjU1MzYgYnl0ZXNcbiAgICAgICAgICAgICAgICAvLyAtIG5vIG5lZWQgZm9yIGFkZGl0aW9uYWwgc2l6ZSBjaGVja1xuICAgICAgICAgICAgICAgIGNvcHksXG4gICAgICAgICAgICAgICAgLypsZW4gKyBjb3B5ID4gc3RhdGUuaGVhZC5leHRyYV9tYXggLSBsZW4gPyBzdGF0ZS5oZWFkLmV4dHJhX21heCA6IGNvcHksKi9cbiAgICAgICAgICAgICAgICBsZW5cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgLy96bWVtY3B5KHN0YXRlLmhlYWQuZXh0cmEgKyBsZW4sIG5leHQsXG4gICAgICAgICAgICAgIC8vICAgICAgICBsZW4gKyBjb3B5ID4gc3RhdGUuaGVhZC5leHRyYV9tYXggP1xuICAgICAgICAgICAgICAvLyAgICAgICAgc3RhdGUuaGVhZC5leHRyYV9tYXggLSBsZW4gOiBjb3B5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDIwMCkge1xuICAgICAgICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyKHN0YXRlLmNoZWNrLCBpbnB1dCwgY29weSwgbmV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYXZlIC09IGNvcHk7XG4gICAgICAgICAgICBuZXh0ICs9IGNvcHk7XG4gICAgICAgICAgICBzdGF0ZS5sZW5ndGggLT0gY29weTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHN0YXRlLmxlbmd0aCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgfVxuICAgICAgICBzdGF0ZS5sZW5ndGggPSAwO1xuICAgICAgICBzdGF0ZS5tb2RlID0gTkFNRTtcbiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgY2FzZSBOQU1FOlxuICAgICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDA4MDApIHtcbiAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICBjb3B5ID0gMDtcbiAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAvLyBUT0RPOiAyIG9yIDEgYnl0ZXM/XG4gICAgICAgICAgICBsZW4gPSBpbnB1dFtuZXh0ICsgY29weSsrXTtcbiAgICAgICAgICAgIC8qIHVzZSBjb25zdGFudCBsaW1pdCBiZWNhdXNlIGluIGpzIHdlIHNob3VsZCBub3QgcHJlYWxsb2NhdGUgbWVtb3J5ICovXG4gICAgICAgICAgICBpZiAoc3RhdGUuaGVhZCAmJiBsZW4gJiZcbiAgICAgICAgICAgICAgICAoc3RhdGUubGVuZ3RoIDwgNjU1MzYgLypzdGF0ZS5oZWFkLm5hbWVfbWF4Ki8pKSB7XG4gICAgICAgICAgICAgIHN0YXRlLmhlYWQubmFtZSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGxlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSB3aGlsZSAobGVuICYmIGNvcHkgPCBoYXZlKTtcblxuICAgICAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDIwMCkge1xuICAgICAgICAgICAgc3RhdGUuY2hlY2sgPSBjcmMzMihzdGF0ZS5jaGVjaywgaW5wdXQsIGNvcHksIG5leHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBoYXZlIC09IGNvcHk7XG4gICAgICAgICAgbmV4dCArPSBjb3B5O1xuICAgICAgICAgIGlmIChsZW4pIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICAgIHN0YXRlLmhlYWQubmFtZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUubGVuZ3RoID0gMDtcbiAgICAgICAgc3RhdGUubW9kZSA9IENPTU1FTlQ7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgQ09NTUVOVDpcbiAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgxMDAwKSB7XG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgY29weSA9IDA7XG4gICAgICAgICAgZG8ge1xuICAgICAgICAgICAgbGVuID0gaW5wdXRbbmV4dCArIGNvcHkrK107XG4gICAgICAgICAgICAvKiB1c2UgY29uc3RhbnQgbGltaXQgYmVjYXVzZSBpbiBqcyB3ZSBzaG91bGQgbm90IHByZWFsbG9jYXRlIG1lbW9yeSAqL1xuICAgICAgICAgICAgaWYgKHN0YXRlLmhlYWQgJiYgbGVuICYmXG4gICAgICAgICAgICAgICAgKHN0YXRlLmxlbmd0aCA8IDY1NTM2IC8qc3RhdGUuaGVhZC5jb21tX21heCovKSkge1xuICAgICAgICAgICAgICBzdGF0ZS5oZWFkLmNvbW1lbnQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShsZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gd2hpbGUgKGxlbiAmJiBjb3B5IDwgaGF2ZSk7XG4gICAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwMjAwKSB7XG4gICAgICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyKHN0YXRlLmNoZWNrLCBpbnB1dCwgY29weSwgbmV4dCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGhhdmUgLT0gY29weTtcbiAgICAgICAgICBuZXh0ICs9IGNvcHk7XG4gICAgICAgICAgaWYgKGxlbikgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzdGF0ZS5oZWFkKSB7XG4gICAgICAgICAgc3RhdGUuaGVhZC5jb21tZW50ID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBzdGF0ZS5tb2RlID0gSENSQztcbiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgY2FzZSBIQ1JDOlxuICAgICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDAyMDApIHtcbiAgICAgICAgICAvLz09PSBORUVEQklUUygxNik7ICovXG4gICAgICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICAgIGlmIChob2xkICE9PSAoc3RhdGUuY2hlY2sgJiAweGZmZmYpKSB7XG4gICAgICAgICAgICBzdHJtLm1zZyA9ICdoZWFkZXIgY3JjIG1pc21hdGNoJztcbiAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgLy89PT0gSU5JVEJJVFMoKTtcbiAgICAgICAgICBob2xkID0gMDtcbiAgICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgICAvLz09PS8vXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0YXRlLmhlYWQpIHtcbiAgICAgICAgICBzdGF0ZS5oZWFkLmhjcmMgPSAoKHN0YXRlLmZsYWdzID4+IDkpICYgMSk7XG4gICAgICAgICAgc3RhdGUuaGVhZC5kb25lID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBzdHJtLmFkbGVyID0gc3RhdGUuY2hlY2sgPSAwO1xuICAgICAgICBzdGF0ZS5tb2RlID0gVFlQRTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIERJQ1RJRDpcbiAgICAgICAgLy89PT0gTkVFREJJVFMoMzIpOyAqL1xuICAgICAgICB3aGlsZSAoYml0cyA8IDMyKSB7XG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgfVxuICAgICAgICAvLz09PS8vXG4gICAgICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS5jaGVjayA9IHpzd2FwMzIoaG9sZCk7XG4gICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgIGhvbGQgPSAwO1xuICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5tb2RlID0gRElDVDtcbiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgY2FzZSBESUNUOlxuICAgICAgICBpZiAoc3RhdGUuaGF2ZWRpY3QgPT09IDApIHtcbiAgICAgICAgICAvLy0tLSBSRVNUT1JFKCkgLS0tXG4gICAgICAgICAgc3RybS5uZXh0X291dCA9IHB1dDtcbiAgICAgICAgICBzdHJtLmF2YWlsX291dCA9IGxlZnQ7XG4gICAgICAgICAgc3RybS5uZXh0X2luID0gbmV4dDtcbiAgICAgICAgICBzdHJtLmF2YWlsX2luID0gaGF2ZTtcbiAgICAgICAgICBzdGF0ZS5ob2xkID0gaG9sZDtcbiAgICAgICAgICBzdGF0ZS5iaXRzID0gYml0cztcbiAgICAgICAgICAvLy0tLVxuICAgICAgICAgIHJldHVybiBaX05FRURfRElDVDtcbiAgICAgICAgfVxuICAgICAgICBzdHJtLmFkbGVyID0gc3RhdGUuY2hlY2sgPSAxLyphZGxlcjMyKDBMLCBaX05VTEwsIDApKi87XG4gICAgICAgIHN0YXRlLm1vZGUgPSBUWVBFO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIFRZUEU6XG4gICAgICAgIGlmIChmbHVzaCA9PT0gWl9CTE9DSyB8fCBmbHVzaCA9PT0gWl9UUkVFUykgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgY2FzZSBUWVBFRE86XG4gICAgICAgIGlmIChzdGF0ZS5sYXN0KSB7XG4gICAgICAgICAgLy8tLS0gQllURUJJVFMoKSAtLS0vL1xuICAgICAgICAgIGhvbGQgPj4+PSBiaXRzICYgNztcbiAgICAgICAgICBiaXRzIC09IGJpdHMgJiA3O1xuICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICBzdGF0ZS5tb2RlID0gQ0hFQ0s7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0gTkVFREJJVFMoMyk7ICovXG4gICAgICAgIHdoaWxlIChiaXRzIDwgMykge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5sYXN0ID0gKGhvbGQgJiAweDAxKS8qQklUUygxKSovO1xuICAgICAgICAvLy0tLSBEUk9QQklUUygxKSAtLS0vL1xuICAgICAgICBob2xkID4+Pj0gMTtcbiAgICAgICAgYml0cyAtPSAxO1xuICAgICAgICAvLy0tLS8vXG5cbiAgICAgICAgc3dpdGNoICgoaG9sZCAmIDB4MDMpLypCSVRTKDIpKi8pIHtcbiAgICAgICAgICBjYXNlIDA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzdG9yZWQgYmxvY2sgKi9cbiAgICAgICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgIHN0b3JlZCBibG9jayVzXFxuXCIsXG4gICAgICAgICAgICAvLyAgICAgICAgc3RhdGUubGFzdCA/IFwiIChsYXN0KVwiIDogXCJcIikpO1xuICAgICAgICAgICAgc3RhdGUubW9kZSA9IFNUT1JFRDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgMTogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGZpeGVkIGJsb2NrICovXG4gICAgICAgICAgICBmaXhlZHRhYmxlcyhzdGF0ZSk7XG4gICAgICAgICAgICAvL1RyYWNldigoc3RkZXJyLCBcImluZmxhdGU6ICAgICBmaXhlZCBjb2RlcyBibG9jayVzXFxuXCIsXG4gICAgICAgICAgICAvLyAgICAgICAgc3RhdGUubGFzdCA/IFwiIChsYXN0KVwiIDogXCJcIikpO1xuICAgICAgICAgICAgc3RhdGUubW9kZSA9IExFTl87ICAgICAgICAgICAgIC8qIGRlY29kZSBjb2RlcyAqL1xuICAgICAgICAgICAgaWYgKGZsdXNoID09PSBaX1RSRUVTKSB7XG4gICAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKDIpIC0tLS8vXG4gICAgICAgICAgICAgIGhvbGQgPj4+PSAyO1xuICAgICAgICAgICAgICBiaXRzIC09IDI7XG4gICAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAyOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZHluYW1pYyBibG9jayAqL1xuICAgICAgICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgICAgZHluYW1pYyBjb2RlcyBibG9jayVzXFxuXCIsXG4gICAgICAgICAgICAvLyAgICAgICAgc3RhdGUubGFzdCA/IFwiIChsYXN0KVwiIDogXCJcIikpO1xuICAgICAgICAgICAgc3RhdGUubW9kZSA9IFRBQkxFO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBibG9jayB0eXBlJztcbiAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8tLS0gRFJPUEJJVFMoMikgLS0tLy9cbiAgICAgICAgaG9sZCA+Pj49IDI7XG4gICAgICAgIGJpdHMgLT0gMjtcbiAgICAgICAgLy8tLS0vL1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgU1RPUkVEOlxuICAgICAgICAvLy0tLSBCWVRFQklUUygpIC0tLS8vIC8qIGdvIHRvIGJ5dGUgYm91bmRhcnkgKi9cbiAgICAgICAgaG9sZCA+Pj49IGJpdHMgJiA3O1xuICAgICAgICBiaXRzIC09IGJpdHMgJiA3O1xuICAgICAgICAvLy0tLS8vXG4gICAgICAgIC8vPT09IE5FRURCSVRTKDMyKTsgKi9cbiAgICAgICAgd2hpbGUgKGJpdHMgPCAzMikge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBpZiAoKGhvbGQgJiAweGZmZmYpICE9PSAoKGhvbGQgPj4+IDE2KSBeIDB4ZmZmZikpIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIHN0b3JlZCBibG9jayBsZW5ndGhzJztcbiAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRlLmxlbmd0aCA9IGhvbGQgJiAweGZmZmY7XG4gICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgc3RvcmVkIGxlbmd0aCAldVxcblwiLFxuICAgICAgICAvLyAgICAgICAgc3RhdGUubGVuZ3RoKSk7XG4gICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgIGhvbGQgPSAwO1xuICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5tb2RlID0gQ09QWV87XG4gICAgICAgIGlmIChmbHVzaCA9PT0gWl9UUkVFUykgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgY2FzZSBDT1BZXzpcbiAgICAgICAgc3RhdGUubW9kZSA9IENPUFk7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgQ09QWTpcbiAgICAgICAgY29weSA9IHN0YXRlLmxlbmd0aDtcbiAgICAgICAgaWYgKGNvcHkpIHtcbiAgICAgICAgICBpZiAoY29weSA+IGhhdmUpIHsgY29weSA9IGhhdmU7IH1cbiAgICAgICAgICBpZiAoY29weSA+IGxlZnQpIHsgY29weSA9IGxlZnQ7IH1cbiAgICAgICAgICBpZiAoY29weSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICAvLy0tLSB6bWVtY3B5KHB1dCwgbmV4dCwgY29weSk7IC0tLVxuICAgICAgICAgIHV0aWxzLmFycmF5U2V0KG91dHB1dCwgaW5wdXQsIG5leHQsIGNvcHksIHB1dCk7XG4gICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIGhhdmUgLT0gY29weTtcbiAgICAgICAgICBuZXh0ICs9IGNvcHk7XG4gICAgICAgICAgbGVmdCAtPSBjb3B5O1xuICAgICAgICAgIHB1dCArPSBjb3B5O1xuICAgICAgICAgIHN0YXRlLmxlbmd0aCAtPSBjb3B5O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgc3RvcmVkIGVuZFxcblwiKSk7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBUWVBFO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVEFCTEU6XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDE0KTsgKi9cbiAgICAgICAgd2hpbGUgKGJpdHMgPCAxNCkge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5ubGVuID0gKGhvbGQgJiAweDFmKS8qQklUUyg1KSovICsgMjU3O1xuICAgICAgICAvLy0tLSBEUk9QQklUUyg1KSAtLS0vL1xuICAgICAgICBob2xkID4+Pj0gNTtcbiAgICAgICAgYml0cyAtPSA1O1xuICAgICAgICAvLy0tLS8vXG4gICAgICAgIHN0YXRlLm5kaXN0ID0gKGhvbGQgJiAweDFmKS8qQklUUyg1KSovICsgMTtcbiAgICAgICAgLy8tLS0gRFJPUEJJVFMoNSkgLS0tLy9cbiAgICAgICAgaG9sZCA+Pj49IDU7XG4gICAgICAgIGJpdHMgLT0gNTtcbiAgICAgICAgLy8tLS0vL1xuICAgICAgICBzdGF0ZS5uY29kZSA9IChob2xkICYgMHgwZikvKkJJVFMoNCkqLyArIDQ7XG4gICAgICAgIC8vLS0tIERST1BCSVRTKDQpIC0tLS8vXG4gICAgICAgIGhvbGQgPj4+PSA0O1xuICAgICAgICBiaXRzIC09IDQ7XG4gICAgICAgIC8vLS0tLy9cbi8vI2lmbmRlZiBQS1pJUF9CVUdfV09SS0FST1VORFxuICAgICAgICBpZiAoc3RhdGUubmxlbiA+IDI4NiB8fCBzdGF0ZS5uZGlzdCA+IDMwKSB7XG4gICAgICAgICAgc3RybS5tc2cgPSAndG9vIG1hbnkgbGVuZ3RoIG9yIGRpc3RhbmNlIHN5bWJvbHMnO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbi8vI2VuZGlmXG4gICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgdGFibGUgc2l6ZXMgb2tcXG5cIikpO1xuICAgICAgICBzdGF0ZS5oYXZlID0gMDtcbiAgICAgICAgc3RhdGUubW9kZSA9IExFTkxFTlM7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgTEVOTEVOUzpcbiAgICAgICAgd2hpbGUgKHN0YXRlLmhhdmUgPCBzdGF0ZS5uY29kZSkge1xuICAgICAgICAgIC8vPT09IE5FRURCSVRTKDMpO1xuICAgICAgICAgIHdoaWxlIChiaXRzIDwgMykge1xuICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICAgIHN0YXRlLmxlbnNbb3JkZXJbc3RhdGUuaGF2ZSsrXV0gPSAoaG9sZCAmIDB4MDcpOy8vQklUUygzKTtcbiAgICAgICAgICAvLy0tLSBEUk9QQklUUygzKSAtLS0vL1xuICAgICAgICAgIGhvbGQgPj4+PSAzO1xuICAgICAgICAgIGJpdHMgLT0gMztcbiAgICAgICAgICAvLy0tLS8vXG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKHN0YXRlLmhhdmUgPCAxOSkge1xuICAgICAgICAgIHN0YXRlLmxlbnNbb3JkZXJbc3RhdGUuaGF2ZSsrXV0gPSAwO1xuICAgICAgICB9XG4gICAgICAgIC8vIFdlIGhhdmUgc2VwYXJhdGUgdGFibGVzICYgbm8gcG9pbnRlcnMuIDIgY29tbWVudGVkIGxpbmVzIGJlbG93IG5vdCBuZWVkZWQuXG4gICAgICAgIC8vc3RhdGUubmV4dCA9IHN0YXRlLmNvZGVzO1xuICAgICAgICAvL3N0YXRlLmxlbmNvZGUgPSBzdGF0ZS5uZXh0O1xuICAgICAgICAvLyBTd2l0Y2ggdG8gdXNlIGR5bmFtaWMgdGFibGVcbiAgICAgICAgc3RhdGUubGVuY29kZSA9IHN0YXRlLmxlbmR5bjtcbiAgICAgICAgc3RhdGUubGVuYml0cyA9IDc7XG5cbiAgICAgICAgb3B0cyA9IHsgYml0czogc3RhdGUubGVuYml0cyB9O1xuICAgICAgICByZXQgPSBpbmZsYXRlX3RhYmxlKENPREVTLCBzdGF0ZS5sZW5zLCAwLCAxOSwgc3RhdGUubGVuY29kZSwgMCwgc3RhdGUud29yaywgb3B0cyk7XG4gICAgICAgIHN0YXRlLmxlbmJpdHMgPSBvcHRzLmJpdHM7XG5cbiAgICAgICAgaWYgKHJldCkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgY29kZSBsZW5ndGhzIHNldCc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvL1RyYWNldigoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgIGNvZGUgbGVuZ3RocyBva1xcblwiKSk7XG4gICAgICAgIHN0YXRlLmhhdmUgPSAwO1xuICAgICAgICBzdGF0ZS5tb2RlID0gQ09ERUxFTlM7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgQ09ERUxFTlM6XG4gICAgICAgIHdoaWxlIChzdGF0ZS5oYXZlIDwgc3RhdGUubmxlbiArIHN0YXRlLm5kaXN0KSB7XG4gICAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgICAgaGVyZSA9IHN0YXRlLmxlbmNvZGVbaG9sZCAmICgoMSA8PCBzdGF0ZS5sZW5iaXRzKSAtIDEpXTsvKkJJVFMoc3RhdGUubGVuYml0cykqL1xuICAgICAgICAgICAgaGVyZV9iaXRzID0gaGVyZSA+Pj4gMjQ7XG4gICAgICAgICAgICBoZXJlX29wID0gKGhlcmUgPj4+IDE2KSAmIDB4ZmY7XG4gICAgICAgICAgICBoZXJlX3ZhbCA9IGhlcmUgJiAweGZmZmY7XG5cbiAgICAgICAgICAgIGlmICgoaGVyZV9iaXRzKSA8PSBiaXRzKSB7IGJyZWFrOyB9XG4gICAgICAgICAgICAvLy0tLSBQVUxMQllURSgpIC0tLS8vXG4gICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaGVyZV92YWwgPCAxNikge1xuICAgICAgICAgICAgLy8tLS0gRFJPUEJJVFMoaGVyZS5iaXRzKSAtLS0vL1xuICAgICAgICAgICAgaG9sZCA+Pj49IGhlcmVfYml0cztcbiAgICAgICAgICAgIGJpdHMgLT0gaGVyZV9iaXRzO1xuICAgICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgICAgc3RhdGUubGVuc1tzdGF0ZS5oYXZlKytdID0gaGVyZV92YWw7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKGhlcmVfdmFsID09PSAxNikge1xuICAgICAgICAgICAgICAvLz09PSBORUVEQklUUyhoZXJlLmJpdHMgKyAyKTtcbiAgICAgICAgICAgICAgbiA9IGhlcmVfYml0cyArIDI7XG4gICAgICAgICAgICAgIHdoaWxlIChiaXRzIDwgbikge1xuICAgICAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy89PT0vL1xuICAgICAgICAgICAgICAvLy0tLSBEUk9QQklUUyhoZXJlLmJpdHMpIC0tLS8vXG4gICAgICAgICAgICAgIGhvbGQgPj4+PSBoZXJlX2JpdHM7XG4gICAgICAgICAgICAgIGJpdHMgLT0gaGVyZV9iaXRzO1xuICAgICAgICAgICAgICAvLy0tLS8vXG4gICAgICAgICAgICAgIGlmIChzdGF0ZS5oYXZlID09PSAwKSB7XG4gICAgICAgICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBiaXQgbGVuZ3RoIHJlcGVhdCc7XG4gICAgICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBsZW4gPSBzdGF0ZS5sZW5zW3N0YXRlLmhhdmUgLSAxXTtcbiAgICAgICAgICAgICAgY29weSA9IDMgKyAoaG9sZCAmIDB4MDMpOy8vQklUUygyKTtcbiAgICAgICAgICAgICAgLy8tLS0gRFJPUEJJVFMoMikgLS0tLy9cbiAgICAgICAgICAgICAgaG9sZCA+Pj49IDI7XG4gICAgICAgICAgICAgIGJpdHMgLT0gMjtcbiAgICAgICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaGVyZV92YWwgPT09IDE3KSB7XG4gICAgICAgICAgICAgIC8vPT09IE5FRURCSVRTKGhlcmUuYml0cyArIDMpO1xuICAgICAgICAgICAgICBuID0gaGVyZV9iaXRzICsgMztcbiAgICAgICAgICAgICAgd2hpbGUgKGJpdHMgPCBuKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAvLz09PS8vXG4gICAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKGhlcmUuYml0cykgLS0tLy9cbiAgICAgICAgICAgICAgaG9sZCA+Pj49IGhlcmVfYml0cztcbiAgICAgICAgICAgICAgYml0cyAtPSBoZXJlX2JpdHM7XG4gICAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICAgICAgbGVuID0gMDtcbiAgICAgICAgICAgICAgY29weSA9IDMgKyAoaG9sZCAmIDB4MDcpOy8vQklUUygzKTtcbiAgICAgICAgICAgICAgLy8tLS0gRFJPUEJJVFMoMykgLS0tLy9cbiAgICAgICAgICAgICAgaG9sZCA+Pj49IDM7XG4gICAgICAgICAgICAgIGJpdHMgLT0gMztcbiAgICAgICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIC8vPT09IE5FRURCSVRTKGhlcmUuYml0cyArIDcpO1xuICAgICAgICAgICAgICBuID0gaGVyZV9iaXRzICsgNztcbiAgICAgICAgICAgICAgd2hpbGUgKGJpdHMgPCBuKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAvLz09PS8vXG4gICAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKGhlcmUuYml0cykgLS0tLy9cbiAgICAgICAgICAgICAgaG9sZCA+Pj49IGhlcmVfYml0cztcbiAgICAgICAgICAgICAgYml0cyAtPSBoZXJlX2JpdHM7XG4gICAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICAgICAgbGVuID0gMDtcbiAgICAgICAgICAgICAgY29weSA9IDExICsgKGhvbGQgJiAweDdmKTsvL0JJVFMoNyk7XG4gICAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKDcpIC0tLS8vXG4gICAgICAgICAgICAgIGhvbGQgPj4+PSA3O1xuICAgICAgICAgICAgICBiaXRzIC09IDc7XG4gICAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzdGF0ZS5oYXZlICsgY29weSA+IHN0YXRlLm5sZW4gKyBzdGF0ZS5uZGlzdCkge1xuICAgICAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGJpdCBsZW5ndGggcmVwZWF0JztcbiAgICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB3aGlsZSAoY29weS0tKSB7XG4gICAgICAgICAgICAgIHN0YXRlLmxlbnNbc3RhdGUuaGF2ZSsrXSA9IGxlbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvKiBoYW5kbGUgZXJyb3IgYnJlYWtzIGluIHdoaWxlICovXG4gICAgICAgIGlmIChzdGF0ZS5tb2RlID09PSBCQUQpIHsgYnJlYWs7IH1cblxuICAgICAgICAvKiBjaGVjayBmb3IgZW5kLW9mLWJsb2NrIGNvZGUgKGJldHRlciBoYXZlIG9uZSkgKi9cbiAgICAgICAgaWYgKHN0YXRlLmxlbnNbMjU2XSA9PT0gMCkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgY29kZSAtLSBtaXNzaW5nIGVuZC1vZi1ibG9jayc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIC8qIGJ1aWxkIGNvZGUgdGFibGVzIC0tIG5vdGU6IGRvIG5vdCBjaGFuZ2UgdGhlIGxlbmJpdHMgb3IgZGlzdGJpdHNcbiAgICAgICAgICAgdmFsdWVzIGhlcmUgKDkgYW5kIDYpIHdpdGhvdXQgcmVhZGluZyB0aGUgY29tbWVudHMgaW4gaW5mdHJlZXMuaFxuICAgICAgICAgICBjb25jZXJuaW5nIHRoZSBFTk9VR0ggY29uc3RhbnRzLCB3aGljaCBkZXBlbmQgb24gdGhvc2UgdmFsdWVzICovXG4gICAgICAgIHN0YXRlLmxlbmJpdHMgPSA5O1xuXG4gICAgICAgIG9wdHMgPSB7IGJpdHM6IHN0YXRlLmxlbmJpdHMgfTtcbiAgICAgICAgcmV0ID0gaW5mbGF0ZV90YWJsZShMRU5TLCBzdGF0ZS5sZW5zLCAwLCBzdGF0ZS5ubGVuLCBzdGF0ZS5sZW5jb2RlLCAwLCBzdGF0ZS53b3JrLCBvcHRzKTtcbiAgICAgICAgLy8gV2UgaGF2ZSBzZXBhcmF0ZSB0YWJsZXMgJiBubyBwb2ludGVycy4gMiBjb21tZW50ZWQgbGluZXMgYmVsb3cgbm90IG5lZWRlZC5cbiAgICAgICAgLy8gc3RhdGUubmV4dF9pbmRleCA9IG9wdHMudGFibGVfaW5kZXg7XG4gICAgICAgIHN0YXRlLmxlbmJpdHMgPSBvcHRzLmJpdHM7XG4gICAgICAgIC8vIHN0YXRlLmxlbmNvZGUgPSBzdGF0ZS5uZXh0O1xuXG4gICAgICAgIGlmIChyZXQpIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGxpdGVyYWwvbGVuZ3RocyBzZXQnO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZS5kaXN0Yml0cyA9IDY7XG4gICAgICAgIC8vc3RhdGUuZGlzdGNvZGUuY29weShzdGF0ZS5jb2Rlcyk7XG4gICAgICAgIC8vIFN3aXRjaCB0byB1c2UgZHluYW1pYyB0YWJsZVxuICAgICAgICBzdGF0ZS5kaXN0Y29kZSA9IHN0YXRlLmRpc3RkeW47XG4gICAgICAgIG9wdHMgPSB7IGJpdHM6IHN0YXRlLmRpc3RiaXRzIH07XG4gICAgICAgIHJldCA9IGluZmxhdGVfdGFibGUoRElTVFMsIHN0YXRlLmxlbnMsIHN0YXRlLm5sZW4sIHN0YXRlLm5kaXN0LCBzdGF0ZS5kaXN0Y29kZSwgMCwgc3RhdGUud29yaywgb3B0cyk7XG4gICAgICAgIC8vIFdlIGhhdmUgc2VwYXJhdGUgdGFibGVzICYgbm8gcG9pbnRlcnMuIDIgY29tbWVudGVkIGxpbmVzIGJlbG93IG5vdCBuZWVkZWQuXG4gICAgICAgIC8vIHN0YXRlLm5leHRfaW5kZXggPSBvcHRzLnRhYmxlX2luZGV4O1xuICAgICAgICBzdGF0ZS5kaXN0Yml0cyA9IG9wdHMuYml0cztcbiAgICAgICAgLy8gc3RhdGUuZGlzdGNvZGUgPSBzdGF0ZS5uZXh0O1xuXG4gICAgICAgIGlmIChyZXQpIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGRpc3RhbmNlcyBzZXQnO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgJ2luZmxhdGU6ICAgICAgIGNvZGVzIG9rXFxuJykpO1xuICAgICAgICBzdGF0ZS5tb2RlID0gTEVOXztcbiAgICAgICAgaWYgKGZsdXNoID09PSBaX1RSRUVTKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIExFTl86XG4gICAgICAgIHN0YXRlLm1vZGUgPSBMRU47XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgTEVOOlxuICAgICAgICBpZiAoaGF2ZSA+PSA2ICYmIGxlZnQgPj0gMjU4KSB7XG4gICAgICAgICAgLy8tLS0gUkVTVE9SRSgpIC0tLVxuICAgICAgICAgIHN0cm0ubmV4dF9vdXQgPSBwdXQ7XG4gICAgICAgICAgc3RybS5hdmFpbF9vdXQgPSBsZWZ0O1xuICAgICAgICAgIHN0cm0ubmV4dF9pbiA9IG5leHQ7XG4gICAgICAgICAgc3RybS5hdmFpbF9pbiA9IGhhdmU7XG4gICAgICAgICAgc3RhdGUuaG9sZCA9IGhvbGQ7XG4gICAgICAgICAgc3RhdGUuYml0cyA9IGJpdHM7XG4gICAgICAgICAgLy8tLS1cbiAgICAgICAgICBpbmZsYXRlX2Zhc3Qoc3RybSwgX291dCk7XG4gICAgICAgICAgLy8tLS0gTE9BRCgpIC0tLVxuICAgICAgICAgIHB1dCA9IHN0cm0ubmV4dF9vdXQ7XG4gICAgICAgICAgb3V0cHV0ID0gc3RybS5vdXRwdXQ7XG4gICAgICAgICAgbGVmdCA9IHN0cm0uYXZhaWxfb3V0O1xuICAgICAgICAgIG5leHQgPSBzdHJtLm5leHRfaW47XG4gICAgICAgICAgaW5wdXQgPSBzdHJtLmlucHV0O1xuICAgICAgICAgIGhhdmUgPSBzdHJtLmF2YWlsX2luO1xuICAgICAgICAgIGhvbGQgPSBzdGF0ZS5ob2xkO1xuICAgICAgICAgIGJpdHMgPSBzdGF0ZS5iaXRzO1xuICAgICAgICAgIC8vLS0tXG5cbiAgICAgICAgICBpZiAoc3RhdGUubW9kZSA9PT0gVFlQRSkge1xuICAgICAgICAgICAgc3RhdGUuYmFjayA9IC0xO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBzdGF0ZS5iYWNrID0gMDtcbiAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgIGhlcmUgPSBzdGF0ZS5sZW5jb2RlW2hvbGQgJiAoKDEgPDwgc3RhdGUubGVuYml0cykgLSAxKV07ICAvKkJJVFMoc3RhdGUubGVuYml0cykqL1xuICAgICAgICAgIGhlcmVfYml0cyA9IGhlcmUgPj4+IDI0O1xuICAgICAgICAgIGhlcmVfb3AgPSAoaGVyZSA+Pj4gMTYpICYgMHhmZjtcbiAgICAgICAgICBoZXJlX3ZhbCA9IGhlcmUgJiAweGZmZmY7XG5cbiAgICAgICAgICBpZiAoaGVyZV9iaXRzIDw9IGJpdHMpIHsgYnJlYWs7IH1cbiAgICAgICAgICAvLy0tLSBQVUxMQllURSgpIC0tLS8vXG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAvLy0tLS8vXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhlcmVfb3AgJiYgKGhlcmVfb3AgJiAweGYwKSA9PT0gMCkge1xuICAgICAgICAgIGxhc3RfYml0cyA9IGhlcmVfYml0cztcbiAgICAgICAgICBsYXN0X29wID0gaGVyZV9vcDtcbiAgICAgICAgICBsYXN0X3ZhbCA9IGhlcmVfdmFsO1xuICAgICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICAgIGhlcmUgPSBzdGF0ZS5sZW5jb2RlW2xhc3RfdmFsICtcbiAgICAgICAgICAgICAgICAgICAgKChob2xkICYgKCgxIDw8IChsYXN0X2JpdHMgKyBsYXN0X29wKSkgLSAxKSkvKkJJVFMobGFzdC5iaXRzICsgbGFzdC5vcCkqLyA+PiBsYXN0X2JpdHMpXTtcbiAgICAgICAgICAgIGhlcmVfYml0cyA9IGhlcmUgPj4+IDI0O1xuICAgICAgICAgICAgaGVyZV9vcCA9IChoZXJlID4+PiAxNikgJiAweGZmO1xuICAgICAgICAgICAgaGVyZV92YWwgPSBoZXJlICYgMHhmZmZmO1xuXG4gICAgICAgICAgICBpZiAoKGxhc3RfYml0cyArIGhlcmVfYml0cykgPD0gYml0cykgeyBicmVhazsgfVxuICAgICAgICAgICAgLy8tLS0gUFVMTEJZVEUoKSAtLS0vL1xuICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICB9XG4gICAgICAgICAgLy8tLS0gRFJPUEJJVFMobGFzdC5iaXRzKSAtLS0vL1xuICAgICAgICAgIGhvbGQgPj4+PSBsYXN0X2JpdHM7XG4gICAgICAgICAgYml0cyAtPSBsYXN0X2JpdHM7XG4gICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIHN0YXRlLmJhY2sgKz0gbGFzdF9iaXRzO1xuICAgICAgICB9XG4gICAgICAgIC8vLS0tIERST1BCSVRTKGhlcmUuYml0cykgLS0tLy9cbiAgICAgICAgaG9sZCA+Pj49IGhlcmVfYml0cztcbiAgICAgICAgYml0cyAtPSBoZXJlX2JpdHM7XG4gICAgICAgIC8vLS0tLy9cbiAgICAgICAgc3RhdGUuYmFjayArPSBoZXJlX2JpdHM7XG4gICAgICAgIHN0YXRlLmxlbmd0aCA9IGhlcmVfdmFsO1xuICAgICAgICBpZiAoaGVyZV9vcCA9PT0gMCkge1xuICAgICAgICAgIC8vVHJhY2V2digoc3RkZXJyLCBoZXJlLnZhbCA+PSAweDIwICYmIGhlcmUudmFsIDwgMHg3ZiA/XG4gICAgICAgICAgLy8gICAgICAgIFwiaW5mbGF0ZTogICAgICAgICBsaXRlcmFsICclYydcXG5cIiA6XG4gICAgICAgICAgLy8gICAgICAgIFwiaW5mbGF0ZTogICAgICAgICBsaXRlcmFsIDB4JTAyeFxcblwiLCBoZXJlLnZhbCkpO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBMSVQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhlcmVfb3AgJiAzMikge1xuICAgICAgICAgIC8vVHJhY2V2digoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgICAgZW5kIG9mIGJsb2NrXFxuXCIpKTtcbiAgICAgICAgICBzdGF0ZS5iYWNrID0gLTE7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IFRZUEU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhlcmVfb3AgJiA2NCkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgbGl0ZXJhbC9sZW5ndGggY29kZSc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBzdGF0ZS5leHRyYSA9IGhlcmVfb3AgJiAxNTtcbiAgICAgICAgc3RhdGUubW9kZSA9IExFTkVYVDtcbiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgY2FzZSBMRU5FWFQ6XG4gICAgICAgIGlmIChzdGF0ZS5leHRyYSkge1xuICAgICAgICAgIC8vPT09IE5FRURCSVRTKHN0YXRlLmV4dHJhKTtcbiAgICAgICAgICBuID0gc3RhdGUuZXh0cmE7XG4gICAgICAgICAgd2hpbGUgKGJpdHMgPCBuKSB7XG4gICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLz09PS8vXG4gICAgICAgICAgc3RhdGUubGVuZ3RoICs9IGhvbGQgJiAoKDEgPDwgc3RhdGUuZXh0cmEpIC0gMSkvKkJJVFMoc3RhdGUuZXh0cmEpKi87XG4gICAgICAgICAgLy8tLS0gRFJPUEJJVFMoc3RhdGUuZXh0cmEpIC0tLS8vXG4gICAgICAgICAgaG9sZCA+Pj49IHN0YXRlLmV4dHJhO1xuICAgICAgICAgIGJpdHMgLT0gc3RhdGUuZXh0cmE7XG4gICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIHN0YXRlLmJhY2sgKz0gc3RhdGUuZXh0cmE7XG4gICAgICAgIH1cbiAgICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgICBsZW5ndGggJXVcXG5cIiwgc3RhdGUubGVuZ3RoKSk7XG4gICAgICAgIHN0YXRlLndhcyA9IHN0YXRlLmxlbmd0aDtcbiAgICAgICAgc3RhdGUubW9kZSA9IERJU1Q7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgRElTVDpcbiAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgIGhlcmUgPSBzdGF0ZS5kaXN0Y29kZVtob2xkICYgKCgxIDw8IHN0YXRlLmRpc3RiaXRzKSAtIDEpXTsvKkJJVFMoc3RhdGUuZGlzdGJpdHMpKi9cbiAgICAgICAgICBoZXJlX2JpdHMgPSBoZXJlID4+PiAyNDtcbiAgICAgICAgICBoZXJlX29wID0gKGhlcmUgPj4+IDE2KSAmIDB4ZmY7XG4gICAgICAgICAgaGVyZV92YWwgPSBoZXJlICYgMHhmZmZmO1xuXG4gICAgICAgICAgaWYgKChoZXJlX2JpdHMpIDw9IGJpdHMpIHsgYnJlYWs7IH1cbiAgICAgICAgICAvLy0tLSBQVUxMQllURSgpIC0tLS8vXG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAvLy0tLS8vXG4gICAgICAgIH1cbiAgICAgICAgaWYgKChoZXJlX29wICYgMHhmMCkgPT09IDApIHtcbiAgICAgICAgICBsYXN0X2JpdHMgPSBoZXJlX2JpdHM7XG4gICAgICAgICAgbGFzdF9vcCA9IGhlcmVfb3A7XG4gICAgICAgICAgbGFzdF92YWwgPSBoZXJlX3ZhbDtcbiAgICAgICAgICBmb3IgKDs7KSB7XG4gICAgICAgICAgICBoZXJlID0gc3RhdGUuZGlzdGNvZGVbbGFzdF92YWwgK1xuICAgICAgICAgICAgICAgICAgICAoKGhvbGQgJiAoKDEgPDwgKGxhc3RfYml0cyArIGxhc3Rfb3ApKSAtIDEpKS8qQklUUyhsYXN0LmJpdHMgKyBsYXN0Lm9wKSovID4+IGxhc3RfYml0cyldO1xuICAgICAgICAgICAgaGVyZV9iaXRzID0gaGVyZSA+Pj4gMjQ7XG4gICAgICAgICAgICBoZXJlX29wID0gKGhlcmUgPj4+IDE2KSAmIDB4ZmY7XG4gICAgICAgICAgICBoZXJlX3ZhbCA9IGhlcmUgJiAweGZmZmY7XG5cbiAgICAgICAgICAgIGlmICgobGFzdF9iaXRzICsgaGVyZV9iaXRzKSA8PSBiaXRzKSB7IGJyZWFrOyB9XG4gICAgICAgICAgICAvLy0tLSBQVUxMQllURSgpIC0tLS8vXG4gICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLy0tLSBEUk9QQklUUyhsYXN0LmJpdHMpIC0tLS8vXG4gICAgICAgICAgaG9sZCA+Pj49IGxhc3RfYml0cztcbiAgICAgICAgICBiaXRzIC09IGxhc3RfYml0cztcbiAgICAgICAgICAvLy0tLS8vXG4gICAgICAgICAgc3RhdGUuYmFjayArPSBsYXN0X2JpdHM7XG4gICAgICAgIH1cbiAgICAgICAgLy8tLS0gRFJPUEJJVFMoaGVyZS5iaXRzKSAtLS0vL1xuICAgICAgICBob2xkID4+Pj0gaGVyZV9iaXRzO1xuICAgICAgICBiaXRzIC09IGhlcmVfYml0cztcbiAgICAgICAgLy8tLS0vL1xuICAgICAgICBzdGF0ZS5iYWNrICs9IGhlcmVfYml0cztcbiAgICAgICAgaWYgKGhlcmVfb3AgJiA2NCkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgZGlzdGFuY2UgY29kZSc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBzdGF0ZS5vZmZzZXQgPSBoZXJlX3ZhbDtcbiAgICAgICAgc3RhdGUuZXh0cmEgPSAoaGVyZV9vcCkgJiAxNTtcbiAgICAgICAgc3RhdGUubW9kZSA9IERJU1RFWFQ7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgRElTVEVYVDpcbiAgICAgICAgaWYgKHN0YXRlLmV4dHJhKSB7XG4gICAgICAgICAgLy89PT0gTkVFREJJVFMoc3RhdGUuZXh0cmEpO1xuICAgICAgICAgIG4gPSBzdGF0ZS5leHRyYTtcbiAgICAgICAgICB3aGlsZSAoYml0cyA8IG4pIHtcbiAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7XG4gICAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vPT09Ly9cbiAgICAgICAgICBzdGF0ZS5vZmZzZXQgKz0gaG9sZCAmICgoMSA8PCBzdGF0ZS5leHRyYSkgLSAxKS8qQklUUyhzdGF0ZS5leHRyYSkqLztcbiAgICAgICAgICAvLy0tLSBEUk9QQklUUyhzdGF0ZS5leHRyYSkgLS0tLy9cbiAgICAgICAgICBob2xkID4+Pj0gc3RhdGUuZXh0cmE7XG4gICAgICAgICAgYml0cyAtPSBzdGF0ZS5leHRyYTtcbiAgICAgICAgICAvLy0tLS8vXG4gICAgICAgICAgc3RhdGUuYmFjayArPSBzdGF0ZS5leHRyYTtcbiAgICAgICAgfVxuLy8jaWZkZWYgSU5GTEFURV9TVFJJQ1RcbiAgICAgICAgaWYgKHN0YXRlLm9mZnNldCA+IHN0YXRlLmRtYXgpIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGRpc3RhbmNlIHRvbyBmYXIgYmFjayc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuLy8jZW5kaWZcbiAgICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgICBkaXN0YW5jZSAldVxcblwiLCBzdGF0ZS5vZmZzZXQpKTtcbiAgICAgICAgc3RhdGUubW9kZSA9IE1BVENIO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIE1BVENIOlxuICAgICAgICBpZiAobGVmdCA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgY29weSA9IF9vdXQgLSBsZWZ0O1xuICAgICAgICBpZiAoc3RhdGUub2Zmc2V0ID4gY29weSkgeyAgICAgICAgIC8qIGNvcHkgZnJvbSB3aW5kb3cgKi9cbiAgICAgICAgICBjb3B5ID0gc3RhdGUub2Zmc2V0IC0gY29weTtcbiAgICAgICAgICBpZiAoY29weSA+IHN0YXRlLndoYXZlKSB7XG4gICAgICAgICAgICBpZiAoc3RhdGUuc2FuZSkge1xuICAgICAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGRpc3RhbmNlIHRvbyBmYXIgYmFjayc7XG4gICAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuLy8gKCEpIFRoaXMgYmxvY2sgaXMgZGlzYWJsZWQgaW4gemxpYiBkZWZhdWx0cyxcbi8vIGRvbid0IGVuYWJsZSBpdCBmb3IgYmluYXJ5IGNvbXBhdGliaWxpdHlcbi8vI2lmZGVmIElORkxBVEVfQUxMT1dfSU5WQUxJRF9ESVNUQU5DRV9UT09GQVJfQVJSUlxuLy8gICAgICAgICAgVHJhY2UoKHN0ZGVyciwgXCJpbmZsYXRlLmMgdG9vIGZhclxcblwiKSk7XG4vLyAgICAgICAgICBjb3B5IC09IHN0YXRlLndoYXZlO1xuLy8gICAgICAgICAgaWYgKGNvcHkgPiBzdGF0ZS5sZW5ndGgpIHsgY29weSA9IHN0YXRlLmxlbmd0aDsgfVxuLy8gICAgICAgICAgaWYgKGNvcHkgPiBsZWZ0KSB7IGNvcHkgPSBsZWZ0OyB9XG4vLyAgICAgICAgICBsZWZ0IC09IGNvcHk7XG4vLyAgICAgICAgICBzdGF0ZS5sZW5ndGggLT0gY29weTtcbi8vICAgICAgICAgIGRvIHtcbi8vICAgICAgICAgICAgb3V0cHV0W3B1dCsrXSA9IDA7XG4vLyAgICAgICAgICB9IHdoaWxlICgtLWNvcHkpO1xuLy8gICAgICAgICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgeyBzdGF0ZS5tb2RlID0gTEVOOyB9XG4vLyAgICAgICAgICBicmVhaztcbi8vI2VuZGlmXG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjb3B5ID4gc3RhdGUud25leHQpIHtcbiAgICAgICAgICAgIGNvcHkgLT0gc3RhdGUud25leHQ7XG4gICAgICAgICAgICBmcm9tID0gc3RhdGUud3NpemUgLSBjb3B5O1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGZyb20gPSBzdGF0ZS53bmV4dCAtIGNvcHk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjb3B5ID4gc3RhdGUubGVuZ3RoKSB7IGNvcHkgPSBzdGF0ZS5sZW5ndGg7IH1cbiAgICAgICAgICBmcm9tX3NvdXJjZSA9IHN0YXRlLndpbmRvdztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjb3B5IGZyb20gb3V0cHV0ICovXG4gICAgICAgICAgZnJvbV9zb3VyY2UgPSBvdXRwdXQ7XG4gICAgICAgICAgZnJvbSA9IHB1dCAtIHN0YXRlLm9mZnNldDtcbiAgICAgICAgICBjb3B5ID0gc3RhdGUubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb3B5ID4gbGVmdCkgeyBjb3B5ID0gbGVmdDsgfVxuICAgICAgICBsZWZ0IC09IGNvcHk7XG4gICAgICAgIHN0YXRlLmxlbmd0aCAtPSBjb3B5O1xuICAgICAgICBkbyB7XG4gICAgICAgICAgb3V0cHV0W3B1dCsrXSA9IGZyb21fc291cmNlW2Zyb20rK107XG4gICAgICAgIH0gd2hpbGUgKC0tY29weSk7XG4gICAgICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHsgc3RhdGUubW9kZSA9IExFTjsgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTElUOlxuICAgICAgICBpZiAobGVmdCA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgb3V0cHV0W3B1dCsrXSA9IHN0YXRlLmxlbmd0aDtcbiAgICAgICAgbGVmdC0tO1xuICAgICAgICBzdGF0ZS5tb2RlID0gTEVOO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQ0hFQ0s6XG4gICAgICAgIGlmIChzdGF0ZS53cmFwKSB7XG4gICAgICAgICAgLy89PT0gTkVFREJJVFMoMzIpO1xuICAgICAgICAgIHdoaWxlIChiaXRzIDwgMzIpIHtcbiAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgICAgLy8gVXNlICd8JyBpbnN0ZWFkIG9mICcrJyB0byBtYWtlIHN1cmUgdGhhdCByZXN1bHQgaXMgc2lnbmVkXG4gICAgICAgICAgICBob2xkIHw9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICAgIF9vdXQgLT0gbGVmdDtcbiAgICAgICAgICBzdHJtLnRvdGFsX291dCArPSBfb3V0O1xuICAgICAgICAgIHN0YXRlLnRvdGFsICs9IF9vdXQ7XG4gICAgICAgICAgaWYgKF9vdXQpIHtcbiAgICAgICAgICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS5jaGVjayA9XG4gICAgICAgICAgICAgICAgLypVUERBVEUoc3RhdGUuY2hlY2ssIHB1dCAtIF9vdXQsIF9vdXQpOyovXG4gICAgICAgICAgICAgICAgKHN0YXRlLmZsYWdzID8gY3JjMzIoc3RhdGUuY2hlY2ssIG91dHB1dCwgX291dCwgcHV0IC0gX291dCkgOiBhZGxlcjMyKHN0YXRlLmNoZWNrLCBvdXRwdXQsIF9vdXQsIHB1dCAtIF9vdXQpKTtcblxuICAgICAgICAgIH1cbiAgICAgICAgICBfb3V0ID0gbGVmdDtcbiAgICAgICAgICAvLyBOQjogY3JjMzIgc3RvcmVkIGFzIHNpZ25lZCAzMi1iaXQgaW50LCB6c3dhcDMyIHJldHVybnMgc2lnbmVkIHRvb1xuICAgICAgICAgIGlmICgoc3RhdGUuZmxhZ3MgPyBob2xkIDogenN3YXAzMihob2xkKSkgIT09IHN0YXRlLmNoZWNrKSB7XG4gICAgICAgICAgICBzdHJtLm1zZyA9ICdpbmNvcnJlY3QgZGF0YSBjaGVjayc7XG4gICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgICAgaG9sZCA9IDA7XG4gICAgICAgICAgYml0cyA9IDA7XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICBjaGVjayBtYXRjaGVzIHRyYWlsZXJcXG5cIikpO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRlLm1vZGUgPSBMRU5HVEg7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgTEVOR1RIOlxuICAgICAgICBpZiAoc3RhdGUud3JhcCAmJiBzdGF0ZS5mbGFncykge1xuICAgICAgICAgIC8vPT09IE5FRURCSVRTKDMyKTtcbiAgICAgICAgICB3aGlsZSAoYml0cyA8IDMyKSB7XG4gICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLz09PS8vXG4gICAgICAgICAgaWYgKGhvbGQgIT09IChzdGF0ZS50b3RhbCAmIDB4ZmZmZmZmZmYpKSB7XG4gICAgICAgICAgICBzdHJtLm1zZyA9ICdpbmNvcnJlY3QgbGVuZ3RoIGNoZWNrJztcbiAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgLy89PT0gSU5JVEJJVFMoKTtcbiAgICAgICAgICBob2xkID0gMDtcbiAgICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgICAvLz09PS8vXG4gICAgICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgIGxlbmd0aCBtYXRjaGVzIHRyYWlsZXJcXG5cIikpO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRlLm1vZGUgPSBET05FO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIERPTkU6XG4gICAgICAgIHJldCA9IFpfU1RSRUFNX0VORDtcbiAgICAgICAgYnJlYWsgaW5mX2xlYXZlO1xuICAgICAgY2FzZSBCQUQ6XG4gICAgICAgIHJldCA9IFpfREFUQV9FUlJPUjtcbiAgICAgICAgYnJlYWsgaW5mX2xlYXZlO1xuICAgICAgY2FzZSBNRU06XG4gICAgICAgIHJldHVybiBaX01FTV9FUlJPUjtcbiAgICAgIGNhc2UgU1lOQzpcbiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SO1xuICAgIH1cbiAgfVxuXG4gIC8vIGluZl9sZWF2ZSA8LSBoZXJlIGlzIHJlYWwgcGxhY2UgZm9yIFwiZ290byBpbmZfbGVhdmVcIiwgZW11bGF0ZWQgdmlhIFwiYnJlYWsgaW5mX2xlYXZlXCJcblxuICAvKlxuICAgICBSZXR1cm4gZnJvbSBpbmZsYXRlKCksIHVwZGF0aW5nIHRoZSB0b3RhbCBjb3VudHMgYW5kIHRoZSBjaGVjayB2YWx1ZS5cbiAgICAgSWYgdGhlcmUgd2FzIG5vIHByb2dyZXNzIGR1cmluZyB0aGUgaW5mbGF0ZSgpIGNhbGwsIHJldHVybiBhIGJ1ZmZlclxuICAgICBlcnJvci4gIENhbGwgdXBkYXRld2luZG93KCkgdG8gY3JlYXRlIGFuZC9vciB1cGRhdGUgdGhlIHdpbmRvdyBzdGF0ZS5cbiAgICAgTm90ZTogYSBtZW1vcnkgZXJyb3IgZnJvbSBpbmZsYXRlKCkgaXMgbm9uLXJlY292ZXJhYmxlLlxuICAgKi9cblxuICAvLy0tLSBSRVNUT1JFKCkgLS0tXG4gIHN0cm0ubmV4dF9vdXQgPSBwdXQ7XG4gIHN0cm0uYXZhaWxfb3V0ID0gbGVmdDtcbiAgc3RybS5uZXh0X2luID0gbmV4dDtcbiAgc3RybS5hdmFpbF9pbiA9IGhhdmU7XG4gIHN0YXRlLmhvbGQgPSBob2xkO1xuICBzdGF0ZS5iaXRzID0gYml0cztcbiAgLy8tLS1cblxuICBpZiAoc3RhdGUud3NpemUgfHwgKF9vdXQgIT09IHN0cm0uYXZhaWxfb3V0ICYmIHN0YXRlLm1vZGUgPCBCQUQgJiZcbiAgICAgICAgICAgICAgICAgICAgICAoc3RhdGUubW9kZSA8IENIRUNLIHx8IGZsdXNoICE9PSBaX0ZJTklTSCkpKSB7XG4gICAgaWYgKHVwZGF0ZXdpbmRvdyhzdHJtLCBzdHJtLm91dHB1dCwgc3RybS5uZXh0X291dCwgX291dCAtIHN0cm0uYXZhaWxfb3V0KSkge1xuICAgICAgc3RhdGUubW9kZSA9IE1FTTtcbiAgICAgIHJldHVybiBaX01FTV9FUlJPUjtcbiAgICB9XG4gIH1cbiAgX2luIC09IHN0cm0uYXZhaWxfaW47XG4gIF9vdXQgLT0gc3RybS5hdmFpbF9vdXQ7XG4gIHN0cm0udG90YWxfaW4gKz0gX2luO1xuICBzdHJtLnRvdGFsX291dCArPSBfb3V0O1xuICBzdGF0ZS50b3RhbCArPSBfb3V0O1xuICBpZiAoc3RhdGUud3JhcCAmJiBfb3V0KSB7XG4gICAgc3RybS5hZGxlciA9IHN0YXRlLmNoZWNrID0gLypVUERBVEUoc3RhdGUuY2hlY2ssIHN0cm0ubmV4dF9vdXQgLSBfb3V0LCBfb3V0KTsqL1xuICAgICAgKHN0YXRlLmZsYWdzID8gY3JjMzIoc3RhdGUuY2hlY2ssIG91dHB1dCwgX291dCwgc3RybS5uZXh0X291dCAtIF9vdXQpIDogYWRsZXIzMihzdGF0ZS5jaGVjaywgb3V0cHV0LCBfb3V0LCBzdHJtLm5leHRfb3V0IC0gX291dCkpO1xuICB9XG4gIHN0cm0uZGF0YV90eXBlID0gc3RhdGUuYml0cyArIChzdGF0ZS5sYXN0ID8gNjQgOiAwKSArXG4gICAgICAgICAgICAgICAgICAgIChzdGF0ZS5tb2RlID09PSBUWVBFID8gMTI4IDogMCkgK1xuICAgICAgICAgICAgICAgICAgICAoc3RhdGUubW9kZSA9PT0gTEVOXyB8fCBzdGF0ZS5tb2RlID09PSBDT1BZXyA/IDI1NiA6IDApO1xuICBpZiAoKChfaW4gPT09IDAgJiYgX291dCA9PT0gMCkgfHwgZmx1c2ggPT09IFpfRklOSVNIKSAmJiByZXQgPT09IFpfT0spIHtcbiAgICByZXQgPSBaX0JVRl9FUlJPUjtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBpbmZsYXRlRW5kKHN0cm0pIHtcblxuICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUgLyp8fCBzdHJtLT56ZnJlZSA9PSAoZnJlZV9mdW5jKTAqLykge1xuICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUjtcbiAgfVxuXG4gIHZhciBzdGF0ZSA9IHN0cm0uc3RhdGU7XG4gIGlmIChzdGF0ZS53aW5kb3cpIHtcbiAgICBzdGF0ZS53aW5kb3cgPSBudWxsO1xuICB9XG4gIHN0cm0uc3RhdGUgPSBudWxsO1xuICByZXR1cm4gWl9PSztcbn1cblxuZnVuY3Rpb24gaW5mbGF0ZUdldEhlYWRlcihzdHJtLCBoZWFkKSB7XG4gIHZhciBzdGF0ZTtcblxuICAvKiBjaGVjayBzdGF0ZSAqL1xuICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUpIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SOyB9XG4gIHN0YXRlID0gc3RybS5zdGF0ZTtcbiAgaWYgKChzdGF0ZS53cmFwICYgMikgPT09IDApIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SOyB9XG5cbiAgLyogc2F2ZSBoZWFkZXIgc3RydWN0dXJlICovXG4gIHN0YXRlLmhlYWQgPSBoZWFkO1xuICBoZWFkLmRvbmUgPSBmYWxzZTtcbiAgcmV0dXJuIFpfT0s7XG59XG5cbmZ1bmN0aW9uIGluZmxhdGVTZXREaWN0aW9uYXJ5KHN0cm0sIGRpY3Rpb25hcnkpIHtcbiAgdmFyIGRpY3RMZW5ndGggPSBkaWN0aW9uYXJ5Lmxlbmd0aDtcblxuICB2YXIgc3RhdGU7XG4gIHZhciBkaWN0aWQ7XG4gIHZhciByZXQ7XG5cbiAgLyogY2hlY2sgc3RhdGUgKi9cbiAgaWYgKCFzdHJtIC8qID09IFpfTlVMTCAqLyB8fCAhc3RybS5zdGF0ZSAvKiA9PSBaX05VTEwgKi8pIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SOyB9XG4gIHN0YXRlID0gc3RybS5zdGF0ZTtcblxuICBpZiAoc3RhdGUud3JhcCAhPT0gMCAmJiBzdGF0ZS5tb2RlICE9PSBESUNUKSB7XG4gICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SO1xuICB9XG5cbiAgLyogY2hlY2sgZm9yIGNvcnJlY3QgZGljdGlvbmFyeSBpZGVudGlmaWVyICovXG4gIGlmIChzdGF0ZS5tb2RlID09PSBESUNUKSB7XG4gICAgZGljdGlkID0gMTsgLyogYWRsZXIzMigwLCBudWxsLCAwKSovXG4gICAgLyogZGljdGlkID0gYWRsZXIzMihkaWN0aWQsIGRpY3Rpb25hcnksIGRpY3RMZW5ndGgpOyAqL1xuICAgIGRpY3RpZCA9IGFkbGVyMzIoZGljdGlkLCBkaWN0aW9uYXJ5LCBkaWN0TGVuZ3RoLCAwKTtcbiAgICBpZiAoZGljdGlkICE9PSBzdGF0ZS5jaGVjaykge1xuICAgICAgcmV0dXJuIFpfREFUQV9FUlJPUjtcbiAgICB9XG4gIH1cbiAgLyogY29weSBkaWN0aW9uYXJ5IHRvIHdpbmRvdyB1c2luZyB1cGRhdGV3aW5kb3coKSwgd2hpY2ggd2lsbCBhbWVuZCB0aGVcbiAgIGV4aXN0aW5nIGRpY3Rpb25hcnkgaWYgYXBwcm9wcmlhdGUgKi9cbiAgcmV0ID0gdXBkYXRld2luZG93KHN0cm0sIGRpY3Rpb25hcnksIGRpY3RMZW5ndGgsIGRpY3RMZW5ndGgpO1xuICBpZiAocmV0KSB7XG4gICAgc3RhdGUubW9kZSA9IE1FTTtcbiAgICByZXR1cm4gWl9NRU1fRVJST1I7XG4gIH1cbiAgc3RhdGUuaGF2ZWRpY3QgPSAxO1xuICAvLyBUcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgIGRpY3Rpb25hcnkgc2V0XFxuXCIpKTtcbiAgcmV0dXJuIFpfT0s7XG59XG5cbmV4cG9ydHMuaW5mbGF0ZVJlc2V0ID0gaW5mbGF0ZVJlc2V0O1xuZXhwb3J0cy5pbmZsYXRlUmVzZXQyID0gaW5mbGF0ZVJlc2V0MjtcbmV4cG9ydHMuaW5mbGF0ZVJlc2V0S2VlcCA9IGluZmxhdGVSZXNldEtlZXA7XG5leHBvcnRzLmluZmxhdGVJbml0ID0gaW5mbGF0ZUluaXQ7XG5leHBvcnRzLmluZmxhdGVJbml0MiA9IGluZmxhdGVJbml0MjtcbmV4cG9ydHMuaW5mbGF0ZSA9IGluZmxhdGU7XG5leHBvcnRzLmluZmxhdGVFbmQgPSBpbmZsYXRlRW5kO1xuZXhwb3J0cy5pbmZsYXRlR2V0SGVhZGVyID0gaW5mbGF0ZUdldEhlYWRlcjtcbmV4cG9ydHMuaW5mbGF0ZVNldERpY3Rpb25hcnkgPSBpbmZsYXRlU2V0RGljdGlvbmFyeTtcbmV4cG9ydHMuaW5mbGF0ZUluZm8gPSAncGFrbyBpbmZsYXRlIChmcm9tIE5vZGVjYSBwcm9qZWN0KSc7XG5cbi8qIE5vdCBpbXBsZW1lbnRlZFxuZXhwb3J0cy5pbmZsYXRlQ29weSA9IGluZmxhdGVDb3B5O1xuZXhwb3J0cy5pbmZsYXRlR2V0RGljdGlvbmFyeSA9IGluZmxhdGVHZXREaWN0aW9uYXJ5O1xuZXhwb3J0cy5pbmZsYXRlTWFyayA9IGluZmxhdGVNYXJrO1xuZXhwb3J0cy5pbmZsYXRlUHJpbWUgPSBpbmZsYXRlUHJpbWU7XG5leHBvcnRzLmluZmxhdGVTeW5jID0gaW5mbGF0ZVN5bmM7XG5leHBvcnRzLmluZmxhdGVTeW5jUG9pbnQgPSBpbmZsYXRlU3luY1BvaW50O1xuZXhwb3J0cy5pbmZsYXRlVW5kZXJtaW5lID0gaW5mbGF0ZVVuZGVybWluZTtcbiovXG4iLCIndXNlIHN0cmljdCc7XG5cbi8vIChDKSAxOTk1LTIwMTMgSmVhbi1sb3VwIEdhaWxseSBhbmQgTWFyayBBZGxlclxuLy8gKEMpIDIwMTQtMjAxNyBWaXRhbHkgUHV6cmluIGFuZCBBbmRyZXkgVHVwaXRzaW5cbi8vXG4vLyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZFxuLy8gd2FycmFudHkuIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzXG4vLyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLFxuLy8gaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdFxuLy8gZnJlZWx5LCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOlxuLy9cbi8vIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90XG4vLyAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlXG4vLyAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZVxuLy8gICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLlxuLy8gMi4gQWx0ZXJlZCBzb3VyY2UgdmVyc2lvbnMgbXVzdCBiZSBwbGFpbmx5IG1hcmtlZCBhcyBzdWNoLCBhbmQgbXVzdCBub3QgYmVcbi8vICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLlxuLy8gMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi5cblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMvY29tbW9uJyk7XG5cbnZhciBNQVhCSVRTID0gMTU7XG52YXIgRU5PVUdIX0xFTlMgPSA4NTI7XG52YXIgRU5PVUdIX0RJU1RTID0gNTkyO1xuLy92YXIgRU5PVUdIID0gKEVOT1VHSF9MRU5TK0VOT1VHSF9ESVNUUyk7XG5cbnZhciBDT0RFUyA9IDA7XG52YXIgTEVOUyA9IDE7XG52YXIgRElTVFMgPSAyO1xuXG52YXIgbGJhc2UgPSBbIC8qIExlbmd0aCBjb2RlcyAyNTcuLjI4NSBiYXNlICovXG4gIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTMsIDE1LCAxNywgMTksIDIzLCAyNywgMzEsXG4gIDM1LCA0MywgNTEsIDU5LCA2NywgODMsIDk5LCAxMTUsIDEzMSwgMTYzLCAxOTUsIDIyNywgMjU4LCAwLCAwXG5dO1xuXG52YXIgbGV4dCA9IFsgLyogTGVuZ3RoIGNvZGVzIDI1Ny4uMjg1IGV4dHJhICovXG4gIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTcsIDE3LCAxNywgMTcsIDE4LCAxOCwgMTgsIDE4LFxuICAxOSwgMTksIDE5LCAxOSwgMjAsIDIwLCAyMCwgMjAsIDIxLCAyMSwgMjEsIDIxLCAxNiwgNzIsIDc4XG5dO1xuXG52YXIgZGJhc2UgPSBbIC8qIERpc3RhbmNlIGNvZGVzIDAuLjI5IGJhc2UgKi9cbiAgMSwgMiwgMywgNCwgNSwgNywgOSwgMTMsIDE3LCAyNSwgMzMsIDQ5LCA2NSwgOTcsIDEyOSwgMTkzLFxuICAyNTcsIDM4NSwgNTEzLCA3NjksIDEwMjUsIDE1MzcsIDIwNDksIDMwNzMsIDQwOTcsIDYxNDUsXG4gIDgxOTMsIDEyMjg5LCAxNjM4NSwgMjQ1NzcsIDAsIDBcbl07XG5cbnZhciBkZXh0ID0gWyAvKiBEaXN0YW5jZSBjb2RlcyAwLi4yOSBleHRyYSAqL1xuICAxNiwgMTYsIDE2LCAxNiwgMTcsIDE3LCAxOCwgMTgsIDE5LCAxOSwgMjAsIDIwLCAyMSwgMjEsIDIyLCAyMixcbiAgMjMsIDIzLCAyNCwgMjQsIDI1LCAyNSwgMjYsIDI2LCAyNywgMjcsXG4gIDI4LCAyOCwgMjksIDI5LCA2NCwgNjRcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5mbGF0ZV90YWJsZSh0eXBlLCBsZW5zLCBsZW5zX2luZGV4LCBjb2RlcywgdGFibGUsIHRhYmxlX2luZGV4LCB3b3JrLCBvcHRzKVxue1xuICB2YXIgYml0cyA9IG9wdHMuYml0cztcbiAgICAgIC8vaGVyZSA9IG9wdHMuaGVyZTsgLyogdGFibGUgZW50cnkgZm9yIGR1cGxpY2F0aW9uICovXG5cbiAgdmFyIGxlbiA9IDA7ICAgICAgICAgICAgICAgLyogYSBjb2RlJ3MgbGVuZ3RoIGluIGJpdHMgKi9cbiAgdmFyIHN5bSA9IDA7ICAgICAgICAgICAgICAgLyogaW5kZXggb2YgY29kZSBzeW1ib2xzICovXG4gIHZhciBtaW4gPSAwLCBtYXggPSAwOyAgICAgICAgICAvKiBtaW5pbXVtIGFuZCBtYXhpbXVtIGNvZGUgbGVuZ3RocyAqL1xuICB2YXIgcm9vdCA9IDA7ICAgICAgICAgICAgICAvKiBudW1iZXIgb2YgaW5kZXggYml0cyBmb3Igcm9vdCB0YWJsZSAqL1xuICB2YXIgY3VyciA9IDA7ICAgICAgICAgICAgICAvKiBudW1iZXIgb2YgaW5kZXggYml0cyBmb3IgY3VycmVudCB0YWJsZSAqL1xuICB2YXIgZHJvcCA9IDA7ICAgICAgICAgICAgICAvKiBjb2RlIGJpdHMgdG8gZHJvcCBmb3Igc3ViLXRhYmxlICovXG4gIHZhciBsZWZ0ID0gMDsgICAgICAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIHByZWZpeCBjb2RlcyBhdmFpbGFibGUgKi9cbiAgdmFyIHVzZWQgPSAwOyAgICAgICAgICAgICAgLyogY29kZSBlbnRyaWVzIGluIHRhYmxlIHVzZWQgKi9cbiAgdmFyIGh1ZmYgPSAwOyAgICAgICAgICAgICAgLyogSHVmZm1hbiBjb2RlICovXG4gIHZhciBpbmNyOyAgICAgICAgICAgICAgLyogZm9yIGluY3JlbWVudGluZyBjb2RlLCBpbmRleCAqL1xuICB2YXIgZmlsbDsgICAgICAgICAgICAgIC8qIGluZGV4IGZvciByZXBsaWNhdGluZyBlbnRyaWVzICovXG4gIHZhciBsb3c7ICAgICAgICAgICAgICAgLyogbG93IGJpdHMgZm9yIGN1cnJlbnQgcm9vdCBlbnRyeSAqL1xuICB2YXIgbWFzazsgICAgICAgICAgICAgIC8qIG1hc2sgZm9yIGxvdyByb290IGJpdHMgKi9cbiAgdmFyIG5leHQ7ICAgICAgICAgICAgIC8qIG5leHQgYXZhaWxhYmxlIHNwYWNlIGluIHRhYmxlICovXG4gIHZhciBiYXNlID0gbnVsbDsgICAgIC8qIGJhc2UgdmFsdWUgdGFibGUgdG8gdXNlICovXG4gIHZhciBiYXNlX2luZGV4ID0gMDtcbi8vICB2YXIgc2hvZXh0cmE7ICAgIC8qIGV4dHJhIGJpdHMgdGFibGUgdG8gdXNlICovXG4gIHZhciBlbmQ7ICAgICAgICAgICAgICAgICAgICAvKiB1c2UgYmFzZSBhbmQgZXh0cmEgZm9yIHN5bWJvbCA+IGVuZCAqL1xuICB2YXIgY291bnQgPSBuZXcgdXRpbHMuQnVmMTYoTUFYQklUUyArIDEpOyAvL1tNQVhCSVRTKzFdOyAgICAvKiBudW1iZXIgb2YgY29kZXMgb2YgZWFjaCBsZW5ndGggKi9cbiAgdmFyIG9mZnMgPSBuZXcgdXRpbHMuQnVmMTYoTUFYQklUUyArIDEpOyAvL1tNQVhCSVRTKzFdOyAgICAgLyogb2Zmc2V0cyBpbiB0YWJsZSBmb3IgZWFjaCBsZW5ndGggKi9cbiAgdmFyIGV4dHJhID0gbnVsbDtcbiAgdmFyIGV4dHJhX2luZGV4ID0gMDtcblxuICB2YXIgaGVyZV9iaXRzLCBoZXJlX29wLCBoZXJlX3ZhbDtcblxuICAvKlxuICAgUHJvY2VzcyBhIHNldCBvZiBjb2RlIGxlbmd0aHMgdG8gY3JlYXRlIGEgY2Fub25pY2FsIEh1ZmZtYW4gY29kZS4gIFRoZVxuICAgY29kZSBsZW5ndGhzIGFyZSBsZW5zWzAuLmNvZGVzLTFdLiAgRWFjaCBsZW5ndGggY29ycmVzcG9uZHMgdG8gdGhlXG4gICBzeW1ib2xzIDAuLmNvZGVzLTEuICBUaGUgSHVmZm1hbiBjb2RlIGlzIGdlbmVyYXRlZCBieSBmaXJzdCBzb3J0aW5nIHRoZVxuICAgc3ltYm9scyBieSBsZW5ndGggZnJvbSBzaG9ydCB0byBsb25nLCBhbmQgcmV0YWluaW5nIHRoZSBzeW1ib2wgb3JkZXJcbiAgIGZvciBjb2RlcyB3aXRoIGVxdWFsIGxlbmd0aHMuICBUaGVuIHRoZSBjb2RlIHN0YXJ0cyB3aXRoIGFsbCB6ZXJvIGJpdHNcbiAgIGZvciB0aGUgZmlyc3QgY29kZSBvZiB0aGUgc2hvcnRlc3QgbGVuZ3RoLCBhbmQgdGhlIGNvZGVzIGFyZSBpbnRlZ2VyXG4gICBpbmNyZW1lbnRzIGZvciB0aGUgc2FtZSBsZW5ndGgsIGFuZCB6ZXJvcyBhcmUgYXBwZW5kZWQgYXMgdGhlIGxlbmd0aFxuICAgaW5jcmVhc2VzLiAgRm9yIHRoZSBkZWZsYXRlIGZvcm1hdCwgdGhlc2UgYml0cyBhcmUgc3RvcmVkIGJhY2t3YXJkc1xuICAgZnJvbSB0aGVpciBtb3JlIG5hdHVyYWwgaW50ZWdlciBpbmNyZW1lbnQgb3JkZXJpbmcsIGFuZCBzbyB3aGVuIHRoZVxuICAgZGVjb2RpbmcgdGFibGVzIGFyZSBidWlsdCBpbiB0aGUgbGFyZ2UgbG9vcCBiZWxvdywgdGhlIGludGVnZXIgY29kZXNcbiAgIGFyZSBpbmNyZW1lbnRlZCBiYWNrd2FyZHMuXG5cbiAgIFRoaXMgcm91dGluZSBhc3N1bWVzLCBidXQgZG9lcyBub3QgY2hlY2ssIHRoYXQgYWxsIG9mIHRoZSBlbnRyaWVzIGluXG4gICBsZW5zW10gYXJlIGluIHRoZSByYW5nZSAwLi5NQVhCSVRTLiAgVGhlIGNhbGxlciBtdXN0IGFzc3VyZSB0aGlzLlxuICAgMS4uTUFYQklUUyBpcyBpbnRlcnByZXRlZCBhcyB0aGF0IGNvZGUgbGVuZ3RoLiAgemVybyBtZWFucyB0aGF0IHRoYXRcbiAgIHN5bWJvbCBkb2VzIG5vdCBvY2N1ciBpbiB0aGlzIGNvZGUuXG5cbiAgIFRoZSBjb2RlcyBhcmUgc29ydGVkIGJ5IGNvbXB1dGluZyBhIGNvdW50IG9mIGNvZGVzIGZvciBlYWNoIGxlbmd0aCxcbiAgIGNyZWF0aW5nIGZyb20gdGhhdCBhIHRhYmxlIG9mIHN0YXJ0aW5nIGluZGljZXMgZm9yIGVhY2ggbGVuZ3RoIGluIHRoZVxuICAgc29ydGVkIHRhYmxlLCBhbmQgdGhlbiBlbnRlcmluZyB0aGUgc3ltYm9scyBpbiBvcmRlciBpbiB0aGUgc29ydGVkXG4gICB0YWJsZS4gIFRoZSBzb3J0ZWQgdGFibGUgaXMgd29ya1tdLCB3aXRoIHRoYXQgc3BhY2UgYmVpbmcgcHJvdmlkZWQgYnlcbiAgIHRoZSBjYWxsZXIuXG5cbiAgIFRoZSBsZW5ndGggY291bnRzIGFyZSB1c2VkIGZvciBvdGhlciBwdXJwb3NlcyBhcyB3ZWxsLCBpLmUuIGZpbmRpbmdcbiAgIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIGxlbmd0aCBjb2RlcywgZGV0ZXJtaW5pbmcgaWYgdGhlcmUgYXJlIGFueVxuICAgY29kZXMgYXQgYWxsLCBjaGVja2luZyBmb3IgYSB2YWxpZCBzZXQgb2YgbGVuZ3RocywgYW5kIGxvb2tpbmcgYWhlYWRcbiAgIGF0IGxlbmd0aCBjb3VudHMgdG8gZGV0ZXJtaW5lIHN1Yi10YWJsZSBzaXplcyB3aGVuIGJ1aWxkaW5nIHRoZVxuICAgZGVjb2RpbmcgdGFibGVzLlxuICAgKi9cblxuICAvKiBhY2N1bXVsYXRlIGxlbmd0aHMgZm9yIGNvZGVzIChhc3N1bWVzIGxlbnNbXSBhbGwgaW4gMC4uTUFYQklUUykgKi9cbiAgZm9yIChsZW4gPSAwOyBsZW4gPD0gTUFYQklUUzsgbGVuKyspIHtcbiAgICBjb3VudFtsZW5dID0gMDtcbiAgfVxuICBmb3IgKHN5bSA9IDA7IHN5bSA8IGNvZGVzOyBzeW0rKykge1xuICAgIGNvdW50W2xlbnNbbGVuc19pbmRleCArIHN5bV1dKys7XG4gIH1cblxuICAvKiBib3VuZCBjb2RlIGxlbmd0aHMsIGZvcmNlIHJvb3QgdG8gYmUgd2l0aGluIGNvZGUgbGVuZ3RocyAqL1xuICByb290ID0gYml0cztcbiAgZm9yIChtYXggPSBNQVhCSVRTOyBtYXggPj0gMTsgbWF4LS0pIHtcbiAgICBpZiAoY291bnRbbWF4XSAhPT0gMCkgeyBicmVhazsgfVxuICB9XG4gIGlmIChyb290ID4gbWF4KSB7XG4gICAgcm9vdCA9IG1heDtcbiAgfVxuICBpZiAobWF4ID09PSAwKSB7ICAgICAgICAgICAgICAgICAgICAgLyogbm8gc3ltYm9scyB0byBjb2RlIGF0IGFsbCAqL1xuICAgIC8vdGFibGUub3Bbb3B0cy50YWJsZV9pbmRleF0gPSA2NDsgIC8vaGVyZS5vcCA9ICh2YXIgY2hhcik2NDsgICAgLyogaW52YWxpZCBjb2RlIG1hcmtlciAqL1xuICAgIC8vdGFibGUuYml0c1tvcHRzLnRhYmxlX2luZGV4XSA9IDE7ICAgLy9oZXJlLmJpdHMgPSAodmFyIGNoYXIpMTtcbiAgICAvL3RhYmxlLnZhbFtvcHRzLnRhYmxlX2luZGV4KytdID0gMDsgICAvL2hlcmUudmFsID0gKHZhciBzaG9ydCkwO1xuICAgIHRhYmxlW3RhYmxlX2luZGV4KytdID0gKDEgPDwgMjQpIHwgKDY0IDw8IDE2KSB8IDA7XG5cblxuICAgIC8vdGFibGUub3Bbb3B0cy50YWJsZV9pbmRleF0gPSA2NDtcbiAgICAvL3RhYmxlLmJpdHNbb3B0cy50YWJsZV9pbmRleF0gPSAxO1xuICAgIC8vdGFibGUudmFsW29wdHMudGFibGVfaW5kZXgrK10gPSAwO1xuICAgIHRhYmxlW3RhYmxlX2luZGV4KytdID0gKDEgPDwgMjQpIHwgKDY0IDw8IDE2KSB8IDA7XG5cbiAgICBvcHRzLmJpdHMgPSAxO1xuICAgIHJldHVybiAwOyAgICAgLyogbm8gc3ltYm9scywgYnV0IHdhaXQgZm9yIGRlY29kaW5nIHRvIHJlcG9ydCBlcnJvciAqL1xuICB9XG4gIGZvciAobWluID0gMTsgbWluIDwgbWF4OyBtaW4rKykge1xuICAgIGlmIChjb3VudFttaW5dICE9PSAwKSB7IGJyZWFrOyB9XG4gIH1cbiAgaWYgKHJvb3QgPCBtaW4pIHtcbiAgICByb290ID0gbWluO1xuICB9XG5cbiAgLyogY2hlY2sgZm9yIGFuIG92ZXItc3Vic2NyaWJlZCBvciBpbmNvbXBsZXRlIHNldCBvZiBsZW5ndGhzICovXG4gIGxlZnQgPSAxO1xuICBmb3IgKGxlbiA9IDE7IGxlbiA8PSBNQVhCSVRTOyBsZW4rKykge1xuICAgIGxlZnQgPDw9IDE7XG4gICAgbGVmdCAtPSBjb3VudFtsZW5dO1xuICAgIGlmIChsZWZ0IDwgMCkge1xuICAgICAgcmV0dXJuIC0xO1xuICAgIH0gICAgICAgIC8qIG92ZXItc3Vic2NyaWJlZCAqL1xuICB9XG4gIGlmIChsZWZ0ID4gMCAmJiAodHlwZSA9PT0gQ09ERVMgfHwgbWF4ICE9PSAxKSkge1xuICAgIHJldHVybiAtMTsgICAgICAgICAgICAgICAgICAgICAgLyogaW5jb21wbGV0ZSBzZXQgKi9cbiAgfVxuXG4gIC8qIGdlbmVyYXRlIG9mZnNldHMgaW50byBzeW1ib2wgdGFibGUgZm9yIGVhY2ggbGVuZ3RoIGZvciBzb3J0aW5nICovXG4gIG9mZnNbMV0gPSAwO1xuICBmb3IgKGxlbiA9IDE7IGxlbiA8IE1BWEJJVFM7IGxlbisrKSB7XG4gICAgb2Zmc1tsZW4gKyAxXSA9IG9mZnNbbGVuXSArIGNvdW50W2xlbl07XG4gIH1cblxuICAvKiBzb3J0IHN5bWJvbHMgYnkgbGVuZ3RoLCBieSBzeW1ib2wgb3JkZXIgd2l0aGluIGVhY2ggbGVuZ3RoICovXG4gIGZvciAoc3ltID0gMDsgc3ltIDwgY29kZXM7IHN5bSsrKSB7XG4gICAgaWYgKGxlbnNbbGVuc19pbmRleCArIHN5bV0gIT09IDApIHtcbiAgICAgIHdvcmtbb2Zmc1tsZW5zW2xlbnNfaW5kZXggKyBzeW1dXSsrXSA9IHN5bTtcbiAgICB9XG4gIH1cblxuICAvKlxuICAgQ3JlYXRlIGFuZCBmaWxsIGluIGRlY29kaW5nIHRhYmxlcy4gIEluIHRoaXMgbG9vcCwgdGhlIHRhYmxlIGJlaW5nXG4gICBmaWxsZWQgaXMgYXQgbmV4dCBhbmQgaGFzIGN1cnIgaW5kZXggYml0cy4gIFRoZSBjb2RlIGJlaW5nIHVzZWQgaXMgaHVmZlxuICAgd2l0aCBsZW5ndGggbGVuLiAgVGhhdCBjb2RlIGlzIGNvbnZlcnRlZCB0byBhbiBpbmRleCBieSBkcm9wcGluZyBkcm9wXG4gICBiaXRzIG9mZiBvZiB0aGUgYm90dG9tLiAgRm9yIGNvZGVzIHdoZXJlIGxlbiBpcyBsZXNzIHRoYW4gZHJvcCArIGN1cnIsXG4gICB0aG9zZSB0b3AgZHJvcCArIGN1cnIgLSBsZW4gYml0cyBhcmUgaW5jcmVtZW50ZWQgdGhyb3VnaCBhbGwgdmFsdWVzIHRvXG4gICBmaWxsIHRoZSB0YWJsZSB3aXRoIHJlcGxpY2F0ZWQgZW50cmllcy5cblxuICAgcm9vdCBpcyB0aGUgbnVtYmVyIG9mIGluZGV4IGJpdHMgZm9yIHRoZSByb290IHRhYmxlLiAgV2hlbiBsZW4gZXhjZWVkc1xuICAgcm9vdCwgc3ViLXRhYmxlcyBhcmUgY3JlYXRlZCBwb2ludGVkIHRvIGJ5IHRoZSByb290IGVudHJ5IHdpdGggYW4gaW5kZXhcbiAgIG9mIHRoZSBsb3cgcm9vdCBiaXRzIG9mIGh1ZmYuICBUaGlzIGlzIHNhdmVkIGluIGxvdyB0byBjaGVjayBmb3Igd2hlbiBhXG4gICBuZXcgc3ViLXRhYmxlIHNob3VsZCBiZSBzdGFydGVkLiAgZHJvcCBpcyB6ZXJvIHdoZW4gdGhlIHJvb3QgdGFibGUgaXNcbiAgIGJlaW5nIGZpbGxlZCwgYW5kIGRyb3AgaXMgcm9vdCB3aGVuIHN1Yi10YWJsZXMgYXJlIGJlaW5nIGZpbGxlZC5cblxuICAgV2hlbiBhIG5ldyBzdWItdGFibGUgaXMgbmVlZGVkLCBpdCBpcyBuZWNlc3NhcnkgdG8gbG9vayBhaGVhZCBpbiB0aGVcbiAgIGNvZGUgbGVuZ3RocyB0byBkZXRlcm1pbmUgd2hhdCBzaXplIHN1Yi10YWJsZSBpcyBuZWVkZWQuICBUaGUgbGVuZ3RoXG4gICBjb3VudHMgYXJlIHVzZWQgZm9yIHRoaXMsIGFuZCBzbyBjb3VudFtdIGlzIGRlY3JlbWVudGVkIGFzIGNvZGVzIGFyZVxuICAgZW50ZXJlZCBpbiB0aGUgdGFibGVzLlxuXG4gICB1c2VkIGtlZXBzIHRyYWNrIG9mIGhvdyBtYW55IHRhYmxlIGVudHJpZXMgaGF2ZSBiZWVuIGFsbG9jYXRlZCBmcm9tIHRoZVxuICAgcHJvdmlkZWQgKnRhYmxlIHNwYWNlLiAgSXQgaXMgY2hlY2tlZCBmb3IgTEVOUyBhbmQgRElTVCB0YWJsZXMgYWdhaW5zdFxuICAgdGhlIGNvbnN0YW50cyBFTk9VR0hfTEVOUyBhbmQgRU5PVUdIX0RJU1RTIHRvIGd1YXJkIGFnYWluc3QgY2hhbmdlcyBpblxuICAgdGhlIGluaXRpYWwgcm9vdCB0YWJsZSBzaXplIGNvbnN0YW50cy4gIFNlZSB0aGUgY29tbWVudHMgaW4gaW5mdHJlZXMuaFxuICAgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG5cbiAgIHN5bSBpbmNyZW1lbnRzIHRocm91Z2ggYWxsIHN5bWJvbHMsIGFuZCB0aGUgbG9vcCB0ZXJtaW5hdGVzIHdoZW5cbiAgIGFsbCBjb2RlcyBvZiBsZW5ndGggbWF4LCBpLmUuIGFsbCBjb2RlcywgaGF2ZSBiZWVuIHByb2Nlc3NlZC4gIFRoaXNcbiAgIHJvdXRpbmUgcGVybWl0cyBpbmNvbXBsZXRlIGNvZGVzLCBzbyBhbm90aGVyIGxvb3AgYWZ0ZXIgdGhpcyBvbmUgZmlsbHNcbiAgIGluIHRoZSByZXN0IG9mIHRoZSBkZWNvZGluZyB0YWJsZXMgd2l0aCBpbnZhbGlkIGNvZGUgbWFya2Vycy5cbiAgICovXG5cbiAgLyogc2V0IHVwIGZvciBjb2RlIHR5cGUgKi9cbiAgLy8gcG9vciBtYW4gb3B0aW1pemF0aW9uIC0gdXNlIGlmLWVsc2UgaW5zdGVhZCBvZiBzd2l0Y2gsXG4gIC8vIHRvIGF2b2lkIGRlb3B0cyBpbiBvbGQgdjhcbiAgaWYgKHR5cGUgPT09IENPREVTKSB7XG4gICAgYmFzZSA9IGV4dHJhID0gd29yazsgICAgLyogZHVtbXkgdmFsdWUtLW5vdCB1c2VkICovXG4gICAgZW5kID0gMTk7XG5cbiAgfSBlbHNlIGlmICh0eXBlID09PSBMRU5TKSB7XG4gICAgYmFzZSA9IGxiYXNlO1xuICAgIGJhc2VfaW5kZXggLT0gMjU3O1xuICAgIGV4dHJhID0gbGV4dDtcbiAgICBleHRyYV9pbmRleCAtPSAyNTc7XG4gICAgZW5kID0gMjU2O1xuXG4gIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAvKiBESVNUUyAqL1xuICAgIGJhc2UgPSBkYmFzZTtcbiAgICBleHRyYSA9IGRleHQ7XG4gICAgZW5kID0gLTE7XG4gIH1cblxuICAvKiBpbml0aWFsaXplIG9wdHMgZm9yIGxvb3AgKi9cbiAgaHVmZiA9IDA7ICAgICAgICAgICAgICAgICAgIC8qIHN0YXJ0aW5nIGNvZGUgKi9cbiAgc3ltID0gMDsgICAgICAgICAgICAgICAgICAgIC8qIHN0YXJ0aW5nIGNvZGUgc3ltYm9sICovXG4gIGxlbiA9IG1pbjsgICAgICAgICAgICAgICAgICAvKiBzdGFydGluZyBjb2RlIGxlbmd0aCAqL1xuICBuZXh0ID0gdGFibGVfaW5kZXg7ICAgICAgICAgICAgICAvKiBjdXJyZW50IHRhYmxlIHRvIGZpbGwgaW4gKi9cbiAgY3VyciA9IHJvb3Q7ICAgICAgICAgICAgICAgIC8qIGN1cnJlbnQgdGFibGUgaW5kZXggYml0cyAqL1xuICBkcm9wID0gMDsgICAgICAgICAgICAgICAgICAgLyogY3VycmVudCBiaXRzIHRvIGRyb3AgZnJvbSBjb2RlIGZvciBpbmRleCAqL1xuICBsb3cgPSAtMTsgICAgICAgICAgICAgICAgICAgLyogdHJpZ2dlciBuZXcgc3ViLXRhYmxlIHdoZW4gbGVuID4gcm9vdCAqL1xuICB1c2VkID0gMSA8PCByb290OyAgICAgICAgICAvKiB1c2Ugcm9vdCB0YWJsZSBlbnRyaWVzICovXG4gIG1hc2sgPSB1c2VkIC0gMTsgICAgICAgICAgICAvKiBtYXNrIGZvciBjb21wYXJpbmcgbG93ICovXG5cbiAgLyogY2hlY2sgYXZhaWxhYmxlIHRhYmxlIHNwYWNlICovXG4gIGlmICgodHlwZSA9PT0gTEVOUyAmJiB1c2VkID4gRU5PVUdIX0xFTlMpIHx8XG4gICAgKHR5cGUgPT09IERJU1RTICYmIHVzZWQgPiBFTk9VR0hfRElTVFMpKSB7XG4gICAgcmV0dXJuIDE7XG4gIH1cblxuICAvKiBwcm9jZXNzIGFsbCBjb2RlcyBhbmQgbWFrZSB0YWJsZSBlbnRyaWVzICovXG4gIGZvciAoOzspIHtcbiAgICAvKiBjcmVhdGUgdGFibGUgZW50cnkgKi9cbiAgICBoZXJlX2JpdHMgPSBsZW4gLSBkcm9wO1xuICAgIGlmICh3b3JrW3N5bV0gPCBlbmQpIHtcbiAgICAgIGhlcmVfb3AgPSAwO1xuICAgICAgaGVyZV92YWwgPSB3b3JrW3N5bV07XG4gICAgfVxuICAgIGVsc2UgaWYgKHdvcmtbc3ltXSA+IGVuZCkge1xuICAgICAgaGVyZV9vcCA9IGV4dHJhW2V4dHJhX2luZGV4ICsgd29ya1tzeW1dXTtcbiAgICAgIGhlcmVfdmFsID0gYmFzZVtiYXNlX2luZGV4ICsgd29ya1tzeW1dXTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBoZXJlX29wID0gMzIgKyA2NDsgICAgICAgICAvKiBlbmQgb2YgYmxvY2sgKi9cbiAgICAgIGhlcmVfdmFsID0gMDtcbiAgICB9XG5cbiAgICAvKiByZXBsaWNhdGUgZm9yIHRob3NlIGluZGljZXMgd2l0aCBsb3cgbGVuIGJpdHMgZXF1YWwgdG8gaHVmZiAqL1xuICAgIGluY3IgPSAxIDw8IChsZW4gLSBkcm9wKTtcbiAgICBmaWxsID0gMSA8PCBjdXJyO1xuICAgIG1pbiA9IGZpbGw7ICAgICAgICAgICAgICAgICAvKiBzYXZlIG9mZnNldCB0byBuZXh0IHRhYmxlICovXG4gICAgZG8ge1xuICAgICAgZmlsbCAtPSBpbmNyO1xuICAgICAgdGFibGVbbmV4dCArIChodWZmID4+IGRyb3ApICsgZmlsbF0gPSAoaGVyZV9iaXRzIDw8IDI0KSB8IChoZXJlX29wIDw8IDE2KSB8IGhlcmVfdmFsIHwwO1xuICAgIH0gd2hpbGUgKGZpbGwgIT09IDApO1xuXG4gICAgLyogYmFja3dhcmRzIGluY3JlbWVudCB0aGUgbGVuLWJpdCBjb2RlIGh1ZmYgKi9cbiAgICBpbmNyID0gMSA8PCAobGVuIC0gMSk7XG4gICAgd2hpbGUgKGh1ZmYgJiBpbmNyKSB7XG4gICAgICBpbmNyID4+PSAxO1xuICAgIH1cbiAgICBpZiAoaW5jciAhPT0gMCkge1xuICAgICAgaHVmZiAmPSBpbmNyIC0gMTtcbiAgICAgIGh1ZmYgKz0gaW5jcjtcbiAgICB9IGVsc2Uge1xuICAgICAgaHVmZiA9IDA7XG4gICAgfVxuXG4gICAgLyogZ28gdG8gbmV4dCBzeW1ib2wsIHVwZGF0ZSBjb3VudCwgbGVuICovXG4gICAgc3ltKys7XG4gICAgaWYgKC0tY291bnRbbGVuXSA9PT0gMCkge1xuICAgICAgaWYgKGxlbiA9PT0gbWF4KSB7IGJyZWFrOyB9XG4gICAgICBsZW4gPSBsZW5zW2xlbnNfaW5kZXggKyB3b3JrW3N5bV1dO1xuICAgIH1cblxuICAgIC8qIGNyZWF0ZSBuZXcgc3ViLXRhYmxlIGlmIG5lZWRlZCAqL1xuICAgIGlmIChsZW4gPiByb290ICYmIChodWZmICYgbWFzaykgIT09IGxvdykge1xuICAgICAgLyogaWYgZmlyc3QgdGltZSwgdHJhbnNpdGlvbiB0byBzdWItdGFibGVzICovXG4gICAgICBpZiAoZHJvcCA9PT0gMCkge1xuICAgICAgICBkcm9wID0gcm9vdDtcbiAgICAgIH1cblxuICAgICAgLyogaW5jcmVtZW50IHBhc3QgbGFzdCB0YWJsZSAqL1xuICAgICAgbmV4dCArPSBtaW47ICAgICAgICAgICAgLyogaGVyZSBtaW4gaXMgMSA8PCBjdXJyICovXG5cbiAgICAgIC8qIGRldGVybWluZSBsZW5ndGggb2YgbmV4dCB0YWJsZSAqL1xuICAgICAgY3VyciA9IGxlbiAtIGRyb3A7XG4gICAgICBsZWZ0ID0gMSA8PCBjdXJyO1xuICAgICAgd2hpbGUgKGN1cnIgKyBkcm9wIDwgbWF4KSB7XG4gICAgICAgIGxlZnQgLT0gY291bnRbY3VyciArIGRyb3BdO1xuICAgICAgICBpZiAobGVmdCA8PSAwKSB7IGJyZWFrOyB9XG4gICAgICAgIGN1cnIrKztcbiAgICAgICAgbGVmdCA8PD0gMTtcbiAgICAgIH1cblxuICAgICAgLyogY2hlY2sgZm9yIGVub3VnaCBzcGFjZSAqL1xuICAgICAgdXNlZCArPSAxIDw8IGN1cnI7XG4gICAgICBpZiAoKHR5cGUgPT09IExFTlMgJiYgdXNlZCA+IEVOT1VHSF9MRU5TKSB8fFxuICAgICAgICAodHlwZSA9PT0gRElTVFMgJiYgdXNlZCA+IEVOT1VHSF9ESVNUUykpIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgICB9XG5cbiAgICAgIC8qIHBvaW50IGVudHJ5IGluIHJvb3QgdGFibGUgdG8gc3ViLXRhYmxlICovXG4gICAgICBsb3cgPSBodWZmICYgbWFzaztcbiAgICAgIC8qdGFibGUub3BbbG93XSA9IGN1cnI7XG4gICAgICB0YWJsZS5iaXRzW2xvd10gPSByb290O1xuICAgICAgdGFibGUudmFsW2xvd10gPSBuZXh0IC0gb3B0cy50YWJsZV9pbmRleDsqL1xuICAgICAgdGFibGVbbG93XSA9IChyb290IDw8IDI0KSB8IChjdXJyIDw8IDE2KSB8IChuZXh0IC0gdGFibGVfaW5kZXgpIHwwO1xuICAgIH1cbiAgfVxuXG4gIC8qIGZpbGwgaW4gcmVtYWluaW5nIHRhYmxlIGVudHJ5IGlmIGNvZGUgaXMgaW5jb21wbGV0ZSAoZ3VhcmFudGVlZCB0byBoYXZlXG4gICBhdCBtb3N0IG9uZSByZW1haW5pbmcgZW50cnksIHNpbmNlIGlmIHRoZSBjb2RlIGlzIGluY29tcGxldGUsIHRoZVxuICAgbWF4aW11bSBjb2RlIGxlbmd0aCB0aGF0IHdhcyBhbGxvd2VkIHRvIGdldCB0aGlzIGZhciBpcyBvbmUgYml0KSAqL1xuICBpZiAoaHVmZiAhPT0gMCkge1xuICAgIC8vdGFibGUub3BbbmV4dCArIGh1ZmZdID0gNjQ7ICAgICAgICAgICAgLyogaW52YWxpZCBjb2RlIG1hcmtlciAqL1xuICAgIC8vdGFibGUuYml0c1tuZXh0ICsgaHVmZl0gPSBsZW4gLSBkcm9wO1xuICAgIC8vdGFibGUudmFsW25leHQgKyBodWZmXSA9IDA7XG4gICAgdGFibGVbbmV4dCArIGh1ZmZdID0gKChsZW4gLSBkcm9wKSA8PCAyNCkgfCAoNjQgPDwgMTYpIHwwO1xuICB9XG5cbiAgLyogc2V0IHJldHVybiBwYXJhbWV0ZXJzICovXG4gIC8vb3B0cy50YWJsZV9pbmRleCArPSB1c2VkO1xuICBvcHRzLmJpdHMgPSByb290O1xuICByZXR1cm4gMDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbi8vIChDKSAxOTk1LTIwMTMgSmVhbi1sb3VwIEdhaWxseSBhbmQgTWFyayBBZGxlclxuLy8gKEMpIDIwMTQtMjAxNyBWaXRhbHkgUHV6cmluIGFuZCBBbmRyZXkgVHVwaXRzaW5cbi8vXG4vLyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZFxuLy8gd2FycmFudHkuIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzXG4vLyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLFxuLy8gaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdFxuLy8gZnJlZWx5LCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOlxuLy9cbi8vIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90XG4vLyAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlXG4vLyAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZVxuLy8gICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLlxuLy8gMi4gQWx0ZXJlZCBzb3VyY2UgdmVyc2lvbnMgbXVzdCBiZSBwbGFpbmx5IG1hcmtlZCBhcyBzdWNoLCBhbmQgbXVzdCBub3QgYmVcbi8vICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLlxuLy8gMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIDI6ICAgICAgJ25lZWQgZGljdGlvbmFyeScsICAgICAvKiBaX05FRURfRElDVCAgICAgICAyICAqL1xuICAxOiAgICAgICdzdHJlYW0gZW5kJywgICAgICAgICAgLyogWl9TVFJFQU1fRU5EICAgICAgMSAgKi9cbiAgMDogICAgICAnJywgICAgICAgICAgICAgICAgICAgIC8qIFpfT0sgICAgICAgICAgICAgIDAgICovXG4gICctMSc6ICAgJ2ZpbGUgZXJyb3InLCAgICAgICAgICAvKiBaX0VSUk5PICAgICAgICAgKC0xKSAqL1xuICAnLTInOiAgICdzdHJlYW0gZXJyb3InLCAgICAgICAgLyogWl9TVFJFQU1fRVJST1IgICgtMikgKi9cbiAgJy0zJzogICAnZGF0YSBlcnJvcicsICAgICAgICAgIC8qIFpfREFUQV9FUlJPUiAgICAoLTMpICovXG4gICctNCc6ICAgJ2luc3VmZmljaWVudCBtZW1vcnknLCAvKiBaX01FTV9FUlJPUiAgICAgKC00KSAqL1xuICAnLTUnOiAgICdidWZmZXIgZXJyb3InLCAgICAgICAgLyogWl9CVUZfRVJST1IgICAgICgtNSkgKi9cbiAgJy02JzogICAnaW5jb21wYXRpYmxlIHZlcnNpb24nIC8qIFpfVkVSU0lPTl9FUlJPUiAoLTYpICovXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXJcbi8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luXG4vL1xuLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWRcbi8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlc1xuLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSxcbi8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXRcbi8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczpcbi8vXG4vLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdFxuLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZVxuLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmVcbi8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC5cbi8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlXG4vLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS5cbi8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uXG5cbi8qIGVzbGludC1kaXNhYmxlIHNwYWNlLXVuYXJ5LW9wcyAqL1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscy9jb21tb24nKTtcblxuLyogUHVibGljIGNvbnN0YW50cyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cblxuLy92YXIgWl9GSUxURVJFRCAgICAgICAgICA9IDE7XG4vL3ZhciBaX0hVRkZNQU5fT05MWSAgICAgID0gMjtcbi8vdmFyIFpfUkxFICAgICAgICAgICAgICAgPSAzO1xudmFyIFpfRklYRUQgICAgICAgICAgICAgICA9IDQ7XG4vL3ZhciBaX0RFRkFVTFRfU1RSQVRFR1kgID0gMDtcblxuLyogUG9zc2libGUgdmFsdWVzIG9mIHRoZSBkYXRhX3R5cGUgZmllbGQgKHRob3VnaCBzZWUgaW5mbGF0ZSgpKSAqL1xudmFyIFpfQklOQVJZICAgICAgICAgICAgICA9IDA7XG52YXIgWl9URVhUICAgICAgICAgICAgICAgID0gMTtcbi8vdmFyIFpfQVNDSUkgICAgICAgICAgICAgPSAxOyAvLyA9IFpfVEVYVFxudmFyIFpfVU5LTk9XTiAgICAgICAgICAgICA9IDI7XG5cbi8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cblxuZnVuY3Rpb24gemVybyhidWYpIHsgdmFyIGxlbiA9IGJ1Zi5sZW5ndGg7IHdoaWxlICgtLWxlbiA+PSAwKSB7IGJ1ZltsZW5dID0gMDsgfSB9XG5cbi8vIEZyb20genV0aWwuaFxuXG52YXIgU1RPUkVEX0JMT0NLID0gMDtcbnZhciBTVEFUSUNfVFJFRVMgPSAxO1xudmFyIERZTl9UUkVFUyAgICA9IDI7XG4vKiBUaGUgdGhyZWUga2luZHMgb2YgYmxvY2sgdHlwZSAqL1xuXG52YXIgTUlOX01BVENIICAgID0gMztcbnZhciBNQVhfTUFUQ0ggICAgPSAyNTg7XG4vKiBUaGUgbWluaW11bSBhbmQgbWF4aW11bSBtYXRjaCBsZW5ndGhzICovXG5cbi8vIEZyb20gZGVmbGF0ZS5oXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEludGVybmFsIGNvbXByZXNzaW9uIHN0YXRlLlxuICovXG5cbnZhciBMRU5HVEhfQ09ERVMgID0gMjk7XG4vKiBudW1iZXIgb2YgbGVuZ3RoIGNvZGVzLCBub3QgY291bnRpbmcgdGhlIHNwZWNpYWwgRU5EX0JMT0NLIGNvZGUgKi9cblxudmFyIExJVEVSQUxTICAgICAgPSAyNTY7XG4vKiBudW1iZXIgb2YgbGl0ZXJhbCBieXRlcyAwLi4yNTUgKi9cblxudmFyIExfQ09ERVMgICAgICAgPSBMSVRFUkFMUyArIDEgKyBMRU5HVEhfQ09ERVM7XG4vKiBudW1iZXIgb2YgTGl0ZXJhbCBvciBMZW5ndGggY29kZXMsIGluY2x1ZGluZyB0aGUgRU5EX0JMT0NLIGNvZGUgKi9cblxudmFyIERfQ09ERVMgICAgICAgPSAzMDtcbi8qIG51bWJlciBvZiBkaXN0YW5jZSBjb2RlcyAqL1xuXG52YXIgQkxfQ09ERVMgICAgICA9IDE5O1xuLyogbnVtYmVyIG9mIGNvZGVzIHVzZWQgdG8gdHJhbnNmZXIgdGhlIGJpdCBsZW5ndGhzICovXG5cbnZhciBIRUFQX1NJWkUgICAgID0gMiAqIExfQ09ERVMgKyAxO1xuLyogbWF4aW11bSBoZWFwIHNpemUgKi9cblxudmFyIE1BWF9CSVRTICAgICAgPSAxNTtcbi8qIEFsbCBjb2RlcyBtdXN0IG5vdCBleGNlZWQgTUFYX0JJVFMgYml0cyAqL1xuXG52YXIgQnVmX3NpemUgICAgICA9IDE2O1xuLyogc2l6ZSBvZiBiaXQgYnVmZmVyIGluIGJpX2J1ZiAqL1xuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29uc3RhbnRzXG4gKi9cblxudmFyIE1BWF9CTF9CSVRTID0gNztcbi8qIEJpdCBsZW5ndGggY29kZXMgbXVzdCBub3QgZXhjZWVkIE1BWF9CTF9CSVRTIGJpdHMgKi9cblxudmFyIEVORF9CTE9DSyAgID0gMjU2O1xuLyogZW5kIG9mIGJsb2NrIGxpdGVyYWwgY29kZSAqL1xuXG52YXIgUkVQXzNfNiAgICAgPSAxNjtcbi8qIHJlcGVhdCBwcmV2aW91cyBiaXQgbGVuZ3RoIDMtNiB0aW1lcyAoMiBiaXRzIG9mIHJlcGVhdCBjb3VudCkgKi9cblxudmFyIFJFUFpfM18xMCAgID0gMTc7XG4vKiByZXBlYXQgYSB6ZXJvIGxlbmd0aCAzLTEwIHRpbWVzICAoMyBiaXRzIG9mIHJlcGVhdCBjb3VudCkgKi9cblxudmFyIFJFUFpfMTFfMTM4ID0gMTg7XG4vKiByZXBlYXQgYSB6ZXJvIGxlbmd0aCAxMS0xMzggdGltZXMgICg3IGJpdHMgb2YgcmVwZWF0IGNvdW50KSAqL1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBjb21tYS1zcGFjaW5nLGFycmF5LWJyYWNrZXQtc3BhY2luZyAqL1xudmFyIGV4dHJhX2xiaXRzID0gICAvKiBleHRyYSBiaXRzIGZvciBlYWNoIGxlbmd0aCBjb2RlICovXG4gIFswLDAsMCwwLDAsMCwwLDAsMSwxLDEsMSwyLDIsMiwyLDMsMywzLDMsNCw0LDQsNCw1LDUsNSw1LDBdO1xuXG52YXIgZXh0cmFfZGJpdHMgPSAgIC8qIGV4dHJhIGJpdHMgZm9yIGVhY2ggZGlzdGFuY2UgY29kZSAqL1xuICBbMCwwLDAsMCwxLDEsMiwyLDMsMyw0LDQsNSw1LDYsNiw3LDcsOCw4LDksOSwxMCwxMCwxMSwxMSwxMiwxMiwxMywxM107XG5cbnZhciBleHRyYV9ibGJpdHMgPSAgLyogZXh0cmEgYml0cyBmb3IgZWFjaCBiaXQgbGVuZ3RoIGNvZGUgKi9cbiAgWzAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMiwzLDddO1xuXG52YXIgYmxfb3JkZXIgPVxuICBbMTYsMTcsMTgsMCw4LDcsOSw2LDEwLDUsMTEsNCwxMiwzLDEzLDIsMTQsMSwxNV07XG4vKiBlc2xpbnQtZW5hYmxlIGNvbW1hLXNwYWNpbmcsYXJyYXktYnJhY2tldC1zcGFjaW5nICovXG5cbi8qIFRoZSBsZW5ndGhzIG9mIHRoZSBiaXQgbGVuZ3RoIGNvZGVzIGFyZSBzZW50IGluIG9yZGVyIG9mIGRlY3JlYXNpbmdcbiAqIHByb2JhYmlsaXR5LCB0byBhdm9pZCB0cmFuc21pdHRpbmcgdGhlIGxlbmd0aHMgZm9yIHVudXNlZCBiaXQgbGVuZ3RoIGNvZGVzLlxuICovXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogTG9jYWwgZGF0YS4gVGhlc2UgYXJlIGluaXRpYWxpemVkIG9ubHkgb25jZS5cbiAqL1xuXG4vLyBXZSBwcmUtZmlsbCBhcnJheXMgd2l0aCAwIHRvIGF2b2lkIHVuaW5pdGlhbGl6ZWQgZ2Fwc1xuXG52YXIgRElTVF9DT0RFX0xFTiA9IDUxMjsgLyogc2VlIGRlZmluaXRpb24gb2YgYXJyYXkgZGlzdF9jb2RlIGJlbG93ICovXG5cbi8vICEhISEgVXNlIGZsYXQgYXJyYXkgaW5zdGVhZCBvZiBzdHJ1Y3R1cmUsIEZyZXEgPSBpKjIsIExlbiA9IGkqMisxXG52YXIgc3RhdGljX2x0cmVlICA9IG5ldyBBcnJheSgoTF9DT0RFUyArIDIpICogMik7XG56ZXJvKHN0YXRpY19sdHJlZSk7XG4vKiBUaGUgc3RhdGljIGxpdGVyYWwgdHJlZS4gU2luY2UgdGhlIGJpdCBsZW5ndGhzIGFyZSBpbXBvc2VkLCB0aGVyZSBpcyBub1xuICogbmVlZCBmb3IgdGhlIExfQ09ERVMgZXh0cmEgY29kZXMgdXNlZCBkdXJpbmcgaGVhcCBjb25zdHJ1Y3Rpb24uIEhvd2V2ZXJcbiAqIFRoZSBjb2RlcyAyODYgYW5kIDI4NyBhcmUgbmVlZGVkIHRvIGJ1aWxkIGEgY2Fub25pY2FsIHRyZWUgKHNlZSBfdHJfaW5pdFxuICogYmVsb3cpLlxuICovXG5cbnZhciBzdGF0aWNfZHRyZWUgID0gbmV3IEFycmF5KERfQ09ERVMgKiAyKTtcbnplcm8oc3RhdGljX2R0cmVlKTtcbi8qIFRoZSBzdGF0aWMgZGlzdGFuY2UgdHJlZS4gKEFjdHVhbGx5IGEgdHJpdmlhbCB0cmVlIHNpbmNlIGFsbCBjb2RlcyB1c2VcbiAqIDUgYml0cy4pXG4gKi9cblxudmFyIF9kaXN0X2NvZGUgICAgPSBuZXcgQXJyYXkoRElTVF9DT0RFX0xFTik7XG56ZXJvKF9kaXN0X2NvZGUpO1xuLyogRGlzdGFuY2UgY29kZXMuIFRoZSBmaXJzdCAyNTYgdmFsdWVzIGNvcnJlc3BvbmQgdG8gdGhlIGRpc3RhbmNlc1xuICogMyAuLiAyNTgsIHRoZSBsYXN0IDI1NiB2YWx1ZXMgY29ycmVzcG9uZCB0byB0aGUgdG9wIDggYml0cyBvZlxuICogdGhlIDE1IGJpdCBkaXN0YW5jZXMuXG4gKi9cblxudmFyIF9sZW5ndGhfY29kZSAgPSBuZXcgQXJyYXkoTUFYX01BVENIIC0gTUlOX01BVENIICsgMSk7XG56ZXJvKF9sZW5ndGhfY29kZSk7XG4vKiBsZW5ndGggY29kZSBmb3IgZWFjaCBub3JtYWxpemVkIG1hdGNoIGxlbmd0aCAoMCA9PSBNSU5fTUFUQ0gpICovXG5cbnZhciBiYXNlX2xlbmd0aCAgID0gbmV3IEFycmF5KExFTkdUSF9DT0RFUyk7XG56ZXJvKGJhc2VfbGVuZ3RoKTtcbi8qIEZpcnN0IG5vcm1hbGl6ZWQgbGVuZ3RoIGZvciBlYWNoIGNvZGUgKDAgPSBNSU5fTUFUQ0gpICovXG5cbnZhciBiYXNlX2Rpc3QgICAgID0gbmV3IEFycmF5KERfQ09ERVMpO1xuemVybyhiYXNlX2Rpc3QpO1xuLyogRmlyc3Qgbm9ybWFsaXplZCBkaXN0YW5jZSBmb3IgZWFjaCBjb2RlICgwID0gZGlzdGFuY2Ugb2YgMSkgKi9cblxuXG5mdW5jdGlvbiBTdGF0aWNUcmVlRGVzYyhzdGF0aWNfdHJlZSwgZXh0cmFfYml0cywgZXh0cmFfYmFzZSwgZWxlbXMsIG1heF9sZW5ndGgpIHtcblxuICB0aGlzLnN0YXRpY190cmVlICA9IHN0YXRpY190cmVlOyAgLyogc3RhdGljIHRyZWUgb3IgTlVMTCAqL1xuICB0aGlzLmV4dHJhX2JpdHMgICA9IGV4dHJhX2JpdHM7ICAgLyogZXh0cmEgYml0cyBmb3IgZWFjaCBjb2RlIG9yIE5VTEwgKi9cbiAgdGhpcy5leHRyYV9iYXNlICAgPSBleHRyYV9iYXNlOyAgIC8qIGJhc2UgaW5kZXggZm9yIGV4dHJhX2JpdHMgKi9cbiAgdGhpcy5lbGVtcyAgICAgICAgPSBlbGVtczsgICAgICAgIC8qIG1heCBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIHRyZWUgKi9cbiAgdGhpcy5tYXhfbGVuZ3RoICAgPSBtYXhfbGVuZ3RoOyAgIC8qIG1heCBiaXQgbGVuZ3RoIGZvciB0aGUgY29kZXMgKi9cblxuICAvLyBzaG93IGlmIGBzdGF0aWNfdHJlZWAgaGFzIGRhdGEgb3IgZHVtbXkgLSBuZWVkZWQgZm9yIG1vbm9tb3JwaGljIG9iamVjdHNcbiAgdGhpcy5oYXNfc3RyZWUgICAgPSBzdGF0aWNfdHJlZSAmJiBzdGF0aWNfdHJlZS5sZW5ndGg7XG59XG5cblxudmFyIHN0YXRpY19sX2Rlc2M7XG52YXIgc3RhdGljX2RfZGVzYztcbnZhciBzdGF0aWNfYmxfZGVzYztcblxuXG5mdW5jdGlvbiBUcmVlRGVzYyhkeW5fdHJlZSwgc3RhdF9kZXNjKSB7XG4gIHRoaXMuZHluX3RyZWUgPSBkeW5fdHJlZTsgICAgIC8qIHRoZSBkeW5hbWljIHRyZWUgKi9cbiAgdGhpcy5tYXhfY29kZSA9IDA7ICAgICAgICAgICAgLyogbGFyZ2VzdCBjb2RlIHdpdGggbm9uIHplcm8gZnJlcXVlbmN5ICovXG4gIHRoaXMuc3RhdF9kZXNjID0gc3RhdF9kZXNjOyAgIC8qIHRoZSBjb3JyZXNwb25kaW5nIHN0YXRpYyB0cmVlICovXG59XG5cblxuXG5mdW5jdGlvbiBkX2NvZGUoZGlzdCkge1xuICByZXR1cm4gZGlzdCA8IDI1NiA/IF9kaXN0X2NvZGVbZGlzdF0gOiBfZGlzdF9jb2RlWzI1NiArIChkaXN0ID4+PiA3KV07XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBPdXRwdXQgYSBzaG9ydCBMU0IgZmlyc3Qgb24gdGhlIHN0cmVhbS5cbiAqIElOIGFzc2VydGlvbjogdGhlcmUgaXMgZW5vdWdoIHJvb20gaW4gcGVuZGluZ0J1Zi5cbiAqL1xuZnVuY3Rpb24gcHV0X3Nob3J0KHMsIHcpIHtcbi8vICAgIHB1dF9ieXRlKHMsICh1Y2gpKCh3KSAmIDB4ZmYpKTtcbi8vICAgIHB1dF9ieXRlKHMsICh1Y2gpKCh1c2gpKHcpID4+IDgpKTtcbiAgcy5wZW5kaW5nX2J1ZltzLnBlbmRpbmcrK10gPSAodykgJiAweGZmO1xuICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZysrXSA9ICh3ID4+PiA4KSAmIDB4ZmY7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTZW5kIGEgdmFsdWUgb24gYSBnaXZlbiBudW1iZXIgb2YgYml0cy5cbiAqIElOIGFzc2VydGlvbjogbGVuZ3RoIDw9IDE2IGFuZCB2YWx1ZSBmaXRzIGluIGxlbmd0aCBiaXRzLlxuICovXG5mdW5jdGlvbiBzZW5kX2JpdHMocywgdmFsdWUsIGxlbmd0aCkge1xuICBpZiAocy5iaV92YWxpZCA+IChCdWZfc2l6ZSAtIGxlbmd0aCkpIHtcbiAgICBzLmJpX2J1ZiB8PSAodmFsdWUgPDwgcy5iaV92YWxpZCkgJiAweGZmZmY7XG4gICAgcHV0X3Nob3J0KHMsIHMuYmlfYnVmKTtcbiAgICBzLmJpX2J1ZiA9IHZhbHVlID4+IChCdWZfc2l6ZSAtIHMuYmlfdmFsaWQpO1xuICAgIHMuYmlfdmFsaWQgKz0gbGVuZ3RoIC0gQnVmX3NpemU7XG4gIH0gZWxzZSB7XG4gICAgcy5iaV9idWYgfD0gKHZhbHVlIDw8IHMuYmlfdmFsaWQpICYgMHhmZmZmO1xuICAgIHMuYmlfdmFsaWQgKz0gbGVuZ3RoO1xuICB9XG59XG5cblxuZnVuY3Rpb24gc2VuZF9jb2RlKHMsIGMsIHRyZWUpIHtcbiAgc2VuZF9iaXRzKHMsIHRyZWVbYyAqIDJdLyouQ29kZSovLCB0cmVlW2MgKiAyICsgMV0vKi5MZW4qLyk7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBSZXZlcnNlIHRoZSBmaXJzdCBsZW4gYml0cyBvZiBhIGNvZGUsIHVzaW5nIHN0cmFpZ2h0Zm9yd2FyZCBjb2RlIChhIGZhc3RlclxuICogbWV0aG9kIHdvdWxkIHVzZSBhIHRhYmxlKVxuICogSU4gYXNzZXJ0aW9uOiAxIDw9IGxlbiA8PSAxNVxuICovXG5mdW5jdGlvbiBiaV9yZXZlcnNlKGNvZGUsIGxlbikge1xuICB2YXIgcmVzID0gMDtcbiAgZG8ge1xuICAgIHJlcyB8PSBjb2RlICYgMTtcbiAgICBjb2RlID4+Pj0gMTtcbiAgICByZXMgPDw9IDE7XG4gIH0gd2hpbGUgKC0tbGVuID4gMCk7XG4gIHJldHVybiByZXMgPj4+IDE7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBGbHVzaCB0aGUgYml0IGJ1ZmZlciwga2VlcGluZyBhdCBtb3N0IDcgYml0cyBpbiBpdC5cbiAqL1xuZnVuY3Rpb24gYmlfZmx1c2gocykge1xuICBpZiAocy5iaV92YWxpZCA9PT0gMTYpIHtcbiAgICBwdXRfc2hvcnQocywgcy5iaV9idWYpO1xuICAgIHMuYmlfYnVmID0gMDtcbiAgICBzLmJpX3ZhbGlkID0gMDtcblxuICB9IGVsc2UgaWYgKHMuYmlfdmFsaWQgPj0gOCkge1xuICAgIHMucGVuZGluZ19idWZbcy5wZW5kaW5nKytdID0gcy5iaV9idWYgJiAweGZmO1xuICAgIHMuYmlfYnVmID4+PSA4O1xuICAgIHMuYmlfdmFsaWQgLT0gODtcbiAgfVxufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29tcHV0ZSB0aGUgb3B0aW1hbCBiaXQgbGVuZ3RocyBmb3IgYSB0cmVlIGFuZCB1cGRhdGUgdGhlIHRvdGFsIGJpdCBsZW5ndGhcbiAqIGZvciB0aGUgY3VycmVudCBibG9jay5cbiAqIElOIGFzc2VydGlvbjogdGhlIGZpZWxkcyBmcmVxIGFuZCBkYWQgYXJlIHNldCwgaGVhcFtoZWFwX21heF0gYW5kXG4gKiAgICBhYm92ZSBhcmUgdGhlIHRyZWUgbm9kZXMgc29ydGVkIGJ5IGluY3JlYXNpbmcgZnJlcXVlbmN5LlxuICogT1VUIGFzc2VydGlvbnM6IHRoZSBmaWVsZCBsZW4gaXMgc2V0IHRvIHRoZSBvcHRpbWFsIGJpdCBsZW5ndGgsIHRoZVxuICogICAgIGFycmF5IGJsX2NvdW50IGNvbnRhaW5zIHRoZSBmcmVxdWVuY2llcyBmb3IgZWFjaCBiaXQgbGVuZ3RoLlxuICogICAgIFRoZSBsZW5ndGggb3B0X2xlbiBpcyB1cGRhdGVkOyBzdGF0aWNfbGVuIGlzIGFsc28gdXBkYXRlZCBpZiBzdHJlZSBpc1xuICogICAgIG5vdCBudWxsLlxuICovXG5mdW5jdGlvbiBnZW5fYml0bGVuKHMsIGRlc2MpXG4vLyAgICBkZWZsYXRlX3N0YXRlICpzO1xuLy8gICAgdHJlZV9kZXNjICpkZXNjOyAgICAvKiB0aGUgdHJlZSBkZXNjcmlwdG9yICovXG57XG4gIHZhciB0cmVlICAgICAgICAgICAgPSBkZXNjLmR5bl90cmVlO1xuICB2YXIgbWF4X2NvZGUgICAgICAgID0gZGVzYy5tYXhfY29kZTtcbiAgdmFyIHN0cmVlICAgICAgICAgICA9IGRlc2Muc3RhdF9kZXNjLnN0YXRpY190cmVlO1xuICB2YXIgaGFzX3N0cmVlICAgICAgID0gZGVzYy5zdGF0X2Rlc2MuaGFzX3N0cmVlO1xuICB2YXIgZXh0cmEgICAgICAgICAgID0gZGVzYy5zdGF0X2Rlc2MuZXh0cmFfYml0cztcbiAgdmFyIGJhc2UgICAgICAgICAgICA9IGRlc2Muc3RhdF9kZXNjLmV4dHJhX2Jhc2U7XG4gIHZhciBtYXhfbGVuZ3RoICAgICAgPSBkZXNjLnN0YXRfZGVzYy5tYXhfbGVuZ3RoO1xuICB2YXIgaDsgICAgICAgICAgICAgIC8qIGhlYXAgaW5kZXggKi9cbiAgdmFyIG4sIG07ICAgICAgICAgICAvKiBpdGVyYXRlIG92ZXIgdGhlIHRyZWUgZWxlbWVudHMgKi9cbiAgdmFyIGJpdHM7ICAgICAgICAgICAvKiBiaXQgbGVuZ3RoICovXG4gIHZhciB4Yml0czsgICAgICAgICAgLyogZXh0cmEgYml0cyAqL1xuICB2YXIgZjsgICAgICAgICAgICAgIC8qIGZyZXF1ZW5jeSAqL1xuICB2YXIgb3ZlcmZsb3cgPSAwOyAgIC8qIG51bWJlciBvZiBlbGVtZW50cyB3aXRoIGJpdCBsZW5ndGggdG9vIGxhcmdlICovXG5cbiAgZm9yIChiaXRzID0gMDsgYml0cyA8PSBNQVhfQklUUzsgYml0cysrKSB7XG4gICAgcy5ibF9jb3VudFtiaXRzXSA9IDA7XG4gIH1cblxuICAvKiBJbiBhIGZpcnN0IHBhc3MsIGNvbXB1dGUgdGhlIG9wdGltYWwgYml0IGxlbmd0aHMgKHdoaWNoIG1heVxuICAgKiBvdmVyZmxvdyBpbiB0aGUgY2FzZSBvZiB0aGUgYml0IGxlbmd0aCB0cmVlKS5cbiAgICovXG4gIHRyZWVbcy5oZWFwW3MuaGVhcF9tYXhdICogMiArIDFdLyouTGVuKi8gPSAwOyAvKiByb290IG9mIHRoZSBoZWFwICovXG5cbiAgZm9yIChoID0gcy5oZWFwX21heCArIDE7IGggPCBIRUFQX1NJWkU7IGgrKykge1xuICAgIG4gPSBzLmhlYXBbaF07XG4gICAgYml0cyA9IHRyZWVbdHJlZVtuICogMiArIDFdLyouRGFkKi8gKiAyICsgMV0vKi5MZW4qLyArIDE7XG4gICAgaWYgKGJpdHMgPiBtYXhfbGVuZ3RoKSB7XG4gICAgICBiaXRzID0gbWF4X2xlbmd0aDtcbiAgICAgIG92ZXJmbG93Kys7XG4gICAgfVxuICAgIHRyZWVbbiAqIDIgKyAxXS8qLkxlbiovID0gYml0cztcbiAgICAvKiBXZSBvdmVyd3JpdGUgdHJlZVtuXS5EYWQgd2hpY2ggaXMgbm8gbG9uZ2VyIG5lZWRlZCAqL1xuXG4gICAgaWYgKG4gPiBtYXhfY29kZSkgeyBjb250aW51ZTsgfSAvKiBub3QgYSBsZWFmIG5vZGUgKi9cblxuICAgIHMuYmxfY291bnRbYml0c10rKztcbiAgICB4Yml0cyA9IDA7XG4gICAgaWYgKG4gPj0gYmFzZSkge1xuICAgICAgeGJpdHMgPSBleHRyYVtuIC0gYmFzZV07XG4gICAgfVxuICAgIGYgPSB0cmVlW24gKiAyXS8qLkZyZXEqLztcbiAgICBzLm9wdF9sZW4gKz0gZiAqIChiaXRzICsgeGJpdHMpO1xuICAgIGlmIChoYXNfc3RyZWUpIHtcbiAgICAgIHMuc3RhdGljX2xlbiArPSBmICogKHN0cmVlW24gKiAyICsgMV0vKi5MZW4qLyArIHhiaXRzKTtcbiAgICB9XG4gIH1cbiAgaWYgKG92ZXJmbG93ID09PSAwKSB7IHJldHVybjsgfVxuXG4gIC8vIFRyYWNlKChzdGRlcnIsXCJcXG5iaXQgbGVuZ3RoIG92ZXJmbG93XFxuXCIpKTtcbiAgLyogVGhpcyBoYXBwZW5zIGZvciBleGFtcGxlIG9uIG9iajIgYW5kIHBpYyBvZiB0aGUgQ2FsZ2FyeSBjb3JwdXMgKi9cblxuICAvKiBGaW5kIHRoZSBmaXJzdCBiaXQgbGVuZ3RoIHdoaWNoIGNvdWxkIGluY3JlYXNlOiAqL1xuICBkbyB7XG4gICAgYml0cyA9IG1heF9sZW5ndGggLSAxO1xuICAgIHdoaWxlIChzLmJsX2NvdW50W2JpdHNdID09PSAwKSB7IGJpdHMtLTsgfVxuICAgIHMuYmxfY291bnRbYml0c10tLTsgICAgICAvKiBtb3ZlIG9uZSBsZWFmIGRvd24gdGhlIHRyZWUgKi9cbiAgICBzLmJsX2NvdW50W2JpdHMgKyAxXSArPSAyOyAvKiBtb3ZlIG9uZSBvdmVyZmxvdyBpdGVtIGFzIGl0cyBicm90aGVyICovXG4gICAgcy5ibF9jb3VudFttYXhfbGVuZ3RoXS0tO1xuICAgIC8qIFRoZSBicm90aGVyIG9mIHRoZSBvdmVyZmxvdyBpdGVtIGFsc28gbW92ZXMgb25lIHN0ZXAgdXAsXG4gICAgICogYnV0IHRoaXMgZG9lcyBub3QgYWZmZWN0IGJsX2NvdW50W21heF9sZW5ndGhdXG4gICAgICovXG4gICAgb3ZlcmZsb3cgLT0gMjtcbiAgfSB3aGlsZSAob3ZlcmZsb3cgPiAwKTtcblxuICAvKiBOb3cgcmVjb21wdXRlIGFsbCBiaXQgbGVuZ3Rocywgc2Nhbm5pbmcgaW4gaW5jcmVhc2luZyBmcmVxdWVuY3kuXG4gICAqIGggaXMgc3RpbGwgZXF1YWwgdG8gSEVBUF9TSVpFLiAoSXQgaXMgc2ltcGxlciB0byByZWNvbnN0cnVjdCBhbGxcbiAgICogbGVuZ3RocyBpbnN0ZWFkIG9mIGZpeGluZyBvbmx5IHRoZSB3cm9uZyBvbmVzLiBUaGlzIGlkZWEgaXMgdGFrZW5cbiAgICogZnJvbSAnYXInIHdyaXR0ZW4gYnkgSGFydWhpa28gT2t1bXVyYS4pXG4gICAqL1xuICBmb3IgKGJpdHMgPSBtYXhfbGVuZ3RoOyBiaXRzICE9PSAwOyBiaXRzLS0pIHtcbiAgICBuID0gcy5ibF9jb3VudFtiaXRzXTtcbiAgICB3aGlsZSAobiAhPT0gMCkge1xuICAgICAgbSA9IHMuaGVhcFstLWhdO1xuICAgICAgaWYgKG0gPiBtYXhfY29kZSkgeyBjb250aW51ZTsgfVxuICAgICAgaWYgKHRyZWVbbSAqIDIgKyAxXS8qLkxlbiovICE9PSBiaXRzKSB7XG4gICAgICAgIC8vIFRyYWNlKChzdGRlcnIsXCJjb2RlICVkIGJpdHMgJWQtPiVkXFxuXCIsIG0sIHRyZWVbbV0uTGVuLCBiaXRzKSk7XG4gICAgICAgIHMub3B0X2xlbiArPSAoYml0cyAtIHRyZWVbbSAqIDIgKyAxXS8qLkxlbiovKSAqIHRyZWVbbSAqIDJdLyouRnJlcSovO1xuICAgICAgICB0cmVlW20gKiAyICsgMV0vKi5MZW4qLyA9IGJpdHM7XG4gICAgICB9XG4gICAgICBuLS07XG4gICAgfVxuICB9XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBHZW5lcmF0ZSB0aGUgY29kZXMgZm9yIGEgZ2l2ZW4gdHJlZSBhbmQgYml0IGNvdW50cyAod2hpY2ggbmVlZCBub3QgYmVcbiAqIG9wdGltYWwpLlxuICogSU4gYXNzZXJ0aW9uOiB0aGUgYXJyYXkgYmxfY291bnQgY29udGFpbnMgdGhlIGJpdCBsZW5ndGggc3RhdGlzdGljcyBmb3JcbiAqIHRoZSBnaXZlbiB0cmVlIGFuZCB0aGUgZmllbGQgbGVuIGlzIHNldCBmb3IgYWxsIHRyZWUgZWxlbWVudHMuXG4gKiBPVVQgYXNzZXJ0aW9uOiB0aGUgZmllbGQgY29kZSBpcyBzZXQgZm9yIGFsbCB0cmVlIGVsZW1lbnRzIG9mIG5vblxuICogICAgIHplcm8gY29kZSBsZW5ndGguXG4gKi9cbmZ1bmN0aW9uIGdlbl9jb2Rlcyh0cmVlLCBtYXhfY29kZSwgYmxfY291bnQpXG4vLyAgICBjdF9kYXRhICp0cmVlOyAgICAgICAgICAgICAvKiB0aGUgdHJlZSB0byBkZWNvcmF0ZSAqL1xuLy8gICAgaW50IG1heF9jb2RlOyAgICAgICAgICAgICAgLyogbGFyZ2VzdCBjb2RlIHdpdGggbm9uIHplcm8gZnJlcXVlbmN5ICovXG4vLyAgICB1c2hmICpibF9jb3VudDsgICAgICAgICAgICAvKiBudW1iZXIgb2YgY29kZXMgYXQgZWFjaCBiaXQgbGVuZ3RoICovXG57XG4gIHZhciBuZXh0X2NvZGUgPSBuZXcgQXJyYXkoTUFYX0JJVFMgKyAxKTsgLyogbmV4dCBjb2RlIHZhbHVlIGZvciBlYWNoIGJpdCBsZW5ndGggKi9cbiAgdmFyIGNvZGUgPSAwOyAgICAgICAgICAgICAgLyogcnVubmluZyBjb2RlIHZhbHVlICovXG4gIHZhciBiaXRzOyAgICAgICAgICAgICAgICAgIC8qIGJpdCBpbmRleCAqL1xuICB2YXIgbjsgICAgICAgICAgICAgICAgICAgICAvKiBjb2RlIGluZGV4ICovXG5cbiAgLyogVGhlIGRpc3RyaWJ1dGlvbiBjb3VudHMgYXJlIGZpcnN0IHVzZWQgdG8gZ2VuZXJhdGUgdGhlIGNvZGUgdmFsdWVzXG4gICAqIHdpdGhvdXQgYml0IHJldmVyc2FsLlxuICAgKi9cbiAgZm9yIChiaXRzID0gMTsgYml0cyA8PSBNQVhfQklUUzsgYml0cysrKSB7XG4gICAgbmV4dF9jb2RlW2JpdHNdID0gY29kZSA9IChjb2RlICsgYmxfY291bnRbYml0cyAtIDFdKSA8PCAxO1xuICB9XG4gIC8qIENoZWNrIHRoYXQgdGhlIGJpdCBjb3VudHMgaW4gYmxfY291bnQgYXJlIGNvbnNpc3RlbnQuIFRoZSBsYXN0IGNvZGVcbiAgICogbXVzdCBiZSBhbGwgb25lcy5cbiAgICovXG4gIC8vQXNzZXJ0IChjb2RlICsgYmxfY291bnRbTUFYX0JJVFNdLTEgPT0gKDE8PE1BWF9CSVRTKS0xLFxuICAvLyAgICAgICAgXCJpbmNvbnNpc3RlbnQgYml0IGNvdW50c1wiKTtcbiAgLy9UcmFjZXYoKHN0ZGVycixcIlxcbmdlbl9jb2RlczogbWF4X2NvZGUgJWQgXCIsIG1heF9jb2RlKSk7XG5cbiAgZm9yIChuID0gMDsgIG4gPD0gbWF4X2NvZGU7IG4rKykge1xuICAgIHZhciBsZW4gPSB0cmVlW24gKiAyICsgMV0vKi5MZW4qLztcbiAgICBpZiAobGVuID09PSAwKSB7IGNvbnRpbnVlOyB9XG4gICAgLyogTm93IHJldmVyc2UgdGhlIGJpdHMgKi9cbiAgICB0cmVlW24gKiAyXS8qLkNvZGUqLyA9IGJpX3JldmVyc2UobmV4dF9jb2RlW2xlbl0rKywgbGVuKTtcblxuICAgIC8vVHJhY2Vjdih0cmVlICE9IHN0YXRpY19sdHJlZSwgKHN0ZGVycixcIlxcbm4gJTNkICVjIGwgJTJkIGMgJTR4ICgleCkgXCIsXG4gICAgLy8gICAgIG4sIChpc2dyYXBoKG4pID8gbiA6ICcgJyksIGxlbiwgdHJlZVtuXS5Db2RlLCBuZXh0X2NvZGVbbGVuXS0xKSk7XG4gIH1cbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEluaXRpYWxpemUgdGhlIHZhcmlvdXMgJ2NvbnN0YW50JyB0YWJsZXMuXG4gKi9cbmZ1bmN0aW9uIHRyX3N0YXRpY19pbml0KCkge1xuICB2YXIgbjsgICAgICAgIC8qIGl0ZXJhdGVzIG92ZXIgdHJlZSBlbGVtZW50cyAqL1xuICB2YXIgYml0czsgICAgIC8qIGJpdCBjb3VudGVyICovXG4gIHZhciBsZW5ndGg7ICAgLyogbGVuZ3RoIHZhbHVlICovXG4gIHZhciBjb2RlOyAgICAgLyogY29kZSB2YWx1ZSAqL1xuICB2YXIgZGlzdDsgICAgIC8qIGRpc3RhbmNlIGluZGV4ICovXG4gIHZhciBibF9jb3VudCA9IG5ldyBBcnJheShNQVhfQklUUyArIDEpO1xuICAvKiBudW1iZXIgb2YgY29kZXMgYXQgZWFjaCBiaXQgbGVuZ3RoIGZvciBhbiBvcHRpbWFsIHRyZWUgKi9cblxuICAvLyBkbyBjaGVjayBpbiBfdHJfaW5pdCgpXG4gIC8vaWYgKHN0YXRpY19pbml0X2RvbmUpIHJldHVybjtcblxuICAvKiBGb3Igc29tZSBlbWJlZGRlZCB0YXJnZXRzLCBnbG9iYWwgdmFyaWFibGVzIGFyZSBub3QgaW5pdGlhbGl6ZWQ6ICovXG4vKiNpZmRlZiBOT19JTklUX0dMT0JBTF9QT0lOVEVSU1xuICBzdGF0aWNfbF9kZXNjLnN0YXRpY190cmVlID0gc3RhdGljX2x0cmVlO1xuICBzdGF0aWNfbF9kZXNjLmV4dHJhX2JpdHMgPSBleHRyYV9sYml0cztcbiAgc3RhdGljX2RfZGVzYy5zdGF0aWNfdHJlZSA9IHN0YXRpY19kdHJlZTtcbiAgc3RhdGljX2RfZGVzYy5leHRyYV9iaXRzID0gZXh0cmFfZGJpdHM7XG4gIHN0YXRpY19ibF9kZXNjLmV4dHJhX2JpdHMgPSBleHRyYV9ibGJpdHM7XG4jZW5kaWYqL1xuXG4gIC8qIEluaXRpYWxpemUgdGhlIG1hcHBpbmcgbGVuZ3RoICgwLi4yNTUpIC0+IGxlbmd0aCBjb2RlICgwLi4yOCkgKi9cbiAgbGVuZ3RoID0gMDtcbiAgZm9yIChjb2RlID0gMDsgY29kZSA8IExFTkdUSF9DT0RFUyAtIDE7IGNvZGUrKykge1xuICAgIGJhc2VfbGVuZ3RoW2NvZGVdID0gbGVuZ3RoO1xuICAgIGZvciAobiA9IDA7IG4gPCAoMSA8PCBleHRyYV9sYml0c1tjb2RlXSk7IG4rKykge1xuICAgICAgX2xlbmd0aF9jb2RlW2xlbmd0aCsrXSA9IGNvZGU7XG4gICAgfVxuICB9XG4gIC8vQXNzZXJ0IChsZW5ndGggPT0gMjU2LCBcInRyX3N0YXRpY19pbml0OiBsZW5ndGggIT0gMjU2XCIpO1xuICAvKiBOb3RlIHRoYXQgdGhlIGxlbmd0aCAyNTUgKG1hdGNoIGxlbmd0aCAyNTgpIGNhbiBiZSByZXByZXNlbnRlZFxuICAgKiBpbiB0d28gZGlmZmVyZW50IHdheXM6IGNvZGUgMjg0ICsgNSBiaXRzIG9yIGNvZGUgMjg1LCBzbyB3ZVxuICAgKiBvdmVyd3JpdGUgbGVuZ3RoX2NvZGVbMjU1XSB0byB1c2UgdGhlIGJlc3QgZW5jb2Rpbmc6XG4gICAqL1xuICBfbGVuZ3RoX2NvZGVbbGVuZ3RoIC0gMV0gPSBjb2RlO1xuXG4gIC8qIEluaXRpYWxpemUgdGhlIG1hcHBpbmcgZGlzdCAoMC4uMzJLKSAtPiBkaXN0IGNvZGUgKDAuLjI5KSAqL1xuICBkaXN0ID0gMDtcbiAgZm9yIChjb2RlID0gMDsgY29kZSA8IDE2OyBjb2RlKyspIHtcbiAgICBiYXNlX2Rpc3RbY29kZV0gPSBkaXN0O1xuICAgIGZvciAobiA9IDA7IG4gPCAoMSA8PCBleHRyYV9kYml0c1tjb2RlXSk7IG4rKykge1xuICAgICAgX2Rpc3RfY29kZVtkaXN0KytdID0gY29kZTtcbiAgICB9XG4gIH1cbiAgLy9Bc3NlcnQgKGRpc3QgPT0gMjU2LCBcInRyX3N0YXRpY19pbml0OiBkaXN0ICE9IDI1NlwiKTtcbiAgZGlzdCA+Pj0gNzsgLyogZnJvbSBub3cgb24sIGFsbCBkaXN0YW5jZXMgYXJlIGRpdmlkZWQgYnkgMTI4ICovXG4gIGZvciAoOyBjb2RlIDwgRF9DT0RFUzsgY29kZSsrKSB7XG4gICAgYmFzZV9kaXN0W2NvZGVdID0gZGlzdCA8PCA3O1xuICAgIGZvciAobiA9IDA7IG4gPCAoMSA8PCAoZXh0cmFfZGJpdHNbY29kZV0gLSA3KSk7IG4rKykge1xuICAgICAgX2Rpc3RfY29kZVsyNTYgKyBkaXN0KytdID0gY29kZTtcbiAgICB9XG4gIH1cbiAgLy9Bc3NlcnQgKGRpc3QgPT0gMjU2LCBcInRyX3N0YXRpY19pbml0OiAyNTYrZGlzdCAhPSA1MTJcIik7XG5cbiAgLyogQ29uc3RydWN0IHRoZSBjb2RlcyBvZiB0aGUgc3RhdGljIGxpdGVyYWwgdHJlZSAqL1xuICBmb3IgKGJpdHMgPSAwOyBiaXRzIDw9IE1BWF9CSVRTOyBiaXRzKyspIHtcbiAgICBibF9jb3VudFtiaXRzXSA9IDA7XG4gIH1cblxuICBuID0gMDtcbiAgd2hpbGUgKG4gPD0gMTQzKSB7XG4gICAgc3RhdGljX2x0cmVlW24gKiAyICsgMV0vKi5MZW4qLyA9IDg7XG4gICAgbisrO1xuICAgIGJsX2NvdW50WzhdKys7XG4gIH1cbiAgd2hpbGUgKG4gPD0gMjU1KSB7XG4gICAgc3RhdGljX2x0cmVlW24gKiAyICsgMV0vKi5MZW4qLyA9IDk7XG4gICAgbisrO1xuICAgIGJsX2NvdW50WzldKys7XG4gIH1cbiAgd2hpbGUgKG4gPD0gMjc5KSB7XG4gICAgc3RhdGljX2x0cmVlW24gKiAyICsgMV0vKi5MZW4qLyA9IDc7XG4gICAgbisrO1xuICAgIGJsX2NvdW50WzddKys7XG4gIH1cbiAgd2hpbGUgKG4gPD0gMjg3KSB7XG4gICAgc3RhdGljX2x0cmVlW24gKiAyICsgMV0vKi5MZW4qLyA9IDg7XG4gICAgbisrO1xuICAgIGJsX2NvdW50WzhdKys7XG4gIH1cbiAgLyogQ29kZXMgMjg2IGFuZCAyODcgZG8gbm90IGV4aXN0LCBidXQgd2UgbXVzdCBpbmNsdWRlIHRoZW0gaW4gdGhlXG4gICAqIHRyZWUgY29uc3RydWN0aW9uIHRvIGdldCBhIGNhbm9uaWNhbCBIdWZmbWFuIHRyZWUgKGxvbmdlc3QgY29kZVxuICAgKiBhbGwgb25lcylcbiAgICovXG4gIGdlbl9jb2RlcyhzdGF0aWNfbHRyZWUsIExfQ09ERVMgKyAxLCBibF9jb3VudCk7XG5cbiAgLyogVGhlIHN0YXRpYyBkaXN0YW5jZSB0cmVlIGlzIHRyaXZpYWw6ICovXG4gIGZvciAobiA9IDA7IG4gPCBEX0NPREVTOyBuKyspIHtcbiAgICBzdGF0aWNfZHRyZWVbbiAqIDIgKyAxXS8qLkxlbiovID0gNTtcbiAgICBzdGF0aWNfZHRyZWVbbiAqIDJdLyouQ29kZSovID0gYmlfcmV2ZXJzZShuLCA1KTtcbiAgfVxuXG4gIC8vIE5vdyBkYXRhIHJlYWR5IGFuZCB3ZSBjYW4gaW5pdCBzdGF0aWMgdHJlZXNcbiAgc3RhdGljX2xfZGVzYyA9IG5ldyBTdGF0aWNUcmVlRGVzYyhzdGF0aWNfbHRyZWUsIGV4dHJhX2xiaXRzLCBMSVRFUkFMUyArIDEsIExfQ09ERVMsIE1BWF9CSVRTKTtcbiAgc3RhdGljX2RfZGVzYyA9IG5ldyBTdGF0aWNUcmVlRGVzYyhzdGF0aWNfZHRyZWUsIGV4dHJhX2RiaXRzLCAwLCAgICAgICAgICBEX0NPREVTLCBNQVhfQklUUyk7XG4gIHN0YXRpY19ibF9kZXNjID0gbmV3IFN0YXRpY1RyZWVEZXNjKG5ldyBBcnJheSgwKSwgZXh0cmFfYmxiaXRzLCAwLCAgICAgICAgIEJMX0NPREVTLCBNQVhfQkxfQklUUyk7XG5cbiAgLy9zdGF0aWNfaW5pdF9kb25lID0gdHJ1ZTtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEluaXRpYWxpemUgYSBuZXcgYmxvY2suXG4gKi9cbmZ1bmN0aW9uIGluaXRfYmxvY2socykge1xuICB2YXIgbjsgLyogaXRlcmF0ZXMgb3ZlciB0cmVlIGVsZW1lbnRzICovXG5cbiAgLyogSW5pdGlhbGl6ZSB0aGUgdHJlZXMuICovXG4gIGZvciAobiA9IDA7IG4gPCBMX0NPREVTOyAgbisrKSB7IHMuZHluX2x0cmVlW24gKiAyXS8qLkZyZXEqLyA9IDA7IH1cbiAgZm9yIChuID0gMDsgbiA8IERfQ09ERVM7ICBuKyspIHsgcy5keW5fZHRyZWVbbiAqIDJdLyouRnJlcSovID0gMDsgfVxuICBmb3IgKG4gPSAwOyBuIDwgQkxfQ09ERVM7IG4rKykgeyBzLmJsX3RyZWVbbiAqIDJdLyouRnJlcSovID0gMDsgfVxuXG4gIHMuZHluX2x0cmVlW0VORF9CTE9DSyAqIDJdLyouRnJlcSovID0gMTtcbiAgcy5vcHRfbGVuID0gcy5zdGF0aWNfbGVuID0gMDtcbiAgcy5sYXN0X2xpdCA9IHMubWF0Y2hlcyA9IDA7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBGbHVzaCB0aGUgYml0IGJ1ZmZlciBhbmQgYWxpZ24gdGhlIG91dHB1dCBvbiBhIGJ5dGUgYm91bmRhcnlcbiAqL1xuZnVuY3Rpb24gYmlfd2luZHVwKHMpXG57XG4gIGlmIChzLmJpX3ZhbGlkID4gOCkge1xuICAgIHB1dF9zaG9ydChzLCBzLmJpX2J1Zik7XG4gIH0gZWxzZSBpZiAocy5iaV92YWxpZCA+IDApIHtcbiAgICAvL3B1dF9ieXRlKHMsIChCeXRlKXMtPmJpX2J1Zik7XG4gICAgcy5wZW5kaW5nX2J1ZltzLnBlbmRpbmcrK10gPSBzLmJpX2J1ZjtcbiAgfVxuICBzLmJpX2J1ZiA9IDA7XG4gIHMuYmlfdmFsaWQgPSAwO1xufVxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvcHkgYSBzdG9yZWQgYmxvY2ssIHN0b3JpbmcgZmlyc3QgdGhlIGxlbmd0aCBhbmQgaXRzXG4gKiBvbmUncyBjb21wbGVtZW50IGlmIHJlcXVlc3RlZC5cbiAqL1xuZnVuY3Rpb24gY29weV9ibG9jayhzLCBidWYsIGxlbiwgaGVhZGVyKVxuLy9EZWZsYXRlU3RhdGUgKnM7XG4vL2NoYXJmICAgICpidWY7ICAgIC8qIHRoZSBpbnB1dCBkYXRhICovXG4vL3Vuc2lnbmVkIGxlbjsgICAgIC8qIGl0cyBsZW5ndGggKi9cbi8vaW50ICAgICAgaGVhZGVyOyAgLyogdHJ1ZSBpZiBibG9jayBoZWFkZXIgbXVzdCBiZSB3cml0dGVuICovXG57XG4gIGJpX3dpbmR1cChzKTsgICAgICAgIC8qIGFsaWduIG9uIGJ5dGUgYm91bmRhcnkgKi9cblxuICBpZiAoaGVhZGVyKSB7XG4gICAgcHV0X3Nob3J0KHMsIGxlbik7XG4gICAgcHV0X3Nob3J0KHMsIH5sZW4pO1xuICB9XG4vLyAgd2hpbGUgKGxlbi0tKSB7XG4vLyAgICBwdXRfYnl0ZShzLCAqYnVmKyspO1xuLy8gIH1cbiAgdXRpbHMuYXJyYXlTZXQocy5wZW5kaW5nX2J1Ziwgcy53aW5kb3csIGJ1ZiwgbGVuLCBzLnBlbmRpbmcpO1xuICBzLnBlbmRpbmcgKz0gbGVuO1xufVxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvbXBhcmVzIHRvIHN1YnRyZWVzLCB1c2luZyB0aGUgdHJlZSBkZXB0aCBhcyB0aWUgYnJlYWtlciB3aGVuXG4gKiB0aGUgc3VidHJlZXMgaGF2ZSBlcXVhbCBmcmVxdWVuY3kuIFRoaXMgbWluaW1pemVzIHRoZSB3b3JzdCBjYXNlIGxlbmd0aC5cbiAqL1xuZnVuY3Rpb24gc21hbGxlcih0cmVlLCBuLCBtLCBkZXB0aCkge1xuICB2YXIgX24yID0gbiAqIDI7XG4gIHZhciBfbTIgPSBtICogMjtcbiAgcmV0dXJuICh0cmVlW19uMl0vKi5GcmVxKi8gPCB0cmVlW19tMl0vKi5GcmVxKi8gfHxcbiAgICAgICAgICh0cmVlW19uMl0vKi5GcmVxKi8gPT09IHRyZWVbX20yXS8qLkZyZXEqLyAmJiBkZXB0aFtuXSA8PSBkZXB0aFttXSkpO1xufVxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFJlc3RvcmUgdGhlIGhlYXAgcHJvcGVydHkgYnkgbW92aW5nIGRvd24gdGhlIHRyZWUgc3RhcnRpbmcgYXQgbm9kZSBrLFxuICogZXhjaGFuZ2luZyBhIG5vZGUgd2l0aCB0aGUgc21hbGxlc3Qgb2YgaXRzIHR3byBzb25zIGlmIG5lY2Vzc2FyeSwgc3RvcHBpbmdcbiAqIHdoZW4gdGhlIGhlYXAgcHJvcGVydHkgaXMgcmUtZXN0YWJsaXNoZWQgKGVhY2ggZmF0aGVyIHNtYWxsZXIgdGhhbiBpdHNcbiAqIHR3byBzb25zKS5cbiAqL1xuZnVuY3Rpb24gcHFkb3duaGVhcChzLCB0cmVlLCBrKVxuLy8gICAgZGVmbGF0ZV9zdGF0ZSAqcztcbi8vICAgIGN0X2RhdGEgKnRyZWU7ICAvKiB0aGUgdHJlZSB0byByZXN0b3JlICovXG4vLyAgICBpbnQgazsgICAgICAgICAgICAgICAvKiBub2RlIHRvIG1vdmUgZG93biAqL1xue1xuICB2YXIgdiA9IHMuaGVhcFtrXTtcbiAgdmFyIGogPSBrIDw8IDE7ICAvKiBsZWZ0IHNvbiBvZiBrICovXG4gIHdoaWxlIChqIDw9IHMuaGVhcF9sZW4pIHtcbiAgICAvKiBTZXQgaiB0byB0aGUgc21hbGxlc3Qgb2YgdGhlIHR3byBzb25zOiAqL1xuICAgIGlmIChqIDwgcy5oZWFwX2xlbiAmJlxuICAgICAgc21hbGxlcih0cmVlLCBzLmhlYXBbaiArIDFdLCBzLmhlYXBbal0sIHMuZGVwdGgpKSB7XG4gICAgICBqKys7XG4gICAgfVxuICAgIC8qIEV4aXQgaWYgdiBpcyBzbWFsbGVyIHRoYW4gYm90aCBzb25zICovXG4gICAgaWYgKHNtYWxsZXIodHJlZSwgdiwgcy5oZWFwW2pdLCBzLmRlcHRoKSkgeyBicmVhazsgfVxuXG4gICAgLyogRXhjaGFuZ2UgdiB3aXRoIHRoZSBzbWFsbGVzdCBzb24gKi9cbiAgICBzLmhlYXBba10gPSBzLmhlYXBbal07XG4gICAgayA9IGo7XG5cbiAgICAvKiBBbmQgY29udGludWUgZG93biB0aGUgdHJlZSwgc2V0dGluZyBqIHRvIHRoZSBsZWZ0IHNvbiBvZiBrICovXG4gICAgaiA8PD0gMTtcbiAgfVxuICBzLmhlYXBba10gPSB2O1xufVxuXG5cbi8vIGlubGluZWQgbWFudWFsbHlcbi8vIHZhciBTTUFMTEVTVCA9IDE7XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogU2VuZCB0aGUgYmxvY2sgZGF0YSBjb21wcmVzc2VkIHVzaW5nIHRoZSBnaXZlbiBIdWZmbWFuIHRyZWVzXG4gKi9cbmZ1bmN0aW9uIGNvbXByZXNzX2Jsb2NrKHMsIGx0cmVlLCBkdHJlZSlcbi8vICAgIGRlZmxhdGVfc3RhdGUgKnM7XG4vLyAgICBjb25zdCBjdF9kYXRhICpsdHJlZTsgLyogbGl0ZXJhbCB0cmVlICovXG4vLyAgICBjb25zdCBjdF9kYXRhICpkdHJlZTsgLyogZGlzdGFuY2UgdHJlZSAqL1xue1xuICB2YXIgZGlzdDsgICAgICAgICAgIC8qIGRpc3RhbmNlIG9mIG1hdGNoZWQgc3RyaW5nICovXG4gIHZhciBsYzsgICAgICAgICAgICAgLyogbWF0Y2ggbGVuZ3RoIG9yIHVubWF0Y2hlZCBjaGFyIChpZiBkaXN0ID09IDApICovXG4gIHZhciBseCA9IDA7ICAgICAgICAgLyogcnVubmluZyBpbmRleCBpbiBsX2J1ZiAqL1xuICB2YXIgY29kZTsgICAgICAgICAgIC8qIHRoZSBjb2RlIHRvIHNlbmQgKi9cbiAgdmFyIGV4dHJhOyAgICAgICAgICAvKiBudW1iZXIgb2YgZXh0cmEgYml0cyB0byBzZW5kICovXG5cbiAgaWYgKHMubGFzdF9saXQgIT09IDApIHtcbiAgICBkbyB7XG4gICAgICBkaXN0ID0gKHMucGVuZGluZ19idWZbcy5kX2J1ZiArIGx4ICogMl0gPDwgOCkgfCAocy5wZW5kaW5nX2J1ZltzLmRfYnVmICsgbHggKiAyICsgMV0pO1xuICAgICAgbGMgPSBzLnBlbmRpbmdfYnVmW3MubF9idWYgKyBseF07XG4gICAgICBseCsrO1xuXG4gICAgICBpZiAoZGlzdCA9PT0gMCkge1xuICAgICAgICBzZW5kX2NvZGUocywgbGMsIGx0cmVlKTsgLyogc2VuZCBhIGxpdGVyYWwgYnl0ZSAqL1xuICAgICAgICAvL1RyYWNlY3YoaXNncmFwaChsYyksIChzdGRlcnIsXCIgJyVjJyBcIiwgbGMpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8qIEhlcmUsIGxjIGlzIHRoZSBtYXRjaCBsZW5ndGggLSBNSU5fTUFUQ0ggKi9cbiAgICAgICAgY29kZSA9IF9sZW5ndGhfY29kZVtsY107XG4gICAgICAgIHNlbmRfY29kZShzLCBjb2RlICsgTElURVJBTFMgKyAxLCBsdHJlZSk7IC8qIHNlbmQgdGhlIGxlbmd0aCBjb2RlICovXG4gICAgICAgIGV4dHJhID0gZXh0cmFfbGJpdHNbY29kZV07XG4gICAgICAgIGlmIChleHRyYSAhPT0gMCkge1xuICAgICAgICAgIGxjIC09IGJhc2VfbGVuZ3RoW2NvZGVdO1xuICAgICAgICAgIHNlbmRfYml0cyhzLCBsYywgZXh0cmEpOyAgICAgICAvKiBzZW5kIHRoZSBleHRyYSBsZW5ndGggYml0cyAqL1xuICAgICAgICB9XG4gICAgICAgIGRpc3QtLTsgLyogZGlzdCBpcyBub3cgdGhlIG1hdGNoIGRpc3RhbmNlIC0gMSAqL1xuICAgICAgICBjb2RlID0gZF9jb2RlKGRpc3QpO1xuICAgICAgICAvL0Fzc2VydCAoY29kZSA8IERfQ09ERVMsIFwiYmFkIGRfY29kZVwiKTtcblxuICAgICAgICBzZW5kX2NvZGUocywgY29kZSwgZHRyZWUpOyAgICAgICAvKiBzZW5kIHRoZSBkaXN0YW5jZSBjb2RlICovXG4gICAgICAgIGV4dHJhID0gZXh0cmFfZGJpdHNbY29kZV07XG4gICAgICAgIGlmIChleHRyYSAhPT0gMCkge1xuICAgICAgICAgIGRpc3QgLT0gYmFzZV9kaXN0W2NvZGVdO1xuICAgICAgICAgIHNlbmRfYml0cyhzLCBkaXN0LCBleHRyYSk7ICAgLyogc2VuZCB0aGUgZXh0cmEgZGlzdGFuY2UgYml0cyAqL1xuICAgICAgICB9XG4gICAgICB9IC8qIGxpdGVyYWwgb3IgbWF0Y2ggcGFpciA/ICovXG5cbiAgICAgIC8qIENoZWNrIHRoYXQgdGhlIG92ZXJsYXkgYmV0d2VlbiBwZW5kaW5nX2J1ZiBhbmQgZF9idWYrbF9idWYgaXMgb2s6ICovXG4gICAgICAvL0Fzc2VydCgodUludCkocy0+cGVuZGluZykgPCBzLT5saXRfYnVmc2l6ZSArIDIqbHgsXG4gICAgICAvLyAgICAgICBcInBlbmRpbmdCdWYgb3ZlcmZsb3dcIik7XG5cbiAgICB9IHdoaWxlIChseCA8IHMubGFzdF9saXQpO1xuICB9XG5cbiAgc2VuZF9jb2RlKHMsIEVORF9CTE9DSywgbHRyZWUpO1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29uc3RydWN0IG9uZSBIdWZmbWFuIHRyZWUgYW5kIGFzc2lnbnMgdGhlIGNvZGUgYml0IHN0cmluZ3MgYW5kIGxlbmd0aHMuXG4gKiBVcGRhdGUgdGhlIHRvdGFsIGJpdCBsZW5ndGggZm9yIHRoZSBjdXJyZW50IGJsb2NrLlxuICogSU4gYXNzZXJ0aW9uOiB0aGUgZmllbGQgZnJlcSBpcyBzZXQgZm9yIGFsbCB0cmVlIGVsZW1lbnRzLlxuICogT1VUIGFzc2VydGlvbnM6IHRoZSBmaWVsZHMgbGVuIGFuZCBjb2RlIGFyZSBzZXQgdG8gdGhlIG9wdGltYWwgYml0IGxlbmd0aFxuICogICAgIGFuZCBjb3JyZXNwb25kaW5nIGNvZGUuIFRoZSBsZW5ndGggb3B0X2xlbiBpcyB1cGRhdGVkOyBzdGF0aWNfbGVuIGlzXG4gKiAgICAgYWxzbyB1cGRhdGVkIGlmIHN0cmVlIGlzIG5vdCBudWxsLiBUaGUgZmllbGQgbWF4X2NvZGUgaXMgc2V0LlxuICovXG5mdW5jdGlvbiBidWlsZF90cmVlKHMsIGRlc2MpXG4vLyAgICBkZWZsYXRlX3N0YXRlICpzO1xuLy8gICAgdHJlZV9kZXNjICpkZXNjOyAvKiB0aGUgdHJlZSBkZXNjcmlwdG9yICovXG57XG4gIHZhciB0cmVlICAgICA9IGRlc2MuZHluX3RyZWU7XG4gIHZhciBzdHJlZSAgICA9IGRlc2Muc3RhdF9kZXNjLnN0YXRpY190cmVlO1xuICB2YXIgaGFzX3N0cmVlID0gZGVzYy5zdGF0X2Rlc2MuaGFzX3N0cmVlO1xuICB2YXIgZWxlbXMgICAgPSBkZXNjLnN0YXRfZGVzYy5lbGVtcztcbiAgdmFyIG4sIG07ICAgICAgICAgIC8qIGl0ZXJhdGUgb3ZlciBoZWFwIGVsZW1lbnRzICovXG4gIHZhciBtYXhfY29kZSA9IC0xOyAvKiBsYXJnZXN0IGNvZGUgd2l0aCBub24gemVybyBmcmVxdWVuY3kgKi9cbiAgdmFyIG5vZGU7ICAgICAgICAgIC8qIG5ldyBub2RlIGJlaW5nIGNyZWF0ZWQgKi9cblxuICAvKiBDb25zdHJ1Y3QgdGhlIGluaXRpYWwgaGVhcCwgd2l0aCBsZWFzdCBmcmVxdWVudCBlbGVtZW50IGluXG4gICAqIGhlYXBbU01BTExFU1RdLiBUaGUgc29ucyBvZiBoZWFwW25dIGFyZSBoZWFwWzIqbl0gYW5kIGhlYXBbMipuKzFdLlxuICAgKiBoZWFwWzBdIGlzIG5vdCB1c2VkLlxuICAgKi9cbiAgcy5oZWFwX2xlbiA9IDA7XG4gIHMuaGVhcF9tYXggPSBIRUFQX1NJWkU7XG5cbiAgZm9yIChuID0gMDsgbiA8IGVsZW1zOyBuKyspIHtcbiAgICBpZiAodHJlZVtuICogMl0vKi5GcmVxKi8gIT09IDApIHtcbiAgICAgIHMuaGVhcFsrK3MuaGVhcF9sZW5dID0gbWF4X2NvZGUgPSBuO1xuICAgICAgcy5kZXB0aFtuXSA9IDA7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgdHJlZVtuICogMiArIDFdLyouTGVuKi8gPSAwO1xuICAgIH1cbiAgfVxuXG4gIC8qIFRoZSBwa3ppcCBmb3JtYXQgcmVxdWlyZXMgdGhhdCBhdCBsZWFzdCBvbmUgZGlzdGFuY2UgY29kZSBleGlzdHMsXG4gICAqIGFuZCB0aGF0IGF0IGxlYXN0IG9uZSBiaXQgc2hvdWxkIGJlIHNlbnQgZXZlbiBpZiB0aGVyZSBpcyBvbmx5IG9uZVxuICAgKiBwb3NzaWJsZSBjb2RlLiBTbyB0byBhdm9pZCBzcGVjaWFsIGNoZWNrcyBsYXRlciBvbiB3ZSBmb3JjZSBhdCBsZWFzdFxuICAgKiB0d28gY29kZXMgb2Ygbm9uIHplcm8gZnJlcXVlbmN5LlxuICAgKi9cbiAgd2hpbGUgKHMuaGVhcF9sZW4gPCAyKSB7XG4gICAgbm9kZSA9IHMuaGVhcFsrK3MuaGVhcF9sZW5dID0gKG1heF9jb2RlIDwgMiA/ICsrbWF4X2NvZGUgOiAwKTtcbiAgICB0cmVlW25vZGUgKiAyXS8qLkZyZXEqLyA9IDE7XG4gICAgcy5kZXB0aFtub2RlXSA9IDA7XG4gICAgcy5vcHRfbGVuLS07XG5cbiAgICBpZiAoaGFzX3N0cmVlKSB7XG4gICAgICBzLnN0YXRpY19sZW4gLT0gc3RyZWVbbm9kZSAqIDIgKyAxXS8qLkxlbiovO1xuICAgIH1cbiAgICAvKiBub2RlIGlzIDAgb3IgMSBzbyBpdCBkb2VzIG5vdCBoYXZlIGV4dHJhIGJpdHMgKi9cbiAgfVxuICBkZXNjLm1heF9jb2RlID0gbWF4X2NvZGU7XG5cbiAgLyogVGhlIGVsZW1lbnRzIGhlYXBbaGVhcF9sZW4vMisxIC4uIGhlYXBfbGVuXSBhcmUgbGVhdmVzIG9mIHRoZSB0cmVlLFxuICAgKiBlc3RhYmxpc2ggc3ViLWhlYXBzIG9mIGluY3JlYXNpbmcgbGVuZ3RoczpcbiAgICovXG4gIGZvciAobiA9IChzLmhlYXBfbGVuID4+IDEvKmludCAvMiovKTsgbiA+PSAxOyBuLS0pIHsgcHFkb3duaGVhcChzLCB0cmVlLCBuKTsgfVxuXG4gIC8qIENvbnN0cnVjdCB0aGUgSHVmZm1hbiB0cmVlIGJ5IHJlcGVhdGVkbHkgY29tYmluaW5nIHRoZSBsZWFzdCB0d29cbiAgICogZnJlcXVlbnQgbm9kZXMuXG4gICAqL1xuICBub2RlID0gZWxlbXM7ICAgICAgICAgICAgICAvKiBuZXh0IGludGVybmFsIG5vZGUgb2YgdGhlIHRyZWUgKi9cbiAgZG8ge1xuICAgIC8vcHFyZW1vdmUocywgdHJlZSwgbik7ICAvKiBuID0gbm9kZSBvZiBsZWFzdCBmcmVxdWVuY3kgKi9cbiAgICAvKioqIHBxcmVtb3ZlICoqKi9cbiAgICBuID0gcy5oZWFwWzEvKlNNQUxMRVNUKi9dO1xuICAgIHMuaGVhcFsxLypTTUFMTEVTVCovXSA9IHMuaGVhcFtzLmhlYXBfbGVuLS1dO1xuICAgIHBxZG93bmhlYXAocywgdHJlZSwgMS8qU01BTExFU1QqLyk7XG4gICAgLyoqKi9cblxuICAgIG0gPSBzLmhlYXBbMS8qU01BTExFU1QqL107IC8qIG0gPSBub2RlIG9mIG5leHQgbGVhc3QgZnJlcXVlbmN5ICovXG5cbiAgICBzLmhlYXBbLS1zLmhlYXBfbWF4XSA9IG47IC8qIGtlZXAgdGhlIG5vZGVzIHNvcnRlZCBieSBmcmVxdWVuY3kgKi9cbiAgICBzLmhlYXBbLS1zLmhlYXBfbWF4XSA9IG07XG5cbiAgICAvKiBDcmVhdGUgYSBuZXcgbm9kZSBmYXRoZXIgb2YgbiBhbmQgbSAqL1xuICAgIHRyZWVbbm9kZSAqIDJdLyouRnJlcSovID0gdHJlZVtuICogMl0vKi5GcmVxKi8gKyB0cmVlW20gKiAyXS8qLkZyZXEqLztcbiAgICBzLmRlcHRoW25vZGVdID0gKHMuZGVwdGhbbl0gPj0gcy5kZXB0aFttXSA/IHMuZGVwdGhbbl0gOiBzLmRlcHRoW21dKSArIDE7XG4gICAgdHJlZVtuICogMiArIDFdLyouRGFkKi8gPSB0cmVlW20gKiAyICsgMV0vKi5EYWQqLyA9IG5vZGU7XG5cbiAgICAvKiBhbmQgaW5zZXJ0IHRoZSBuZXcgbm9kZSBpbiB0aGUgaGVhcCAqL1xuICAgIHMuaGVhcFsxLypTTUFMTEVTVCovXSA9IG5vZGUrKztcbiAgICBwcWRvd25oZWFwKHMsIHRyZWUsIDEvKlNNQUxMRVNUKi8pO1xuXG4gIH0gd2hpbGUgKHMuaGVhcF9sZW4gPj0gMik7XG5cbiAgcy5oZWFwWy0tcy5oZWFwX21heF0gPSBzLmhlYXBbMS8qU01BTExFU1QqL107XG5cbiAgLyogQXQgdGhpcyBwb2ludCwgdGhlIGZpZWxkcyBmcmVxIGFuZCBkYWQgYXJlIHNldC4gV2UgY2FuIG5vd1xuICAgKiBnZW5lcmF0ZSB0aGUgYml0IGxlbmd0aHMuXG4gICAqL1xuICBnZW5fYml0bGVuKHMsIGRlc2MpO1xuXG4gIC8qIFRoZSBmaWVsZCBsZW4gaXMgbm93IHNldCwgd2UgY2FuIGdlbmVyYXRlIHRoZSBiaXQgY29kZXMgKi9cbiAgZ2VuX2NvZGVzKHRyZWUsIG1heF9jb2RlLCBzLmJsX2NvdW50KTtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNjYW4gYSBsaXRlcmFsIG9yIGRpc3RhbmNlIHRyZWUgdG8gZGV0ZXJtaW5lIHRoZSBmcmVxdWVuY2llcyBvZiB0aGUgY29kZXNcbiAqIGluIHRoZSBiaXQgbGVuZ3RoIHRyZWUuXG4gKi9cbmZ1bmN0aW9uIHNjYW5fdHJlZShzLCB0cmVlLCBtYXhfY29kZSlcbi8vICAgIGRlZmxhdGVfc3RhdGUgKnM7XG4vLyAgICBjdF9kYXRhICp0cmVlOyAgIC8qIHRoZSB0cmVlIHRvIGJlIHNjYW5uZWQgKi9cbi8vICAgIGludCBtYXhfY29kZTsgICAgLyogYW5kIGl0cyBsYXJnZXN0IGNvZGUgb2Ygbm9uIHplcm8gZnJlcXVlbmN5ICovXG57XG4gIHZhciBuOyAgICAgICAgICAgICAgICAgICAgIC8qIGl0ZXJhdGVzIG92ZXIgYWxsIHRyZWUgZWxlbWVudHMgKi9cbiAgdmFyIHByZXZsZW4gPSAtMTsgICAgICAgICAgLyogbGFzdCBlbWl0dGVkIGxlbmd0aCAqL1xuICB2YXIgY3VybGVuOyAgICAgICAgICAgICAgICAvKiBsZW5ndGggb2YgY3VycmVudCBjb2RlICovXG5cbiAgdmFyIG5leHRsZW4gPSB0cmVlWzAgKiAyICsgMV0vKi5MZW4qLzsgLyogbGVuZ3RoIG9mIG5leHQgY29kZSAqL1xuXG4gIHZhciBjb3VudCA9IDA7ICAgICAgICAgICAgIC8qIHJlcGVhdCBjb3VudCBvZiB0aGUgY3VycmVudCBjb2RlICovXG4gIHZhciBtYXhfY291bnQgPSA3OyAgICAgICAgIC8qIG1heCByZXBlYXQgY291bnQgKi9cbiAgdmFyIG1pbl9jb3VudCA9IDQ7ICAgICAgICAgLyogbWluIHJlcGVhdCBjb3VudCAqL1xuXG4gIGlmIChuZXh0bGVuID09PSAwKSB7XG4gICAgbWF4X2NvdW50ID0gMTM4O1xuICAgIG1pbl9jb3VudCA9IDM7XG4gIH1cbiAgdHJlZVsobWF4X2NvZGUgKyAxKSAqIDIgKyAxXS8qLkxlbiovID0gMHhmZmZmOyAvKiBndWFyZCAqL1xuXG4gIGZvciAobiA9IDA7IG4gPD0gbWF4X2NvZGU7IG4rKykge1xuICAgIGN1cmxlbiA9IG5leHRsZW47XG4gICAgbmV4dGxlbiA9IHRyZWVbKG4gKyAxKSAqIDIgKyAxXS8qLkxlbiovO1xuXG4gICAgaWYgKCsrY291bnQgPCBtYXhfY291bnQgJiYgY3VybGVuID09PSBuZXh0bGVuKSB7XG4gICAgICBjb250aW51ZTtcblxuICAgIH0gZWxzZSBpZiAoY291bnQgPCBtaW5fY291bnQpIHtcbiAgICAgIHMuYmxfdHJlZVtjdXJsZW4gKiAyXS8qLkZyZXEqLyArPSBjb3VudDtcblxuICAgIH0gZWxzZSBpZiAoY3VybGVuICE9PSAwKSB7XG5cbiAgICAgIGlmIChjdXJsZW4gIT09IHByZXZsZW4pIHsgcy5ibF90cmVlW2N1cmxlbiAqIDJdLyouRnJlcSovKys7IH1cbiAgICAgIHMuYmxfdHJlZVtSRVBfM182ICogMl0vKi5GcmVxKi8rKztcblxuICAgIH0gZWxzZSBpZiAoY291bnQgPD0gMTApIHtcbiAgICAgIHMuYmxfdHJlZVtSRVBaXzNfMTAgKiAyXS8qLkZyZXEqLysrO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIHMuYmxfdHJlZVtSRVBaXzExXzEzOCAqIDJdLyouRnJlcSovKys7XG4gICAgfVxuXG4gICAgY291bnQgPSAwO1xuICAgIHByZXZsZW4gPSBjdXJsZW47XG5cbiAgICBpZiAobmV4dGxlbiA9PT0gMCkge1xuICAgICAgbWF4X2NvdW50ID0gMTM4O1xuICAgICAgbWluX2NvdW50ID0gMztcblxuICAgIH0gZWxzZSBpZiAoY3VybGVuID09PSBuZXh0bGVuKSB7XG4gICAgICBtYXhfY291bnQgPSA2O1xuICAgICAgbWluX2NvdW50ID0gMztcblxuICAgIH0gZWxzZSB7XG4gICAgICBtYXhfY291bnQgPSA3O1xuICAgICAgbWluX2NvdW50ID0gNDtcbiAgICB9XG4gIH1cbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNlbmQgYSBsaXRlcmFsIG9yIGRpc3RhbmNlIHRyZWUgaW4gY29tcHJlc3NlZCBmb3JtLCB1c2luZyB0aGUgY29kZXMgaW5cbiAqIGJsX3RyZWUuXG4gKi9cbmZ1bmN0aW9uIHNlbmRfdHJlZShzLCB0cmVlLCBtYXhfY29kZSlcbi8vICAgIGRlZmxhdGVfc3RhdGUgKnM7XG4vLyAgICBjdF9kYXRhICp0cmVlOyAvKiB0aGUgdHJlZSB0byBiZSBzY2FubmVkICovXG4vLyAgICBpbnQgbWF4X2NvZGU7ICAgICAgIC8qIGFuZCBpdHMgbGFyZ2VzdCBjb2RlIG9mIG5vbiB6ZXJvIGZyZXF1ZW5jeSAqL1xue1xuICB2YXIgbjsgICAgICAgICAgICAgICAgICAgICAvKiBpdGVyYXRlcyBvdmVyIGFsbCB0cmVlIGVsZW1lbnRzICovXG4gIHZhciBwcmV2bGVuID0gLTE7ICAgICAgICAgIC8qIGxhc3QgZW1pdHRlZCBsZW5ndGggKi9cbiAgdmFyIGN1cmxlbjsgICAgICAgICAgICAgICAgLyogbGVuZ3RoIG9mIGN1cnJlbnQgY29kZSAqL1xuXG4gIHZhciBuZXh0bGVuID0gdHJlZVswICogMiArIDFdLyouTGVuKi87IC8qIGxlbmd0aCBvZiBuZXh0IGNvZGUgKi9cblxuICB2YXIgY291bnQgPSAwOyAgICAgICAgICAgICAvKiByZXBlYXQgY291bnQgb2YgdGhlIGN1cnJlbnQgY29kZSAqL1xuICB2YXIgbWF4X2NvdW50ID0gNzsgICAgICAgICAvKiBtYXggcmVwZWF0IGNvdW50ICovXG4gIHZhciBtaW5fY291bnQgPSA0OyAgICAgICAgIC8qIG1pbiByZXBlYXQgY291bnQgKi9cblxuICAvKiB0cmVlW21heF9jb2RlKzFdLkxlbiA9IC0xOyAqLyAgLyogZ3VhcmQgYWxyZWFkeSBzZXQgKi9cbiAgaWYgKG5leHRsZW4gPT09IDApIHtcbiAgICBtYXhfY291bnQgPSAxMzg7XG4gICAgbWluX2NvdW50ID0gMztcbiAgfVxuXG4gIGZvciAobiA9IDA7IG4gPD0gbWF4X2NvZGU7IG4rKykge1xuICAgIGN1cmxlbiA9IG5leHRsZW47XG4gICAgbmV4dGxlbiA9IHRyZWVbKG4gKyAxKSAqIDIgKyAxXS8qLkxlbiovO1xuXG4gICAgaWYgKCsrY291bnQgPCBtYXhfY291bnQgJiYgY3VybGVuID09PSBuZXh0bGVuKSB7XG4gICAgICBjb250aW51ZTtcblxuICAgIH0gZWxzZSBpZiAoY291bnQgPCBtaW5fY291bnQpIHtcbiAgICAgIGRvIHsgc2VuZF9jb2RlKHMsIGN1cmxlbiwgcy5ibF90cmVlKTsgfSB3aGlsZSAoLS1jb3VudCAhPT0gMCk7XG5cbiAgICB9IGVsc2UgaWYgKGN1cmxlbiAhPT0gMCkge1xuICAgICAgaWYgKGN1cmxlbiAhPT0gcHJldmxlbikge1xuICAgICAgICBzZW5kX2NvZGUocywgY3VybGVuLCBzLmJsX3RyZWUpO1xuICAgICAgICBjb3VudC0tO1xuICAgICAgfVxuICAgICAgLy9Bc3NlcnQoY291bnQgPj0gMyAmJiBjb3VudCA8PSA2LCBcIiAzXzY/XCIpO1xuICAgICAgc2VuZF9jb2RlKHMsIFJFUF8zXzYsIHMuYmxfdHJlZSk7XG4gICAgICBzZW5kX2JpdHMocywgY291bnQgLSAzLCAyKTtcblxuICAgIH0gZWxzZSBpZiAoY291bnQgPD0gMTApIHtcbiAgICAgIHNlbmRfY29kZShzLCBSRVBaXzNfMTAsIHMuYmxfdHJlZSk7XG4gICAgICBzZW5kX2JpdHMocywgY291bnQgLSAzLCAzKTtcblxuICAgIH0gZWxzZSB7XG4gICAgICBzZW5kX2NvZGUocywgUkVQWl8xMV8xMzgsIHMuYmxfdHJlZSk7XG4gICAgICBzZW5kX2JpdHMocywgY291bnQgLSAxMSwgNyk7XG4gICAgfVxuXG4gICAgY291bnQgPSAwO1xuICAgIHByZXZsZW4gPSBjdXJsZW47XG4gICAgaWYgKG5leHRsZW4gPT09IDApIHtcbiAgICAgIG1heF9jb3VudCA9IDEzODtcbiAgICAgIG1pbl9jb3VudCA9IDM7XG5cbiAgICB9IGVsc2UgaWYgKGN1cmxlbiA9PT0gbmV4dGxlbikge1xuICAgICAgbWF4X2NvdW50ID0gNjtcbiAgICAgIG1pbl9jb3VudCA9IDM7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgbWF4X2NvdW50ID0gNztcbiAgICAgIG1pbl9jb3VudCA9IDQ7XG4gICAgfVxuICB9XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb25zdHJ1Y3QgdGhlIEh1ZmZtYW4gdHJlZSBmb3IgdGhlIGJpdCBsZW5ndGhzIGFuZCByZXR1cm4gdGhlIGluZGV4IGluXG4gKiBibF9vcmRlciBvZiB0aGUgbGFzdCBiaXQgbGVuZ3RoIGNvZGUgdG8gc2VuZC5cbiAqL1xuZnVuY3Rpb24gYnVpbGRfYmxfdHJlZShzKSB7XG4gIHZhciBtYXhfYmxpbmRleDsgIC8qIGluZGV4IG9mIGxhc3QgYml0IGxlbmd0aCBjb2RlIG9mIG5vbiB6ZXJvIGZyZXEgKi9cblxuICAvKiBEZXRlcm1pbmUgdGhlIGJpdCBsZW5ndGggZnJlcXVlbmNpZXMgZm9yIGxpdGVyYWwgYW5kIGRpc3RhbmNlIHRyZWVzICovXG4gIHNjYW5fdHJlZShzLCBzLmR5bl9sdHJlZSwgcy5sX2Rlc2MubWF4X2NvZGUpO1xuICBzY2FuX3RyZWUocywgcy5keW5fZHRyZWUsIHMuZF9kZXNjLm1heF9jb2RlKTtcblxuICAvKiBCdWlsZCB0aGUgYml0IGxlbmd0aCB0cmVlOiAqL1xuICBidWlsZF90cmVlKHMsIHMuYmxfZGVzYyk7XG4gIC8qIG9wdF9sZW4gbm93IGluY2x1ZGVzIHRoZSBsZW5ndGggb2YgdGhlIHRyZWUgcmVwcmVzZW50YXRpb25zLCBleGNlcHRcbiAgICogdGhlIGxlbmd0aHMgb2YgdGhlIGJpdCBsZW5ndGhzIGNvZGVzIGFuZCB0aGUgNSs1KzQgYml0cyBmb3IgdGhlIGNvdW50cy5cbiAgICovXG5cbiAgLyogRGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgYml0IGxlbmd0aCBjb2RlcyB0byBzZW5kLiBUaGUgcGt6aXAgZm9ybWF0XG4gICAqIHJlcXVpcmVzIHRoYXQgYXQgbGVhc3QgNCBiaXQgbGVuZ3RoIGNvZGVzIGJlIHNlbnQuIChhcHBub3RlLnR4dCBzYXlzXG4gICAqIDMgYnV0IHRoZSBhY3R1YWwgdmFsdWUgdXNlZCBpcyA0LilcbiAgICovXG4gIGZvciAobWF4X2JsaW5kZXggPSBCTF9DT0RFUyAtIDE7IG1heF9ibGluZGV4ID49IDM7IG1heF9ibGluZGV4LS0pIHtcbiAgICBpZiAocy5ibF90cmVlW2JsX29yZGVyW21heF9ibGluZGV4XSAqIDIgKyAxXS8qLkxlbiovICE9PSAwKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgLyogVXBkYXRlIG9wdF9sZW4gdG8gaW5jbHVkZSB0aGUgYml0IGxlbmd0aCB0cmVlIGFuZCBjb3VudHMgKi9cbiAgcy5vcHRfbGVuICs9IDMgKiAobWF4X2JsaW5kZXggKyAxKSArIDUgKyA1ICsgNDtcbiAgLy9UcmFjZXYoKHN0ZGVyciwgXCJcXG5keW4gdHJlZXM6IGR5biAlbGQsIHN0YXQgJWxkXCIsXG4gIC8vICAgICAgICBzLT5vcHRfbGVuLCBzLT5zdGF0aWNfbGVuKSk7XG5cbiAgcmV0dXJuIG1heF9ibGluZGV4O1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogU2VuZCB0aGUgaGVhZGVyIGZvciBhIGJsb2NrIHVzaW5nIGR5bmFtaWMgSHVmZm1hbiB0cmVlczogdGhlIGNvdW50cywgdGhlXG4gKiBsZW5ndGhzIG9mIHRoZSBiaXQgbGVuZ3RoIGNvZGVzLCB0aGUgbGl0ZXJhbCB0cmVlIGFuZCB0aGUgZGlzdGFuY2UgdHJlZS5cbiAqIElOIGFzc2VydGlvbjogbGNvZGVzID49IDI1NywgZGNvZGVzID49IDEsIGJsY29kZXMgPj0gNC5cbiAqL1xuZnVuY3Rpb24gc2VuZF9hbGxfdHJlZXMocywgbGNvZGVzLCBkY29kZXMsIGJsY29kZXMpXG4vLyAgICBkZWZsYXRlX3N0YXRlICpzO1xuLy8gICAgaW50IGxjb2RlcywgZGNvZGVzLCBibGNvZGVzOyAvKiBudW1iZXIgb2YgY29kZXMgZm9yIGVhY2ggdHJlZSAqL1xue1xuICB2YXIgcmFuazsgICAgICAgICAgICAgICAgICAgIC8qIGluZGV4IGluIGJsX29yZGVyICovXG5cbiAgLy9Bc3NlcnQgKGxjb2RlcyA+PSAyNTcgJiYgZGNvZGVzID49IDEgJiYgYmxjb2RlcyA+PSA0LCBcIm5vdCBlbm91Z2ggY29kZXNcIik7XG4gIC8vQXNzZXJ0IChsY29kZXMgPD0gTF9DT0RFUyAmJiBkY29kZXMgPD0gRF9DT0RFUyAmJiBibGNvZGVzIDw9IEJMX0NPREVTLFxuICAvLyAgICAgICAgXCJ0b28gbWFueSBjb2Rlc1wiKTtcbiAgLy9UcmFjZXYoKHN0ZGVyciwgXCJcXG5ibCBjb3VudHM6IFwiKSk7XG4gIHNlbmRfYml0cyhzLCBsY29kZXMgLSAyNTcsIDUpOyAvKiBub3QgKzI1NSBhcyBzdGF0ZWQgaW4gYXBwbm90ZS50eHQgKi9cbiAgc2VuZF9iaXRzKHMsIGRjb2RlcyAtIDEsICAgNSk7XG4gIHNlbmRfYml0cyhzLCBibGNvZGVzIC0gNCwgIDQpOyAvKiBub3QgLTMgYXMgc3RhdGVkIGluIGFwcG5vdGUudHh0ICovXG4gIGZvciAocmFuayA9IDA7IHJhbmsgPCBibGNvZGVzOyByYW5rKyspIHtcbiAgICAvL1RyYWNldigoc3RkZXJyLCBcIlxcbmJsIGNvZGUgJTJkIFwiLCBibF9vcmRlcltyYW5rXSkpO1xuICAgIHNlbmRfYml0cyhzLCBzLmJsX3RyZWVbYmxfb3JkZXJbcmFua10gKiAyICsgMV0vKi5MZW4qLywgMyk7XG4gIH1cbiAgLy9UcmFjZXYoKHN0ZGVyciwgXCJcXG5ibCB0cmVlOiBzZW50ICVsZFwiLCBzLT5iaXRzX3NlbnQpKTtcblxuICBzZW5kX3RyZWUocywgcy5keW5fbHRyZWUsIGxjb2RlcyAtIDEpOyAvKiBsaXRlcmFsIHRyZWUgKi9cbiAgLy9UcmFjZXYoKHN0ZGVyciwgXCJcXG5saXQgdHJlZTogc2VudCAlbGRcIiwgcy0+Yml0c19zZW50KSk7XG5cbiAgc2VuZF90cmVlKHMsIHMuZHluX2R0cmVlLCBkY29kZXMgLSAxKTsgLyogZGlzdGFuY2UgdHJlZSAqL1xuICAvL1RyYWNldigoc3RkZXJyLCBcIlxcbmRpc3QgdHJlZTogc2VudCAlbGRcIiwgcy0+Yml0c19zZW50KSk7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDaGVjayBpZiB0aGUgZGF0YSB0eXBlIGlzIFRFWFQgb3IgQklOQVJZLCB1c2luZyB0aGUgZm9sbG93aW5nIGFsZ29yaXRobTpcbiAqIC0gVEVYVCBpZiB0aGUgdHdvIGNvbmRpdGlvbnMgYmVsb3cgYXJlIHNhdGlzZmllZDpcbiAqICAgIGEpIFRoZXJlIGFyZSBubyBub24tcG9ydGFibGUgY29udHJvbCBjaGFyYWN0ZXJzIGJlbG9uZ2luZyB0byB0aGVcbiAqICAgICAgIFwiYmxhY2sgbGlzdFwiICgwLi42LCAxNC4uMjUsIDI4Li4zMSkuXG4gKiAgICBiKSBUaGVyZSBpcyBhdCBsZWFzdCBvbmUgcHJpbnRhYmxlIGNoYXJhY3RlciBiZWxvbmdpbmcgdG8gdGhlXG4gKiAgICAgICBcIndoaXRlIGxpc3RcIiAoOSB7VEFCfSwgMTAge0xGfSwgMTMge0NSfSwgMzIuLjI1NSkuXG4gKiAtIEJJTkFSWSBvdGhlcndpc2UuXG4gKiAtIFRoZSBmb2xsb3dpbmcgcGFydGlhbGx5LXBvcnRhYmxlIGNvbnRyb2wgY2hhcmFjdGVycyBmb3JtIGFcbiAqICAgXCJncmF5IGxpc3RcIiB0aGF0IGlzIGlnbm9yZWQgaW4gdGhpcyBkZXRlY3Rpb24gYWxnb3JpdGhtOlxuICogICAoNyB7QkVMfSwgOCB7QlN9LCAxMSB7VlR9LCAxMiB7RkZ9LCAyNiB7U1VCfSwgMjcge0VTQ30pLlxuICogSU4gYXNzZXJ0aW9uOiB0aGUgZmllbGRzIEZyZXEgb2YgZHluX2x0cmVlIGFyZSBzZXQuXG4gKi9cbmZ1bmN0aW9uIGRldGVjdF9kYXRhX3R5cGUocykge1xuICAvKiBibGFja19tYXNrIGlzIHRoZSBiaXQgbWFzayBvZiBibGFjay1saXN0ZWQgYnl0ZXNcbiAgICogc2V0IGJpdHMgMC4uNiwgMTQuLjI1LCBhbmQgMjguLjMxXG4gICAqIDB4ZjNmZmMwN2YgPSBiaW5hcnkgMTExMTAwMTExMTExMTExMTExMDAwMDAwMDExMTExMTFcbiAgICovXG4gIHZhciBibGFja19tYXNrID0gMHhmM2ZmYzA3ZjtcbiAgdmFyIG47XG5cbiAgLyogQ2hlY2sgZm9yIG5vbi10ZXh0dWFsIChcImJsYWNrLWxpc3RlZFwiKSBieXRlcy4gKi9cbiAgZm9yIChuID0gMDsgbiA8PSAzMTsgbisrLCBibGFja19tYXNrID4+Pj0gMSkge1xuICAgIGlmICgoYmxhY2tfbWFzayAmIDEpICYmIChzLmR5bl9sdHJlZVtuICogMl0vKi5GcmVxKi8gIT09IDApKSB7XG4gICAgICByZXR1cm4gWl9CSU5BUlk7XG4gICAgfVxuICB9XG5cbiAgLyogQ2hlY2sgZm9yIHRleHR1YWwgKFwid2hpdGUtbGlzdGVkXCIpIGJ5dGVzLiAqL1xuICBpZiAocy5keW5fbHRyZWVbOSAqIDJdLyouRnJlcSovICE9PSAwIHx8IHMuZHluX2x0cmVlWzEwICogMl0vKi5GcmVxKi8gIT09IDAgfHxcbiAgICAgIHMuZHluX2x0cmVlWzEzICogMl0vKi5GcmVxKi8gIT09IDApIHtcbiAgICByZXR1cm4gWl9URVhUO1xuICB9XG4gIGZvciAobiA9IDMyOyBuIDwgTElURVJBTFM7IG4rKykge1xuICAgIGlmIChzLmR5bl9sdHJlZVtuICogMl0vKi5GcmVxKi8gIT09IDApIHtcbiAgICAgIHJldHVybiBaX1RFWFQ7XG4gICAgfVxuICB9XG5cbiAgLyogVGhlcmUgYXJlIG5vIFwiYmxhY2stbGlzdGVkXCIgb3IgXCJ3aGl0ZS1saXN0ZWRcIiBieXRlczpcbiAgICogdGhpcyBzdHJlYW0gZWl0aGVyIGlzIGVtcHR5IG9yIGhhcyB0b2xlcmF0ZWQgKFwiZ3JheS1saXN0ZWRcIikgYnl0ZXMgb25seS5cbiAgICovXG4gIHJldHVybiBaX0JJTkFSWTtcbn1cblxuXG52YXIgc3RhdGljX2luaXRfZG9uZSA9IGZhbHNlO1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEluaXRpYWxpemUgdGhlIHRyZWUgZGF0YSBzdHJ1Y3R1cmVzIGZvciBhIG5ldyB6bGliIHN0cmVhbS5cbiAqL1xuZnVuY3Rpb24gX3RyX2luaXQocylcbntcblxuICBpZiAoIXN0YXRpY19pbml0X2RvbmUpIHtcbiAgICB0cl9zdGF0aWNfaW5pdCgpO1xuICAgIHN0YXRpY19pbml0X2RvbmUgPSB0cnVlO1xuICB9XG5cbiAgcy5sX2Rlc2MgID0gbmV3IFRyZWVEZXNjKHMuZHluX2x0cmVlLCBzdGF0aWNfbF9kZXNjKTtcbiAgcy5kX2Rlc2MgID0gbmV3IFRyZWVEZXNjKHMuZHluX2R0cmVlLCBzdGF0aWNfZF9kZXNjKTtcbiAgcy5ibF9kZXNjID0gbmV3IFRyZWVEZXNjKHMuYmxfdHJlZSwgc3RhdGljX2JsX2Rlc2MpO1xuXG4gIHMuYmlfYnVmID0gMDtcbiAgcy5iaV92YWxpZCA9IDA7XG5cbiAgLyogSW5pdGlhbGl6ZSB0aGUgZmlyc3QgYmxvY2sgb2YgdGhlIGZpcnN0IGZpbGU6ICovXG4gIGluaXRfYmxvY2socyk7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTZW5kIGEgc3RvcmVkIGJsb2NrXG4gKi9cbmZ1bmN0aW9uIF90cl9zdG9yZWRfYmxvY2socywgYnVmLCBzdG9yZWRfbGVuLCBsYXN0KVxuLy9EZWZsYXRlU3RhdGUgKnM7XG4vL2NoYXJmICpidWY7ICAgICAgIC8qIGlucHV0IGJsb2NrICovXG4vL3VsZyBzdG9yZWRfbGVuOyAgIC8qIGxlbmd0aCBvZiBpbnB1dCBibG9jayAqL1xuLy9pbnQgbGFzdDsgICAgICAgICAvKiBvbmUgaWYgdGhpcyBpcyB0aGUgbGFzdCBibG9jayBmb3IgYSBmaWxlICovXG57XG4gIHNlbmRfYml0cyhzLCAoU1RPUkVEX0JMT0NLIDw8IDEpICsgKGxhc3QgPyAxIDogMCksIDMpOyAgICAvKiBzZW5kIGJsb2NrIHR5cGUgKi9cbiAgY29weV9ibG9jayhzLCBidWYsIHN0b3JlZF9sZW4sIHRydWUpOyAvKiB3aXRoIGhlYWRlciAqL1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogU2VuZCBvbmUgZW1wdHkgc3RhdGljIGJsb2NrIHRvIGdpdmUgZW5vdWdoIGxvb2thaGVhZCBmb3IgaW5mbGF0ZS5cbiAqIFRoaXMgdGFrZXMgMTAgYml0cywgb2Ygd2hpY2ggNyBtYXkgcmVtYWluIGluIHRoZSBiaXQgYnVmZmVyLlxuICovXG5mdW5jdGlvbiBfdHJfYWxpZ24ocykge1xuICBzZW5kX2JpdHMocywgU1RBVElDX1RSRUVTIDw8IDEsIDMpO1xuICBzZW5kX2NvZGUocywgRU5EX0JMT0NLLCBzdGF0aWNfbHRyZWUpO1xuICBiaV9mbHVzaChzKTtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIERldGVybWluZSB0aGUgYmVzdCBlbmNvZGluZyBmb3IgdGhlIGN1cnJlbnQgYmxvY2s6IGR5bmFtaWMgdHJlZXMsIHN0YXRpY1xuICogdHJlZXMgb3Igc3RvcmUsIGFuZCBvdXRwdXQgdGhlIGVuY29kZWQgYmxvY2sgdG8gdGhlIHppcCBmaWxlLlxuICovXG5mdW5jdGlvbiBfdHJfZmx1c2hfYmxvY2socywgYnVmLCBzdG9yZWRfbGVuLCBsYXN0KVxuLy9EZWZsYXRlU3RhdGUgKnM7XG4vL2NoYXJmICpidWY7ICAgICAgIC8qIGlucHV0IGJsb2NrLCBvciBOVUxMIGlmIHRvbyBvbGQgKi9cbi8vdWxnIHN0b3JlZF9sZW47ICAgLyogbGVuZ3RoIG9mIGlucHV0IGJsb2NrICovXG4vL2ludCBsYXN0OyAgICAgICAgIC8qIG9uZSBpZiB0aGlzIGlzIHRoZSBsYXN0IGJsb2NrIGZvciBhIGZpbGUgKi9cbntcbiAgdmFyIG9wdF9sZW5iLCBzdGF0aWNfbGVuYjsgIC8qIG9wdF9sZW4gYW5kIHN0YXRpY19sZW4gaW4gYnl0ZXMgKi9cbiAgdmFyIG1heF9ibGluZGV4ID0gMDsgICAgICAgIC8qIGluZGV4IG9mIGxhc3QgYml0IGxlbmd0aCBjb2RlIG9mIG5vbiB6ZXJvIGZyZXEgKi9cblxuICAvKiBCdWlsZCB0aGUgSHVmZm1hbiB0cmVlcyB1bmxlc3MgYSBzdG9yZWQgYmxvY2sgaXMgZm9yY2VkICovXG4gIGlmIChzLmxldmVsID4gMCkge1xuXG4gICAgLyogQ2hlY2sgaWYgdGhlIGZpbGUgaXMgYmluYXJ5IG9yIHRleHQgKi9cbiAgICBpZiAocy5zdHJtLmRhdGFfdHlwZSA9PT0gWl9VTktOT1dOKSB7XG4gICAgICBzLnN0cm0uZGF0YV90eXBlID0gZGV0ZWN0X2RhdGFfdHlwZShzKTtcbiAgICB9XG5cbiAgICAvKiBDb25zdHJ1Y3QgdGhlIGxpdGVyYWwgYW5kIGRpc3RhbmNlIHRyZWVzICovXG4gICAgYnVpbGRfdHJlZShzLCBzLmxfZGVzYyk7XG4gICAgLy8gVHJhY2V2KChzdGRlcnIsIFwiXFxubGl0IGRhdGE6IGR5biAlbGQsIHN0YXQgJWxkXCIsIHMtPm9wdF9sZW4sXG4gICAgLy8gICAgICAgIHMtPnN0YXRpY19sZW4pKTtcblxuICAgIGJ1aWxkX3RyZWUocywgcy5kX2Rlc2MpO1xuICAgIC8vIFRyYWNldigoc3RkZXJyLCBcIlxcbmRpc3QgZGF0YTogZHluICVsZCwgc3RhdCAlbGRcIiwgcy0+b3B0X2xlbixcbiAgICAvLyAgICAgICAgcy0+c3RhdGljX2xlbikpO1xuICAgIC8qIEF0IHRoaXMgcG9pbnQsIG9wdF9sZW4gYW5kIHN0YXRpY19sZW4gYXJlIHRoZSB0b3RhbCBiaXQgbGVuZ3RocyBvZlxuICAgICAqIHRoZSBjb21wcmVzc2VkIGJsb2NrIGRhdGEsIGV4Y2x1ZGluZyB0aGUgdHJlZSByZXByZXNlbnRhdGlvbnMuXG4gICAgICovXG5cbiAgICAvKiBCdWlsZCB0aGUgYml0IGxlbmd0aCB0cmVlIGZvciB0aGUgYWJvdmUgdHdvIHRyZWVzLCBhbmQgZ2V0IHRoZSBpbmRleFxuICAgICAqIGluIGJsX29yZGVyIG9mIHRoZSBsYXN0IGJpdCBsZW5ndGggY29kZSB0byBzZW5kLlxuICAgICAqL1xuICAgIG1heF9ibGluZGV4ID0gYnVpbGRfYmxfdHJlZShzKTtcblxuICAgIC8qIERldGVybWluZSB0aGUgYmVzdCBlbmNvZGluZy4gQ29tcHV0ZSB0aGUgYmxvY2sgbGVuZ3RocyBpbiBieXRlcy4gKi9cbiAgICBvcHRfbGVuYiA9IChzLm9wdF9sZW4gKyAzICsgNykgPj4+IDM7XG4gICAgc3RhdGljX2xlbmIgPSAocy5zdGF0aWNfbGVuICsgMyArIDcpID4+PiAzO1xuXG4gICAgLy8gVHJhY2V2KChzdGRlcnIsIFwiXFxub3B0ICVsdSglbHUpIHN0YXQgJWx1KCVsdSkgc3RvcmVkICVsdSBsaXQgJXUgXCIsXG4gICAgLy8gICAgICAgIG9wdF9sZW5iLCBzLT5vcHRfbGVuLCBzdGF0aWNfbGVuYiwgcy0+c3RhdGljX2xlbiwgc3RvcmVkX2xlbixcbiAgICAvLyAgICAgICAgcy0+bGFzdF9saXQpKTtcblxuICAgIGlmIChzdGF0aWNfbGVuYiA8PSBvcHRfbGVuYikgeyBvcHRfbGVuYiA9IHN0YXRpY19sZW5iOyB9XG5cbiAgfSBlbHNlIHtcbiAgICAvLyBBc3NlcnQoYnVmICE9IChjaGFyKikwLCBcImxvc3QgYnVmXCIpO1xuICAgIG9wdF9sZW5iID0gc3RhdGljX2xlbmIgPSBzdG9yZWRfbGVuICsgNTsgLyogZm9yY2UgYSBzdG9yZWQgYmxvY2sgKi9cbiAgfVxuXG4gIGlmICgoc3RvcmVkX2xlbiArIDQgPD0gb3B0X2xlbmIpICYmIChidWYgIT09IC0xKSkge1xuICAgIC8qIDQ6IHR3byB3b3JkcyBmb3IgdGhlIGxlbmd0aHMgKi9cblxuICAgIC8qIFRoZSB0ZXN0IGJ1ZiAhPSBOVUxMIGlzIG9ubHkgbmVjZXNzYXJ5IGlmIExJVF9CVUZTSVpFID4gV1NJWkUuXG4gICAgICogT3RoZXJ3aXNlIHdlIGNhbid0IGhhdmUgcHJvY2Vzc2VkIG1vcmUgdGhhbiBXU0laRSBpbnB1dCBieXRlcyBzaW5jZVxuICAgICAqIHRoZSBsYXN0IGJsb2NrIGZsdXNoLCBiZWNhdXNlIGNvbXByZXNzaW9uIHdvdWxkIGhhdmUgYmVlblxuICAgICAqIHN1Y2Nlc3NmdWwuIElmIExJVF9CVUZTSVpFIDw9IFdTSVpFLCBpdCBpcyBuZXZlciB0b28gbGF0ZSB0b1xuICAgICAqIHRyYW5zZm9ybSBhIGJsb2NrIGludG8gYSBzdG9yZWQgYmxvY2suXG4gICAgICovXG4gICAgX3RyX3N0b3JlZF9ibG9jayhzLCBidWYsIHN0b3JlZF9sZW4sIGxhc3QpO1xuXG4gIH0gZWxzZSBpZiAocy5zdHJhdGVneSA9PT0gWl9GSVhFRCB8fCBzdGF0aWNfbGVuYiA9PT0gb3B0X2xlbmIpIHtcblxuICAgIHNlbmRfYml0cyhzLCAoU1RBVElDX1RSRUVTIDw8IDEpICsgKGxhc3QgPyAxIDogMCksIDMpO1xuICAgIGNvbXByZXNzX2Jsb2NrKHMsIHN0YXRpY19sdHJlZSwgc3RhdGljX2R0cmVlKTtcblxuICB9IGVsc2Uge1xuICAgIHNlbmRfYml0cyhzLCAoRFlOX1RSRUVTIDw8IDEpICsgKGxhc3QgPyAxIDogMCksIDMpO1xuICAgIHNlbmRfYWxsX3RyZWVzKHMsIHMubF9kZXNjLm1heF9jb2RlICsgMSwgcy5kX2Rlc2MubWF4X2NvZGUgKyAxLCBtYXhfYmxpbmRleCArIDEpO1xuICAgIGNvbXByZXNzX2Jsb2NrKHMsIHMuZHluX2x0cmVlLCBzLmR5bl9kdHJlZSk7XG4gIH1cbiAgLy8gQXNzZXJ0IChzLT5jb21wcmVzc2VkX2xlbiA9PSBzLT5iaXRzX3NlbnQsIFwiYmFkIGNvbXByZXNzZWQgc2l6ZVwiKTtcbiAgLyogVGhlIGFib3ZlIGNoZWNrIGlzIG1hZGUgbW9kIDJeMzIsIGZvciBmaWxlcyBsYXJnZXIgdGhhbiA1MTIgTUJcbiAgICogYW5kIHVMb25nIGltcGxlbWVudGVkIG9uIDMyIGJpdHMuXG4gICAqL1xuICBpbml0X2Jsb2NrKHMpO1xuXG4gIGlmIChsYXN0KSB7XG4gICAgYmlfd2luZHVwKHMpO1xuICB9XG4gIC8vIFRyYWNldigoc3RkZXJyLFwiXFxuY29tcHJsZW4gJWx1KCVsdSkgXCIsIHMtPmNvbXByZXNzZWRfbGVuPj4zLFxuICAvLyAgICAgICBzLT5jb21wcmVzc2VkX2xlbi03Kmxhc3QpKTtcbn1cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTYXZlIHRoZSBtYXRjaCBpbmZvIGFuZCB0YWxseSB0aGUgZnJlcXVlbmN5IGNvdW50cy4gUmV0dXJuIHRydWUgaWZcbiAqIHRoZSBjdXJyZW50IGJsb2NrIG11c3QgYmUgZmx1c2hlZC5cbiAqL1xuZnVuY3Rpb24gX3RyX3RhbGx5KHMsIGRpc3QsIGxjKVxuLy8gICAgZGVmbGF0ZV9zdGF0ZSAqcztcbi8vICAgIHVuc2lnbmVkIGRpc3Q7ICAvKiBkaXN0YW5jZSBvZiBtYXRjaGVkIHN0cmluZyAqL1xuLy8gICAgdW5zaWduZWQgbGM7ICAgIC8qIG1hdGNoIGxlbmd0aC1NSU5fTUFUQ0ggb3IgdW5tYXRjaGVkIGNoYXIgKGlmIGRpc3Q9PTApICovXG57XG4gIC8vdmFyIG91dF9sZW5ndGgsIGluX2xlbmd0aCwgZGNvZGU7XG5cbiAgcy5wZW5kaW5nX2J1ZltzLmRfYnVmICsgcy5sYXN0X2xpdCAqIDJdICAgICA9IChkaXN0ID4+PiA4KSAmIDB4ZmY7XG4gIHMucGVuZGluZ19idWZbcy5kX2J1ZiArIHMubGFzdF9saXQgKiAyICsgMV0gPSBkaXN0ICYgMHhmZjtcblxuICBzLnBlbmRpbmdfYnVmW3MubF9idWYgKyBzLmxhc3RfbGl0XSA9IGxjICYgMHhmZjtcbiAgcy5sYXN0X2xpdCsrO1xuXG4gIGlmIChkaXN0ID09PSAwKSB7XG4gICAgLyogbGMgaXMgdGhlIHVubWF0Y2hlZCBjaGFyICovXG4gICAgcy5keW5fbHRyZWVbbGMgKiAyXS8qLkZyZXEqLysrO1xuICB9IGVsc2Uge1xuICAgIHMubWF0Y2hlcysrO1xuICAgIC8qIEhlcmUsIGxjIGlzIHRoZSBtYXRjaCBsZW5ndGggLSBNSU5fTUFUQ0ggKi9cbiAgICBkaXN0LS07ICAgICAgICAgICAgIC8qIGRpc3QgPSBtYXRjaCBkaXN0YW5jZSAtIDEgKi9cbiAgICAvL0Fzc2VydCgodXNoKWRpc3QgPCAodXNoKU1BWF9ESVNUKHMpICYmXG4gICAgLy8gICAgICAgKHVzaClsYyA8PSAodXNoKShNQVhfTUFUQ0gtTUlOX01BVENIKSAmJlxuICAgIC8vICAgICAgICh1c2gpZF9jb2RlKGRpc3QpIDwgKHVzaClEX0NPREVTLCAgXCJfdHJfdGFsbHk6IGJhZCBtYXRjaFwiKTtcblxuICAgIHMuZHluX2x0cmVlWyhfbGVuZ3RoX2NvZGVbbGNdICsgTElURVJBTFMgKyAxKSAqIDJdLyouRnJlcSovKys7XG4gICAgcy5keW5fZHRyZWVbZF9jb2RlKGRpc3QpICogMl0vKi5GcmVxKi8rKztcbiAgfVxuXG4vLyAoISkgVGhpcyBibG9jayBpcyBkaXNhYmxlZCBpbiB6bGliIGRlZmF1bHRzLFxuLy8gZG9uJ3QgZW5hYmxlIGl0IGZvciBiaW5hcnkgY29tcGF0aWJpbGl0eVxuXG4vLyNpZmRlZiBUUlVOQ0FURV9CTE9DS1xuLy8gIC8qIFRyeSB0byBndWVzcyBpZiBpdCBpcyBwcm9maXRhYmxlIHRvIHN0b3AgdGhlIGN1cnJlbnQgYmxvY2sgaGVyZSAqL1xuLy8gIGlmICgocy5sYXN0X2xpdCAmIDB4MWZmZikgPT09IDAgJiYgcy5sZXZlbCA+IDIpIHtcbi8vICAgIC8qIENvbXB1dGUgYW4gdXBwZXIgYm91bmQgZm9yIHRoZSBjb21wcmVzc2VkIGxlbmd0aCAqL1xuLy8gICAgb3V0X2xlbmd0aCA9IHMubGFzdF9saXQqODtcbi8vICAgIGluX2xlbmd0aCA9IHMuc3Ryc3RhcnQgLSBzLmJsb2NrX3N0YXJ0O1xuLy9cbi8vICAgIGZvciAoZGNvZGUgPSAwOyBkY29kZSA8IERfQ09ERVM7IGRjb2RlKyspIHtcbi8vICAgICAgb3V0X2xlbmd0aCArPSBzLmR5bl9kdHJlZVtkY29kZSoyXS8qLkZyZXEqLyAqICg1ICsgZXh0cmFfZGJpdHNbZGNvZGVdKTtcbi8vICAgIH1cbi8vICAgIG91dF9sZW5ndGggPj4+PSAzO1xuLy8gICAgLy9UcmFjZXYoKHN0ZGVycixcIlxcbmxhc3RfbGl0ICV1LCBpbiAlbGQsIG91dCB+JWxkKCVsZCUlKSBcIixcbi8vICAgIC8vICAgICAgIHMtPmxhc3RfbGl0LCBpbl9sZW5ndGgsIG91dF9sZW5ndGgsXG4vLyAgICAvLyAgICAgICAxMDBMIC0gb3V0X2xlbmd0aCoxMDBML2luX2xlbmd0aCkpO1xuLy8gICAgaWYgKHMubWF0Y2hlcyA8IChzLmxhc3RfbGl0Pj4xKS8qaW50IC8yKi8gJiYgb3V0X2xlbmd0aCA8IChpbl9sZW5ndGg+PjEpLyppbnQgLzIqLykge1xuLy8gICAgICByZXR1cm4gdHJ1ZTtcbi8vICAgIH1cbi8vICB9XG4vLyNlbmRpZlxuXG4gIHJldHVybiAocy5sYXN0X2xpdCA9PT0gcy5saXRfYnVmc2l6ZSAtIDEpO1xuICAvKiBXZSBhdm9pZCBlcXVhbGl0eSB3aXRoIGxpdF9idWZzaXplIGJlY2F1c2Ugb2Ygd3JhcGFyb3VuZCBhdCA2NEtcbiAgICogb24gMTYgYml0IG1hY2hpbmVzIGFuZCBiZWNhdXNlIHN0b3JlZCBibG9ja3MgYXJlIHJlc3RyaWN0ZWQgdG9cbiAgICogNjRLLTEgYnl0ZXMuXG4gICAqL1xufVxuXG5leHBvcnRzLl90cl9pbml0ICA9IF90cl9pbml0O1xuZXhwb3J0cy5fdHJfc3RvcmVkX2Jsb2NrID0gX3RyX3N0b3JlZF9ibG9jaztcbmV4cG9ydHMuX3RyX2ZsdXNoX2Jsb2NrICA9IF90cl9mbHVzaF9ibG9jaztcbmV4cG9ydHMuX3RyX3RhbGx5ID0gX3RyX3RhbGx5O1xuZXhwb3J0cy5fdHJfYWxpZ24gPSBfdHJfYWxpZ247XG4iLCIndXNlIHN0cmljdCc7XG5cbi8vIChDKSAxOTk1LTIwMTMgSmVhbi1sb3VwIEdhaWxseSBhbmQgTWFyayBBZGxlclxuLy8gKEMpIDIwMTQtMjAxNyBWaXRhbHkgUHV6cmluIGFuZCBBbmRyZXkgVHVwaXRzaW5cbi8vXG4vLyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZFxuLy8gd2FycmFudHkuIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzXG4vLyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLFxuLy8gaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdFxuLy8gZnJlZWx5LCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOlxuLy9cbi8vIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90XG4vLyAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlXG4vLyAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZVxuLy8gICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLlxuLy8gMi4gQWx0ZXJlZCBzb3VyY2UgdmVyc2lvbnMgbXVzdCBiZSBwbGFpbmx5IG1hcmtlZCBhcyBzdWNoLCBhbmQgbXVzdCBub3QgYmVcbi8vICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLlxuLy8gMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi5cblxuZnVuY3Rpb24gWlN0cmVhbSgpIHtcbiAgLyogbmV4dCBpbnB1dCBieXRlICovXG4gIHRoaXMuaW5wdXQgPSBudWxsOyAvLyBKUyBzcGVjaWZpYywgYmVjYXVzZSB3ZSBoYXZlIG5vIHBvaW50ZXJzXG4gIHRoaXMubmV4dF9pbiA9IDA7XG4gIC8qIG51bWJlciBvZiBieXRlcyBhdmFpbGFibGUgYXQgaW5wdXQgKi9cbiAgdGhpcy5hdmFpbF9pbiA9IDA7XG4gIC8qIHRvdGFsIG51bWJlciBvZiBpbnB1dCBieXRlcyByZWFkIHNvIGZhciAqL1xuICB0aGlzLnRvdGFsX2luID0gMDtcbiAgLyogbmV4dCBvdXRwdXQgYnl0ZSBzaG91bGQgYmUgcHV0IHRoZXJlICovXG4gIHRoaXMub3V0cHV0ID0gbnVsbDsgLy8gSlMgc3BlY2lmaWMsIGJlY2F1c2Ugd2UgaGF2ZSBubyBwb2ludGVyc1xuICB0aGlzLm5leHRfb3V0ID0gMDtcbiAgLyogcmVtYWluaW5nIGZyZWUgc3BhY2UgYXQgb3V0cHV0ICovXG4gIHRoaXMuYXZhaWxfb3V0ID0gMDtcbiAgLyogdG90YWwgbnVtYmVyIG9mIGJ5dGVzIG91dHB1dCBzbyBmYXIgKi9cbiAgdGhpcy50b3RhbF9vdXQgPSAwO1xuICAvKiBsYXN0IGVycm9yIG1lc3NhZ2UsIE5VTEwgaWYgbm8gZXJyb3IgKi9cbiAgdGhpcy5tc2cgPSAnJy8qWl9OVUxMKi87XG4gIC8qIG5vdCB2aXNpYmxlIGJ5IGFwcGxpY2F0aW9ucyAqL1xuICB0aGlzLnN0YXRlID0gbnVsbDtcbiAgLyogYmVzdCBndWVzcyBhYm91dCB0aGUgZGF0YSB0eXBlOiBiaW5hcnkgb3IgdGV4dCAqL1xuICB0aGlzLmRhdGFfdHlwZSA9IDIvKlpfVU5LTk9XTiovO1xuICAvKiBhZGxlcjMyIHZhbHVlIG9mIHRoZSB1bmNvbXByZXNzZWQgZGF0YSAqL1xuICB0aGlzLmFkbGVyID0gMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBaU3RyZWFtO1xuIiwiLy8gZnJvbSBodHRwczovL2dpdGh1Yi5jb20vaW5kdXRueS9zZWxmLXNpZ25lZC9ibG9iL2doLXBhZ2VzL2xpYi9hc24xLmpzXG4vLyBGZWRvciwgeW91IGFyZSBhbWF6aW5nLlxuJ3VzZSBzdHJpY3QnXG5cbnZhciBhc24xID0gcmVxdWlyZSgnYXNuMS5qcycpXG5cbmV4cG9ydHMuY2VydGlmaWNhdGUgPSByZXF1aXJlKCcuL2NlcnRpZmljYXRlJylcblxudmFyIFJTQVByaXZhdGVLZXkgPSBhc24xLmRlZmluZSgnUlNBUHJpdmF0ZUtleScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ3ZlcnNpb24nKS5pbnQoKSxcbiAgICB0aGlzLmtleSgnbW9kdWx1cycpLmludCgpLFxuICAgIHRoaXMua2V5KCdwdWJsaWNFeHBvbmVudCcpLmludCgpLFxuICAgIHRoaXMua2V5KCdwcml2YXRlRXhwb25lbnQnKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncHJpbWUxJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3ByaW1lMicpLmludCgpLFxuICAgIHRoaXMua2V5KCdleHBvbmVudDEnKS5pbnQoKSxcbiAgICB0aGlzLmtleSgnZXhwb25lbnQyJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ2NvZWZmaWNpZW50JykuaW50KClcbiAgKVxufSlcbmV4cG9ydHMuUlNBUHJpdmF0ZUtleSA9IFJTQVByaXZhdGVLZXlcblxudmFyIFJTQVB1YmxpY0tleSA9IGFzbjEuZGVmaW5lKCdSU0FQdWJsaWNLZXknLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCdtb2R1bHVzJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3B1YmxpY0V4cG9uZW50JykuaW50KClcbiAgKVxufSlcbmV4cG9ydHMuUlNBUHVibGljS2V5ID0gUlNBUHVibGljS2V5XG5cbnZhciBQdWJsaWNLZXkgPSBhc24xLmRlZmluZSgnU3ViamVjdFB1YmxpY0tleUluZm8nLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCdhbGdvcml0aG0nKS51c2UoQWxnb3JpdGhtSWRlbnRpZmllciksXG4gICAgdGhpcy5rZXkoJ3N1YmplY3RQdWJsaWNLZXknKS5iaXRzdHIoKVxuICApXG59KVxuZXhwb3J0cy5QdWJsaWNLZXkgPSBQdWJsaWNLZXlcblxudmFyIEFsZ29yaXRobUlkZW50aWZpZXIgPSBhc24xLmRlZmluZSgnQWxnb3JpdGhtSWRlbnRpZmllcicsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ2FsZ29yaXRobScpLm9iamlkKCksXG4gICAgdGhpcy5rZXkoJ25vbmUnKS5udWxsXygpLm9wdGlvbmFsKCksXG4gICAgdGhpcy5rZXkoJ2N1cnZlJykub2JqaWQoKS5vcHRpb25hbCgpLFxuICAgIHRoaXMua2V5KCdwYXJhbXMnKS5zZXEoKS5vYmooXG4gICAgICB0aGlzLmtleSgncCcpLmludCgpLFxuICAgICAgdGhpcy5rZXkoJ3EnKS5pbnQoKSxcbiAgICAgIHRoaXMua2V5KCdnJykuaW50KClcbiAgICApLm9wdGlvbmFsKClcbiAgKVxufSlcblxudmFyIFByaXZhdGVLZXlJbmZvID0gYXNuMS5kZWZpbmUoJ1ByaXZhdGVLZXlJbmZvJywgZnVuY3Rpb24gKCkge1xuICB0aGlzLnNlcSgpLm9iaihcbiAgICB0aGlzLmtleSgndmVyc2lvbicpLmludCgpLFxuICAgIHRoaXMua2V5KCdhbGdvcml0aG0nKS51c2UoQWxnb3JpdGhtSWRlbnRpZmllciksXG4gICAgdGhpcy5rZXkoJ3N1YmplY3RQcml2YXRlS2V5Jykub2N0c3RyKClcbiAgKVxufSlcbmV4cG9ydHMuUHJpdmF0ZUtleSA9IFByaXZhdGVLZXlJbmZvXG52YXIgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gPSBhc24xLmRlZmluZSgnRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8nLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCdhbGdvcml0aG0nKS5zZXEoKS5vYmooXG4gICAgICB0aGlzLmtleSgnaWQnKS5vYmppZCgpLFxuICAgICAgdGhpcy5rZXkoJ2RlY3J5cHQnKS5zZXEoKS5vYmooXG4gICAgICAgIHRoaXMua2V5KCdrZGUnKS5zZXEoKS5vYmooXG4gICAgICAgICAgdGhpcy5rZXkoJ2lkJykub2JqaWQoKSxcbiAgICAgICAgICB0aGlzLmtleSgna2RlcGFyYW1zJykuc2VxKCkub2JqKFxuICAgICAgICAgICAgdGhpcy5rZXkoJ3NhbHQnKS5vY3RzdHIoKSxcbiAgICAgICAgICAgIHRoaXMua2V5KCdpdGVycycpLmludCgpXG4gICAgICAgICAgKVxuICAgICAgICApLFxuICAgICAgICB0aGlzLmtleSgnY2lwaGVyJykuc2VxKCkub2JqKFxuICAgICAgICAgIHRoaXMua2V5KCdhbGdvJykub2JqaWQoKSxcbiAgICAgICAgICB0aGlzLmtleSgnaXYnKS5vY3RzdHIoKVxuICAgICAgICApXG4gICAgICApXG4gICAgKSxcbiAgICB0aGlzLmtleSgnc3ViamVjdFByaXZhdGVLZXknKS5vY3RzdHIoKVxuICApXG59KVxuXG5leHBvcnRzLkVuY3J5cHRlZFByaXZhdGVLZXkgPSBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb1xuXG52YXIgRFNBUHJpdmF0ZUtleSA9IGFzbjEuZGVmaW5lKCdEU0FQcml2YXRlS2V5JywgZnVuY3Rpb24gKCkge1xuICB0aGlzLnNlcSgpLm9iaihcbiAgICB0aGlzLmtleSgndmVyc2lvbicpLmludCgpLFxuICAgIHRoaXMua2V5KCdwJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3EnKS5pbnQoKSxcbiAgICB0aGlzLmtleSgnZycpLmludCgpLFxuICAgIHRoaXMua2V5KCdwdWJfa2V5JykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3ByaXZfa2V5JykuaW50KClcbiAgKVxufSlcbmV4cG9ydHMuRFNBUHJpdmF0ZUtleSA9IERTQVByaXZhdGVLZXlcblxuZXhwb3J0cy5EU0FwYXJhbSA9IGFzbjEuZGVmaW5lKCdEU0FwYXJhbScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5pbnQoKVxufSlcblxudmFyIEVDUHJpdmF0ZUtleSA9IGFzbjEuZGVmaW5lKCdFQ1ByaXZhdGVLZXknLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCd2ZXJzaW9uJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3ByaXZhdGVLZXknKS5vY3RzdHIoKSxcbiAgICB0aGlzLmtleSgncGFyYW1ldGVycycpLm9wdGlvbmFsKCkuZXhwbGljaXQoMCkudXNlKEVDUGFyYW1ldGVycyksXG4gICAgdGhpcy5rZXkoJ3B1YmxpY0tleScpLm9wdGlvbmFsKCkuZXhwbGljaXQoMSkuYml0c3RyKClcbiAgKVxufSlcbmV4cG9ydHMuRUNQcml2YXRlS2V5ID0gRUNQcml2YXRlS2V5XG5cbnZhciBFQ1BhcmFtZXRlcnMgPSBhc24xLmRlZmluZSgnRUNQYXJhbWV0ZXJzJywgZnVuY3Rpb24gKCkge1xuICB0aGlzLmNob2ljZSh7XG4gICAgbmFtZWRDdXJ2ZTogdGhpcy5vYmppZCgpXG4gIH0pXG59KVxuXG5leHBvcnRzLnNpZ25hdHVyZSA9IGFzbjEuZGVmaW5lKCdzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCdyJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3MnKS5pbnQoKVxuICApXG59KVxuIiwiLy8gZnJvbSBodHRwczovL2dpdGh1Yi5jb20vUmFudGFuZW4vbm9kZS1kdGxzL2Jsb2IvMjVhN2RjODYxYmRhMzhjZmVhYzkzYTcyMzUwMGVlYTRmMGFjMmU4Ni9DZXJ0aWZpY2F0ZS5qc1xuLy8gdGhhbmtzIHRvIEBSYW50YW5lblxuXG4ndXNlIHN0cmljdCdcblxudmFyIGFzbiA9IHJlcXVpcmUoJ2FzbjEuanMnKVxuXG52YXIgVGltZSA9IGFzbi5kZWZpbmUoJ1RpbWUnLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuY2hvaWNlKHtcbiAgICB1dGNUaW1lOiB0aGlzLnV0Y3RpbWUoKSxcbiAgICBnZW5lcmFsVGltZTogdGhpcy5nZW50aW1lKClcbiAgfSlcbn0pXG5cbnZhciBBdHRyaWJ1dGVUeXBlVmFsdWUgPSBhc24uZGVmaW5lKCdBdHRyaWJ1dGVUeXBlVmFsdWUnLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCd0eXBlJykub2JqaWQoKSxcbiAgICB0aGlzLmtleSgndmFsdWUnKS5hbnkoKVxuICApXG59KVxuXG52YXIgQWxnb3JpdGhtSWRlbnRpZmllciA9IGFzbi5kZWZpbmUoJ0FsZ29yaXRobUlkZW50aWZpZXInLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCdhbGdvcml0aG0nKS5vYmppZCgpLFxuICAgIHRoaXMua2V5KCdwYXJhbWV0ZXJzJykub3B0aW9uYWwoKSxcbiAgICB0aGlzLmtleSgnY3VydmUnKS5vYmppZCgpLm9wdGlvbmFsKClcbiAgKVxufSlcblxudmFyIFN1YmplY3RQdWJsaWNLZXlJbmZvID0gYXNuLmRlZmluZSgnU3ViamVjdFB1YmxpY0tleUluZm8nLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCdhbGdvcml0aG0nKS51c2UoQWxnb3JpdGhtSWRlbnRpZmllciksXG4gICAgdGhpcy5rZXkoJ3N1YmplY3RQdWJsaWNLZXknKS5iaXRzdHIoKVxuICApXG59KVxuXG52YXIgUmVsYXRpdmVEaXN0aW5ndWlzaGVkTmFtZSA9IGFzbi5kZWZpbmUoJ1JlbGF0aXZlRGlzdGluZ3Vpc2hlZE5hbWUnLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2V0b2YoQXR0cmlidXRlVHlwZVZhbHVlKVxufSlcblxudmFyIFJETlNlcXVlbmNlID0gYXNuLmRlZmluZSgnUkROU2VxdWVuY2UnLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2Vxb2YoUmVsYXRpdmVEaXN0aW5ndWlzaGVkTmFtZSlcbn0pXG5cbnZhciBOYW1lID0gYXNuLmRlZmluZSgnTmFtZScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5jaG9pY2Uoe1xuICAgIHJkblNlcXVlbmNlOiB0aGlzLnVzZShSRE5TZXF1ZW5jZSlcbiAgfSlcbn0pXG5cbnZhciBWYWxpZGl0eSA9IGFzbi5kZWZpbmUoJ1ZhbGlkaXR5JywgZnVuY3Rpb24gKCkge1xuICB0aGlzLnNlcSgpLm9iaihcbiAgICB0aGlzLmtleSgnbm90QmVmb3JlJykudXNlKFRpbWUpLFxuICAgIHRoaXMua2V5KCdub3RBZnRlcicpLnVzZShUaW1lKVxuICApXG59KVxuXG52YXIgRXh0ZW5zaW9uID0gYXNuLmRlZmluZSgnRXh0ZW5zaW9uJywgZnVuY3Rpb24gKCkge1xuICB0aGlzLnNlcSgpLm9iaihcbiAgICB0aGlzLmtleSgnZXh0bklEJykub2JqaWQoKSxcbiAgICB0aGlzLmtleSgnY3JpdGljYWwnKS5ib29sKCkuZGVmKGZhbHNlKSxcbiAgICB0aGlzLmtleSgnZXh0blZhbHVlJykub2N0c3RyKClcbiAgKVxufSlcblxudmFyIFRCU0NlcnRpZmljYXRlID0gYXNuLmRlZmluZSgnVEJTQ2VydGlmaWNhdGUnLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCd2ZXJzaW9uJykuZXhwbGljaXQoMCkuaW50KCkub3B0aW9uYWwoKSxcbiAgICB0aGlzLmtleSgnc2VyaWFsTnVtYmVyJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3NpZ25hdHVyZScpLnVzZShBbGdvcml0aG1JZGVudGlmaWVyKSxcbiAgICB0aGlzLmtleSgnaXNzdWVyJykudXNlKE5hbWUpLFxuICAgIHRoaXMua2V5KCd2YWxpZGl0eScpLnVzZShWYWxpZGl0eSksXG4gICAgdGhpcy5rZXkoJ3N1YmplY3QnKS51c2UoTmFtZSksXG4gICAgdGhpcy5rZXkoJ3N1YmplY3RQdWJsaWNLZXlJbmZvJykudXNlKFN1YmplY3RQdWJsaWNLZXlJbmZvKSxcbiAgICB0aGlzLmtleSgnaXNzdWVyVW5pcXVlSUQnKS5pbXBsaWNpdCgxKS5iaXRzdHIoKS5vcHRpb25hbCgpLFxuICAgIHRoaXMua2V5KCdzdWJqZWN0VW5pcXVlSUQnKS5pbXBsaWNpdCgyKS5iaXRzdHIoKS5vcHRpb25hbCgpLFxuICAgIHRoaXMua2V5KCdleHRlbnNpb25zJykuZXhwbGljaXQoMykuc2Vxb2YoRXh0ZW5zaW9uKS5vcHRpb25hbCgpXG4gIClcbn0pXG5cbnZhciBYNTA5Q2VydGlmaWNhdGUgPSBhc24uZGVmaW5lKCdYNTA5Q2VydGlmaWNhdGUnLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCd0YnNDZXJ0aWZpY2F0ZScpLnVzZShUQlNDZXJ0aWZpY2F0ZSksXG4gICAgdGhpcy5rZXkoJ3NpZ25hdHVyZUFsZ29yaXRobScpLnVzZShBbGdvcml0aG1JZGVudGlmaWVyKSxcbiAgICB0aGlzLmtleSgnc2lnbmF0dXJlVmFsdWUnKS5iaXRzdHIoKVxuICApXG59KVxuXG5tb2R1bGUuZXhwb3J0cyA9IFg1MDlDZXJ0aWZpY2F0ZVxuIiwiLy8gYWRhcHRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9hcGF0aWwvcGVtc3RyaXBcbnZhciBmaW5kUHJvYyA9IC9Qcm9jLVR5cGU6IDQsRU5DUllQVEVEW1xcblxccl0rREVLLUluZm86IEFFUy0oKD86MTI4KXwoPzoxOTIpfCg/OjI1NikpLUNCQywoWzAtOUEtSF0rKVtcXG5cXHJdKyhbMC05QS16XFxuXFxyXFwrXFwvXFw9XSspW1xcblxccl0rL21cbnZhciBzdGFydFJlZ2V4ID0gL14tLS0tLUJFR0lOICgoPzouKj8gS0VZKXxDRVJUSUZJQ0FURSktLS0tLS9tXG52YXIgZnVsbFJlZ2V4ID0gL14tLS0tLUJFR0lOICgoPzouKj8gS0VZKXxDRVJUSUZJQ0FURSktLS0tLShbMC05QS16XFxuXFxyXFwrXFwvXFw9XSspLS0tLS1FTkQgXFwxLS0tLS0kL21cbnZhciBldnAgPSByZXF1aXJlKCdldnBfYnl0ZXN0b2tleScpXG52YXIgY2lwaGVycyA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktYWVzJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2tleSwgcGFzc3dvcmQpIHtcbiAgdmFyIGtleSA9IG9rZXkudG9TdHJpbmcoKVxuICB2YXIgbWF0Y2ggPSBrZXkubWF0Y2goZmluZFByb2MpXG4gIHZhciBkZWNyeXB0ZWRcbiAgaWYgKCFtYXRjaCkge1xuICAgIHZhciBtYXRjaDIgPSBrZXkubWF0Y2goZnVsbFJlZ2V4KVxuICAgIGRlY3J5cHRlZCA9IG5ldyBCdWZmZXIobWF0Y2gyWzJdLnJlcGxhY2UoL1tcXHJcXG5dL2csICcnKSwgJ2Jhc2U2NCcpXG4gIH0gZWxzZSB7XG4gICAgdmFyIHN1aXRlID0gJ2FlcycgKyBtYXRjaFsxXVxuICAgIHZhciBpdiA9IEJ1ZmZlci5mcm9tKG1hdGNoWzJdLCAnaGV4JylcbiAgICB2YXIgY2lwaGVyVGV4dCA9IEJ1ZmZlci5mcm9tKG1hdGNoWzNdLnJlcGxhY2UoL1tcXHJcXG5dL2csICcnKSwgJ2Jhc2U2NCcpXG4gICAgdmFyIGNpcGhlcktleSA9IGV2cChwYXNzd29yZCwgaXYuc2xpY2UoMCwgOCksIHBhcnNlSW50KG1hdGNoWzFdLCAxMCkpLmtleVxuICAgIHZhciBvdXQgPSBbXVxuICAgIHZhciBjaXBoZXIgPSBjaXBoZXJzLmNyZWF0ZURlY2lwaGVyaXYoc3VpdGUsIGNpcGhlcktleSwgaXYpXG4gICAgb3V0LnB1c2goY2lwaGVyLnVwZGF0ZShjaXBoZXJUZXh0KSlcbiAgICBvdXQucHVzaChjaXBoZXIuZmluYWwoKSlcbiAgICBkZWNyeXB0ZWQgPSBCdWZmZXIuY29uY2F0KG91dClcbiAgfVxuICB2YXIgdGFnID0ga2V5Lm1hdGNoKHN0YXJ0UmVnZXgpWzFdXG4gIHJldHVybiB7XG4gICAgdGFnOiB0YWcsXG4gICAgZGF0YTogZGVjcnlwdGVkXG4gIH1cbn1cbiIsInZhciBhc24xID0gcmVxdWlyZSgnLi9hc24xJylcbnZhciBhZXNpZCA9IHJlcXVpcmUoJy4vYWVzaWQuanNvbicpXG52YXIgZml4UHJvYyA9IHJlcXVpcmUoJy4vZml4UHJvYycpXG52YXIgY2lwaGVycyA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktYWVzJylcbnZhciBjb21wYXQgPSByZXF1aXJlKCdwYmtkZjInKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG5tb2R1bGUuZXhwb3J0cyA9IHBhcnNlS2V5c1xuXG5mdW5jdGlvbiBwYXJzZUtleXMgKGJ1ZmZlcikge1xuICB2YXIgcGFzc3dvcmRcbiAgaWYgKHR5cGVvZiBidWZmZXIgPT09ICdvYmplY3QnICYmICFCdWZmZXIuaXNCdWZmZXIoYnVmZmVyKSkge1xuICAgIHBhc3N3b3JkID0gYnVmZmVyLnBhc3NwaHJhc2VcbiAgICBidWZmZXIgPSBidWZmZXIua2V5XG4gIH1cbiAgaWYgKHR5cGVvZiBidWZmZXIgPT09ICdzdHJpbmcnKSB7XG4gICAgYnVmZmVyID0gQnVmZmVyLmZyb20oYnVmZmVyKVxuICB9XG5cbiAgdmFyIHN0cmlwcGVkID0gZml4UHJvYyhidWZmZXIsIHBhc3N3b3JkKVxuXG4gIHZhciB0eXBlID0gc3RyaXBwZWQudGFnXG4gIHZhciBkYXRhID0gc3RyaXBwZWQuZGF0YVxuICB2YXIgc3VidHlwZSwgbmRhdGFcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnQ0VSVElGSUNBVEUnOlxuICAgICAgbmRhdGEgPSBhc24xLmNlcnRpZmljYXRlLmRlY29kZShkYXRhLCAnZGVyJykudGJzQ2VydGlmaWNhdGUuc3ViamVjdFB1YmxpY0tleUluZm9cbiAgICAgIC8vIGZhbGxzIHRocm91Z2hcbiAgICBjYXNlICdQVUJMSUMgS0VZJzpcbiAgICAgIGlmICghbmRhdGEpIHtcbiAgICAgICAgbmRhdGEgPSBhc24xLlB1YmxpY0tleS5kZWNvZGUoZGF0YSwgJ2RlcicpXG4gICAgICB9XG4gICAgICBzdWJ0eXBlID0gbmRhdGEuYWxnb3JpdGhtLmFsZ29yaXRobS5qb2luKCcuJylcbiAgICAgIHN3aXRjaCAoc3VidHlwZSkge1xuICAgICAgICBjYXNlICcxLjIuODQwLjExMzU0OS4xLjEuMSc6XG4gICAgICAgICAgcmV0dXJuIGFzbjEuUlNBUHVibGljS2V5LmRlY29kZShuZGF0YS5zdWJqZWN0UHVibGljS2V5LmRhdGEsICdkZXInKVxuICAgICAgICBjYXNlICcxLjIuODQwLjEwMDQ1LjIuMSc6XG4gICAgICAgICAgbmRhdGEuc3ViamVjdFByaXZhdGVLZXkgPSBuZGF0YS5zdWJqZWN0UHVibGljS2V5XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdlYycsXG4gICAgICAgICAgICBkYXRhOiBuZGF0YVxuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAnMS4yLjg0MC4xMDA0MC40LjEnOlxuICAgICAgICAgIG5kYXRhLmFsZ29yaXRobS5wYXJhbXMucHViX2tleSA9IGFzbjEuRFNBcGFyYW0uZGVjb2RlKG5kYXRhLnN1YmplY3RQdWJsaWNLZXkuZGF0YSwgJ2RlcicpXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdkc2EnLFxuICAgICAgICAgICAgZGF0YTogbmRhdGEuYWxnb3JpdGhtLnBhcmFtc1xuICAgICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGtleSBpZCAnICsgc3VidHlwZSlcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBrZXkgdHlwZSAnICsgdHlwZSlcbiAgICBjYXNlICdFTkNSWVBURUQgUFJJVkFURSBLRVknOlxuICAgICAgZGF0YSA9IGFzbjEuRW5jcnlwdGVkUHJpdmF0ZUtleS5kZWNvZGUoZGF0YSwgJ2RlcicpXG4gICAgICBkYXRhID0gZGVjcnlwdChkYXRhLCBwYXNzd29yZClcbiAgICAgIC8vIGZhbGxzIHRocm91Z2hcbiAgICBjYXNlICdQUklWQVRFIEtFWSc6XG4gICAgICBuZGF0YSA9IGFzbjEuUHJpdmF0ZUtleS5kZWNvZGUoZGF0YSwgJ2RlcicpXG4gICAgICBzdWJ0eXBlID0gbmRhdGEuYWxnb3JpdGhtLmFsZ29yaXRobS5qb2luKCcuJylcbiAgICAgIHN3aXRjaCAoc3VidHlwZSkge1xuICAgICAgICBjYXNlICcxLjIuODQwLjExMzU0OS4xLjEuMSc6XG4gICAgICAgICAgcmV0dXJuIGFzbjEuUlNBUHJpdmF0ZUtleS5kZWNvZGUobmRhdGEuc3ViamVjdFByaXZhdGVLZXksICdkZXInKVxuICAgICAgICBjYXNlICcxLjIuODQwLjEwMDQ1LjIuMSc6XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGN1cnZlOiBuZGF0YS5hbGdvcml0aG0uY3VydmUsXG4gICAgICAgICAgICBwcml2YXRlS2V5OiBhc24xLkVDUHJpdmF0ZUtleS5kZWNvZGUobmRhdGEuc3ViamVjdFByaXZhdGVLZXksICdkZXInKS5wcml2YXRlS2V5XG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICcxLjIuODQwLjEwMDQwLjQuMSc6XG4gICAgICAgICAgbmRhdGEuYWxnb3JpdGhtLnBhcmFtcy5wcml2X2tleSA9IGFzbjEuRFNBcGFyYW0uZGVjb2RlKG5kYXRhLnN1YmplY3RQcml2YXRlS2V5LCAnZGVyJylcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ2RzYScsXG4gICAgICAgICAgICBwYXJhbXM6IG5kYXRhLmFsZ29yaXRobS5wYXJhbXNcbiAgICAgICAgICB9XG4gICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcigndW5rbm93biBrZXkgaWQgJyArIHN1YnR5cGUpXG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24ga2V5IHR5cGUgJyArIHR5cGUpXG4gICAgY2FzZSAnUlNBIFBVQkxJQyBLRVknOlxuICAgICAgcmV0dXJuIGFzbjEuUlNBUHVibGljS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICBjYXNlICdSU0EgUFJJVkFURSBLRVknOlxuICAgICAgcmV0dXJuIGFzbjEuUlNBUHJpdmF0ZUtleS5kZWNvZGUoZGF0YSwgJ2RlcicpXG4gICAgY2FzZSAnRFNBIFBSSVZBVEUgS0VZJzpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdkc2EnLFxuICAgICAgICBwYXJhbXM6IGFzbjEuRFNBUHJpdmF0ZUtleS5kZWNvZGUoZGF0YSwgJ2RlcicpXG4gICAgICB9XG4gICAgY2FzZSAnRUMgUFJJVkFURSBLRVknOlxuICAgICAgZGF0YSA9IGFzbjEuRUNQcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGN1cnZlOiBkYXRhLnBhcmFtZXRlcnMudmFsdWUsXG4gICAgICAgIHByaXZhdGVLZXk6IGRhdGEucHJpdmF0ZUtleVxuICAgICAgfVxuICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcigndW5rbm93biBrZXkgdHlwZSAnICsgdHlwZSlcbiAgfVxufVxucGFyc2VLZXlzLnNpZ25hdHVyZSA9IGFzbjEuc2lnbmF0dXJlXG5mdW5jdGlvbiBkZWNyeXB0IChkYXRhLCBwYXNzd29yZCkge1xuICB2YXIgc2FsdCA9IGRhdGEuYWxnb3JpdGhtLmRlY3J5cHQua2RlLmtkZXBhcmFtcy5zYWx0XG4gIHZhciBpdGVycyA9IHBhcnNlSW50KGRhdGEuYWxnb3JpdGhtLmRlY3J5cHQua2RlLmtkZXBhcmFtcy5pdGVycy50b1N0cmluZygpLCAxMClcbiAgdmFyIGFsZ28gPSBhZXNpZFtkYXRhLmFsZ29yaXRobS5kZWNyeXB0LmNpcGhlci5hbGdvLmpvaW4oJy4nKV1cbiAgdmFyIGl2ID0gZGF0YS5hbGdvcml0aG0uZGVjcnlwdC5jaXBoZXIuaXZcbiAgdmFyIGNpcGhlclRleHQgPSBkYXRhLnN1YmplY3RQcml2YXRlS2V5XG4gIHZhciBrZXlsZW4gPSBwYXJzZUludChhbGdvLnNwbGl0KCctJylbMV0sIDEwKSAvIDhcbiAgdmFyIGtleSA9IGNvbXBhdC5wYmtkZjJTeW5jKHBhc3N3b3JkLCBzYWx0LCBpdGVycywga2V5bGVuLCAnc2hhMScpXG4gIHZhciBjaXBoZXIgPSBjaXBoZXJzLmNyZWF0ZURlY2lwaGVyaXYoYWxnbywga2V5LCBpdilcbiAgdmFyIG91dCA9IFtdXG4gIG91dC5wdXNoKGNpcGhlci51cGRhdGUoY2lwaGVyVGV4dCkpXG4gIG91dC5wdXNoKGNpcGhlci5maW5hbCgpKVxuICByZXR1cm4gQnVmZmVyLmNvbmNhdChvdXQpXG59XG4iLCJleHBvcnRzLnBia2RmMiA9IHJlcXVpcmUoJy4vbGliL2FzeW5jJylcbmV4cG9ydHMucGJrZGYyU3luYyA9IHJlcXVpcmUoJy4vbGliL3N5bmMnKVxuIiwidmFyIGNoZWNrUGFyYW1ldGVycyA9IHJlcXVpcmUoJy4vcHJlY29uZGl0aW9uJylcbnZhciBkZWZhdWx0RW5jb2RpbmcgPSByZXF1aXJlKCcuL2RlZmF1bHQtZW5jb2RpbmcnKVxudmFyIHN5bmMgPSByZXF1aXJlKCcuL3N5bmMnKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG5cbnZhciBaRVJPX0JVRlxudmFyIHN1YnRsZSA9IGdsb2JhbC5jcnlwdG8gJiYgZ2xvYmFsLmNyeXB0by5zdWJ0bGVcbnZhciB0b0Jyb3dzZXIgPSB7XG4gICdzaGEnOiAnU0hBLTEnLFxuICAnc2hhLTEnOiAnU0hBLTEnLFxuICAnc2hhMSc6ICdTSEEtMScsXG4gICdzaGEyNTYnOiAnU0hBLTI1NicsXG4gICdzaGEtMjU2JzogJ1NIQS0yNTYnLFxuICAnc2hhMzg0JzogJ1NIQS0zODQnLFxuICAnc2hhLTM4NCc6ICdTSEEtMzg0JyxcbiAgJ3NoYS01MTInOiAnU0hBLTUxMicsXG4gICdzaGE1MTInOiAnU0hBLTUxMidcbn1cbnZhciBjaGVja3MgPSBbXVxuZnVuY3Rpb24gY2hlY2tOYXRpdmUgKGFsZ28pIHtcbiAgaWYgKGdsb2JhbC5wcm9jZXNzICYmICFnbG9iYWwucHJvY2Vzcy5icm93c2VyKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmYWxzZSlcbiAgfVxuICBpZiAoIXN1YnRsZSB8fCAhc3VidGxlLmltcG9ydEtleSB8fCAhc3VidGxlLmRlcml2ZUJpdHMpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKVxuICB9XG4gIGlmIChjaGVja3NbYWxnb10gIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBjaGVja3NbYWxnb11cbiAgfVxuICBaRVJPX0JVRiA9IFpFUk9fQlVGIHx8IEJ1ZmZlci5hbGxvYyg4KVxuICB2YXIgcHJvbSA9IGJyb3dzZXJQYmtkZjIoWkVST19CVUYsIFpFUk9fQlVGLCAxMCwgMTI4LCBhbGdvKVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfSkuY2F0Y2goZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfSlcbiAgY2hlY2tzW2FsZ29dID0gcHJvbVxuICByZXR1cm4gcHJvbVxufVxuXG5mdW5jdGlvbiBicm93c2VyUGJrZGYyIChwYXNzd29yZCwgc2FsdCwgaXRlcmF0aW9ucywgbGVuZ3RoLCBhbGdvKSB7XG4gIHJldHVybiBzdWJ0bGUuaW1wb3J0S2V5KFxuICAgICdyYXcnLCBwYXNzd29yZCwge25hbWU6ICdQQktERjInfSwgZmFsc2UsIFsnZGVyaXZlQml0cyddXG4gICkudGhlbihmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIHN1YnRsZS5kZXJpdmVCaXRzKHtcbiAgICAgIG5hbWU6ICdQQktERjInLFxuICAgICAgc2FsdDogc2FsdCxcbiAgICAgIGl0ZXJhdGlvbnM6IGl0ZXJhdGlvbnMsXG4gICAgICBoYXNoOiB7XG4gICAgICAgIG5hbWU6IGFsZ29cbiAgICAgIH1cbiAgICB9LCBrZXksIGxlbmd0aCA8PCAzKVxuICB9KS50aGVuKGZ1bmN0aW9uIChyZXMpIHtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20ocmVzKVxuICB9KVxufVxuXG5mdW5jdGlvbiByZXNvbHZlUHJvbWlzZSAocHJvbWlzZSwgY2FsbGJhY2spIHtcbiAgcHJvbWlzZS50aGVuKGZ1bmN0aW9uIChvdXQpIHtcbiAgICBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNhbGxiYWNrKG51bGwsIG91dClcbiAgICB9KVxuICB9LCBmdW5jdGlvbiAoZSkge1xuICAgIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgY2FsbGJhY2soZSlcbiAgICB9KVxuICB9KVxufVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAocGFzc3dvcmQsIHNhbHQsIGl0ZXJhdGlvbnMsIGtleWxlbiwgZGlnZXN0LCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIGRpZ2VzdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNhbGxiYWNrID0gZGlnZXN0XG4gICAgZGlnZXN0ID0gdW5kZWZpbmVkXG4gIH1cblxuICBkaWdlc3QgPSBkaWdlc3QgfHwgJ3NoYTEnXG4gIHZhciBhbGdvID0gdG9Ccm93c2VyW2RpZ2VzdC50b0xvd2VyQ2FzZSgpXVxuXG4gIGlmICghYWxnbyB8fCB0eXBlb2YgZ2xvYmFsLlByb21pc2UgIT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgb3V0XG4gICAgICB0cnkge1xuICAgICAgICBvdXQgPSBzeW5jKHBhc3N3b3JkLCBzYWx0LCBpdGVyYXRpb25zLCBrZXlsZW4sIGRpZ2VzdClcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGUpXG4gICAgICB9XG4gICAgICBjYWxsYmFjayhudWxsLCBvdXQpXG4gICAgfSlcbiAgfVxuXG4gIGNoZWNrUGFyYW1ldGVycyhwYXNzd29yZCwgc2FsdCwgaXRlcmF0aW9ucywga2V5bGVuKVxuICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSAnZnVuY3Rpb24nKSB0aHJvdyBuZXcgRXJyb3IoJ05vIGNhbGxiYWNrIHByb3ZpZGVkIHRvIHBia2RmMicpXG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHBhc3N3b3JkKSkgcGFzc3dvcmQgPSBCdWZmZXIuZnJvbShwYXNzd29yZCwgZGVmYXVsdEVuY29kaW5nKVxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihzYWx0KSkgc2FsdCA9IEJ1ZmZlci5mcm9tKHNhbHQsIGRlZmF1bHRFbmNvZGluZylcblxuICByZXNvbHZlUHJvbWlzZShjaGVja05hdGl2ZShhbGdvKS50aGVuKGZ1bmN0aW9uIChyZXNwKSB7XG4gICAgaWYgKHJlc3ApIHJldHVybiBicm93c2VyUGJrZGYyKHBhc3N3b3JkLCBzYWx0LCBpdGVyYXRpb25zLCBrZXlsZW4sIGFsZ28pXG5cbiAgICByZXR1cm4gc3luYyhwYXNzd29yZCwgc2FsdCwgaXRlcmF0aW9ucywga2V5bGVuLCBkaWdlc3QpXG4gIH0pLCBjYWxsYmFjaylcbn1cbiIsInZhciBkZWZhdWx0RW5jb2Rpbmdcbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5pZiAocHJvY2Vzcy5icm93c2VyKSB7XG4gIGRlZmF1bHRFbmNvZGluZyA9ICd1dGYtOCdcbn0gZWxzZSB7XG4gIHZhciBwVmVyc2lvbk1ham9yID0gcGFyc2VJbnQocHJvY2Vzcy52ZXJzaW9uLnNwbGl0KCcuJylbMF0uc2xpY2UoMSksIDEwKVxuXG4gIGRlZmF1bHRFbmNvZGluZyA9IHBWZXJzaW9uTWFqb3IgPj0gNiA/ICd1dGYtOCcgOiAnYmluYXJ5J1xufVxubW9kdWxlLmV4cG9ydHMgPSBkZWZhdWx0RW5jb2RpbmdcbiIsInZhciBNQVhfQUxMT0MgPSBNYXRoLnBvdygyLCAzMCkgLSAxIC8vIGRlZmF1bHQgaW4gaW9qc1xuXG5mdW5jdGlvbiBjaGVja0J1ZmZlciAoYnVmLCBuYW1lKSB7XG4gIGlmICh0eXBlb2YgYnVmICE9PSAnc3RyaW5nJyAmJiAhQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKG5hbWUgKyAnIG11c3QgYmUgYSBidWZmZXIgb3Igc3RyaW5nJylcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChwYXNzd29yZCwgc2FsdCwgaXRlcmF0aW9ucywga2V5bGVuKSB7XG4gIGNoZWNrQnVmZmVyKHBhc3N3b3JkLCAnUGFzc3dvcmQnKVxuICBjaGVja0J1ZmZlcihzYWx0LCAnU2FsdCcpXG5cbiAgaWYgKHR5cGVvZiBpdGVyYXRpb25zICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0l0ZXJhdGlvbnMgbm90IGEgbnVtYmVyJylcbiAgfVxuXG4gIGlmIChpdGVyYXRpb25zIDwgMCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0JhZCBpdGVyYXRpb25zJylcbiAgfVxuXG4gIGlmICh0eXBlb2Yga2V5bGVuICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0tleSBsZW5ndGggbm90IGEgbnVtYmVyJylcbiAgfVxuXG4gIGlmIChrZXlsZW4gPCAwIHx8IGtleWxlbiA+IE1BWF9BTExPQyB8fCBrZXlsZW4gIT09IGtleWxlbikgeyAvKiBlc2xpbnQgbm8tc2VsZi1jb21wYXJlOiAwICovXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQmFkIGtleSBsZW5ndGgnKVxuICB9XG59XG4iLCJ2YXIgbWQ1ID0gcmVxdWlyZSgnY3JlYXRlLWhhc2gvbWQ1JylcbnZhciBSSVBFTUQxNjAgPSByZXF1aXJlKCdyaXBlbWQxNjAnKVxudmFyIHNoYSA9IHJlcXVpcmUoJ3NoYS5qcycpXG5cbnZhciBjaGVja1BhcmFtZXRlcnMgPSByZXF1aXJlKCcuL3ByZWNvbmRpdGlvbicpXG52YXIgZGVmYXVsdEVuY29kaW5nID0gcmVxdWlyZSgnLi9kZWZhdWx0LWVuY29kaW5nJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxudmFyIFpFUk9TID0gQnVmZmVyLmFsbG9jKDEyOClcbnZhciBzaXplcyA9IHtcbiAgbWQ1OiAxNixcbiAgc2hhMTogMjAsXG4gIHNoYTIyNDogMjgsXG4gIHNoYTI1NjogMzIsXG4gIHNoYTM4NDogNDgsXG4gIHNoYTUxMjogNjQsXG4gIHJtZDE2MDogMjAsXG4gIHJpcGVtZDE2MDogMjBcbn1cblxuZnVuY3Rpb24gSG1hYyAoYWxnLCBrZXksIHNhbHRMZW4pIHtcbiAgdmFyIGhhc2ggPSBnZXREaWdlc3QoYWxnKVxuICB2YXIgYmxvY2tzaXplID0gKGFsZyA9PT0gJ3NoYTUxMicgfHwgYWxnID09PSAnc2hhMzg0JykgPyAxMjggOiA2NFxuXG4gIGlmIChrZXkubGVuZ3RoID4gYmxvY2tzaXplKSB7XG4gICAga2V5ID0gaGFzaChrZXkpXG4gIH0gZWxzZSBpZiAoa2V5Lmxlbmd0aCA8IGJsb2Nrc2l6ZSkge1xuICAgIGtleSA9IEJ1ZmZlci5jb25jYXQoW2tleSwgWkVST1NdLCBibG9ja3NpemUpXG4gIH1cblxuICB2YXIgaXBhZCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShibG9ja3NpemUgKyBzaXplc1thbGddKVxuICB2YXIgb3BhZCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShibG9ja3NpemUgKyBzaXplc1thbGddKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2Nrc2l6ZTsgaSsrKSB7XG4gICAgaXBhZFtpXSA9IGtleVtpXSBeIDB4MzZcbiAgICBvcGFkW2ldID0ga2V5W2ldIF4gMHg1Q1xuICB9XG5cbiAgdmFyIGlwYWQxID0gQnVmZmVyLmFsbG9jVW5zYWZlKGJsb2Nrc2l6ZSArIHNhbHRMZW4gKyA0KVxuICBpcGFkLmNvcHkoaXBhZDEsIDAsIDAsIGJsb2Nrc2l6ZSlcbiAgdGhpcy5pcGFkMSA9IGlwYWQxXG4gIHRoaXMuaXBhZDIgPSBpcGFkXG4gIHRoaXMub3BhZCA9IG9wYWRcbiAgdGhpcy5hbGcgPSBhbGdcbiAgdGhpcy5ibG9ja3NpemUgPSBibG9ja3NpemVcbiAgdGhpcy5oYXNoID0gaGFzaFxuICB0aGlzLnNpemUgPSBzaXplc1thbGddXG59XG5cbkhtYWMucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uIChkYXRhLCBpcGFkKSB7XG4gIGRhdGEuY29weShpcGFkLCB0aGlzLmJsb2Nrc2l6ZSlcbiAgdmFyIGggPSB0aGlzLmhhc2goaXBhZClcbiAgaC5jb3B5KHRoaXMub3BhZCwgdGhpcy5ibG9ja3NpemUpXG4gIHJldHVybiB0aGlzLmhhc2godGhpcy5vcGFkKVxufVxuXG5mdW5jdGlvbiBnZXREaWdlc3QgKGFsZykge1xuICBmdW5jdGlvbiBzaGFGdW5jIChkYXRhKSB7XG4gICAgcmV0dXJuIHNoYShhbGcpLnVwZGF0ZShkYXRhKS5kaWdlc3QoKVxuICB9XG4gIGZ1bmN0aW9uIHJtZDE2MEZ1bmMgKGRhdGEpIHtcbiAgICByZXR1cm4gbmV3IFJJUEVNRDE2MCgpLnVwZGF0ZShkYXRhKS5kaWdlc3QoKVxuICB9XG5cbiAgaWYgKGFsZyA9PT0gJ3JtZDE2MCcgfHwgYWxnID09PSAncmlwZW1kMTYwJykgcmV0dXJuIHJtZDE2MEZ1bmNcbiAgaWYgKGFsZyA9PT0gJ21kNScpIHJldHVybiBtZDVcbiAgcmV0dXJuIHNoYUZ1bmNcbn1cblxuZnVuY3Rpb24gcGJrZGYyIChwYXNzd29yZCwgc2FsdCwgaXRlcmF0aW9ucywga2V5bGVuLCBkaWdlc3QpIHtcbiAgY2hlY2tQYXJhbWV0ZXJzKHBhc3N3b3JkLCBzYWx0LCBpdGVyYXRpb25zLCBrZXlsZW4pXG5cbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIocGFzc3dvcmQpKSBwYXNzd29yZCA9IEJ1ZmZlci5mcm9tKHBhc3N3b3JkLCBkZWZhdWx0RW5jb2RpbmcpXG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHNhbHQpKSBzYWx0ID0gQnVmZmVyLmZyb20oc2FsdCwgZGVmYXVsdEVuY29kaW5nKVxuXG4gIGRpZ2VzdCA9IGRpZ2VzdCB8fCAnc2hhMSdcblxuICB2YXIgaG1hYyA9IG5ldyBIbWFjKGRpZ2VzdCwgcGFzc3dvcmQsIHNhbHQubGVuZ3RoKVxuXG4gIHZhciBESyA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShrZXlsZW4pXG4gIHZhciBibG9jazEgPSBCdWZmZXIuYWxsb2NVbnNhZmUoc2FsdC5sZW5ndGggKyA0KVxuICBzYWx0LmNvcHkoYmxvY2sxLCAwLCAwLCBzYWx0Lmxlbmd0aClcblxuICB2YXIgZGVzdFBvcyA9IDBcbiAgdmFyIGhMZW4gPSBzaXplc1tkaWdlc3RdXG4gIHZhciBsID0gTWF0aC5jZWlsKGtleWxlbiAvIGhMZW4pXG5cbiAgZm9yICh2YXIgaSA9IDE7IGkgPD0gbDsgaSsrKSB7XG4gICAgYmxvY2sxLndyaXRlVUludDMyQkUoaSwgc2FsdC5sZW5ndGgpXG5cbiAgICB2YXIgVCA9IGhtYWMucnVuKGJsb2NrMSwgaG1hYy5pcGFkMSlcbiAgICB2YXIgVSA9IFRcblxuICAgIGZvciAodmFyIGogPSAxOyBqIDwgaXRlcmF0aW9uczsgaisrKSB7XG4gICAgICBVID0gaG1hYy5ydW4oVSwgaG1hYy5pcGFkMilcbiAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgaExlbjsgaysrKSBUW2tdIF49IFVba11cbiAgICB9XG5cbiAgICBULmNvcHkoREssIGRlc3RQb3MpXG4gICAgZGVzdFBvcyArPSBoTGVuXG4gIH1cblxuICByZXR1cm4gREtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBwYmtkZjJcbiIsIid1c2Ugc3RyaWN0JztcblxuaWYgKCFwcm9jZXNzLnZlcnNpb24gfHxcbiAgICBwcm9jZXNzLnZlcnNpb24uaW5kZXhPZigndjAuJykgPT09IDAgfHxcbiAgICBwcm9jZXNzLnZlcnNpb24uaW5kZXhPZigndjEuJykgPT09IDAgJiYgcHJvY2Vzcy52ZXJzaW9uLmluZGV4T2YoJ3YxLjguJykgIT09IDApIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSB7IG5leHRUaWNrOiBuZXh0VGljayB9O1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBwcm9jZXNzXG59XG5cbmZ1bmN0aW9uIG5leHRUaWNrKGZuLCBhcmcxLCBhcmcyLCBhcmczKSB7XG4gIGlmICh0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImNhbGxiYWNrXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIH1cbiAgdmFyIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHZhciBhcmdzLCBpO1xuICBzd2l0Y2ggKGxlbikge1xuICBjYXNlIDA6XG4gIGNhc2UgMTpcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmbik7XG4gIGNhc2UgMjpcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2tPbmUoKSB7XG4gICAgICBmbi5jYWxsKG51bGwsIGFyZzEpO1xuICAgIH0pO1xuICBjYXNlIDM6XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrVHdvKCkge1xuICAgICAgZm4uY2FsbChudWxsLCBhcmcxLCBhcmcyKTtcbiAgICB9KTtcbiAgY2FzZSA0OlxuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja1RocmVlKCkge1xuICAgICAgZm4uY2FsbChudWxsLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgICB9KTtcbiAgZGVmYXVsdDpcbiAgICBhcmdzID0gbmV3IEFycmF5KGxlbiAtIDEpO1xuICAgIGkgPSAwO1xuICAgIHdoaWxlIChpIDwgYXJncy5sZW5ndGgpIHtcbiAgICAgIGFyZ3NbaSsrXSA9IGFyZ3VtZW50c1tpXTtcbiAgICB9XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrKCkge1xuICAgICAgZm4uYXBwbHkobnVsbCwgYXJncyk7XG4gICAgfSk7XG4gIH1cbn1cblxuIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbi8vIGNhY2hlZCBmcm9tIHdoYXRldmVyIGdsb2JhbCBpcyBwcmVzZW50IHNvIHRoYXQgdGVzdCBydW5uZXJzIHRoYXQgc3R1YiBpdFxuLy8gZG9uJ3QgYnJlYWsgdGhpbmdzLiAgQnV0IHdlIG5lZWQgdG8gd3JhcCBpdCBpbiBhIHRyeSBjYXRjaCBpbiBjYXNlIGl0IGlzXG4vLyB3cmFwcGVkIGluIHN0cmljdCBtb2RlIGNvZGUgd2hpY2ggZG9lc24ndCBkZWZpbmUgYW55IGdsb2JhbHMuICBJdCdzIGluc2lkZSBhXG4vLyBmdW5jdGlvbiBiZWNhdXNlIHRyeS9jYXRjaGVzIGRlb3B0aW1pemUgaW4gY2VydGFpbiBlbmdpbmVzLlxuXG52YXIgY2FjaGVkU2V0VGltZW91dDtcbnZhciBjYWNoZWRDbGVhclRpbWVvdXQ7XG5cbmZ1bmN0aW9uIGRlZmF1bHRTZXRUaW1vdXQoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG5mdW5jdGlvbiBkZWZhdWx0Q2xlYXJUaW1lb3V0ICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NsZWFyVGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuKGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICB9XG59ICgpKVxuZnVuY3Rpb24gcnVuVGltZW91dChmdW4pIHtcbiAgICBpZiAoY2FjaGVkU2V0VGltZW91dCA9PT0gc2V0VGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgLy8gaWYgc2V0VGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZFNldFRpbWVvdXQgPT09IGRlZmF1bHRTZXRUaW1vdXQgfHwgIWNhY2hlZFNldFRpbWVvdXQpICYmIHNldFRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9IGNhdGNoKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0IHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKG51bGwsIGZ1biwgMCk7XG4gICAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvclxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbCh0aGlzLCBmdW4sIDApO1xuICAgICAgICB9XG4gICAgfVxuXG5cbn1cbmZ1bmN0aW9uIHJ1bkNsZWFyVGltZW91dChtYXJrZXIpIHtcbiAgICBpZiAoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgLy8gaWYgY2xlYXJUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBkZWZhdWx0Q2xlYXJUaW1lb3V0IHx8ICFjYWNoZWRDbGVhclRpbWVvdXQpICYmIGNsZWFyVGltZW91dCkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfSBjYXRjaCAoZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgIHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwobnVsbCwgbWFya2VyKTtcbiAgICAgICAgfSBjYXRjaCAoZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvci5cbiAgICAgICAgICAgIC8vIFNvbWUgdmVyc2lvbnMgb2YgSS5FLiBoYXZlIGRpZmZlcmVudCBydWxlcyBmb3IgY2xlYXJUaW1lb3V0IHZzIHNldFRpbWVvdXRcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLCBtYXJrZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG5cblxufVxudmFyIHF1ZXVlID0gW107XG52YXIgZHJhaW5pbmcgPSBmYWxzZTtcbnZhciBjdXJyZW50UXVldWU7XG52YXIgcXVldWVJbmRleCA9IC0xO1xuXG5mdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG4gICAgaWYgKCFkcmFpbmluZyB8fCAhY3VycmVudFF1ZXVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBpZiAoY3VycmVudFF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICB9XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBkcmFpblF1ZXVlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB0aW1lb3V0ID0gcnVuVGltZW91dChjbGVhblVwTmV4dFRpY2spO1xuICAgIGRyYWluaW5nID0gdHJ1ZTtcblxuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB3aGlsZSAoKytxdWV1ZUluZGV4IDwgbGVuKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudFF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFF1ZXVlW3F1ZXVlSW5kZXhdLnJ1bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICAgICAgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIH1cbiAgICBjdXJyZW50UXVldWUgPSBudWxsO1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgcnVuQ2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xufVxuXG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHF1ZXVlLnB1c2gobmV3IEl0ZW0oZnVuLCBhcmdzKSk7XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCA9PT0gMSAmJiAhZHJhaW5pbmcpIHtcbiAgICAgICAgcnVuVGltZW91dChkcmFpblF1ZXVlKTtcbiAgICB9XG59O1xuXG4vLyB2OCBsaWtlcyBwcmVkaWN0aWJsZSBvYmplY3RzXG5mdW5jdGlvbiBJdGVtKGZ1biwgYXJyYXkpIHtcbiAgICB0aGlzLmZ1biA9IGZ1bjtcbiAgICB0aGlzLmFycmF5ID0gYXJyYXk7XG59XG5JdGVtLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5mdW4uYXBwbHkobnVsbCwgdGhpcy5hcnJheSk7XG59O1xucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kT25jZUxpc3RlbmVyID0gbm9vcDtcblxucHJvY2Vzcy5saXN0ZW5lcnMgPSBmdW5jdGlvbiAobmFtZSkgeyByZXR1cm4gW10gfVxuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcbiIsImV4cG9ydHMucHVibGljRW5jcnlwdCA9IHJlcXVpcmUoJy4vcHVibGljRW5jcnlwdCcpXG5leHBvcnRzLnByaXZhdGVEZWNyeXB0ID0gcmVxdWlyZSgnLi9wcml2YXRlRGVjcnlwdCcpXG5cbmV4cG9ydHMucHJpdmF0ZUVuY3J5cHQgPSBmdW5jdGlvbiBwcml2YXRlRW5jcnlwdCAoa2V5LCBidWYpIHtcbiAgcmV0dXJuIGV4cG9ydHMucHVibGljRW5jcnlwdChrZXksIGJ1ZiwgdHJ1ZSlcbn1cblxuZXhwb3J0cy5wdWJsaWNEZWNyeXB0ID0gZnVuY3Rpb24gcHVibGljRGVjcnlwdCAoa2V5LCBidWYpIHtcbiAgcmV0dXJuIGV4cG9ydHMucHJpdmF0ZURlY3J5cHQoa2V5LCBidWYsIHRydWUpXG59XG4iLCJ2YXIgY3JlYXRlSGFzaCA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChzZWVkLCBsZW4pIHtcbiAgdmFyIHQgPSBCdWZmZXIuYWxsb2MoMClcbiAgdmFyIGkgPSAwXG4gIHZhciBjXG4gIHdoaWxlICh0Lmxlbmd0aCA8IGxlbikge1xuICAgIGMgPSBpMm9wcyhpKyspXG4gICAgdCA9IEJ1ZmZlci5jb25jYXQoW3QsIGNyZWF0ZUhhc2goJ3NoYTEnKS51cGRhdGUoc2VlZCkudXBkYXRlKGMpLmRpZ2VzdCgpXSlcbiAgfVxuICByZXR1cm4gdC5zbGljZSgwLCBsZW4pXG59XG5cbmZ1bmN0aW9uIGkyb3BzIChjKSB7XG4gIHZhciBvdXQgPSBCdWZmZXIuYWxsb2NVbnNhZmUoNClcbiAgb3V0LndyaXRlVUludDMyQkUoYywgMClcbiAgcmV0dXJuIG91dFxufVxuIiwidmFyIHBhcnNlS2V5cyA9IHJlcXVpcmUoJ3BhcnNlLWFzbjEnKVxudmFyIG1nZiA9IHJlcXVpcmUoJy4vbWdmJylcbnZhciB4b3IgPSByZXF1aXJlKCcuL3hvcicpXG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpXG52YXIgY3J0ID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1yc2EnKVxudmFyIGNyZWF0ZUhhc2ggPSByZXF1aXJlKCdjcmVhdGUtaGFzaCcpXG52YXIgd2l0aFB1YmxpYyA9IHJlcXVpcmUoJy4vd2l0aFB1YmxpYycpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwcml2YXRlRGVjcnlwdCAocHJpdmF0ZUtleSwgZW5jLCByZXZlcnNlKSB7XG4gIHZhciBwYWRkaW5nXG4gIGlmIChwcml2YXRlS2V5LnBhZGRpbmcpIHtcbiAgICBwYWRkaW5nID0gcHJpdmF0ZUtleS5wYWRkaW5nXG4gIH0gZWxzZSBpZiAocmV2ZXJzZSkge1xuICAgIHBhZGRpbmcgPSAxXG4gIH0gZWxzZSB7XG4gICAgcGFkZGluZyA9IDRcbiAgfVxuXG4gIHZhciBrZXkgPSBwYXJzZUtleXMocHJpdmF0ZUtleSlcbiAgdmFyIGsgPSBrZXkubW9kdWx1cy5ieXRlTGVuZ3RoKClcbiAgaWYgKGVuYy5sZW5ndGggPiBrIHx8IG5ldyBCTihlbmMpLmNtcChrZXkubW9kdWx1cykgPj0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignZGVjcnlwdGlvbiBlcnJvcicpXG4gIH1cbiAgdmFyIG1zZ1xuICBpZiAocmV2ZXJzZSkge1xuICAgIG1zZyA9IHdpdGhQdWJsaWMobmV3IEJOKGVuYyksIGtleSlcbiAgfSBlbHNlIHtcbiAgICBtc2cgPSBjcnQoZW5jLCBrZXkpXG4gIH1cbiAgdmFyIHpCdWZmZXIgPSBCdWZmZXIuYWxsb2MoayAtIG1zZy5sZW5ndGgpXG4gIG1zZyA9IEJ1ZmZlci5jb25jYXQoW3pCdWZmZXIsIG1zZ10sIGspXG4gIGlmIChwYWRkaW5nID09PSA0KSB7XG4gICAgcmV0dXJuIG9hZXAoa2V5LCBtc2cpXG4gIH0gZWxzZSBpZiAocGFkZGluZyA9PT0gMSkge1xuICAgIHJldHVybiBwa2NzMShrZXksIG1zZywgcmV2ZXJzZSlcbiAgfSBlbHNlIGlmIChwYWRkaW5nID09PSAzKSB7XG4gICAgcmV0dXJuIG1zZ1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBwYWRkaW5nJylcbiAgfVxufVxuXG5mdW5jdGlvbiBvYWVwIChrZXksIG1zZykge1xuICB2YXIgayA9IGtleS5tb2R1bHVzLmJ5dGVMZW5ndGgoKVxuICB2YXIgaUhhc2ggPSBjcmVhdGVIYXNoKCdzaGExJykudXBkYXRlKEJ1ZmZlci5hbGxvYygwKSkuZGlnZXN0KClcbiAgdmFyIGhMZW4gPSBpSGFzaC5sZW5ndGhcbiAgaWYgKG1zZ1swXSAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignZGVjcnlwdGlvbiBlcnJvcicpXG4gIH1cbiAgdmFyIG1hc2tlZFNlZWQgPSBtc2cuc2xpY2UoMSwgaExlbiArIDEpXG4gIHZhciBtYXNrZWREYiA9IG1zZy5zbGljZShoTGVuICsgMSlcbiAgdmFyIHNlZWQgPSB4b3IobWFza2VkU2VlZCwgbWdmKG1hc2tlZERiLCBoTGVuKSlcbiAgdmFyIGRiID0geG9yKG1hc2tlZERiLCBtZ2Yoc2VlZCwgayAtIGhMZW4gLSAxKSlcbiAgaWYgKGNvbXBhcmUoaUhhc2gsIGRiLnNsaWNlKDAsIGhMZW4pKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignZGVjcnlwdGlvbiBlcnJvcicpXG4gIH1cbiAgdmFyIGkgPSBoTGVuXG4gIHdoaWxlIChkYltpXSA9PT0gMCkge1xuICAgIGkrK1xuICB9XG4gIGlmIChkYltpKytdICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkZWNyeXB0aW9uIGVycm9yJylcbiAgfVxuICByZXR1cm4gZGIuc2xpY2UoaSlcbn1cblxuZnVuY3Rpb24gcGtjczEgKGtleSwgbXNnLCByZXZlcnNlKSB7XG4gIHZhciBwMSA9IG1zZy5zbGljZSgwLCAyKVxuICB2YXIgaSA9IDJcbiAgdmFyIHN0YXR1cyA9IDBcbiAgd2hpbGUgKG1zZ1tpKytdICE9PSAwKSB7XG4gICAgaWYgKGkgPj0gbXNnLmxlbmd0aCkge1xuICAgICAgc3RhdHVzKytcbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG4gIHZhciBwcyA9IG1zZy5zbGljZSgyLCBpIC0gMSlcblxuICBpZiAoKHAxLnRvU3RyaW5nKCdoZXgnKSAhPT0gJzAwMDInICYmICFyZXZlcnNlKSB8fCAocDEudG9TdHJpbmcoJ2hleCcpICE9PSAnMDAwMScgJiYgcmV2ZXJzZSkpIHtcbiAgICBzdGF0dXMrK1xuICB9XG4gIGlmIChwcy5sZW5ndGggPCA4KSB7XG4gICAgc3RhdHVzKytcbiAgfVxuICBpZiAoc3RhdHVzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkZWNyeXB0aW9uIGVycm9yJylcbiAgfVxuICByZXR1cm4gbXNnLnNsaWNlKGkpXG59XG5mdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIGEgPSBCdWZmZXIuZnJvbShhKVxuICBiID0gQnVmZmVyLmZyb20oYilcbiAgdmFyIGRpZiA9IDBcbiAgdmFyIGxlbiA9IGEubGVuZ3RoXG4gIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHtcbiAgICBkaWYrK1xuICAgIGxlbiA9IE1hdGgubWluKGEubGVuZ3RoLCBiLmxlbmd0aClcbiAgfVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBkaWYgKz0gKGFbaV0gXiBiW2ldKVxuICB9XG4gIHJldHVybiBkaWZcbn1cbiIsInZhciBwYXJzZUtleXMgPSByZXF1aXJlKCdwYXJzZS1hc24xJylcbnZhciByYW5kb21CeXRlcyA9IHJlcXVpcmUoJ3JhbmRvbWJ5dGVzJylcbnZhciBjcmVhdGVIYXNoID0gcmVxdWlyZSgnY3JlYXRlLWhhc2gnKVxudmFyIG1nZiA9IHJlcXVpcmUoJy4vbWdmJylcbnZhciB4b3IgPSByZXF1aXJlKCcuL3hvcicpXG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpXG52YXIgd2l0aFB1YmxpYyA9IHJlcXVpcmUoJy4vd2l0aFB1YmxpYycpXG52YXIgY3J0ID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1yc2EnKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcHVibGljRW5jcnlwdCAocHVibGljS2V5LCBtc2csIHJldmVyc2UpIHtcbiAgdmFyIHBhZGRpbmdcbiAgaWYgKHB1YmxpY0tleS5wYWRkaW5nKSB7XG4gICAgcGFkZGluZyA9IHB1YmxpY0tleS5wYWRkaW5nXG4gIH0gZWxzZSBpZiAocmV2ZXJzZSkge1xuICAgIHBhZGRpbmcgPSAxXG4gIH0gZWxzZSB7XG4gICAgcGFkZGluZyA9IDRcbiAgfVxuICB2YXIga2V5ID0gcGFyc2VLZXlzKHB1YmxpY0tleSlcbiAgdmFyIHBhZGRlZE1zZ1xuICBpZiAocGFkZGluZyA9PT0gNCkge1xuICAgIHBhZGRlZE1zZyA9IG9hZXAoa2V5LCBtc2cpXG4gIH0gZWxzZSBpZiAocGFkZGluZyA9PT0gMSkge1xuICAgIHBhZGRlZE1zZyA9IHBrY3MxKGtleSwgbXNnLCByZXZlcnNlKVxuICB9IGVsc2UgaWYgKHBhZGRpbmcgPT09IDMpIHtcbiAgICBwYWRkZWRNc2cgPSBuZXcgQk4obXNnKVxuICAgIGlmIChwYWRkZWRNc2cuY21wKGtleS5tb2R1bHVzKSA+PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2RhdGEgdG9vIGxvbmcgZm9yIG1vZHVsdXMnKVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gcGFkZGluZycpXG4gIH1cbiAgaWYgKHJldmVyc2UpIHtcbiAgICByZXR1cm4gY3J0KHBhZGRlZE1zZywga2V5KVxuICB9IGVsc2Uge1xuICAgIHJldHVybiB3aXRoUHVibGljKHBhZGRlZE1zZywga2V5KVxuICB9XG59XG5cbmZ1bmN0aW9uIG9hZXAgKGtleSwgbXNnKSB7XG4gIHZhciBrID0ga2V5Lm1vZHVsdXMuYnl0ZUxlbmd0aCgpXG4gIHZhciBtTGVuID0gbXNnLmxlbmd0aFxuICB2YXIgaUhhc2ggPSBjcmVhdGVIYXNoKCdzaGExJykudXBkYXRlKEJ1ZmZlci5hbGxvYygwKSkuZGlnZXN0KClcbiAgdmFyIGhMZW4gPSBpSGFzaC5sZW5ndGhcbiAgdmFyIGhMZW4yID0gMiAqIGhMZW5cbiAgaWYgKG1MZW4gPiBrIC0gaExlbjIgLSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdtZXNzYWdlIHRvbyBsb25nJylcbiAgfVxuICB2YXIgcHMgPSBCdWZmZXIuYWxsb2MoayAtIG1MZW4gLSBoTGVuMiAtIDIpXG4gIHZhciBkYmxlbiA9IGsgLSBoTGVuIC0gMVxuICB2YXIgc2VlZCA9IHJhbmRvbUJ5dGVzKGhMZW4pXG4gIHZhciBtYXNrZWREYiA9IHhvcihCdWZmZXIuY29uY2F0KFtpSGFzaCwgcHMsIEJ1ZmZlci5hbGxvYygxLCAxKSwgbXNnXSwgZGJsZW4pLCBtZ2Yoc2VlZCwgZGJsZW4pKVxuICB2YXIgbWFza2VkU2VlZCA9IHhvcihzZWVkLCBtZ2YobWFza2VkRGIsIGhMZW4pKVxuICByZXR1cm4gbmV3IEJOKEJ1ZmZlci5jb25jYXQoW0J1ZmZlci5hbGxvYygxKSwgbWFza2VkU2VlZCwgbWFza2VkRGJdLCBrKSlcbn1cbmZ1bmN0aW9uIHBrY3MxIChrZXksIG1zZywgcmV2ZXJzZSkge1xuICB2YXIgbUxlbiA9IG1zZy5sZW5ndGhcbiAgdmFyIGsgPSBrZXkubW9kdWx1cy5ieXRlTGVuZ3RoKClcbiAgaWYgKG1MZW4gPiBrIC0gMTEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ21lc3NhZ2UgdG9vIGxvbmcnKVxuICB9XG4gIHZhciBwc1xuICBpZiAocmV2ZXJzZSkge1xuICAgIHBzID0gQnVmZmVyLmFsbG9jKGsgLSBtTGVuIC0gMywgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBwcyA9IG5vblplcm8oayAtIG1MZW4gLSAzKVxuICB9XG4gIHJldHVybiBuZXcgQk4oQnVmZmVyLmNvbmNhdChbQnVmZmVyLmZyb20oWzAsIHJldmVyc2UgPyAxIDogMl0pLCBwcywgQnVmZmVyLmFsbG9jKDEpLCBtc2ddLCBrKSlcbn1cbmZ1bmN0aW9uIG5vblplcm8gKGxlbikge1xuICB2YXIgb3V0ID0gQnVmZmVyLmFsbG9jVW5zYWZlKGxlbilcbiAgdmFyIGkgPSAwXG4gIHZhciBjYWNoZSA9IHJhbmRvbUJ5dGVzKGxlbiAqIDIpXG4gIHZhciBjdXIgPSAwXG4gIHZhciBudW1cbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICBpZiAoY3VyID09PSBjYWNoZS5sZW5ndGgpIHtcbiAgICAgIGNhY2hlID0gcmFuZG9tQnl0ZXMobGVuICogMilcbiAgICAgIGN1ciA9IDBcbiAgICB9XG4gICAgbnVtID0gY2FjaGVbY3VyKytdXG4gICAgaWYgKG51bSkge1xuICAgICAgb3V0W2krK10gPSBudW1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwidmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG5cbmZ1bmN0aW9uIHdpdGhQdWJsaWMgKHBhZGRlZE1zZywga2V5KSB7XG4gIHJldHVybiBCdWZmZXIuZnJvbShwYWRkZWRNc2dcbiAgICAudG9SZWQoQk4ubW9udChrZXkubW9kdWx1cykpXG4gICAgLnJlZFBvdyhuZXcgQk4oa2V5LnB1YmxpY0V4cG9uZW50KSlcbiAgICAuZnJvbVJlZCgpXG4gICAgLnRvQXJyYXkoKSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB3aXRoUHVibGljXG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHhvciAoYSwgYikge1xuICB2YXIgbGVuID0gYS5sZW5ndGhcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgYVtpXSBePSBiW2ldXG4gIH1cbiAgcmV0dXJuIGFcbn1cbiIsIid1c2Ugc3RyaWN0J1xuXG4vLyBsaW1pdCBvZiBDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKClcbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9DcnlwdG8vZ2V0UmFuZG9tVmFsdWVzXG52YXIgTUFYX0JZVEVTID0gNjU1MzZcblxuLy8gTm9kZSBzdXBwb3J0cyByZXF1ZXN0aW5nIHVwIHRvIHRoaXMgbnVtYmVyIG9mIGJ5dGVzXG4vLyBodHRwczovL2dpdGh1Yi5jb20vbm9kZWpzL25vZGUvYmxvYi9tYXN0ZXIvbGliL2ludGVybmFsL2NyeXB0by9yYW5kb20uanMjTDQ4XG52YXIgTUFYX1VJTlQzMiA9IDQyOTQ5NjcyOTVcblxuZnVuY3Rpb24gb2xkQnJvd3NlciAoKSB7XG4gIHRocm93IG5ldyBFcnJvcignU2VjdXJlIHJhbmRvbSBudW1iZXIgZ2VuZXJhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgYnJvd3Nlci5cXG5Vc2UgQ2hyb21lLCBGaXJlZm94IG9yIEludGVybmV0IEV4cGxvcmVyIDExJylcbn1cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG52YXIgY3J5cHRvID0gZ2xvYmFsLmNyeXB0byB8fCBnbG9iYWwubXNDcnlwdG9cblxuaWYgKGNyeXB0byAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcmFuZG9tQnl0ZXNcbn0gZWxzZSB7XG4gIG1vZHVsZS5leHBvcnRzID0gb2xkQnJvd3NlclxufVxuXG5mdW5jdGlvbiByYW5kb21CeXRlcyAoc2l6ZSwgY2IpIHtcbiAgLy8gcGhhbnRvbWpzIG5lZWRzIHRvIHRocm93XG4gIGlmIChzaXplID4gTUFYX1VJTlQzMikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3JlcXVlc3RlZCB0b28gbWFueSByYW5kb20gYnl0ZXMnKVxuXG4gIHZhciBieXRlcyA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShzaXplKVxuXG4gIGlmIChzaXplID4gMCkgeyAgLy8gZ2V0UmFuZG9tVmFsdWVzIGZhaWxzIG9uIElFIGlmIHNpemUgPT0gMFxuICAgIGlmIChzaXplID4gTUFYX0JZVEVTKSB7IC8vIHRoaXMgaXMgdGhlIG1heCBieXRlcyBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzXG4gICAgICAvLyBjYW4gZG8gYXQgb25jZSBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL3dpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzXG4gICAgICBmb3IgKHZhciBnZW5lcmF0ZWQgPSAwOyBnZW5lcmF0ZWQgPCBzaXplOyBnZW5lcmF0ZWQgKz0gTUFYX0JZVEVTKSB7XG4gICAgICAgIC8vIGJ1ZmZlci5zbGljZSBhdXRvbWF0aWNhbGx5IGNoZWNrcyBpZiB0aGUgZW5kIGlzIHBhc3QgdGhlIGVuZCBvZlxuICAgICAgICAvLyB0aGUgYnVmZmVyIHNvIHdlIGRvbid0IGhhdmUgdG8gaGVyZVxuICAgICAgICBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGJ5dGVzLnNsaWNlKGdlbmVyYXRlZCwgZ2VuZXJhdGVkICsgTUFYX0JZVEVTKSlcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhieXRlcylcbiAgICB9XG4gIH1cblxuICBpZiAodHlwZW9mIGNiID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgY2IobnVsbCwgYnl0ZXMpXG4gICAgfSlcbiAgfVxuXG4gIHJldHVybiBieXRlc1xufVxuIiwiJ3VzZSBzdHJpY3QnXG5cbmZ1bmN0aW9uIG9sZEJyb3dzZXIgKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3NlY3VyZSByYW5kb20gbnVtYmVyIGdlbmVyYXRpb24gbm90IHN1cHBvcnRlZCBieSB0aGlzIGJyb3dzZXJcXG51c2UgY2hyb21lLCBGaXJlRm94IG9yIEludGVybmV0IEV4cGxvcmVyIDExJylcbn1cbnZhciBzYWZlQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKVxudmFyIHJhbmRvbWJ5dGVzID0gcmVxdWlyZSgncmFuZG9tYnl0ZXMnKVxudmFyIEJ1ZmZlciA9IHNhZmVCdWZmZXIuQnVmZmVyXG52YXIga0J1ZmZlck1heExlbmd0aCA9IHNhZmVCdWZmZXIua01heExlbmd0aFxudmFyIGNyeXB0byA9IGdsb2JhbC5jcnlwdG8gfHwgZ2xvYmFsLm1zQ3J5cHRvXG52YXIga01heFVpbnQzMiA9IE1hdGgucG93KDIsIDMyKSAtIDFcbmZ1bmN0aW9uIGFzc2VydE9mZnNldCAob2Zmc2V0LCBsZW5ndGgpIHtcbiAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAhPT0gb2Zmc2V0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb2Zmc2V0IG11c3QgYmUgYSBudW1iZXInKVxuICB9XG5cbiAgaWYgKG9mZnNldCA+IGtNYXhVaW50MzIgfHwgb2Zmc2V0IDwgMCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ29mZnNldCBtdXN0IGJlIGEgdWludDMyJylcbiAgfVxuXG4gIGlmIChvZmZzZXQgPiBrQnVmZmVyTWF4TGVuZ3RoIHx8IG9mZnNldCA+IGxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdvZmZzZXQgb3V0IG9mIHJhbmdlJylcbiAgfVxufVxuXG5mdW5jdGlvbiBhc3NlcnRTaXplIChzaXplLCBvZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInIHx8IHNpemUgIT09IHNpemUpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdzaXplIG11c3QgYmUgYSBudW1iZXInKVxuICB9XG5cbiAgaWYgKHNpemUgPiBrTWF4VWludDMyIHx8IHNpemUgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignc2l6ZSBtdXN0IGJlIGEgdWludDMyJylcbiAgfVxuXG4gIGlmIChzaXplICsgb2Zmc2V0ID4gbGVuZ3RoIHx8IHNpemUgPiBrQnVmZmVyTWF4TGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2J1ZmZlciB0b28gc21hbGwnKVxuICB9XG59XG5pZiAoKGNyeXB0byAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB8fCAhcHJvY2Vzcy5icm93c2VyKSB7XG4gIGV4cG9ydHMucmFuZG9tRmlsbCA9IHJhbmRvbUZpbGxcbiAgZXhwb3J0cy5yYW5kb21GaWxsU3luYyA9IHJhbmRvbUZpbGxTeW5jXG59IGVsc2Uge1xuICBleHBvcnRzLnJhbmRvbUZpbGwgPSBvbGRCcm93c2VyXG4gIGV4cG9ydHMucmFuZG9tRmlsbFN5bmMgPSBvbGRCcm93c2VyXG59XG5mdW5jdGlvbiByYW5kb21GaWxsIChidWYsIG9mZnNldCwgc2l6ZSwgY2IpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSAmJiAhKGJ1ZiBpbnN0YW5jZW9mIGdsb2JhbC5VaW50OEFycmF5KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiYnVmXCIgYXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlciBvciBVaW50OEFycmF5JylcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb2Zmc2V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBvZmZzZXRcbiAgICBvZmZzZXQgPSAwXG4gICAgc2l6ZSA9IGJ1Zi5sZW5ndGhcbiAgfSBlbHNlIGlmICh0eXBlb2Ygc2l6ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gc2l6ZVxuICAgIHNpemUgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG4gIH0gZWxzZSBpZiAodHlwZW9mIGNiICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJjYlwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpXG4gIH1cbiAgYXNzZXJ0T2Zmc2V0KG9mZnNldCwgYnVmLmxlbmd0aClcbiAgYXNzZXJ0U2l6ZShzaXplLCBvZmZzZXQsIGJ1Zi5sZW5ndGgpXG4gIHJldHVybiBhY3R1YWxGaWxsKGJ1Ziwgb2Zmc2V0LCBzaXplLCBjYilcbn1cblxuZnVuY3Rpb24gYWN0dWFsRmlsbCAoYnVmLCBvZmZzZXQsIHNpemUsIGNiKSB7XG4gIGlmIChwcm9jZXNzLmJyb3dzZXIpIHtcbiAgICB2YXIgb3VyQnVmID0gYnVmLmJ1ZmZlclxuICAgIHZhciB1aW50ID0gbmV3IFVpbnQ4QXJyYXkob3VyQnVmLCBvZmZzZXQsIHNpemUpXG4gICAgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyh1aW50KVxuICAgIGlmIChjYikge1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNiKG51bGwsIGJ1ZilcbiAgICAgIH0pXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgcmV0dXJuIGJ1ZlxuICB9XG4gIGlmIChjYikge1xuICAgIHJhbmRvbWJ5dGVzKHNpemUsIGZ1bmN0aW9uIChlcnIsIGJ5dGVzKSB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIHJldHVybiBjYihlcnIpXG4gICAgICB9XG4gICAgICBieXRlcy5jb3B5KGJ1Ziwgb2Zmc2V0KVxuICAgICAgY2IobnVsbCwgYnVmKVxuICAgIH0pXG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIGJ5dGVzID0gcmFuZG9tYnl0ZXMoc2l6ZSlcbiAgYnl0ZXMuY29weShidWYsIG9mZnNldClcbiAgcmV0dXJuIGJ1ZlxufVxuZnVuY3Rpb24gcmFuZG9tRmlsbFN5bmMgKGJ1Ziwgb2Zmc2V0LCBzaXplKSB7XG4gIGlmICh0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJykge1xuICAgIG9mZnNldCA9IDBcbiAgfVxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpICYmICEoYnVmIGluc3RhbmNlb2YgZ2xvYmFsLlVpbnQ4QXJyYXkpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJidWZcIiBhcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyIG9yIFVpbnQ4QXJyYXknKVxuICB9XG5cbiAgYXNzZXJ0T2Zmc2V0KG9mZnNldCwgYnVmLmxlbmd0aClcblxuICBpZiAoc2l6ZSA9PT0gdW5kZWZpbmVkKSBzaXplID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuXG4gIGFzc2VydFNpemUoc2l6ZSwgb2Zmc2V0LCBidWYubGVuZ3RoKVxuXG4gIHJldHVybiBhY3R1YWxGaWxsKGJ1Ziwgb2Zmc2V0LCBzaXplKVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX2R1cGxleC5qcycpO1xuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIGEgZHVwbGV4IHN0cmVhbSBpcyBqdXN0IGEgc3RyZWFtIHRoYXQgaXMgYm90aCByZWFkYWJsZSBhbmQgd3JpdGFibGUuXG4vLyBTaW5jZSBKUyBkb2Vzbid0IGhhdmUgbXVsdGlwbGUgcHJvdG90eXBhbCBpbmhlcml0YW5jZSwgdGhpcyBjbGFzc1xuLy8gcHJvdG90eXBhbGx5IGluaGVyaXRzIGZyb20gUmVhZGFibGUsIGFuZCB0aGVuIHBhcmFzaXRpY2FsbHkgZnJvbVxuLy8gV3JpdGFibGUuXG5cbid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIHBuYSA9IHJlcXVpcmUoJ3Byb2Nlc3MtbmV4dGljay1hcmdzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iaikge1xuICB2YXIga2V5cyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAga2V5cy5wdXNoKGtleSk7XG4gIH1yZXR1cm4ga2V5cztcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxubW9kdWxlLmV4cG9ydHMgPSBEdXBsZXg7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIFJlYWRhYmxlID0gcmVxdWlyZSgnLi9fc3RyZWFtX3JlYWRhYmxlJyk7XG52YXIgV3JpdGFibGUgPSByZXF1aXJlKCcuL19zdHJlYW1fd3JpdGFibGUnKTtcblxudXRpbC5pbmhlcml0cyhEdXBsZXgsIFJlYWRhYmxlKTtcblxue1xuICAvLyBhdm9pZCBzY29wZSBjcmVlcCwgdGhlIGtleXMgYXJyYXkgY2FuIHRoZW4gYmUgY29sbGVjdGVkXG4gIHZhciBrZXlzID0gb2JqZWN0S2V5cyhXcml0YWJsZS5wcm90b3R5cGUpO1xuICBmb3IgKHZhciB2ID0gMDsgdiA8IGtleXMubGVuZ3RoOyB2KyspIHtcbiAgICB2YXIgbWV0aG9kID0ga2V5c1t2XTtcbiAgICBpZiAoIUR1cGxleC5wcm90b3R5cGVbbWV0aG9kXSkgRHVwbGV4LnByb3RvdHlwZVttZXRob2RdID0gV3JpdGFibGUucHJvdG90eXBlW21ldGhvZF07XG4gIH1cbn1cblxuZnVuY3Rpb24gRHVwbGV4KG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpIHJldHVybiBuZXcgRHVwbGV4KG9wdGlvbnMpO1xuXG4gIFJlYWRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG4gIFdyaXRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5yZWFkYWJsZSA9PT0gZmFsc2UpIHRoaXMucmVhZGFibGUgPSBmYWxzZTtcblxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLndyaXRhYmxlID09PSBmYWxzZSkgdGhpcy53cml0YWJsZSA9IGZhbHNlO1xuXG4gIHRoaXMuYWxsb3dIYWxmT3BlbiA9IHRydWU7XG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMuYWxsb3dIYWxmT3BlbiA9PT0gZmFsc2UpIHRoaXMuYWxsb3dIYWxmT3BlbiA9IGZhbHNlO1xuXG4gIHRoaXMub25jZSgnZW5kJywgb25lbmQpO1xufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRHVwbGV4LnByb3RvdHlwZSwgJ3dyaXRhYmxlSGlnaFdhdGVyTWFyaycsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3dyaXRhYmxlU3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgfVxufSk7XG5cbi8vIHRoZSBuby1oYWxmLW9wZW4gZW5mb3JjZXJcbmZ1bmN0aW9uIG9uZW5kKCkge1xuICAvLyBpZiB3ZSBhbGxvdyBoYWxmLW9wZW4gc3RhdGUsIG9yIGlmIHRoZSB3cml0YWJsZSBzaWRlIGVuZGVkLFxuICAvLyB0aGVuIHdlJ3JlIG9rLlxuICBpZiAodGhpcy5hbGxvd0hhbGZPcGVuIHx8IHRoaXMuX3dyaXRhYmxlU3RhdGUuZW5kZWQpIHJldHVybjtcblxuICAvLyBubyBtb3JlIGRhdGEgY2FuIGJlIHdyaXR0ZW4uXG4gIC8vIEJ1dCBhbGxvdyBtb3JlIHdyaXRlcyB0byBoYXBwZW4gaW4gdGhpcyB0aWNrLlxuICBwbmEubmV4dFRpY2sob25FbmROVCwgdGhpcyk7XG59XG5cbmZ1bmN0aW9uIG9uRW5kTlQoc2VsZikge1xuICBzZWxmLmVuZCgpO1xufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRHVwbGV4LnByb3RvdHlwZSwgJ2Rlc3Ryb3llZCcsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUgPT09IHVuZGVmaW5lZCB8fCB0aGlzLl93cml0YWJsZVN0YXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVzdHJveWVkICYmIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkO1xuICB9LFxuICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIC8vIHdlIGlnbm9yZSB0aGUgdmFsdWUgaWYgdGhlIHN0cmVhbVxuICAgIC8vIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZCB5ZXRcbiAgICBpZiAodGhpcy5fcmVhZGFibGVTdGF0ZSA9PT0gdW5kZWZpbmVkIHx8IHRoaXMuX3dyaXRhYmxlU3RhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHRoZSB1c2VyIGlzIGV4cGxpY2l0bHlcbiAgICAvLyBtYW5hZ2luZyBkZXN0cm95ZWRcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZCA9IHZhbHVlO1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkID0gdmFsdWU7XG4gIH1cbn0pO1xuXG5EdXBsZXgucHJvdG90eXBlLl9kZXN0cm95ID0gZnVuY3Rpb24gKGVyciwgY2IpIHtcbiAgdGhpcy5wdXNoKG51bGwpO1xuICB0aGlzLmVuZCgpO1xuXG4gIHBuYS5uZXh0VGljayhjYiwgZXJyKTtcbn07IiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIGEgcGFzc3Rocm91Z2ggc3RyZWFtLlxuLy8gYmFzaWNhbGx5IGp1c3QgdGhlIG1vc3QgbWluaW1hbCBzb3J0IG9mIFRyYW5zZm9ybSBzdHJlYW0uXG4vLyBFdmVyeSB3cml0dGVuIGNodW5rIGdldHMgb3V0cHV0IGFzLWlzLlxuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gUGFzc1Rocm91Z2g7XG5cbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCcuL19zdHJlYW1fdHJhbnNmb3JtJyk7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudXRpbC5pbmhlcml0cyhQYXNzVGhyb3VnaCwgVHJhbnNmb3JtKTtcblxuZnVuY3Rpb24gUGFzc1Rocm91Z2gob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUGFzc1Rocm91Z2gpKSByZXR1cm4gbmV3IFBhc3NUaHJvdWdoKG9wdGlvbnMpO1xuXG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xufVxuXG5QYXNzVGhyb3VnaC5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGNiKG51bGwsIGNodW5rKTtcbn07IiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIHBuYSA9IHJlcXVpcmUoJ3Byb2Nlc3MtbmV4dGljay1hcmdzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxubW9kdWxlLmV4cG9ydHMgPSBSZWFkYWJsZTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXNhcnJheScpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgRHVwbGV4O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cblJlYWRhYmxlLlJlYWRhYmxlU3RhdGUgPSBSZWFkYWJsZVN0YXRlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIEVFID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuXG52YXIgRUVsaXN0ZW5lckNvdW50ID0gZnVuY3Rpb24gKGVtaXR0ZXIsIHR5cGUpIHtcbiAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJzKHR5cGUpLmxlbmd0aDtcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBTdHJlYW0gPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvc3RyZWFtJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyO1xudmFyIE91clVpbnQ4QXJyYXkgPSBnbG9iYWwuVWludDhBcnJheSB8fCBmdW5jdGlvbiAoKSB7fTtcbmZ1bmN0aW9uIF91aW50OEFycmF5VG9CdWZmZXIoY2h1bmspIHtcbiAgcmV0dXJuIEJ1ZmZlci5mcm9tKGNodW5rKTtcbn1cbmZ1bmN0aW9uIF9pc1VpbnQ4QXJyYXkob2JqKSB7XG4gIHJldHVybiBCdWZmZXIuaXNCdWZmZXIob2JqKSB8fCBvYmogaW5zdGFuY2VvZiBPdXJVaW50OEFycmF5O1xufVxuXG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSgnY29yZS11dGlsLWlzJyk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGRlYnVnVXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciBkZWJ1ZyA9IHZvaWQgMDtcbmlmIChkZWJ1Z1V0aWwgJiYgZGVidWdVdGlsLmRlYnVnbG9nKSB7XG4gIGRlYnVnID0gZGVidWdVdGlsLmRlYnVnbG9nKCdzdHJlYW0nKTtcbn0gZWxzZSB7XG4gIGRlYnVnID0gZnVuY3Rpb24gKCkge307XG59XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlckxpc3QgPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvQnVmZmVyTGlzdCcpO1xudmFyIGRlc3Ryb3lJbXBsID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL2Rlc3Ryb3knKTtcbnZhciBTdHJpbmdEZWNvZGVyO1xuXG51dGlsLmluaGVyaXRzKFJlYWRhYmxlLCBTdHJlYW0pO1xuXG52YXIga1Byb3h5RXZlbnRzID0gWydlcnJvcicsICdjbG9zZScsICdkZXN0cm95JywgJ3BhdXNlJywgJ3Jlc3VtZSddO1xuXG5mdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIoZW1pdHRlciwgZXZlbnQsIGZuKSB7XG4gIC8vIFNhZGx5IHRoaXMgaXMgbm90IGNhY2hlYWJsZSBhcyBzb21lIGxpYnJhcmllcyBidW5kbGUgdGhlaXIgb3duXG4gIC8vIGV2ZW50IGVtaXR0ZXIgaW1wbGVtZW50YXRpb24gd2l0aCB0aGVtLlxuICBpZiAodHlwZW9mIGVtaXR0ZXIucHJlcGVuZExpc3RlbmVyID09PSAnZnVuY3Rpb24nKSByZXR1cm4gZW1pdHRlci5wcmVwZW5kTGlzdGVuZXIoZXZlbnQsIGZuKTtcblxuICAvLyBUaGlzIGlzIGEgaGFjayB0byBtYWtlIHN1cmUgdGhhdCBvdXIgZXJyb3IgaGFuZGxlciBpcyBhdHRhY2hlZCBiZWZvcmUgYW55XG4gIC8vIHVzZXJsYW5kIG9uZXMuICBORVZFUiBETyBUSElTLiBUaGlzIGlzIGhlcmUgb25seSBiZWNhdXNlIHRoaXMgY29kZSBuZWVkc1xuICAvLyB0byBjb250aW51ZSB0byB3b3JrIHdpdGggb2xkZXIgdmVyc2lvbnMgb2YgTm9kZS5qcyB0aGF0IGRvIG5vdCBpbmNsdWRlXG4gIC8vIHRoZSBwcmVwZW5kTGlzdGVuZXIoKSBtZXRob2QuIFRoZSBnb2FsIGlzIHRvIGV2ZW50dWFsbHkgcmVtb3ZlIHRoaXMgaGFjay5cbiAgaWYgKCFlbWl0dGVyLl9ldmVudHMgfHwgIWVtaXR0ZXIuX2V2ZW50c1tldmVudF0pIGVtaXR0ZXIub24oZXZlbnQsIGZuKTtlbHNlIGlmIChpc0FycmF5KGVtaXR0ZXIuX2V2ZW50c1tldmVudF0pKSBlbWl0dGVyLl9ldmVudHNbZXZlbnRdLnVuc2hpZnQoZm4pO2Vsc2UgZW1pdHRlci5fZXZlbnRzW2V2ZW50XSA9IFtmbiwgZW1pdHRlci5fZXZlbnRzW2V2ZW50XV07XG59XG5cbmZ1bmN0aW9uIFJlYWRhYmxlU3RhdGUob3B0aW9ucywgc3RyZWFtKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgLy8gRHVwbGV4IHN0cmVhbXMgYXJlIGJvdGggcmVhZGFibGUgYW5kIHdyaXRhYmxlLCBidXQgc2hhcmVcbiAgLy8gdGhlIHNhbWUgb3B0aW9ucyBvYmplY3QuXG4gIC8vIEhvd2V2ZXIsIHNvbWUgY2FzZXMgcmVxdWlyZSBzZXR0aW5nIG9wdGlvbnMgdG8gZGlmZmVyZW50XG4gIC8vIHZhbHVlcyBmb3IgdGhlIHJlYWRhYmxlIGFuZCB0aGUgd3JpdGFibGUgc2lkZXMgb2YgdGhlIGR1cGxleCBzdHJlYW0uXG4gIC8vIFRoZXNlIG9wdGlvbnMgY2FuIGJlIHByb3ZpZGVkIHNlcGFyYXRlbHkgYXMgcmVhZGFibGVYWFggYW5kIHdyaXRhYmxlWFhYLlxuICB2YXIgaXNEdXBsZXggPSBzdHJlYW0gaW5zdGFuY2VvZiBEdXBsZXg7XG5cbiAgLy8gb2JqZWN0IHN0cmVhbSBmbGFnLiBVc2VkIHRvIG1ha2UgcmVhZChuKSBpZ25vcmUgbiBhbmQgdG9cbiAgLy8gbWFrZSBhbGwgdGhlIGJ1ZmZlciBtZXJnaW5nIGFuZCBsZW5ndGggY2hlY2tzIGdvIGF3YXlcbiAgdGhpcy5vYmplY3RNb2RlID0gISFvcHRpb25zLm9iamVjdE1vZGU7XG5cbiAgaWYgKGlzRHVwbGV4KSB0aGlzLm9iamVjdE1vZGUgPSB0aGlzLm9iamVjdE1vZGUgfHwgISFvcHRpb25zLnJlYWRhYmxlT2JqZWN0TW9kZTtcblxuICAvLyB0aGUgcG9pbnQgYXQgd2hpY2ggaXQgc3RvcHMgY2FsbGluZyBfcmVhZCgpIHRvIGZpbGwgdGhlIGJ1ZmZlclxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIFwiZG9uJ3QgY2FsbCBfcmVhZCBwcmVlbXB0aXZlbHkgZXZlclwiXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHZhciByZWFkYWJsZUh3bSA9IG9wdGlvbnMucmVhZGFibGVIaWdoV2F0ZXJNYXJrO1xuICB2YXIgZGVmYXVsdEh3bSA9IHRoaXMub2JqZWN0TW9kZSA/IDE2IDogMTYgKiAxMDI0O1xuXG4gIGlmIChod20gfHwgaHdtID09PSAwKSB0aGlzLmhpZ2hXYXRlck1hcmsgPSBod207ZWxzZSBpZiAoaXNEdXBsZXggJiYgKHJlYWRhYmxlSHdtIHx8IHJlYWRhYmxlSHdtID09PSAwKSkgdGhpcy5oaWdoV2F0ZXJNYXJrID0gcmVhZGFibGVId207ZWxzZSB0aGlzLmhpZ2hXYXRlck1hcmsgPSBkZWZhdWx0SHdtO1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gTWF0aC5mbG9vcih0aGlzLmhpZ2hXYXRlck1hcmspO1xuXG4gIC8vIEEgbGlua2VkIGxpc3QgaXMgdXNlZCB0byBzdG9yZSBkYXRhIGNodW5rcyBpbnN0ZWFkIG9mIGFuIGFycmF5IGJlY2F1c2UgdGhlXG4gIC8vIGxpbmtlZCBsaXN0IGNhbiByZW1vdmUgZWxlbWVudHMgZnJvbSB0aGUgYmVnaW5uaW5nIGZhc3RlciB0aGFuXG4gIC8vIGFycmF5LnNoaWZ0KClcbiAgdGhpcy5idWZmZXIgPSBuZXcgQnVmZmVyTGlzdCgpO1xuICB0aGlzLmxlbmd0aCA9IDA7XG4gIHRoaXMucGlwZXMgPSBudWxsO1xuICB0aGlzLnBpcGVzQ291bnQgPSAwO1xuICB0aGlzLmZsb3dpbmcgPSBudWxsO1xuICB0aGlzLmVuZGVkID0gZmFsc2U7XG4gIHRoaXMuZW5kRW1pdHRlZCA9IGZhbHNlO1xuICB0aGlzLnJlYWRpbmcgPSBmYWxzZTtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBldmVudCAncmVhZGFibGUnLydkYXRhJyBpcyBlbWl0dGVkXG4gIC8vIGltbWVkaWF0ZWx5LCBvciBvbiBhIGxhdGVyIHRpY2suICBXZSBzZXQgdGhpcyB0byB0cnVlIGF0IGZpcnN0LCBiZWNhdXNlXG4gIC8vIGFueSBhY3Rpb25zIHRoYXQgc2hvdWxkbid0IGhhcHBlbiB1bnRpbCBcImxhdGVyXCIgc2hvdWxkIGdlbmVyYWxseSBhbHNvXG4gIC8vIG5vdCBoYXBwZW4gYmVmb3JlIHRoZSBmaXJzdCByZWFkIGNhbGwuXG4gIHRoaXMuc3luYyA9IHRydWU7XG5cbiAgLy8gd2hlbmV2ZXIgd2UgcmV0dXJuIG51bGwsIHRoZW4gd2Ugc2V0IGEgZmxhZyB0byBzYXlcbiAgLy8gdGhhdCB3ZSdyZSBhd2FpdGluZyBhICdyZWFkYWJsZScgZXZlbnQgZW1pc3Npb24uXG4gIHRoaXMubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIHRoaXMuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gIHRoaXMucmVhZGFibGVMaXN0ZW5pbmcgPSBmYWxzZTtcbiAgdGhpcy5yZXN1bWVTY2hlZHVsZWQgPSBmYWxzZTtcblxuICAvLyBoYXMgaXQgYmVlbiBkZXN0cm95ZWRcbiAgdGhpcy5kZXN0cm95ZWQgPSBmYWxzZTtcblxuICAvLyBDcnlwdG8gaXMga2luZCBvZiBvbGQgYW5kIGNydXN0eS4gIEhpc3RvcmljYWxseSwgaXRzIGRlZmF1bHQgc3RyaW5nXG4gIC8vIGVuY29kaW5nIGlzICdiaW5hcnknIHNvIHdlIGhhdmUgdG8gbWFrZSB0aGlzIGNvbmZpZ3VyYWJsZS5cbiAgLy8gRXZlcnl0aGluZyBlbHNlIGluIHRoZSB1bml2ZXJzZSB1c2VzICd1dGY4JywgdGhvdWdoLlxuICB0aGlzLmRlZmF1bHRFbmNvZGluZyA9IG9wdGlvbnMuZGVmYXVsdEVuY29kaW5nIHx8ICd1dGY4JztcblxuICAvLyB0aGUgbnVtYmVyIG9mIHdyaXRlcnMgdGhhdCBhcmUgYXdhaXRpbmcgYSBkcmFpbiBldmVudCBpbiAucGlwZSgpc1xuICB0aGlzLmF3YWl0RHJhaW4gPSAwO1xuXG4gIC8vIGlmIHRydWUsIGEgbWF5YmVSZWFkTW9yZSBoYXMgYmVlbiBzY2hlZHVsZWRcbiAgdGhpcy5yZWFkaW5nTW9yZSA9IGZhbHNlO1xuXG4gIHRoaXMuZGVjb2RlciA9IG51bGw7XG4gIHRoaXMuZW5jb2RpbmcgPSBudWxsO1xuICBpZiAob3B0aW9ucy5lbmNvZGluZykge1xuICAgIGlmICghU3RyaW5nRGVjb2RlcikgU3RyaW5nRGVjb2RlciA9IHJlcXVpcmUoJ3N0cmluZ19kZWNvZGVyLycpLlN0cmluZ0RlY29kZXI7XG4gICAgdGhpcy5kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIob3B0aW9ucy5lbmNvZGluZyk7XG4gICAgdGhpcy5lbmNvZGluZyA9IG9wdGlvbnMuZW5jb2Rpbmc7XG4gIH1cbn1cblxuZnVuY3Rpb24gUmVhZGFibGUob3B0aW9ucykge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBSZWFkYWJsZSkpIHJldHVybiBuZXcgUmVhZGFibGUob3B0aW9ucyk7XG5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZSA9IG5ldyBSZWFkYWJsZVN0YXRlKG9wdGlvbnMsIHRoaXMpO1xuXG4gIC8vIGxlZ2FjeVxuICB0aGlzLnJlYWRhYmxlID0gdHJ1ZTtcblxuICBpZiAob3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5yZWFkID09PSAnZnVuY3Rpb24nKSB0aGlzLl9yZWFkID0gb3B0aW9ucy5yZWFkO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmRlc3Ryb3kgPT09ICdmdW5jdGlvbicpIHRoaXMuX2Rlc3Ryb3kgPSBvcHRpb25zLmRlc3Ryb3k7XG4gIH1cblxuICBTdHJlYW0uY2FsbCh0aGlzKTtcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlLnByb3RvdHlwZSwgJ2Rlc3Ryb3llZCcsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQ7XG4gIH0sXG4gIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgLy8gd2UgaWdub3JlIHRoZSB2YWx1ZSBpZiB0aGUgc3RyZWFtXG4gICAgLy8gaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkIHlldFxuICAgIGlmICghdGhpcy5fcmVhZGFibGVTdGF0ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHRoZSB1c2VyIGlzIGV4cGxpY2l0bHlcbiAgICAvLyBtYW5hZ2luZyBkZXN0cm95ZWRcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZCA9IHZhbHVlO1xuICB9XG59KTtcblxuUmVhZGFibGUucHJvdG90eXBlLmRlc3Ryb3kgPSBkZXN0cm95SW1wbC5kZXN0cm95O1xuUmVhZGFibGUucHJvdG90eXBlLl91bmRlc3Ryb3kgPSBkZXN0cm95SW1wbC51bmRlc3Ryb3k7XG5SZWFkYWJsZS5wcm90b3R5cGUuX2Rlc3Ryb3kgPSBmdW5jdGlvbiAoZXJyLCBjYikge1xuICB0aGlzLnB1c2gobnVsbCk7XG4gIGNiKGVycik7XG59O1xuXG4vLyBNYW51YWxseSBzaG92ZSBzb21ldGhpbmcgaW50byB0aGUgcmVhZCgpIGJ1ZmZlci5cbi8vIFRoaXMgcmV0dXJucyB0cnVlIGlmIHRoZSBoaWdoV2F0ZXJNYXJrIGhhcyBub3QgYmVlbiBoaXQgeWV0LFxuLy8gc2ltaWxhciB0byBob3cgV3JpdGFibGUud3JpdGUoKSByZXR1cm5zIHRydWUgaWYgeW91IHNob3VsZFxuLy8gd3JpdGUoKSBzb21lIG1vcmUuXG5SZWFkYWJsZS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIHNraXBDaHVua0NoZWNrO1xuXG4gIGlmICghc3RhdGUub2JqZWN0TW9kZSkge1xuICAgIGlmICh0eXBlb2YgY2h1bmsgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IGVuY29kaW5nIHx8IHN0YXRlLmRlZmF1bHRFbmNvZGluZztcbiAgICAgIGlmIChlbmNvZGluZyAhPT0gc3RhdGUuZW5jb2RpbmcpIHtcbiAgICAgICAgY2h1bmsgPSBCdWZmZXIuZnJvbShjaHVuaywgZW5jb2RpbmcpO1xuICAgICAgICBlbmNvZGluZyA9ICcnO1xuICAgICAgfVxuICAgICAgc2tpcENodW5rQ2hlY2sgPSB0cnVlO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBza2lwQ2h1bmtDaGVjayA9IHRydWU7XG4gIH1cblxuICByZXR1cm4gcmVhZGFibGVBZGRDaHVuayh0aGlzLCBjaHVuaywgZW5jb2RpbmcsIGZhbHNlLCBza2lwQ2h1bmtDaGVjayk7XG59O1xuXG4vLyBVbnNoaWZ0IHNob3VsZCAqYWx3YXlzKiBiZSBzb21ldGhpbmcgZGlyZWN0bHkgb3V0IG9mIHJlYWQoKVxuUmVhZGFibGUucHJvdG90eXBlLnVuc2hpZnQgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgcmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcywgY2h1bmssIG51bGwsIHRydWUsIGZhbHNlKTtcbn07XG5cbmZ1bmN0aW9uIHJlYWRhYmxlQWRkQ2h1bmsoc3RyZWFtLCBjaHVuaywgZW5jb2RpbmcsIGFkZFRvRnJvbnQsIHNraXBDaHVua0NoZWNrKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgaWYgKGNodW5rID09PSBudWxsKSB7XG4gICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICAgIG9uRW9mQ2h1bmsoc3RyZWFtLCBzdGF0ZSk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGVyO1xuICAgIGlmICghc2tpcENodW5rQ2hlY2spIGVyID0gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuayk7XG4gICAgaWYgKGVyKSB7XG4gICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gICAgfSBlbHNlIGlmIChzdGF0ZS5vYmplY3RNb2RlIHx8IGNodW5rICYmIGNodW5rLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICh0eXBlb2YgY2h1bmsgIT09ICdzdHJpbmcnICYmICFzdGF0ZS5vYmplY3RNb2RlICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihjaHVuaykgIT09IEJ1ZmZlci5wcm90b3R5cGUpIHtcbiAgICAgICAgY2h1bmsgPSBfdWludDhBcnJheVRvQnVmZmVyKGNodW5rKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFkZFRvRnJvbnQpIHtcbiAgICAgICAgaWYgKHN0YXRlLmVuZEVtaXR0ZWQpIHN0cmVhbS5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignc3RyZWFtLnVuc2hpZnQoKSBhZnRlciBlbmQgZXZlbnQnKSk7ZWxzZSBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgdHJ1ZSk7XG4gICAgICB9IGVsc2UgaWYgKHN0YXRlLmVuZGVkKSB7XG4gICAgICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignc3RyZWFtLnB1c2goKSBhZnRlciBFT0YnKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gICAgICAgIGlmIChzdGF0ZS5kZWNvZGVyICYmICFlbmNvZGluZykge1xuICAgICAgICAgIGNodW5rID0gc3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7XG4gICAgICAgICAgaWYgKHN0YXRlLm9iamVjdE1vZGUgfHwgY2h1bmsubGVuZ3RoICE9PSAwKSBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgZmFsc2UpO2Vsc2UgbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghYWRkVG9Gcm9udCkge1xuICAgICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZWVkTW9yZURhdGEoc3RhdGUpO1xufVxuXG5mdW5jdGlvbiBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgYWRkVG9Gcm9udCkge1xuICBpZiAoc3RhdGUuZmxvd2luZyAmJiBzdGF0ZS5sZW5ndGggPT09IDAgJiYgIXN0YXRlLnN5bmMpIHtcbiAgICBzdHJlYW0uZW1pdCgnZGF0YScsIGNodW5rKTtcbiAgICBzdHJlYW0ucmVhZCgwKTtcbiAgfSBlbHNlIHtcbiAgICAvLyB1cGRhdGUgdGhlIGJ1ZmZlciBpbmZvLlxuICAgIHN0YXRlLmxlbmd0aCArPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcbiAgICBpZiAoYWRkVG9Gcm9udCkgc3RhdGUuYnVmZmVyLnVuc2hpZnQoY2h1bmspO2Vsc2Ugc3RhdGUuYnVmZmVyLnB1c2goY2h1bmspO1xuXG4gICAgaWYgKHN0YXRlLm5lZWRSZWFkYWJsZSkgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG4gIH1cbiAgbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKTtcbn1cblxuZnVuY3Rpb24gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuaykge1xuICB2YXIgZXI7XG4gIGlmICghX2lzVWludDhBcnJheShjaHVuaykgJiYgdHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJyAmJiBjaHVuayAhPT0gdW5kZWZpbmVkICYmICFzdGF0ZS5vYmplY3RNb2RlKSB7XG4gICAgZXIgPSBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rJyk7XG4gIH1cbiAgcmV0dXJuIGVyO1xufVxuXG4vLyBpZiBpdCdzIHBhc3QgdGhlIGhpZ2ggd2F0ZXIgbWFyaywgd2UgY2FuIHB1c2ggaW4gc29tZSBtb3JlLlxuLy8gQWxzbywgaWYgd2UgaGF2ZSBubyBkYXRhIHlldCwgd2UgY2FuIHN0YW5kIHNvbWVcbi8vIG1vcmUgYnl0ZXMuICBUaGlzIGlzIHRvIHdvcmsgYXJvdW5kIGNhc2VzIHdoZXJlIGh3bT0wLFxuLy8gc3VjaCBhcyB0aGUgcmVwbC4gIEFsc28sIGlmIHRoZSBwdXNoKCkgdHJpZ2dlcmVkIGFcbi8vIHJlYWRhYmxlIGV2ZW50LCBhbmQgdGhlIHVzZXIgY2FsbGVkIHJlYWQobGFyZ2VOdW1iZXIpIHN1Y2ggdGhhdFxuLy8gbmVlZFJlYWRhYmxlIHdhcyBzZXQsIHRoZW4gd2Ugb3VnaHQgdG8gcHVzaCBtb3JlLCBzbyB0aGF0IGFub3RoZXJcbi8vICdyZWFkYWJsZScgZXZlbnQgd2lsbCBiZSB0cmlnZ2VyZWQuXG5mdW5jdGlvbiBuZWVkTW9yZURhdGEoc3RhdGUpIHtcbiAgcmV0dXJuICFzdGF0ZS5lbmRlZCAmJiAoc3RhdGUubmVlZFJlYWRhYmxlIHx8IHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcmsgfHwgc3RhdGUubGVuZ3RoID09PSAwKTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLmlzUGF1c2VkID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nID09PSBmYWxzZTtcbn07XG5cbi8vIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LlxuUmVhZGFibGUucHJvdG90eXBlLnNldEVuY29kaW5nID0gZnVuY3Rpb24gKGVuYykge1xuICBpZiAoIVN0cmluZ0RlY29kZXIpIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2Rlci8nKS5TdHJpbmdEZWNvZGVyO1xuICB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlY29kZXIgPSBuZXcgU3RyaW5nRGVjb2RlcihlbmMpO1xuICB0aGlzLl9yZWFkYWJsZVN0YXRlLmVuY29kaW5nID0gZW5jO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIERvbid0IHJhaXNlIHRoZSBod20gPiA4TUJcbnZhciBNQVhfSFdNID0gMHg4MDAwMDA7XG5mdW5jdGlvbiBjb21wdXRlTmV3SGlnaFdhdGVyTWFyayhuKSB7XG4gIGlmIChuID49IE1BWF9IV00pIHtcbiAgICBuID0gTUFYX0hXTTtcbiAgfSBlbHNlIHtcbiAgICAvLyBHZXQgdGhlIG5leHQgaGlnaGVzdCBwb3dlciBvZiAyIHRvIHByZXZlbnQgaW5jcmVhc2luZyBod20gZXhjZXNzaXZlbHkgaW5cbiAgICAvLyB0aW55IGFtb3VudHNcbiAgICBuLS07XG4gICAgbiB8PSBuID4+PiAxO1xuICAgIG4gfD0gbiA+Pj4gMjtcbiAgICBuIHw9IG4gPj4+IDQ7XG4gICAgbiB8PSBuID4+PiA4O1xuICAgIG4gfD0gbiA+Pj4gMTY7XG4gICAgbisrO1xuICB9XG4gIHJldHVybiBuO1xufVxuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIGRlc2lnbmVkIHRvIGJlIGlubGluYWJsZSwgc28gcGxlYXNlIHRha2UgY2FyZSB3aGVuIG1ha2luZ1xuLy8gY2hhbmdlcyB0byB0aGUgZnVuY3Rpb24gYm9keS5cbmZ1bmN0aW9uIGhvd011Y2hUb1JlYWQobiwgc3RhdGUpIHtcbiAgaWYgKG4gPD0gMCB8fCBzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuZW5kZWQpIHJldHVybiAwO1xuICBpZiAoc3RhdGUub2JqZWN0TW9kZSkgcmV0dXJuIDE7XG4gIGlmIChuICE9PSBuKSB7XG4gICAgLy8gT25seSBmbG93IG9uZSBidWZmZXIgYXQgYSB0aW1lXG4gICAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUubGVuZ3RoKSByZXR1cm4gc3RhdGUuYnVmZmVyLmhlYWQuZGF0YS5sZW5ndGg7ZWxzZSByZXR1cm4gc3RhdGUubGVuZ3RoO1xuICB9XG4gIC8vIElmIHdlJ3JlIGFza2luZyBmb3IgbW9yZSB0aGFuIHRoZSBjdXJyZW50IGh3bSwgdGhlbiByYWlzZSB0aGUgaHdtLlxuICBpZiAobiA+IHN0YXRlLmhpZ2hXYXRlck1hcmspIHN0YXRlLmhpZ2hXYXRlck1hcmsgPSBjb21wdXRlTmV3SGlnaFdhdGVyTWFyayhuKTtcbiAgaWYgKG4gPD0gc3RhdGUubGVuZ3RoKSByZXR1cm4gbjtcbiAgLy8gRG9uJ3QgaGF2ZSBlbm91Z2hcbiAgaWYgKCFzdGF0ZS5lbmRlZCkge1xuICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgcmV0dXJuIDA7XG4gIH1cbiAgcmV0dXJuIHN0YXRlLmxlbmd0aDtcbn1cblxuLy8geW91IGNhbiBvdmVycmlkZSBlaXRoZXIgdGhpcyBtZXRob2QsIG9yIHRoZSBhc3luYyBfcmVhZChuKSBiZWxvdy5cblJlYWRhYmxlLnByb3RvdHlwZS5yZWFkID0gZnVuY3Rpb24gKG4pIHtcbiAgZGVidWcoJ3JlYWQnLCBuKTtcbiAgbiA9IHBhcnNlSW50KG4sIDEwKTtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIG5PcmlnID0gbjtcblxuICBpZiAobiAhPT0gMCkgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG5cbiAgLy8gaWYgd2UncmUgZG9pbmcgcmVhZCgwKSB0byB0cmlnZ2VyIGEgcmVhZGFibGUgZXZlbnQsIGJ1dCB3ZVxuICAvLyBhbHJlYWR5IGhhdmUgYSBidW5jaCBvZiBkYXRhIGluIHRoZSBidWZmZXIsIHRoZW4ganVzdCB0cmlnZ2VyXG4gIC8vIHRoZSAncmVhZGFibGUnIGV2ZW50IGFuZCBtb3ZlIG9uLlxuICBpZiAobiA9PT0gMCAmJiBzdGF0ZS5uZWVkUmVhZGFibGUgJiYgKHN0YXRlLmxlbmd0aCA+PSBzdGF0ZS5oaWdoV2F0ZXJNYXJrIHx8IHN0YXRlLmVuZGVkKSkge1xuICAgIGRlYnVnKCdyZWFkOiBlbWl0UmVhZGFibGUnLCBzdGF0ZS5sZW5ndGgsIHN0YXRlLmVuZGVkKTtcbiAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLmVuZGVkKSBlbmRSZWFkYWJsZSh0aGlzKTtlbHNlIGVtaXRSZWFkYWJsZSh0aGlzKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIG4gPSBob3dNdWNoVG9SZWFkKG4sIHN0YXRlKTtcblxuICAvLyBpZiB3ZSd2ZSBlbmRlZCwgYW5kIHdlJ3JlIG5vdyBjbGVhciwgdGhlbiBmaW5pc2ggaXQgdXAuXG4gIGlmIChuID09PSAwICYmIHN0YXRlLmVuZGVkKSB7XG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgZW5kUmVhZGFibGUodGhpcyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBBbGwgdGhlIGFjdHVhbCBjaHVuayBnZW5lcmF0aW9uIGxvZ2ljIG5lZWRzIHRvIGJlXG4gIC8vICpiZWxvdyogdGhlIGNhbGwgdG8gX3JlYWQuICBUaGUgcmVhc29uIGlzIHRoYXQgaW4gY2VydGFpblxuICAvLyBzeW50aGV0aWMgc3RyZWFtIGNhc2VzLCBzdWNoIGFzIHBhc3N0aHJvdWdoIHN0cmVhbXMsIF9yZWFkXG4gIC8vIG1heSBiZSBhIGNvbXBsZXRlbHkgc3luY2hyb25vdXMgb3BlcmF0aW9uIHdoaWNoIG1heSBjaGFuZ2VcbiAgLy8gdGhlIHN0YXRlIG9mIHRoZSByZWFkIGJ1ZmZlciwgcHJvdmlkaW5nIGVub3VnaCBkYXRhIHdoZW5cbiAgLy8gYmVmb3JlIHRoZXJlIHdhcyAqbm90KiBlbm91Z2guXG4gIC8vXG4gIC8vIFNvLCB0aGUgc3RlcHMgYXJlOlxuICAvLyAxLiBGaWd1cmUgb3V0IHdoYXQgdGhlIHN0YXRlIG9mIHRoaW5ncyB3aWxsIGJlIGFmdGVyIHdlIGRvXG4gIC8vIGEgcmVhZCBmcm9tIHRoZSBidWZmZXIuXG4gIC8vXG4gIC8vIDIuIElmIHRoYXQgcmVzdWx0aW5nIHN0YXRlIHdpbGwgdHJpZ2dlciBhIF9yZWFkLCB0aGVuIGNhbGwgX3JlYWQuXG4gIC8vIE5vdGUgdGhhdCB0aGlzIG1heSBiZSBhc3luY2hyb25vdXMsIG9yIHN5bmNocm9ub3VzLiAgWWVzLCBpdCBpc1xuICAvLyBkZWVwbHkgdWdseSB0byB3cml0ZSBBUElzIHRoaXMgd2F5LCBidXQgdGhhdCBzdGlsbCBkb2Vzbid0IG1lYW5cbiAgLy8gdGhhdCB0aGUgUmVhZGFibGUgY2xhc3Mgc2hvdWxkIGJlaGF2ZSBpbXByb3Blcmx5LCBhcyBzdHJlYW1zIGFyZVxuICAvLyBkZXNpZ25lZCB0byBiZSBzeW5jL2FzeW5jIGFnbm9zdGljLlxuICAvLyBUYWtlIG5vdGUgaWYgdGhlIF9yZWFkIGNhbGwgaXMgc3luYyBvciBhc3luYyAoaWUsIGlmIHRoZSByZWFkIGNhbGxcbiAgLy8gaGFzIHJldHVybmVkIHlldCksIHNvIHRoYXQgd2Uga25vdyB3aGV0aGVyIG9yIG5vdCBpdCdzIHNhZmUgdG8gZW1pdFxuICAvLyAncmVhZGFibGUnIGV0Yy5cbiAgLy9cbiAgLy8gMy4gQWN0dWFsbHkgcHVsbCB0aGUgcmVxdWVzdGVkIGNodW5rcyBvdXQgb2YgdGhlIGJ1ZmZlciBhbmQgcmV0dXJuLlxuXG4gIC8vIGlmIHdlIG5lZWQgYSByZWFkYWJsZSBldmVudCwgdGhlbiB3ZSBuZWVkIHRvIGRvIHNvbWUgcmVhZGluZy5cbiAgdmFyIGRvUmVhZCA9IHN0YXRlLm5lZWRSZWFkYWJsZTtcbiAgZGVidWcoJ25lZWQgcmVhZGFibGUnLCBkb1JlYWQpO1xuXG4gIC8vIGlmIHdlIGN1cnJlbnRseSBoYXZlIGxlc3MgdGhhbiB0aGUgaGlnaFdhdGVyTWFyaywgdGhlbiBhbHNvIHJlYWQgc29tZVxuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwIHx8IHN0YXRlLmxlbmd0aCAtIG4gPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgZG9SZWFkID0gdHJ1ZTtcbiAgICBkZWJ1ZygnbGVuZ3RoIGxlc3MgdGhhbiB3YXRlcm1hcmsnLCBkb1JlYWQpO1xuICB9XG5cbiAgLy8gaG93ZXZlciwgaWYgd2UndmUgZW5kZWQsIHRoZW4gdGhlcmUncyBubyBwb2ludCwgYW5kIGlmIHdlJ3JlIGFscmVhZHlcbiAgLy8gcmVhZGluZywgdGhlbiBpdCdzIHVubmVjZXNzYXJ5LlxuICBpZiAoc3RhdGUuZW5kZWQgfHwgc3RhdGUucmVhZGluZykge1xuICAgIGRvUmVhZCA9IGZhbHNlO1xuICAgIGRlYnVnKCdyZWFkaW5nIG9yIGVuZGVkJywgZG9SZWFkKTtcbiAgfSBlbHNlIGlmIChkb1JlYWQpIHtcbiAgICBkZWJ1ZygnZG8gcmVhZCcpO1xuICAgIHN0YXRlLnJlYWRpbmcgPSB0cnVlO1xuICAgIHN0YXRlLnN5bmMgPSB0cnVlO1xuICAgIC8vIGlmIHRoZSBsZW5ndGggaXMgY3VycmVudGx5IHplcm8sIHRoZW4gd2UgKm5lZWQqIGEgcmVhZGFibGUgZXZlbnQuXG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICAvLyBjYWxsIGludGVybmFsIHJlYWQgbWV0aG9kXG4gICAgdGhpcy5fcmVhZChzdGF0ZS5oaWdoV2F0ZXJNYXJrKTtcbiAgICBzdGF0ZS5zeW5jID0gZmFsc2U7XG4gICAgLy8gSWYgX3JlYWQgcHVzaGVkIGRhdGEgc3luY2hyb25vdXNseSwgdGhlbiBgcmVhZGluZ2Agd2lsbCBiZSBmYWxzZSxcbiAgICAvLyBhbmQgd2UgbmVlZCB0byByZS1ldmFsdWF0ZSBob3cgbXVjaCBkYXRhIHdlIGNhbiByZXR1cm4gdG8gdGhlIHVzZXIuXG4gICAgaWYgKCFzdGF0ZS5yZWFkaW5nKSBuID0gaG93TXVjaFRvUmVhZChuT3JpZywgc3RhdGUpO1xuICB9XG5cbiAgdmFyIHJldDtcbiAgaWYgKG4gPiAwKSByZXQgPSBmcm9tTGlzdChuLCBzdGF0ZSk7ZWxzZSByZXQgPSBudWxsO1xuXG4gIGlmIChyZXQgPT09IG51bGwpIHtcbiAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgIG4gPSAwO1xuICB9IGVsc2Uge1xuICAgIHN0YXRlLmxlbmd0aCAtPSBuO1xuICB9XG5cbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIElmIHdlIGhhdmUgbm90aGluZyBpbiB0aGUgYnVmZmVyLCB0aGVuIHdlIHdhbnQgdG8ga25vd1xuICAgIC8vIGFzIHNvb24gYXMgd2UgKmRvKiBnZXQgc29tZXRoaW5nIGludG8gdGhlIGJ1ZmZlci5cbiAgICBpZiAoIXN0YXRlLmVuZGVkKSBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuXG4gICAgLy8gSWYgd2UgdHJpZWQgdG8gcmVhZCgpIHBhc3QgdGhlIEVPRiwgdGhlbiBlbWl0IGVuZCBvbiB0aGUgbmV4dCB0aWNrLlxuICAgIGlmIChuT3JpZyAhPT0gbiAmJiBzdGF0ZS5lbmRlZCkgZW5kUmVhZGFibGUodGhpcyk7XG4gIH1cblxuICBpZiAocmV0ICE9PSBudWxsKSB0aGlzLmVtaXQoJ2RhdGEnLCByZXQpO1xuXG4gIHJldHVybiByZXQ7XG59O1xuXG5mdW5jdGlvbiBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmVuZGVkKSByZXR1cm47XG4gIGlmIChzdGF0ZS5kZWNvZGVyKSB7XG4gICAgdmFyIGNodW5rID0gc3RhdGUuZGVjb2Rlci5lbmQoKTtcbiAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKSB7XG4gICAgICBzdGF0ZS5idWZmZXIucHVzaChjaHVuayk7XG4gICAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgfVxuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcblxuICAvLyBlbWl0ICdyZWFkYWJsZScgbm93IHRvIG1ha2Ugc3VyZSBpdCBnZXRzIHBpY2tlZCB1cC5cbiAgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG59XG5cbi8vIERvbid0IGVtaXQgcmVhZGFibGUgcmlnaHQgYXdheSBpbiBzeW5jIG1vZGUsIGJlY2F1c2UgdGhpcyBjYW4gdHJpZ2dlclxuLy8gYW5vdGhlciByZWFkKCkgY2FsbCA9PiBzdGFjayBvdmVyZmxvdy4gIFRoaXMgd2F5LCBpdCBtaWdodCB0cmlnZ2VyXG4vLyBhIG5leHRUaWNrIHJlY3Vyc2lvbiB3YXJuaW5nLCBidXQgdGhhdCdzIG5vdCBzbyBiYWQuXG5mdW5jdGlvbiBlbWl0UmVhZGFibGUoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgc3RhdGUubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIGlmICghc3RhdGUuZW1pdHRlZFJlYWRhYmxlKSB7XG4gICAgZGVidWcoJ2VtaXRSZWFkYWJsZScsIHN0YXRlLmZsb3dpbmcpO1xuICAgIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgaWYgKHN0YXRlLnN5bmMpIHBuYS5uZXh0VGljayhlbWl0UmVhZGFibGVfLCBzdHJlYW0pO2Vsc2UgZW1pdFJlYWRhYmxlXyhzdHJlYW0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVtaXRSZWFkYWJsZV8oc3RyZWFtKSB7XG4gIGRlYnVnKCdlbWl0IHJlYWRhYmxlJyk7XG4gIHN0cmVhbS5lbWl0KCdyZWFkYWJsZScpO1xuICBmbG93KHN0cmVhbSk7XG59XG5cbi8vIGF0IHRoaXMgcG9pbnQsIHRoZSB1c2VyIGhhcyBwcmVzdW1hYmx5IHNlZW4gdGhlICdyZWFkYWJsZScgZXZlbnQsXG4vLyBhbmQgY2FsbGVkIHJlYWQoKSB0byBjb25zdW1lIHNvbWUgZGF0YS4gIHRoYXQgbWF5IGhhdmUgdHJpZ2dlcmVkXG4vLyBpbiB0dXJuIGFub3RoZXIgX3JlYWQobikgY2FsbCwgaW4gd2hpY2ggY2FzZSByZWFkaW5nID0gdHJ1ZSBpZlxuLy8gaXQncyBpbiBwcm9ncmVzcy5cbi8vIEhvd2V2ZXIsIGlmIHdlJ3JlIG5vdCBlbmRlZCwgb3IgcmVhZGluZywgYW5kIHRoZSBsZW5ndGggPCBod20sXG4vLyB0aGVuIGdvIGFoZWFkIGFuZCB0cnkgdG8gcmVhZCBzb21lIG1vcmUgcHJlZW1wdGl2ZWx5LlxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVhZGluZ01vcmUpIHtcbiAgICBzdGF0ZS5yZWFkaW5nTW9yZSA9IHRydWU7XG4gICAgcG5hLm5leHRUaWNrKG1heWJlUmVhZE1vcmVfLCBzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtYXliZVJlYWRNb3JlXyhzdHJlYW0sIHN0YXRlKSB7XG4gIHZhciBsZW4gPSBzdGF0ZS5sZW5ndGg7XG4gIHdoaWxlICghc3RhdGUucmVhZGluZyAmJiAhc3RhdGUuZmxvd2luZyAmJiAhc3RhdGUuZW5kZWQgJiYgc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaykge1xuICAgIGRlYnVnKCdtYXliZVJlYWRNb3JlIHJlYWQgMCcpO1xuICAgIHN0cmVhbS5yZWFkKDApO1xuICAgIGlmIChsZW4gPT09IHN0YXRlLmxlbmd0aClcbiAgICAgIC8vIGRpZG4ndCBnZXQgYW55IGRhdGEsIHN0b3Agc3Bpbm5pbmcuXG4gICAgICBicmVhaztlbHNlIGxlbiA9IHN0YXRlLmxlbmd0aDtcbiAgfVxuICBzdGF0ZS5yZWFkaW5nTW9yZSA9IGZhbHNlO1xufVxuXG4vLyBhYnN0cmFjdCBtZXRob2QuICB0byBiZSBvdmVycmlkZGVuIGluIHNwZWNpZmljIGltcGxlbWVudGF0aW9uIGNsYXNzZXMuXG4vLyBjYWxsIGNiKGVyLCBkYXRhKSB3aGVyZSBkYXRhIGlzIDw9IG4gaW4gbGVuZ3RoLlxuLy8gZm9yIHZpcnR1YWwgKG5vbi1zdHJpbmcsIG5vbi1idWZmZXIpIHN0cmVhbXMsIFwibGVuZ3RoXCIgaXMgc29tZXdoYXRcbi8vIGFyYml0cmFyeSwgYW5kIHBlcmhhcHMgbm90IHZlcnkgbWVhbmluZ2Z1bC5cblJlYWRhYmxlLnByb3RvdHlwZS5fcmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ19yZWFkKCkgaXMgbm90IGltcGxlbWVudGVkJykpO1xufTtcblxuUmVhZGFibGUucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbiAoZGVzdCwgcGlwZU9wdHMpIHtcbiAgdmFyIHNyYyA9IHRoaXM7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG5cbiAgc3dpdGNoIChzdGF0ZS5waXBlc0NvdW50KSB7XG4gICAgY2FzZSAwOlxuICAgICAgc3RhdGUucGlwZXMgPSBkZXN0O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAxOlxuICAgICAgc3RhdGUucGlwZXMgPSBbc3RhdGUucGlwZXMsIGRlc3RdO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHN0YXRlLnBpcGVzLnB1c2goZGVzdCk7XG4gICAgICBicmVhaztcbiAgfVxuICBzdGF0ZS5waXBlc0NvdW50ICs9IDE7XG4gIGRlYnVnKCdwaXBlIGNvdW50PSVkIG9wdHM9JWonLCBzdGF0ZS5waXBlc0NvdW50LCBwaXBlT3B0cyk7XG5cbiAgdmFyIGRvRW5kID0gKCFwaXBlT3B0cyB8fCBwaXBlT3B0cy5lbmQgIT09IGZhbHNlKSAmJiBkZXN0ICE9PSBwcm9jZXNzLnN0ZG91dCAmJiBkZXN0ICE9PSBwcm9jZXNzLnN0ZGVycjtcblxuICB2YXIgZW5kRm4gPSBkb0VuZCA/IG9uZW5kIDogdW5waXBlO1xuICBpZiAoc3RhdGUuZW5kRW1pdHRlZCkgcG5hLm5leHRUaWNrKGVuZEZuKTtlbHNlIHNyYy5vbmNlKCdlbmQnLCBlbmRGbik7XG5cbiAgZGVzdC5vbigndW5waXBlJywgb251bnBpcGUpO1xuICBmdW5jdGlvbiBvbnVucGlwZShyZWFkYWJsZSwgdW5waXBlSW5mbykge1xuICAgIGRlYnVnKCdvbnVucGlwZScpO1xuICAgIGlmIChyZWFkYWJsZSA9PT0gc3JjKSB7XG4gICAgICBpZiAodW5waXBlSW5mbyAmJiB1bnBpcGVJbmZvLmhhc1VucGlwZWQgPT09IGZhbHNlKSB7XG4gICAgICAgIHVucGlwZUluZm8uaGFzVW5waXBlZCA9IHRydWU7XG4gICAgICAgIGNsZWFudXAoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBvbmVuZCgpIHtcbiAgICBkZWJ1Zygnb25lbmQnKTtcbiAgICBkZXN0LmVuZCgpO1xuICB9XG5cbiAgLy8gd2hlbiB0aGUgZGVzdCBkcmFpbnMsIGl0IHJlZHVjZXMgdGhlIGF3YWl0RHJhaW4gY291bnRlclxuICAvLyBvbiB0aGUgc291cmNlLiAgVGhpcyB3b3VsZCBiZSBtb3JlIGVsZWdhbnQgd2l0aCBhIC5vbmNlKClcbiAgLy8gaGFuZGxlciBpbiBmbG93KCksIGJ1dCBhZGRpbmcgYW5kIHJlbW92aW5nIHJlcGVhdGVkbHkgaXNcbiAgLy8gdG9vIHNsb3cuXG4gIHZhciBvbmRyYWluID0gcGlwZU9uRHJhaW4oc3JjKTtcbiAgZGVzdC5vbignZHJhaW4nLCBvbmRyYWluKTtcblxuICB2YXIgY2xlYW5lZFVwID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG4gICAgZGVidWcoJ2NsZWFudXAnKTtcbiAgICAvLyBjbGVhbnVwIGV2ZW50IGhhbmRsZXJzIG9uY2UgdGhlIHBpcGUgaXMgYnJva2VuXG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZHJhaW4nLCBvbmRyYWluKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ3VucGlwZScsIG9udW5waXBlKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIHVucGlwZSk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgb25kYXRhKTtcblxuICAgIGNsZWFuZWRVcCA9IHRydWU7XG5cbiAgICAvLyBpZiB0aGUgcmVhZGVyIGlzIHdhaXRpbmcgZm9yIGEgZHJhaW4gZXZlbnQgZnJvbSB0aGlzXG4gICAgLy8gc3BlY2lmaWMgd3JpdGVyLCB0aGVuIGl0IHdvdWxkIGNhdXNlIGl0IHRvIG5ldmVyIHN0YXJ0XG4gICAgLy8gZmxvd2luZyBhZ2Fpbi5cbiAgICAvLyBTbywgaWYgdGhpcyBpcyBhd2FpdGluZyBhIGRyYWluLCB0aGVuIHdlIGp1c3QgY2FsbCBpdCBub3cuXG4gICAgLy8gSWYgd2UgZG9uJ3Qga25vdywgdGhlbiBhc3N1bWUgdGhhdCB3ZSBhcmUgd2FpdGluZyBmb3Igb25lLlxuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluICYmICghZGVzdC5fd3JpdGFibGVTdGF0ZSB8fCBkZXN0Ll93cml0YWJsZVN0YXRlLm5lZWREcmFpbikpIG9uZHJhaW4oKTtcbiAgfVxuXG4gIC8vIElmIHRoZSB1c2VyIHB1c2hlcyBtb3JlIGRhdGEgd2hpbGUgd2UncmUgd3JpdGluZyB0byBkZXN0IHRoZW4gd2UnbGwgZW5kIHVwXG4gIC8vIGluIG9uZGF0YSBhZ2Fpbi4gSG93ZXZlciwgd2Ugb25seSB3YW50IHRvIGluY3JlYXNlIGF3YWl0RHJhaW4gb25jZSBiZWNhdXNlXG4gIC8vIGRlc3Qgd2lsbCBvbmx5IGVtaXQgb25lICdkcmFpbicgZXZlbnQgZm9yIHRoZSBtdWx0aXBsZSB3cml0ZXMuXG4gIC8vID0+IEludHJvZHVjZSBhIGd1YXJkIG9uIGluY3JlYXNpbmcgYXdhaXREcmFpbi5cbiAgdmFyIGluY3JlYXNlZEF3YWl0RHJhaW4gPSBmYWxzZTtcbiAgc3JjLm9uKCdkYXRhJywgb25kYXRhKTtcbiAgZnVuY3Rpb24gb25kYXRhKGNodW5rKSB7XG4gICAgZGVidWcoJ29uZGF0YScpO1xuICAgIGluY3JlYXNlZEF3YWl0RHJhaW4gPSBmYWxzZTtcbiAgICB2YXIgcmV0ID0gZGVzdC53cml0ZShjaHVuayk7XG4gICAgaWYgKGZhbHNlID09PSByZXQgJiYgIWluY3JlYXNlZEF3YWl0RHJhaW4pIHtcbiAgICAgIC8vIElmIHRoZSB1c2VyIHVucGlwZWQgZHVyaW5nIGBkZXN0LndyaXRlKClgLCBpdCBpcyBwb3NzaWJsZVxuICAgICAgLy8gdG8gZ2V0IHN0dWNrIGluIGEgcGVybWFuZW50bHkgcGF1c2VkIHN0YXRlIGlmIHRoYXQgd3JpdGVcbiAgICAgIC8vIGFsc28gcmV0dXJuZWQgZmFsc2UuXG4gICAgICAvLyA9PiBDaGVjayB3aGV0aGVyIGBkZXN0YCBpcyBzdGlsbCBhIHBpcGluZyBkZXN0aW5hdGlvbi5cbiAgICAgIGlmICgoc3RhdGUucGlwZXNDb3VudCA9PT0gMSAmJiBzdGF0ZS5waXBlcyA9PT0gZGVzdCB8fCBzdGF0ZS5waXBlc0NvdW50ID4gMSAmJiBpbmRleE9mKHN0YXRlLnBpcGVzLCBkZXN0KSAhPT0gLTEpICYmICFjbGVhbmVkVXApIHtcbiAgICAgICAgZGVidWcoJ2ZhbHNlIHdyaXRlIHJlc3BvbnNlLCBwYXVzZScsIHNyYy5fcmVhZGFibGVTdGF0ZS5hd2FpdERyYWluKTtcbiAgICAgICAgc3JjLl9yZWFkYWJsZVN0YXRlLmF3YWl0RHJhaW4rKztcbiAgICAgICAgaW5jcmVhc2VkQXdhaXREcmFpbiA9IHRydWU7XG4gICAgICB9XG4gICAgICBzcmMucGF1c2UoKTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgZGVzdCBoYXMgYW4gZXJyb3IsIHRoZW4gc3RvcCBwaXBpbmcgaW50byBpdC5cbiAgLy8gaG93ZXZlciwgZG9uJ3Qgc3VwcHJlc3MgdGhlIHRocm93aW5nIGJlaGF2aW9yIGZvciB0aGlzLlxuICBmdW5jdGlvbiBvbmVycm9yKGVyKSB7XG4gICAgZGVidWcoJ29uZXJyb3InLCBlcik7XG4gICAgdW5waXBlKCk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBpZiAoRUVsaXN0ZW5lckNvdW50KGRlc3QsICdlcnJvcicpID09PSAwKSBkZXN0LmVtaXQoJ2Vycm9yJywgZXIpO1xuICB9XG5cbiAgLy8gTWFrZSBzdXJlIG91ciBlcnJvciBoYW5kbGVyIGlzIGF0dGFjaGVkIGJlZm9yZSB1c2VybGFuZCBvbmVzLlxuICBwcmVwZW5kTGlzdGVuZXIoZGVzdCwgJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgLy8gQm90aCBjbG9zZSBhbmQgZmluaXNoIHNob3VsZCB0cmlnZ2VyIHVucGlwZSwgYnV0IG9ubHkgb25jZS5cbiAgZnVuY3Rpb24gb25jbG9zZSgpIHtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgdW5waXBlKCk7XG4gIH1cbiAgZGVzdC5vbmNlKCdjbG9zZScsIG9uY2xvc2UpO1xuICBmdW5jdGlvbiBvbmZpbmlzaCgpIHtcbiAgICBkZWJ1Zygnb25maW5pc2gnKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIHVucGlwZSgpO1xuICB9XG4gIGRlc3Qub25jZSgnZmluaXNoJywgb25maW5pc2gpO1xuXG4gIGZ1bmN0aW9uIHVucGlwZSgpIHtcbiAgICBkZWJ1ZygndW5waXBlJyk7XG4gICAgc3JjLnVucGlwZShkZXN0KTtcbiAgfVxuXG4gIC8vIHRlbGwgdGhlIGRlc3QgdGhhdCBpdCdzIGJlaW5nIHBpcGVkIHRvXG4gIGRlc3QuZW1pdCgncGlwZScsIHNyYyk7XG5cbiAgLy8gc3RhcnQgdGhlIGZsb3cgaWYgaXQgaGFzbid0IGJlZW4gc3RhcnRlZCBhbHJlYWR5LlxuICBpZiAoIXN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncGlwZSByZXN1bWUnKTtcbiAgICBzcmMucmVzdW1lKCk7XG4gIH1cblxuICByZXR1cm4gZGVzdDtcbn07XG5cbmZ1bmN0aW9uIHBpcGVPbkRyYWluKHNyYykge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzdGF0ZSA9IHNyYy5fcmVhZGFibGVTdGF0ZTtcbiAgICBkZWJ1ZygncGlwZU9uRHJhaW4nLCBzdGF0ZS5hd2FpdERyYWluKTtcbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbikgc3RhdGUuYXdhaXREcmFpbi0tO1xuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluID09PSAwICYmIEVFbGlzdGVuZXJDb3VudChzcmMsICdkYXRhJykpIHtcbiAgICAgIHN0YXRlLmZsb3dpbmcgPSB0cnVlO1xuICAgICAgZmxvdyhzcmMpO1xuICAgIH1cbiAgfTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLnVucGlwZSA9IGZ1bmN0aW9uIChkZXN0KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciB1bnBpcGVJbmZvID0geyBoYXNVbnBpcGVkOiBmYWxzZSB9O1xuXG4gIC8vIGlmIHdlJ3JlIG5vdCBwaXBpbmcgYW55d2hlcmUsIHRoZW4gZG8gbm90aGluZy5cbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDApIHJldHVybiB0aGlzO1xuXG4gIC8vIGp1c3Qgb25lIGRlc3RpbmF0aW9uLiAgbW9zdCBjb21tb24gY2FzZS5cbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEpIHtcbiAgICAvLyBwYXNzZWQgaW4gb25lLCBidXQgaXQncyBub3QgdGhlIHJpZ2h0IG9uZS5cbiAgICBpZiAoZGVzdCAmJiBkZXN0ICE9PSBzdGF0ZS5waXBlcykgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAoIWRlc3QpIGRlc3QgPSBzdGF0ZS5waXBlcztcblxuICAgIC8vIGdvdCBhIG1hdGNoLlxuICAgIHN0YXRlLnBpcGVzID0gbnVsbDtcbiAgICBzdGF0ZS5waXBlc0NvdW50ID0gMDtcbiAgICBzdGF0ZS5mbG93aW5nID0gZmFsc2U7XG4gICAgaWYgKGRlc3QpIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcywgdW5waXBlSW5mbyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBzbG93IGNhc2UuIG11bHRpcGxlIHBpcGUgZGVzdGluYXRpb25zLlxuXG4gIGlmICghZGVzdCkge1xuICAgIC8vIHJlbW92ZSBhbGwuXG4gICAgdmFyIGRlc3RzID0gc3RhdGUucGlwZXM7XG4gICAgdmFyIGxlbiA9IHN0YXRlLnBpcGVzQ291bnQ7XG4gICAgc3RhdGUucGlwZXMgPSBudWxsO1xuICAgIHN0YXRlLnBpcGVzQ291bnQgPSAwO1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGRlc3RzW2ldLmVtaXQoJ3VucGlwZScsIHRoaXMsIHVucGlwZUluZm8pO1xuICAgIH1yZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHRyeSB0byBmaW5kIHRoZSByaWdodCBvbmUuXG4gIHZhciBpbmRleCA9IGluZGV4T2Yoc3RhdGUucGlwZXMsIGRlc3QpO1xuICBpZiAoaW5kZXggPT09IC0xKSByZXR1cm4gdGhpcztcblxuICBzdGF0ZS5waXBlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICBzdGF0ZS5waXBlc0NvdW50IC09IDE7XG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAxKSBzdGF0ZS5waXBlcyA9IHN0YXRlLnBpcGVzWzBdO1xuXG4gIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcywgdW5waXBlSW5mbyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBzZXQgdXAgZGF0YSBldmVudHMgaWYgdGhleSBhcmUgYXNrZWQgZm9yXG4vLyBFbnN1cmUgcmVhZGFibGUgbGlzdGVuZXJzIGV2ZW50dWFsbHkgZ2V0IHNvbWV0aGluZ1xuUmVhZGFibGUucHJvdG90eXBlLm9uID0gZnVuY3Rpb24gKGV2LCBmbikge1xuICB2YXIgcmVzID0gU3RyZWFtLnByb3RvdHlwZS5vbi5jYWxsKHRoaXMsIGV2LCBmbik7XG5cbiAgaWYgKGV2ID09PSAnZGF0YScpIHtcbiAgICAvLyBTdGFydCBmbG93aW5nIG9uIG5leHQgdGljayBpZiBzdHJlYW0gaXNuJ3QgZXhwbGljaXRseSBwYXVzZWRcbiAgICBpZiAodGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nICE9PSBmYWxzZSkgdGhpcy5yZXN1bWUoKTtcbiAgfSBlbHNlIGlmIChldiA9PT0gJ3JlYWRhYmxlJykge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gICAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkICYmICFzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZykge1xuICAgICAgc3RhdGUucmVhZGFibGVMaXN0ZW5pbmcgPSBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gICAgICBpZiAoIXN0YXRlLnJlYWRpbmcpIHtcbiAgICAgICAgcG5hLm5leHRUaWNrKG5SZWFkaW5nTmV4dFRpY2ssIHRoaXMpO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZS5sZW5ndGgpIHtcbiAgICAgICAgZW1pdFJlYWRhYmxlKHRoaXMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXM7XG59O1xuUmVhZGFibGUucHJvdG90eXBlLmFkZExpc3RlbmVyID0gUmVhZGFibGUucHJvdG90eXBlLm9uO1xuXG5mdW5jdGlvbiBuUmVhZGluZ05leHRUaWNrKHNlbGYpIHtcbiAgZGVidWcoJ3JlYWRhYmxlIG5leHR0aWNrIHJlYWQgMCcpO1xuICBzZWxmLnJlYWQoMCk7XG59XG5cbi8vIHBhdXNlKCkgYW5kIHJlc3VtZSgpIGFyZSByZW1uYW50cyBvZiB0aGUgbGVnYWN5IHJlYWRhYmxlIHN0cmVhbSBBUElcbi8vIElmIHRoZSB1c2VyIHVzZXMgdGhlbSwgdGhlbiBzd2l0Y2ggaW50byBvbGQgbW9kZS5cblJlYWRhYmxlLnByb3RvdHlwZS5yZXN1bWUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIGlmICghc3RhdGUuZmxvd2luZykge1xuICAgIGRlYnVnKCdyZXN1bWUnKTtcbiAgICBzdGF0ZS5mbG93aW5nID0gdHJ1ZTtcbiAgICByZXN1bWUodGhpcywgc3RhdGUpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gcmVzdW1lKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZXN1bWVTY2hlZHVsZWQpIHtcbiAgICBzdGF0ZS5yZXN1bWVTY2hlZHVsZWQgPSB0cnVlO1xuICAgIHBuYS5uZXh0VGljayhyZXN1bWVfLCBzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXN1bWVfKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZWFkaW5nKSB7XG4gICAgZGVidWcoJ3Jlc3VtZSByZWFkIDAnKTtcbiAgICBzdHJlYW0ucmVhZCgwKTtcbiAgfVxuXG4gIHN0YXRlLnJlc3VtZVNjaGVkdWxlZCA9IGZhbHNlO1xuICBzdGF0ZS5hd2FpdERyYWluID0gMDtcbiAgc3RyZWFtLmVtaXQoJ3Jlc3VtZScpO1xuICBmbG93KHN0cmVhbSk7XG4gIGlmIChzdGF0ZS5mbG93aW5nICYmICFzdGF0ZS5yZWFkaW5nKSBzdHJlYW0ucmVhZCgwKTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1ZygnY2FsbCBwYXVzZSBmbG93aW5nPSVqJywgdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKTtcbiAgaWYgKGZhbHNlICE9PSB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncGF1c2UnKTtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmVtaXQoJ3BhdXNlJyk7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBmbG93KHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIGRlYnVnKCdmbG93Jywgc3RhdGUuZmxvd2luZyk7XG4gIHdoaWxlIChzdGF0ZS5mbG93aW5nICYmIHN0cmVhbS5yZWFkKCkgIT09IG51bGwpIHt9XG59XG5cbi8vIHdyYXAgYW4gb2xkLXN0eWxlIHN0cmVhbSBhcyB0aGUgYXN5bmMgZGF0YSBzb3VyY2UuXG4vLyBUaGlzIGlzICpub3QqIHBhcnQgb2YgdGhlIHJlYWRhYmxlIHN0cmVhbSBpbnRlcmZhY2UuXG4vLyBJdCBpcyBhbiB1Z2x5IHVuZm9ydHVuYXRlIG1lc3Mgb2YgaGlzdG9yeS5cblJlYWRhYmxlLnByb3RvdHlwZS53cmFwID0gZnVuY3Rpb24gKHN0cmVhbSkge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciBwYXVzZWQgPSBmYWxzZTtcblxuICBzdHJlYW0ub24oJ2VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBlbmQnKTtcbiAgICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhc3RhdGUuZW5kZWQpIHtcbiAgICAgIHZhciBjaHVuayA9IHN0YXRlLmRlY29kZXIuZW5kKCk7XG4gICAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKSBfdGhpcy5wdXNoKGNodW5rKTtcbiAgICB9XG5cbiAgICBfdGhpcy5wdXNoKG51bGwpO1xuICB9KTtcblxuICBzdHJlYW0ub24oJ2RhdGEnLCBmdW5jdGlvbiAoY2h1bmspIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBkYXRhJyk7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIpIGNodW5rID0gc3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7XG5cbiAgICAvLyBkb24ndCBza2lwIG92ZXIgZmFsc3kgdmFsdWVzIGluIG9iamVjdE1vZGVcbiAgICBpZiAoc3RhdGUub2JqZWN0TW9kZSAmJiAoY2h1bmsgPT09IG51bGwgfHwgY2h1bmsgPT09IHVuZGVmaW5lZCkpIHJldHVybjtlbHNlIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJiAoIWNodW5rIHx8ICFjaHVuay5sZW5ndGgpKSByZXR1cm47XG5cbiAgICB2YXIgcmV0ID0gX3RoaXMucHVzaChjaHVuayk7XG4gICAgaWYgKCFyZXQpIHtcbiAgICAgIHBhdXNlZCA9IHRydWU7XG4gICAgICBzdHJlYW0ucGF1c2UoKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHByb3h5IGFsbCB0aGUgb3RoZXIgbWV0aG9kcy5cbiAgLy8gaW1wb3J0YW50IHdoZW4gd3JhcHBpbmcgZmlsdGVycyBhbmQgZHVwbGV4ZXMuXG4gIGZvciAodmFyIGkgaW4gc3RyZWFtKSB7XG4gICAgaWYgKHRoaXNbaV0gPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygc3RyZWFtW2ldID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzW2ldID0gZnVuY3Rpb24gKG1ldGhvZCkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiBzdHJlYW1bbWV0aG9kXS5hcHBseShzdHJlYW0sIGFyZ3VtZW50cyk7XG4gICAgICAgIH07XG4gICAgICB9KGkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHByb3h5IGNlcnRhaW4gaW1wb3J0YW50IGV2ZW50cy5cbiAgZm9yICh2YXIgbiA9IDA7IG4gPCBrUHJveHlFdmVudHMubGVuZ3RoOyBuKyspIHtcbiAgICBzdHJlYW0ub24oa1Byb3h5RXZlbnRzW25dLCB0aGlzLmVtaXQuYmluZCh0aGlzLCBrUHJveHlFdmVudHNbbl0pKTtcbiAgfVxuXG4gIC8vIHdoZW4gd2UgdHJ5IHRvIGNvbnN1bWUgc29tZSBtb3JlIGJ5dGVzLCBzaW1wbHkgdW5wYXVzZSB0aGVcbiAgLy8gdW5kZXJseWluZyBzdHJlYW0uXG4gIHRoaXMuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICAgIGRlYnVnKCd3cmFwcGVkIF9yZWFkJywgbik7XG4gICAgaWYgKHBhdXNlZCkge1xuICAgICAgcGF1c2VkID0gZmFsc2U7XG4gICAgICBzdHJlYW0ucmVzdW1lKCk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlLnByb3RvdHlwZSwgJ3JlYWRhYmxlSGlnaFdhdGVyTWFyaycsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgfVxufSk7XG5cbi8vIGV4cG9zZWQgZm9yIHRlc3RpbmcgcHVycG9zZXMgb25seS5cblJlYWRhYmxlLl9mcm9tTGlzdCA9IGZyb21MaXN0O1xuXG4vLyBQbHVjayBvZmYgbiBieXRlcyBmcm9tIGFuIGFycmF5IG9mIGJ1ZmZlcnMuXG4vLyBMZW5ndGggaXMgdGhlIGNvbWJpbmVkIGxlbmd0aHMgb2YgYWxsIHRoZSBidWZmZXJzIGluIHRoZSBsaXN0LlxuLy8gVGhpcyBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBiZSBpbmxpbmFibGUsIHNvIHBsZWFzZSB0YWtlIGNhcmUgd2hlbiBtYWtpbmdcbi8vIGNoYW5nZXMgdG8gdGhlIGZ1bmN0aW9uIGJvZHkuXG5mdW5jdGlvbiBmcm9tTGlzdChuLCBzdGF0ZSkge1xuICAvLyBub3RoaW5nIGJ1ZmZlcmVkXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuXG4gIHZhciByZXQ7XG4gIGlmIChzdGF0ZS5vYmplY3RNb2RlKSByZXQgPSBzdGF0ZS5idWZmZXIuc2hpZnQoKTtlbHNlIGlmICghbiB8fCBuID49IHN0YXRlLmxlbmd0aCkge1xuICAgIC8vIHJlYWQgaXQgYWxsLCB0cnVuY2F0ZSB0aGUgbGlzdFxuICAgIGlmIChzdGF0ZS5kZWNvZGVyKSByZXQgPSBzdGF0ZS5idWZmZXIuam9pbignJyk7ZWxzZSBpZiAoc3RhdGUuYnVmZmVyLmxlbmd0aCA9PT0gMSkgcmV0ID0gc3RhdGUuYnVmZmVyLmhlYWQuZGF0YTtlbHNlIHJldCA9IHN0YXRlLmJ1ZmZlci5jb25jYXQoc3RhdGUubGVuZ3RoKTtcbiAgICBzdGF0ZS5idWZmZXIuY2xlYXIoKTtcbiAgfSBlbHNlIHtcbiAgICAvLyByZWFkIHBhcnQgb2YgbGlzdFxuICAgIHJldCA9IGZyb21MaXN0UGFydGlhbChuLCBzdGF0ZS5idWZmZXIsIHN0YXRlLmRlY29kZXIpO1xuICB9XG5cbiAgcmV0dXJuIHJldDtcbn1cblxuLy8gRXh0cmFjdHMgb25seSBlbm91Z2ggYnVmZmVyZWQgZGF0YSB0byBzYXRpc2Z5IHRoZSBhbW91bnQgcmVxdWVzdGVkLlxuLy8gVGhpcyBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBiZSBpbmxpbmFibGUsIHNvIHBsZWFzZSB0YWtlIGNhcmUgd2hlbiBtYWtpbmdcbi8vIGNoYW5nZXMgdG8gdGhlIGZ1bmN0aW9uIGJvZHkuXG5mdW5jdGlvbiBmcm9tTGlzdFBhcnRpYWwobiwgbGlzdCwgaGFzU3RyaW5ncykge1xuICB2YXIgcmV0O1xuICBpZiAobiA8IGxpc3QuaGVhZC5kYXRhLmxlbmd0aCkge1xuICAgIC8vIHNsaWNlIGlzIHRoZSBzYW1lIGZvciBidWZmZXJzIGFuZCBzdHJpbmdzXG4gICAgcmV0ID0gbGlzdC5oZWFkLmRhdGEuc2xpY2UoMCwgbik7XG4gICAgbGlzdC5oZWFkLmRhdGEgPSBsaXN0LmhlYWQuZGF0YS5zbGljZShuKTtcbiAgfSBlbHNlIGlmIChuID09PSBsaXN0LmhlYWQuZGF0YS5sZW5ndGgpIHtcbiAgICAvLyBmaXJzdCBjaHVuayBpcyBhIHBlcmZlY3QgbWF0Y2hcbiAgICByZXQgPSBsaXN0LnNoaWZ0KCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gcmVzdWx0IHNwYW5zIG1vcmUgdGhhbiBvbmUgYnVmZmVyXG4gICAgcmV0ID0gaGFzU3RyaW5ncyA/IGNvcHlGcm9tQnVmZmVyU3RyaW5nKG4sIGxpc3QpIDogY29weUZyb21CdWZmZXIobiwgbGlzdCk7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuLy8gQ29waWVzIGEgc3BlY2lmaWVkIGFtb3VudCBvZiBjaGFyYWN0ZXJzIGZyb20gdGhlIGxpc3Qgb2YgYnVmZmVyZWQgZGF0YVxuLy8gY2h1bmtzLlxuLy8gVGhpcyBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBiZSBpbmxpbmFibGUsIHNvIHBsZWFzZSB0YWtlIGNhcmUgd2hlbiBtYWtpbmdcbi8vIGNoYW5nZXMgdG8gdGhlIGZ1bmN0aW9uIGJvZHkuXG5mdW5jdGlvbiBjb3B5RnJvbUJ1ZmZlclN0cmluZyhuLCBsaXN0KSB7XG4gIHZhciBwID0gbGlzdC5oZWFkO1xuICB2YXIgYyA9IDE7XG4gIHZhciByZXQgPSBwLmRhdGE7XG4gIG4gLT0gcmV0Lmxlbmd0aDtcbiAgd2hpbGUgKHAgPSBwLm5leHQpIHtcbiAgICB2YXIgc3RyID0gcC5kYXRhO1xuICAgIHZhciBuYiA9IG4gPiBzdHIubGVuZ3RoID8gc3RyLmxlbmd0aCA6IG47XG4gICAgaWYgKG5iID09PSBzdHIubGVuZ3RoKSByZXQgKz0gc3RyO2Vsc2UgcmV0ICs9IHN0ci5zbGljZSgwLCBuKTtcbiAgICBuIC09IG5iO1xuICAgIGlmIChuID09PSAwKSB7XG4gICAgICBpZiAobmIgPT09IHN0ci5sZW5ndGgpIHtcbiAgICAgICAgKytjO1xuICAgICAgICBpZiAocC5uZXh0KSBsaXN0LmhlYWQgPSBwLm5leHQ7ZWxzZSBsaXN0LmhlYWQgPSBsaXN0LnRhaWwgPSBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGlzdC5oZWFkID0gcDtcbiAgICAgICAgcC5kYXRhID0gc3RyLnNsaWNlKG5iKTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICArK2M7XG4gIH1cbiAgbGlzdC5sZW5ndGggLT0gYztcbiAgcmV0dXJuIHJldDtcbn1cblxuLy8gQ29waWVzIGEgc3BlY2lmaWVkIGFtb3VudCBvZiBieXRlcyBmcm9tIHRoZSBsaXN0IG9mIGJ1ZmZlcmVkIGRhdGEgY2h1bmtzLlxuLy8gVGhpcyBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBiZSBpbmxpbmFibGUsIHNvIHBsZWFzZSB0YWtlIGNhcmUgd2hlbiBtYWtpbmdcbi8vIGNoYW5nZXMgdG8gdGhlIGZ1bmN0aW9uIGJvZHkuXG5mdW5jdGlvbiBjb3B5RnJvbUJ1ZmZlcihuLCBsaXN0KSB7XG4gIHZhciByZXQgPSBCdWZmZXIuYWxsb2NVbnNhZmUobik7XG4gIHZhciBwID0gbGlzdC5oZWFkO1xuICB2YXIgYyA9IDE7XG4gIHAuZGF0YS5jb3B5KHJldCk7XG4gIG4gLT0gcC5kYXRhLmxlbmd0aDtcbiAgd2hpbGUgKHAgPSBwLm5leHQpIHtcbiAgICB2YXIgYnVmID0gcC5kYXRhO1xuICAgIHZhciBuYiA9IG4gPiBidWYubGVuZ3RoID8gYnVmLmxlbmd0aCA6IG47XG4gICAgYnVmLmNvcHkocmV0LCByZXQubGVuZ3RoIC0gbiwgMCwgbmIpO1xuICAgIG4gLT0gbmI7XG4gICAgaWYgKG4gPT09IDApIHtcbiAgICAgIGlmIChuYiA9PT0gYnVmLmxlbmd0aCkge1xuICAgICAgICArK2M7XG4gICAgICAgIGlmIChwLm5leHQpIGxpc3QuaGVhZCA9IHAubmV4dDtlbHNlIGxpc3QuaGVhZCA9IGxpc3QudGFpbCA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsaXN0LmhlYWQgPSBwO1xuICAgICAgICBwLmRhdGEgPSBidWYuc2xpY2UobmIpO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgICsrYztcbiAgfVxuICBsaXN0Lmxlbmd0aCAtPSBjO1xuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBlbmRSZWFkYWJsZShzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuXG4gIC8vIElmIHdlIGdldCBoZXJlIGJlZm9yZSBjb25zdW1pbmcgYWxsIHRoZSBieXRlcywgdGhlbiB0aGF0IGlzIGFcbiAgLy8gYnVnIGluIG5vZGUuICBTaG91bGQgbmV2ZXIgaGFwcGVuLlxuICBpZiAoc3RhdGUubGVuZ3RoID4gMCkgdGhyb3cgbmV3IEVycm9yKCdcImVuZFJlYWRhYmxlKClcIiBjYWxsZWQgb24gbm9uLWVtcHR5IHN0cmVhbScpO1xuXG4gIGlmICghc3RhdGUuZW5kRW1pdHRlZCkge1xuICAgIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbiAgICBwbmEubmV4dFRpY2soZW5kUmVhZGFibGVOVCwgc3RhdGUsIHN0cmVhbSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW5kUmVhZGFibGVOVChzdGF0ZSwgc3RyZWFtKSB7XG4gIC8vIENoZWNrIHRoYXQgd2UgZGlkbid0IGdldCBvbmUgbGFzdCB1bnNoaWZ0LlxuICBpZiAoIXN0YXRlLmVuZEVtaXR0ZWQgJiYgc3RhdGUubGVuZ3RoID09PSAwKSB7XG4gICAgc3RhdGUuZW5kRW1pdHRlZCA9IHRydWU7XG4gICAgc3RyZWFtLnJlYWRhYmxlID0gZmFsc2U7XG4gICAgc3RyZWFtLmVtaXQoJ2VuZCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBpZiAoeHNbaV0gPT09IHgpIHJldHVybiBpO1xuICB9XG4gIHJldHVybiAtMTtcbn0iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gYSB0cmFuc2Zvcm0gc3RyZWFtIGlzIGEgcmVhZGFibGUvd3JpdGFibGUgc3RyZWFtIHdoZXJlIHlvdSBkb1xuLy8gc29tZXRoaW5nIHdpdGggdGhlIGRhdGEuICBTb21ldGltZXMgaXQncyBjYWxsZWQgYSBcImZpbHRlclwiLFxuLy8gYnV0IHRoYXQncyBub3QgYSBncmVhdCBuYW1lIGZvciBpdCwgc2luY2UgdGhhdCBpbXBsaWVzIGEgdGhpbmcgd2hlcmVcbi8vIHNvbWUgYml0cyBwYXNzIHRocm91Z2gsIGFuZCBvdGhlcnMgYXJlIHNpbXBseSBpZ25vcmVkLiAgKFRoYXQgd291bGRcbi8vIGJlIGEgdmFsaWQgZXhhbXBsZSBvZiBhIHRyYW5zZm9ybSwgb2YgY291cnNlLilcbi8vXG4vLyBXaGlsZSB0aGUgb3V0cHV0IGlzIGNhdXNhbGx5IHJlbGF0ZWQgdG8gdGhlIGlucHV0LCBpdCdzIG5vdCBhXG4vLyBuZWNlc3NhcmlseSBzeW1tZXRyaWMgb3Igc3luY2hyb25vdXMgdHJhbnNmb3JtYXRpb24uICBGb3IgZXhhbXBsZSxcbi8vIGEgemxpYiBzdHJlYW0gbWlnaHQgdGFrZSBtdWx0aXBsZSBwbGFpbi10ZXh0IHdyaXRlcygpLCBhbmQgdGhlblxuLy8gZW1pdCBhIHNpbmdsZSBjb21wcmVzc2VkIGNodW5rIHNvbWUgdGltZSBpbiB0aGUgZnV0dXJlLlxuLy9cbi8vIEhlcmUncyBob3cgdGhpcyB3b3Jrczpcbi8vXG4vLyBUaGUgVHJhbnNmb3JtIHN0cmVhbSBoYXMgYWxsIHRoZSBhc3BlY3RzIG9mIHRoZSByZWFkYWJsZSBhbmQgd3JpdGFibGVcbi8vIHN0cmVhbSBjbGFzc2VzLiAgV2hlbiB5b3Ugd3JpdGUoY2h1bmspLCB0aGF0IGNhbGxzIF93cml0ZShjaHVuayxjYilcbi8vIGludGVybmFsbHksIGFuZCByZXR1cm5zIGZhbHNlIGlmIHRoZXJlJ3MgYSBsb3Qgb2YgcGVuZGluZyB3cml0ZXNcbi8vIGJ1ZmZlcmVkIHVwLiAgV2hlbiB5b3UgY2FsbCByZWFkKCksIHRoYXQgY2FsbHMgX3JlYWQobikgdW50aWxcbi8vIHRoZXJlJ3MgZW5vdWdoIHBlbmRpbmcgcmVhZGFibGUgZGF0YSBidWZmZXJlZCB1cC5cbi8vXG4vLyBJbiBhIHRyYW5zZm9ybSBzdHJlYW0sIHRoZSB3cml0dGVuIGRhdGEgaXMgcGxhY2VkIGluIGEgYnVmZmVyLiAgV2hlblxuLy8gX3JlYWQobikgaXMgY2FsbGVkLCBpdCB0cmFuc2Zvcm1zIHRoZSBxdWV1ZWQgdXAgZGF0YSwgY2FsbGluZyB0aGVcbi8vIGJ1ZmZlcmVkIF93cml0ZSBjYidzIGFzIGl0IGNvbnN1bWVzIGNodW5rcy4gIElmIGNvbnN1bWluZyBhIHNpbmdsZVxuLy8gd3JpdHRlbiBjaHVuayB3b3VsZCByZXN1bHQgaW4gbXVsdGlwbGUgb3V0cHV0IGNodW5rcywgdGhlbiB0aGUgZmlyc3Rcbi8vIG91dHB1dHRlZCBiaXQgY2FsbHMgdGhlIHJlYWRjYiwgYW5kIHN1YnNlcXVlbnQgY2h1bmtzIGp1c3QgZ28gaW50b1xuLy8gdGhlIHJlYWQgYnVmZmVyLCBhbmQgd2lsbCBjYXVzZSBpdCB0byBlbWl0ICdyZWFkYWJsZScgaWYgbmVjZXNzYXJ5LlxuLy9cbi8vIFRoaXMgd2F5LCBiYWNrLXByZXNzdXJlIGlzIGFjdHVhbGx5IGRldGVybWluZWQgYnkgdGhlIHJlYWRpbmcgc2lkZSxcbi8vIHNpbmNlIF9yZWFkIGhhcyB0byBiZSBjYWxsZWQgdG8gc3RhcnQgcHJvY2Vzc2luZyBhIG5ldyBjaHVuay4gIEhvd2V2ZXIsXG4vLyBhIHBhdGhvbG9naWNhbCBpbmZsYXRlIHR5cGUgb2YgdHJhbnNmb3JtIGNhbiBjYXVzZSBleGNlc3NpdmUgYnVmZmVyaW5nXG4vLyBoZXJlLiAgRm9yIGV4YW1wbGUsIGltYWdpbmUgYSBzdHJlYW0gd2hlcmUgZXZlcnkgYnl0ZSBvZiBpbnB1dCBpc1xuLy8gaW50ZXJwcmV0ZWQgYXMgYW4gaW50ZWdlciBmcm9tIDAtMjU1LCBhbmQgdGhlbiByZXN1bHRzIGluIHRoYXQgbWFueVxuLy8gYnl0ZXMgb2Ygb3V0cHV0LiAgV3JpdGluZyB0aGUgNCBieXRlcyB7ZmYsZmYsZmYsZmZ9IHdvdWxkIHJlc3VsdCBpblxuLy8gMWtiIG9mIGRhdGEgYmVpbmcgb3V0cHV0LiAgSW4gdGhpcyBjYXNlLCB5b3UgY291bGQgd3JpdGUgYSB2ZXJ5IHNtYWxsXG4vLyBhbW91bnQgb2YgaW5wdXQsIGFuZCBlbmQgdXAgd2l0aCBhIHZlcnkgbGFyZ2UgYW1vdW50IG9mIG91dHB1dC4gIEluXG4vLyBzdWNoIGEgcGF0aG9sb2dpY2FsIGluZmxhdGluZyBtZWNoYW5pc20sIHRoZXJlJ2QgYmUgbm8gd2F5IHRvIHRlbGxcbi8vIHRoZSBzeXN0ZW0gdG8gc3RvcCBkb2luZyB0aGUgdHJhbnNmb3JtLiAgQSBzaW5nbGUgNE1CIHdyaXRlIGNvdWxkXG4vLyBjYXVzZSB0aGUgc3lzdGVtIHRvIHJ1biBvdXQgb2YgbWVtb3J5LlxuLy9cbi8vIEhvd2V2ZXIsIGV2ZW4gaW4gc3VjaCBhIHBhdGhvbG9naWNhbCBjYXNlLCBvbmx5IGEgc2luZ2xlIHdyaXR0ZW4gY2h1bmtcbi8vIHdvdWxkIGJlIGNvbnN1bWVkLCBhbmQgdGhlbiB0aGUgcmVzdCB3b3VsZCB3YWl0ICh1bi10cmFuc2Zvcm1lZCkgdW50aWxcbi8vIHRoZSByZXN1bHRzIG9mIHRoZSBwcmV2aW91cyB0cmFuc2Zvcm1lZCBjaHVuayB3ZXJlIGNvbnN1bWVkLlxuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gVHJhbnNmb3JtO1xuXG52YXIgRHVwbGV4ID0gcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSByZXF1aXJlKCdjb3JlLXV0aWwtaXMnKTtcbnV0aWwuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnV0aWwuaW5oZXJpdHMoVHJhbnNmb3JtLCBEdXBsZXgpO1xuXG5mdW5jdGlvbiBhZnRlclRyYW5zZm9ybShlciwgZGF0YSkge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcbiAgdHMudHJhbnNmb3JtaW5nID0gZmFsc2U7XG5cbiAgdmFyIGNiID0gdHMud3JpdGVjYjtcblxuICBpZiAoIWNiKSB7XG4gICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ3dyaXRlIGNhbGxiYWNrIGNhbGxlZCBtdWx0aXBsZSB0aW1lcycpKTtcbiAgfVxuXG4gIHRzLndyaXRlY2h1bmsgPSBudWxsO1xuICB0cy53cml0ZWNiID0gbnVsbDtcblxuICBpZiAoZGF0YSAhPSBudWxsKSAvLyBzaW5nbGUgZXF1YWxzIGNoZWNrIGZvciBib3RoIGBudWxsYCBhbmQgYHVuZGVmaW5lZGBcbiAgICB0aGlzLnB1c2goZGF0YSk7XG5cbiAgY2IoZXIpO1xuXG4gIHZhciBycyA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHJzLnJlYWRpbmcgPSBmYWxzZTtcbiAgaWYgKHJzLm5lZWRSZWFkYWJsZSB8fCBycy5sZW5ndGggPCBycy5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgdGhpcy5fcmVhZChycy5oaWdoV2F0ZXJNYXJrKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBUcmFuc2Zvcm0ob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVHJhbnNmb3JtKSkgcmV0dXJuIG5ldyBUcmFuc2Zvcm0ob3B0aW9ucyk7XG5cbiAgRHVwbGV4LmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgdGhpcy5fdHJhbnNmb3JtU3RhdGUgPSB7XG4gICAgYWZ0ZXJUcmFuc2Zvcm06IGFmdGVyVHJhbnNmb3JtLmJpbmQodGhpcyksXG4gICAgbmVlZFRyYW5zZm9ybTogZmFsc2UsXG4gICAgdHJhbnNmb3JtaW5nOiBmYWxzZSxcbiAgICB3cml0ZWNiOiBudWxsLFxuICAgIHdyaXRlY2h1bms6IG51bGwsXG4gICAgd3JpdGVlbmNvZGluZzogbnVsbFxuICB9O1xuXG4gIC8vIHN0YXJ0IG91dCBhc2tpbmcgZm9yIGEgcmVhZGFibGUgZXZlbnQgb25jZSBkYXRhIGlzIHRyYW5zZm9ybWVkLlxuICB0aGlzLl9yZWFkYWJsZVN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG5cbiAgLy8gd2UgaGF2ZSBpbXBsZW1lbnRlZCB0aGUgX3JlYWQgbWV0aG9kLCBhbmQgZG9uZSB0aGUgb3RoZXIgdGhpbmdzXG4gIC8vIHRoYXQgUmVhZGFibGUgd2FudHMgYmVmb3JlIHRoZSBmaXJzdCBfcmVhZCBjYWxsLCBzbyB1bnNldCB0aGVcbiAgLy8gc3luYyBndWFyZCBmbGFnLlxuICB0aGlzLl9yZWFkYWJsZVN0YXRlLnN5bmMgPSBmYWxzZTtcblxuICBpZiAob3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy50cmFuc2Zvcm0gPT09ICdmdW5jdGlvbicpIHRoaXMuX3RyYW5zZm9ybSA9IG9wdGlvbnMudHJhbnNmb3JtO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmZsdXNoID09PSAnZnVuY3Rpb24nKSB0aGlzLl9mbHVzaCA9IG9wdGlvbnMuZmx1c2g7XG4gIH1cblxuICAvLyBXaGVuIHRoZSB3cml0YWJsZSBzaWRlIGZpbmlzaGVzLCB0aGVuIGZsdXNoIG91dCBhbnl0aGluZyByZW1haW5pbmcuXG4gIHRoaXMub24oJ3ByZWZpbmlzaCcsIHByZWZpbmlzaCk7XG59XG5cbmZ1bmN0aW9uIHByZWZpbmlzaCgpIHtcbiAgdmFyIF90aGlzID0gdGhpcztcblxuICBpZiAodHlwZW9mIHRoaXMuX2ZsdXNoID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhpcy5fZmx1c2goZnVuY3Rpb24gKGVyLCBkYXRhKSB7XG4gICAgICBkb25lKF90aGlzLCBlciwgZGF0YSk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgZG9uZSh0aGlzLCBudWxsLCBudWxsKTtcbiAgfVxufVxuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nKSB7XG4gIHRoaXMuX3RyYW5zZm9ybVN0YXRlLm5lZWRUcmFuc2Zvcm0gPSBmYWxzZTtcbiAgcmV0dXJuIER1cGxleC5wcm90b3R5cGUucHVzaC5jYWxsKHRoaXMsIGNodW5rLCBlbmNvZGluZyk7XG59O1xuXG4vLyBUaGlzIGlzIHRoZSBwYXJ0IHdoZXJlIHlvdSBkbyBzdHVmZiFcbi8vIG92ZXJyaWRlIHRoaXMgZnVuY3Rpb24gaW4gaW1wbGVtZW50YXRpb24gY2xhc3Nlcy5cbi8vICdjaHVuaycgaXMgYW4gaW5wdXQgY2h1bmsuXG4vL1xuLy8gQ2FsbCBgcHVzaChuZXdDaHVuaylgIHRvIHBhc3MgYWxvbmcgdHJhbnNmb3JtZWQgb3V0cHV0XG4vLyB0byB0aGUgcmVhZGFibGUgc2lkZS4gIFlvdSBtYXkgY2FsbCAncHVzaCcgemVybyBvciBtb3JlIHRpbWVzLlxuLy9cbi8vIENhbGwgYGNiKGVycilgIHdoZW4geW91IGFyZSBkb25lIHdpdGggdGhpcyBjaHVuay4gIElmIHlvdSBwYXNzXG4vLyBhbiBlcnJvciwgdGhlbiB0aGF0J2xsIHB1dCB0aGUgaHVydCBvbiB0aGUgd2hvbGUgb3BlcmF0aW9uLiAgSWYgeW91XG4vLyBuZXZlciBjYWxsIGNiKCksIHRoZW4geW91J2xsIG5ldmVyIGdldCBhbm90aGVyIGNodW5rLlxuVHJhbnNmb3JtLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdfdHJhbnNmb3JtKCkgaXMgbm90IGltcGxlbWVudGVkJyk7XG59O1xuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciB0cyA9IHRoaXMuX3RyYW5zZm9ybVN0YXRlO1xuICB0cy53cml0ZWNiID0gY2I7XG4gIHRzLndyaXRlY2h1bmsgPSBjaHVuaztcbiAgdHMud3JpdGVlbmNvZGluZyA9IGVuY29kaW5nO1xuICBpZiAoIXRzLnRyYW5zZm9ybWluZykge1xuICAgIHZhciBycyA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gICAgaWYgKHRzLm5lZWRUcmFuc2Zvcm0gfHwgcnMubmVlZFJlYWRhYmxlIHx8IHJzLmxlbmd0aCA8IHJzLmhpZ2hXYXRlck1hcmspIHRoaXMuX3JlYWQocnMuaGlnaFdhdGVyTWFyayk7XG4gIH1cbn07XG5cbi8vIERvZXNuJ3QgbWF0dGVyIHdoYXQgdGhlIGFyZ3MgYXJlIGhlcmUuXG4vLyBfdHJhbnNmb3JtIGRvZXMgYWxsIHRoZSB3b3JrLlxuLy8gVGhhdCB3ZSBnb3QgaGVyZSBtZWFucyB0aGF0IHRoZSByZWFkYWJsZSBzaWRlIHdhbnRzIG1vcmUgZGF0YS5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcblxuICBpZiAodHMud3JpdGVjaHVuayAhPT0gbnVsbCAmJiB0cy53cml0ZWNiICYmICF0cy50cmFuc2Zvcm1pbmcpIHtcbiAgICB0cy50cmFuc2Zvcm1pbmcgPSB0cnVlO1xuICAgIHRoaXMuX3RyYW5zZm9ybSh0cy53cml0ZWNodW5rLCB0cy53cml0ZWVuY29kaW5nLCB0cy5hZnRlclRyYW5zZm9ybSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gbWFyayB0aGF0IHdlIG5lZWQgYSB0cmFuc2Zvcm0sIHNvIHRoYXQgYW55IGRhdGEgdGhhdCBjb21lcyBpblxuICAgIC8vIHdpbGwgZ2V0IHByb2Nlc3NlZCwgbm93IHRoYXQgd2UndmUgYXNrZWQgZm9yIGl0LlxuICAgIHRzLm5lZWRUcmFuc2Zvcm0gPSB0cnVlO1xuICB9XG59O1xuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl9kZXN0cm95ID0gZnVuY3Rpb24gKGVyciwgY2IpIHtcbiAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgRHVwbGV4LnByb3RvdHlwZS5fZGVzdHJveS5jYWxsKHRoaXMsIGVyciwgZnVuY3Rpb24gKGVycjIpIHtcbiAgICBjYihlcnIyKTtcbiAgICBfdGhpczIuZW1pdCgnY2xvc2UnKTtcbiAgfSk7XG59O1xuXG5mdW5jdGlvbiBkb25lKHN0cmVhbSwgZXIsIGRhdGEpIHtcbiAgaWYgKGVyKSByZXR1cm4gc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuXG4gIGlmIChkYXRhICE9IG51bGwpIC8vIHNpbmdsZSBlcXVhbHMgY2hlY2sgZm9yIGJvdGggYG51bGxgIGFuZCBgdW5kZWZpbmVkYFxuICAgIHN0cmVhbS5wdXNoKGRhdGEpO1xuXG4gIC8vIGlmIHRoZXJlJ3Mgbm90aGluZyBpbiB0aGUgd3JpdGUgYnVmZmVyLCB0aGVuIHRoYXQgbWVhbnNcbiAgLy8gdGhhdCBub3RoaW5nIG1vcmUgd2lsbCBldmVyIGJlIHByb3ZpZGVkXG4gIGlmIChzdHJlYW0uX3dyaXRhYmxlU3RhdGUubGVuZ3RoKSB0aHJvdyBuZXcgRXJyb3IoJ0NhbGxpbmcgdHJhbnNmb3JtIGRvbmUgd2hlbiB3cy5sZW5ndGggIT0gMCcpO1xuXG4gIGlmIChzdHJlYW0uX3RyYW5zZm9ybVN0YXRlLnRyYW5zZm9ybWluZykgdGhyb3cgbmV3IEVycm9yKCdDYWxsaW5nIHRyYW5zZm9ybSBkb25lIHdoZW4gc3RpbGwgdHJhbnNmb3JtaW5nJyk7XG5cbiAgcmV0dXJuIHN0cmVhbS5wdXNoKG51bGwpO1xufSIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBBIGJpdCBzaW1wbGVyIHRoYW4gcmVhZGFibGUgc3RyZWFtcy5cbi8vIEltcGxlbWVudCBhbiBhc3luYyAuX3dyaXRlKGNodW5rLCBlbmNvZGluZywgY2IpLCBhbmQgaXQnbGwgaGFuZGxlIGFsbFxuLy8gdGhlIGRyYWluIGV2ZW50IGVtaXNzaW9uIGFuZCBidWZmZXJpbmcuXG5cbid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIHBuYSA9IHJlcXVpcmUoJ3Byb2Nlc3MtbmV4dGljay1hcmdzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxubW9kdWxlLmV4cG9ydHMgPSBXcml0YWJsZTtcblxuLyogPHJlcGxhY2VtZW50PiAqL1xuZnVuY3Rpb24gV3JpdGVSZXEoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB0aGlzLmNodW5rID0gY2h1bms7XG4gIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZztcbiAgdGhpcy5jYWxsYmFjayA9IGNiO1xuICB0aGlzLm5leHQgPSBudWxsO1xufVxuXG4vLyBJdCBzZWVtcyBhIGxpbmtlZCBsaXN0IGJ1dCBpdCBpcyBub3Rcbi8vIHRoZXJlIHdpbGwgYmUgb25seSAyIG9mIHRoZXNlIGZvciBlYWNoIHN0cmVhbVxuZnVuY3Rpb24gQ29ya2VkUmVxdWVzdChzdGF0ZSkge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIHRoaXMubmV4dCA9IG51bGw7XG4gIHRoaXMuZW50cnkgPSBudWxsO1xuICB0aGlzLmZpbmlzaCA9IGZ1bmN0aW9uICgpIHtcbiAgICBvbkNvcmtlZEZpbmlzaChfdGhpcywgc3RhdGUpO1xuICB9O1xufVxuLyogPC9yZXBsYWNlbWVudD4gKi9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBhc3luY1dyaXRlID0gIXByb2Nlc3MuYnJvd3NlciAmJiBbJ3YwLjEwJywgJ3YwLjkuJ10uaW5kZXhPZihwcm9jZXNzLnZlcnNpb24uc2xpY2UoMCwgNSkpID4gLTEgPyBzZXRJbW1lZGlhdGUgOiBwbmEubmV4dFRpY2s7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBEdXBsZXg7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuV3JpdGFibGUuV3JpdGFibGVTdGF0ZSA9IFdyaXRhYmxlU3RhdGU7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBpbnRlcm5hbFV0aWwgPSB7XG4gIGRlcHJlY2F0ZTogcmVxdWlyZSgndXRpbC1kZXByZWNhdGUnKVxufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIFN0cmVhbSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvc3RyZWFtcy9zdHJlYW0nKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXI7XG52YXIgT3VyVWludDhBcnJheSA9IGdsb2JhbC5VaW50OEFycmF5IHx8IGZ1bmN0aW9uICgpIHt9O1xuZnVuY3Rpb24gX3VpbnQ4QXJyYXlUb0J1ZmZlcihjaHVuaykge1xuICByZXR1cm4gQnVmZmVyLmZyb20oY2h1bmspO1xufVxuZnVuY3Rpb24gX2lzVWludDhBcnJheShvYmopIHtcbiAgcmV0dXJuIEJ1ZmZlci5pc0J1ZmZlcihvYmopIHx8IG9iaiBpbnN0YW5jZW9mIE91clVpbnQ4QXJyYXk7XG59XG5cbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgZGVzdHJveUltcGwgPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvZGVzdHJveScpO1xuXG51dGlsLmluaGVyaXRzKFdyaXRhYmxlLCBTdHJlYW0pO1xuXG5mdW5jdGlvbiBub3AoKSB7fVxuXG5mdW5jdGlvbiBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSkge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIER1cGxleCBzdHJlYW1zIGFyZSBib3RoIHJlYWRhYmxlIGFuZCB3cml0YWJsZSwgYnV0IHNoYXJlXG4gIC8vIHRoZSBzYW1lIG9wdGlvbnMgb2JqZWN0LlxuICAvLyBIb3dldmVyLCBzb21lIGNhc2VzIHJlcXVpcmUgc2V0dGluZyBvcHRpb25zIHRvIGRpZmZlcmVudFxuICAvLyB2YWx1ZXMgZm9yIHRoZSByZWFkYWJsZSBhbmQgdGhlIHdyaXRhYmxlIHNpZGVzIG9mIHRoZSBkdXBsZXggc3RyZWFtLlxuICAvLyBUaGVzZSBvcHRpb25zIGNhbiBiZSBwcm92aWRlZCBzZXBhcmF0ZWx5IGFzIHJlYWRhYmxlWFhYIGFuZCB3cml0YWJsZVhYWC5cbiAgdmFyIGlzRHVwbGV4ID0gc3RyZWFtIGluc3RhbmNlb2YgRHVwbGV4O1xuXG4gIC8vIG9iamVjdCBzdHJlYW0gZmxhZyB0byBpbmRpY2F0ZSB3aGV0aGVyIG9yIG5vdCB0aGlzIHN0cmVhbVxuICAvLyBjb250YWlucyBidWZmZXJzIG9yIG9iamVjdHMuXG4gIHRoaXMub2JqZWN0TW9kZSA9ICEhb3B0aW9ucy5vYmplY3RNb2RlO1xuXG4gIGlmIChpc0R1cGxleCkgdGhpcy5vYmplY3RNb2RlID0gdGhpcy5vYmplY3RNb2RlIHx8ICEhb3B0aW9ucy53cml0YWJsZU9iamVjdE1vZGU7XG5cbiAgLy8gdGhlIHBvaW50IGF0IHdoaWNoIHdyaXRlKCkgc3RhcnRzIHJldHVybmluZyBmYWxzZVxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIHRoYXQgd2UgYWx3YXlzIHJldHVybiBmYWxzZSBpZlxuICAvLyB0aGUgZW50aXJlIGJ1ZmZlciBpcyBub3QgZmx1c2hlZCBpbW1lZGlhdGVseSBvbiB3cml0ZSgpXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHZhciB3cml0YWJsZUh3bSA9IG9wdGlvbnMud3JpdGFibGVIaWdoV2F0ZXJNYXJrO1xuICB2YXIgZGVmYXVsdEh3bSA9IHRoaXMub2JqZWN0TW9kZSA/IDE2IDogMTYgKiAxMDI0O1xuXG4gIGlmIChod20gfHwgaHdtID09PSAwKSB0aGlzLmhpZ2hXYXRlck1hcmsgPSBod207ZWxzZSBpZiAoaXNEdXBsZXggJiYgKHdyaXRhYmxlSHdtIHx8IHdyaXRhYmxlSHdtID09PSAwKSkgdGhpcy5oaWdoV2F0ZXJNYXJrID0gd3JpdGFibGVId207ZWxzZSB0aGlzLmhpZ2hXYXRlck1hcmsgPSBkZWZhdWx0SHdtO1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gTWF0aC5mbG9vcih0aGlzLmhpZ2hXYXRlck1hcmspO1xuXG4gIC8vIGlmIF9maW5hbCBoYXMgYmVlbiBjYWxsZWRcbiAgdGhpcy5maW5hbENhbGxlZCA9IGZhbHNlO1xuXG4gIC8vIGRyYWluIGV2ZW50IGZsYWcuXG4gIHRoaXMubmVlZERyYWluID0gZmFsc2U7XG4gIC8vIGF0IHRoZSBzdGFydCBvZiBjYWxsaW5nIGVuZCgpXG4gIHRoaXMuZW5kaW5nID0gZmFsc2U7XG4gIC8vIHdoZW4gZW5kKCkgaGFzIGJlZW4gY2FsbGVkLCBhbmQgcmV0dXJuZWRcbiAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICAvLyB3aGVuICdmaW5pc2gnIGlzIGVtaXR0ZWRcbiAgdGhpcy5maW5pc2hlZCA9IGZhbHNlO1xuXG4gIC8vIGhhcyBpdCBiZWVuIGRlc3Ryb3llZFxuICB0aGlzLmRlc3Ryb3llZCA9IGZhbHNlO1xuXG4gIC8vIHNob3VsZCB3ZSBkZWNvZGUgc3RyaW5ncyBpbnRvIGJ1ZmZlcnMgYmVmb3JlIHBhc3NpbmcgdG8gX3dyaXRlP1xuICAvLyB0aGlzIGlzIGhlcmUgc28gdGhhdCBzb21lIG5vZGUtY29yZSBzdHJlYW1zIGNhbiBvcHRpbWl6ZSBzdHJpbmdcbiAgLy8gaGFuZGxpbmcgYXQgYSBsb3dlciBsZXZlbC5cbiAgdmFyIG5vRGVjb2RlID0gb3B0aW9ucy5kZWNvZGVTdHJpbmdzID09PSBmYWxzZTtcbiAgdGhpcy5kZWNvZGVTdHJpbmdzID0gIW5vRGVjb2RlO1xuXG4gIC8vIENyeXB0byBpcyBraW5kIG9mIG9sZCBhbmQgY3J1c3R5LiAgSGlzdG9yaWNhbGx5LCBpdHMgZGVmYXVsdCBzdHJpbmdcbiAgLy8gZW5jb2RpbmcgaXMgJ2JpbmFyeScgc28gd2UgaGF2ZSB0byBtYWtlIHRoaXMgY29uZmlndXJhYmxlLlxuICAvLyBFdmVyeXRoaW5nIGVsc2UgaW4gdGhlIHVuaXZlcnNlIHVzZXMgJ3V0ZjgnLCB0aG91Z2guXG4gIHRoaXMuZGVmYXVsdEVuY29kaW5nID0gb3B0aW9ucy5kZWZhdWx0RW5jb2RpbmcgfHwgJ3V0ZjgnO1xuXG4gIC8vIG5vdCBhbiBhY3R1YWwgYnVmZmVyIHdlIGtlZXAgdHJhY2sgb2YsIGJ1dCBhIG1lYXN1cmVtZW50XG4gIC8vIG9mIGhvdyBtdWNoIHdlJ3JlIHdhaXRpbmcgdG8gZ2V0IHB1c2hlZCB0byBzb21lIHVuZGVybHlpbmdcbiAgLy8gc29ja2V0IG9yIGZpbGUuXG4gIHRoaXMubGVuZ3RoID0gMDtcblxuICAvLyBhIGZsYWcgdG8gc2VlIHdoZW4gd2UncmUgaW4gdGhlIG1pZGRsZSBvZiBhIHdyaXRlLlxuICB0aGlzLndyaXRpbmcgPSBmYWxzZTtcblxuICAvLyB3aGVuIHRydWUgYWxsIHdyaXRlcyB3aWxsIGJlIGJ1ZmZlcmVkIHVudGlsIC51bmNvcmsoKSBjYWxsXG4gIHRoaXMuY29ya2VkID0gMDtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBvbndyaXRlIGNiIGlzIGNhbGxlZCBpbW1lZGlhdGVseSxcbiAgLy8gb3Igb24gYSBsYXRlciB0aWNrLiAgV2Ugc2V0IHRoaXMgdG8gdHJ1ZSBhdCBmaXJzdCwgYmVjYXVzZSBhbnlcbiAgLy8gYWN0aW9ucyB0aGF0IHNob3VsZG4ndCBoYXBwZW4gdW50aWwgXCJsYXRlclwiIHNob3VsZCBnZW5lcmFsbHkgYWxzb1xuICAvLyBub3QgaGFwcGVuIGJlZm9yZSB0aGUgZmlyc3Qgd3JpdGUgY2FsbC5cbiAgdGhpcy5zeW5jID0gdHJ1ZTtcblxuICAvLyBhIGZsYWcgdG8ga25vdyBpZiB3ZSdyZSBwcm9jZXNzaW5nIHByZXZpb3VzbHkgYnVmZmVyZWQgaXRlbXMsIHdoaWNoXG4gIC8vIG1heSBjYWxsIHRoZSBfd3JpdGUoKSBjYWxsYmFjayBpbiB0aGUgc2FtZSB0aWNrLCBzbyB0aGF0IHdlIGRvbid0XG4gIC8vIGVuZCB1cCBpbiBhbiBvdmVybGFwcGVkIG9ud3JpdGUgc2l0dWF0aW9uLlxuICB0aGlzLmJ1ZmZlclByb2Nlc3NpbmcgPSBmYWxzZTtcblxuICAvLyB0aGUgY2FsbGJhY2sgdGhhdCdzIHBhc3NlZCB0byBfd3JpdGUoY2h1bmssY2IpXG4gIHRoaXMub253cml0ZSA9IGZ1bmN0aW9uIChlcikge1xuICAgIG9ud3JpdGUoc3RyZWFtLCBlcik7XG4gIH07XG5cbiAgLy8gdGhlIGNhbGxiYWNrIHRoYXQgdGhlIHVzZXIgc3VwcGxpZXMgdG8gd3JpdGUoY2h1bmssZW5jb2RpbmcsY2IpXG4gIHRoaXMud3JpdGVjYiA9IG51bGw7XG5cbiAgLy8gdGhlIGFtb3VudCB0aGF0IGlzIGJlaW5nIHdyaXR0ZW4gd2hlbiBfd3JpdGUgaXMgY2FsbGVkLlxuICB0aGlzLndyaXRlbGVuID0gMDtcblxuICB0aGlzLmJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gIHRoaXMubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG5cbiAgLy8gbnVtYmVyIG9mIHBlbmRpbmcgdXNlci1zdXBwbGllZCB3cml0ZSBjYWxsYmFja3NcbiAgLy8gdGhpcyBtdXN0IGJlIDAgYmVmb3JlICdmaW5pc2gnIGNhbiBiZSBlbWl0dGVkXG4gIHRoaXMucGVuZGluZ2NiID0gMDtcblxuICAvLyBlbWl0IHByZWZpbmlzaCBpZiB0aGUgb25seSB0aGluZyB3ZSdyZSB3YWl0aW5nIGZvciBpcyBfd3JpdGUgY2JzXG4gIC8vIFRoaXMgaXMgcmVsZXZhbnQgZm9yIHN5bmNocm9ub3VzIFRyYW5zZm9ybSBzdHJlYW1zXG4gIHRoaXMucHJlZmluaXNoZWQgPSBmYWxzZTtcblxuICAvLyBUcnVlIGlmIHRoZSBlcnJvciB3YXMgYWxyZWFkeSBlbWl0dGVkIGFuZCBzaG91bGQgbm90IGJlIHRocm93biBhZ2FpblxuICB0aGlzLmVycm9yRW1pdHRlZCA9IGZhbHNlO1xuXG4gIC8vIGNvdW50IGJ1ZmZlcmVkIHJlcXVlc3RzXG4gIHRoaXMuYnVmZmVyZWRSZXF1ZXN0Q291bnQgPSAwO1xuXG4gIC8vIGFsbG9jYXRlIHRoZSBmaXJzdCBDb3JrZWRSZXF1ZXN0LCB0aGVyZSBpcyBhbHdheXNcbiAgLy8gb25lIGFsbG9jYXRlZCBhbmQgZnJlZSB0byB1c2UsIGFuZCB3ZSBtYWludGFpbiBhdCBtb3N0IHR3b1xuICB0aGlzLmNvcmtlZFJlcXVlc3RzRnJlZSA9IG5ldyBDb3JrZWRSZXF1ZXN0KHRoaXMpO1xufVxuXG5Xcml0YWJsZVN0YXRlLnByb3RvdHlwZS5nZXRCdWZmZXIgPSBmdW5jdGlvbiBnZXRCdWZmZXIoKSB7XG4gIHZhciBjdXJyZW50ID0gdGhpcy5idWZmZXJlZFJlcXVlc3Q7XG4gIHZhciBvdXQgPSBbXTtcbiAgd2hpbGUgKGN1cnJlbnQpIHtcbiAgICBvdXQucHVzaChjdXJyZW50KTtcbiAgICBjdXJyZW50ID0gY3VycmVudC5uZXh0O1xuICB9XG4gIHJldHVybiBvdXQ7XG59O1xuXG4oZnVuY3Rpb24gKCkge1xuICB0cnkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZVN0YXRlLnByb3RvdHlwZSwgJ2J1ZmZlcicsIHtcbiAgICAgIGdldDogaW50ZXJuYWxVdGlsLmRlcHJlY2F0ZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEJ1ZmZlcigpO1xuICAgICAgfSwgJ193cml0YWJsZVN0YXRlLmJ1ZmZlciBpcyBkZXByZWNhdGVkLiBVc2UgX3dyaXRhYmxlU3RhdGUuZ2V0QnVmZmVyICcgKyAnaW5zdGVhZC4nLCAnREVQMDAwMycpXG4gICAgfSk7XG4gIH0gY2F0Y2ggKF8pIHt9XG59KSgpO1xuXG4vLyBUZXN0IF93cml0YWJsZVN0YXRlIGZvciBpbmhlcml0YW5jZSB0byBhY2NvdW50IGZvciBEdXBsZXggc3RyZWFtcyxcbi8vIHdob3NlIHByb3RvdHlwZSBjaGFpbiBvbmx5IHBvaW50cyB0byBSZWFkYWJsZS5cbnZhciByZWFsSGFzSW5zdGFuY2U7XG5pZiAodHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiBTeW1ib2wuaGFzSW5zdGFuY2UgJiYgdHlwZW9mIEZ1bmN0aW9uLnByb3RvdHlwZVtTeW1ib2wuaGFzSW5zdGFuY2VdID09PSAnZnVuY3Rpb24nKSB7XG4gIHJlYWxIYXNJbnN0YW5jZSA9IEZ1bmN0aW9uLnByb3RvdHlwZVtTeW1ib2wuaGFzSW5zdGFuY2VdO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGUsIFN5bWJvbC5oYXNJbnN0YW5jZSwge1xuICAgIHZhbHVlOiBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgICBpZiAocmVhbEhhc0luc3RhbmNlLmNhbGwodGhpcywgb2JqZWN0KSkgcmV0dXJuIHRydWU7XG4gICAgICBpZiAodGhpcyAhPT0gV3JpdGFibGUpIHJldHVybiBmYWxzZTtcblxuICAgICAgcmV0dXJuIG9iamVjdCAmJiBvYmplY3QuX3dyaXRhYmxlU3RhdGUgaW5zdGFuY2VvZiBXcml0YWJsZVN0YXRlO1xuICAgIH1cbiAgfSk7XG59IGVsc2Uge1xuICByZWFsSGFzSW5zdGFuY2UgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIHRoaXM7XG4gIH07XG59XG5cbmZ1bmN0aW9uIFdyaXRhYmxlKG9wdGlvbnMpIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuICAvLyBXcml0YWJsZSBjdG9yIGlzIGFwcGxpZWQgdG8gRHVwbGV4ZXMsIHRvby5cbiAgLy8gYHJlYWxIYXNJbnN0YW5jZWAgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgdXNpbmcgcGxhaW4gYGluc3RhbmNlb2ZgXG4gIC8vIHdvdWxkIHJldHVybiBmYWxzZSwgYXMgbm8gYF93cml0YWJsZVN0YXRlYCBwcm9wZXJ0eSBpcyBhdHRhY2hlZC5cblxuICAvLyBUcnlpbmcgdG8gdXNlIHRoZSBjdXN0b20gYGluc3RhbmNlb2ZgIGZvciBXcml0YWJsZSBoZXJlIHdpbGwgYWxzbyBicmVhayB0aGVcbiAgLy8gTm9kZS5qcyBMYXp5VHJhbnNmb3JtIGltcGxlbWVudGF0aW9uLCB3aGljaCBoYXMgYSBub24tdHJpdmlhbCBnZXR0ZXIgZm9yXG4gIC8vIGBfd3JpdGFibGVTdGF0ZWAgdGhhdCB3b3VsZCBsZWFkIHRvIGluZmluaXRlIHJlY3Vyc2lvbi5cbiAgaWYgKCFyZWFsSGFzSW5zdGFuY2UuY2FsbChXcml0YWJsZSwgdGhpcykgJiYgISh0aGlzIGluc3RhbmNlb2YgRHVwbGV4KSkge1xuICAgIHJldHVybiBuZXcgV3JpdGFibGUob3B0aW9ucyk7XG4gIH1cblxuICB0aGlzLl93cml0YWJsZVN0YXRlID0gbmV3IFdyaXRhYmxlU3RhdGUob3B0aW9ucywgdGhpcyk7XG5cbiAgLy8gbGVnYWN5LlxuICB0aGlzLndyaXRhYmxlID0gdHJ1ZTtcblxuICBpZiAob3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy53cml0ZSA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fd3JpdGUgPSBvcHRpb25zLndyaXRlO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLndyaXRldiA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fd3JpdGV2ID0gb3B0aW9ucy53cml0ZXY7XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuZGVzdHJveSA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fZGVzdHJveSA9IG9wdGlvbnMuZGVzdHJveTtcblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5maW5hbCA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fZmluYWwgPSBvcHRpb25zLmZpbmFsO1xuICB9XG5cbiAgU3RyZWFtLmNhbGwodGhpcyk7XG59XG5cbi8vIE90aGVyd2lzZSBwZW9wbGUgY2FuIHBpcGUgV3JpdGFibGUgc3RyZWFtcywgd2hpY2ggaXMganVzdCB3cm9uZy5cbldyaXRhYmxlLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdDYW5ub3QgcGlwZSwgbm90IHJlYWRhYmxlJykpO1xufTtcblxuZnVuY3Rpb24gd3JpdGVBZnRlckVuZChzdHJlYW0sIGNiKSB7XG4gIHZhciBlciA9IG5ldyBFcnJvcignd3JpdGUgYWZ0ZXIgZW5kJyk7XG4gIC8vIFRPRE86IGRlZmVyIGVycm9yIGV2ZW50cyBjb25zaXN0ZW50bHkgZXZlcnl3aGVyZSwgbm90IGp1c3QgdGhlIGNiXG4gIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgcG5hLm5leHRUaWNrKGNiLCBlcik7XG59XG5cbi8vIENoZWNrcyB0aGF0IGEgdXNlci1zdXBwbGllZCBjaHVuayBpcyB2YWxpZCwgZXNwZWNpYWxseSBmb3IgdGhlIHBhcnRpY3VsYXJcbi8vIG1vZGUgdGhlIHN0cmVhbSBpcyBpbi4gQ3VycmVudGx5IHRoaXMgbWVhbnMgdGhhdCBgbnVsbGAgaXMgbmV2ZXIgYWNjZXB0ZWRcbi8vIGFuZCB1bmRlZmluZWQvbm9uLXN0cmluZyB2YWx1ZXMgYXJlIG9ubHkgYWxsb3dlZCBpbiBvYmplY3QgbW9kZS5cbmZ1bmN0aW9uIHZhbGlkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGNiKSB7XG4gIHZhciB2YWxpZCA9IHRydWU7XG4gIHZhciBlciA9IGZhbHNlO1xuXG4gIGlmIChjaHVuayA9PT0gbnVsbCkge1xuICAgIGVyID0gbmV3IFR5cGVFcnJvcignTWF5IG5vdCB3cml0ZSBudWxsIHZhbHVlcyB0byBzdHJlYW0nKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgY2h1bmsgIT09ICdzdHJpbmcnICYmIGNodW5rICE9PSB1bmRlZmluZWQgJiYgIXN0YXRlLm9iamVjdE1vZGUpIHtcbiAgICBlciA9IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbm9uLXN0cmluZy9idWZmZXIgY2h1bmsnKTtcbiAgfVxuICBpZiAoZXIpIHtcbiAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gICAgcG5hLm5leHRUaWNrKGNiLCBlcik7XG4gICAgdmFsaWQgPSBmYWxzZTtcbiAgfVxuICByZXR1cm4gdmFsaWQ7XG59XG5cbldyaXRhYmxlLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG4gIHZhciByZXQgPSBmYWxzZTtcbiAgdmFyIGlzQnVmID0gIXN0YXRlLm9iamVjdE1vZGUgJiYgX2lzVWludDhBcnJheShjaHVuayk7XG5cbiAgaWYgKGlzQnVmICYmICFCdWZmZXIuaXNCdWZmZXIoY2h1bmspKSB7XG4gICAgY2h1bmsgPSBfdWludDhBcnJheVRvQnVmZmVyKGNodW5rKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuXG4gIGlmIChpc0J1ZikgZW5jb2RpbmcgPSAnYnVmZmVyJztlbHNlIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gc3RhdGUuZGVmYXVsdEVuY29kaW5nO1xuXG4gIGlmICh0eXBlb2YgY2IgIT09ICdmdW5jdGlvbicpIGNiID0gbm9wO1xuXG4gIGlmIChzdGF0ZS5lbmRlZCkgd3JpdGVBZnRlckVuZCh0aGlzLCBjYik7ZWxzZSBpZiAoaXNCdWYgfHwgdmFsaWRDaHVuayh0aGlzLCBzdGF0ZSwgY2h1bmssIGNiKSkge1xuICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgIHJldCA9IHdyaXRlT3JCdWZmZXIodGhpcywgc3RhdGUsIGlzQnVmLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuY29yayA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBzdGF0ZS5jb3JrZWQrKztcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS51bmNvcmsgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG5cbiAgaWYgKHN0YXRlLmNvcmtlZCkge1xuICAgIHN0YXRlLmNvcmtlZC0tO1xuXG4gICAgaWYgKCFzdGF0ZS53cml0aW5nICYmICFzdGF0ZS5jb3JrZWQgJiYgIXN0YXRlLmZpbmlzaGVkICYmICFzdGF0ZS5idWZmZXJQcm9jZXNzaW5nICYmIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCkgY2xlYXJCdWZmZXIodGhpcywgc3RhdGUpO1xuICB9XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuc2V0RGVmYXVsdEVuY29kaW5nID0gZnVuY3Rpb24gc2V0RGVmYXVsdEVuY29kaW5nKGVuY29kaW5nKSB7XG4gIC8vIG5vZGU6OlBhcnNlRW5jb2RpbmcoKSByZXF1aXJlcyBsb3dlciBjYXNlLlxuICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJykgZW5jb2RpbmcgPSBlbmNvZGluZy50b0xvd2VyQ2FzZSgpO1xuICBpZiAoIShbJ2hleCcsICd1dGY4JywgJ3V0Zi04JywgJ2FzY2lpJywgJ2JpbmFyeScsICdiYXNlNjQnLCAndWNzMicsICd1Y3MtMicsICd1dGYxNmxlJywgJ3V0Zi0xNmxlJywgJ3JhdyddLmluZGV4T2YoKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKCkpID4gLTEpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpO1xuICB0aGlzLl93cml0YWJsZVN0YXRlLmRlZmF1bHRFbmNvZGluZyA9IGVuY29kaW5nO1xuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIGRlY29kZUNodW5rKHN0YXRlLCBjaHVuaywgZW5jb2RpbmcpIHtcbiAgaWYgKCFzdGF0ZS5vYmplY3RNb2RlICYmIHN0YXRlLmRlY29kZVN0cmluZ3MgIT09IGZhbHNlICYmIHR5cGVvZiBjaHVuayA9PT0gJ3N0cmluZycpIHtcbiAgICBjaHVuayA9IEJ1ZmZlci5mcm9tKGNodW5rLCBlbmNvZGluZyk7XG4gIH1cbiAgcmV0dXJuIGNodW5rO1xufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGUucHJvdG90eXBlLCAnd3JpdGFibGVIaWdoV2F0ZXJNYXJrJywge1xuICAvLyBtYWtpbmcgaXQgZXhwbGljaXQgdGhpcyBwcm9wZXJ0eSBpcyBub3QgZW51bWVyYWJsZVxuICAvLyBiZWNhdXNlIG90aGVyd2lzZSBzb21lIHByb3RvdHlwZSBtYW5pcHVsYXRpb24gaW5cbiAgLy8gdXNlcmxhbmQgd2lsbCBmYWlsXG4gIGVudW1lcmFibGU6IGZhbHNlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5fd3JpdGFibGVTdGF0ZS5oaWdoV2F0ZXJNYXJrO1xuICB9XG59KTtcblxuLy8gaWYgd2UncmUgYWxyZWFkeSB3cml0aW5nIHNvbWV0aGluZywgdGhlbiBqdXN0IHB1dCB0aGlzXG4vLyBpbiB0aGUgcXVldWUsIGFuZCB3YWl0IG91ciB0dXJuLiAgT3RoZXJ3aXNlLCBjYWxsIF93cml0ZVxuLy8gSWYgd2UgcmV0dXJuIGZhbHNlLCB0aGVuIHdlIG5lZWQgYSBkcmFpbiBldmVudCwgc28gc2V0IHRoYXQgZmxhZy5cbmZ1bmN0aW9uIHdyaXRlT3JCdWZmZXIoc3RyZWFtLCBzdGF0ZSwgaXNCdWYsIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgaWYgKCFpc0J1Zikge1xuICAgIHZhciBuZXdDaHVuayA9IGRlY29kZUNodW5rKHN0YXRlLCBjaHVuaywgZW5jb2RpbmcpO1xuICAgIGlmIChjaHVuayAhPT0gbmV3Q2h1bmspIHtcbiAgICAgIGlzQnVmID0gdHJ1ZTtcbiAgICAgIGVuY29kaW5nID0gJ2J1ZmZlcic7XG4gICAgICBjaHVuayA9IG5ld0NodW5rO1xuICAgIH1cbiAgfVxuICB2YXIgbGVuID0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG5cbiAgc3RhdGUubGVuZ3RoICs9IGxlbjtcblxuICB2YXIgcmV0ID0gc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgLy8gd2UgbXVzdCBlbnN1cmUgdGhhdCBwcmV2aW91cyBuZWVkRHJhaW4gd2lsbCBub3QgYmUgcmVzZXQgdG8gZmFsc2UuXG4gIGlmICghcmV0KSBzdGF0ZS5uZWVkRHJhaW4gPSB0cnVlO1xuXG4gIGlmIChzdGF0ZS53cml0aW5nIHx8IHN0YXRlLmNvcmtlZCkge1xuICAgIHZhciBsYXN0ID0gc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtcbiAgICBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0ge1xuICAgICAgY2h1bms6IGNodW5rLFxuICAgICAgZW5jb2Rpbmc6IGVuY29kaW5nLFxuICAgICAgaXNCdWY6IGlzQnVmLFxuICAgICAgY2FsbGJhY2s6IGNiLFxuICAgICAgbmV4dDogbnVsbFxuICAgIH07XG4gICAgaWYgKGxhc3QpIHtcbiAgICAgIGxhc3QubmV4dCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgfVxuICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50ICs9IDE7XG4gIH0gZWxzZSB7XG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBmYWxzZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgd3JpdGV2LCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgc3RhdGUud3JpdGVsZW4gPSBsZW47XG4gIHN0YXRlLndyaXRlY2IgPSBjYjtcbiAgc3RhdGUud3JpdGluZyA9IHRydWU7XG4gIHN0YXRlLnN5bmMgPSB0cnVlO1xuICBpZiAod3JpdGV2KSBzdHJlYW0uX3dyaXRldihjaHVuaywgc3RhdGUub253cml0ZSk7ZWxzZSBzdHJlYW0uX3dyaXRlKGNodW5rLCBlbmNvZGluZywgc3RhdGUub253cml0ZSk7XG4gIHN0YXRlLnN5bmMgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gb253cml0ZUVycm9yKHN0cmVhbSwgc3RhdGUsIHN5bmMsIGVyLCBjYikge1xuICAtLXN0YXRlLnBlbmRpbmdjYjtcblxuICBpZiAoc3luYykge1xuICAgIC8vIGRlZmVyIHRoZSBjYWxsYmFjayBpZiB3ZSBhcmUgYmVpbmcgY2FsbGVkIHN5bmNocm9ub3VzbHlcbiAgICAvLyB0byBhdm9pZCBwaWxpbmcgdXAgdGhpbmdzIG9uIHRoZSBzdGFja1xuICAgIHBuYS5uZXh0VGljayhjYiwgZXIpO1xuICAgIC8vIHRoaXMgY2FuIGVtaXQgZmluaXNoLCBhbmQgaXQgd2lsbCBhbHdheXMgaGFwcGVuXG4gICAgLy8gYWZ0ZXIgZXJyb3JcbiAgICBwbmEubmV4dFRpY2soZmluaXNoTWF5YmUsIHN0cmVhbSwgc3RhdGUpO1xuICAgIHN0cmVhbS5fd3JpdGFibGVTdGF0ZS5lcnJvckVtaXR0ZWQgPSB0cnVlO1xuICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgfSBlbHNlIHtcbiAgICAvLyB0aGUgY2FsbGVyIGV4cGVjdCB0aGlzIHRvIGhhcHBlbiBiZWZvcmUgaWZcbiAgICAvLyBpdCBpcyBhc3luY1xuICAgIGNiKGVyKTtcbiAgICBzdHJlYW0uX3dyaXRhYmxlU3RhdGUuZXJyb3JFbWl0dGVkID0gdHJ1ZTtcbiAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gICAgLy8gdGhpcyBjYW4gZW1pdCBmaW5pc2gsIGJ1dCBmaW5pc2ggbXVzdFxuICAgIC8vIGFsd2F5cyBmb2xsb3cgZXJyb3JcbiAgICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpIHtcbiAgc3RhdGUud3JpdGluZyA9IGZhbHNlO1xuICBzdGF0ZS53cml0ZWNiID0gbnVsbDtcbiAgc3RhdGUubGVuZ3RoIC09IHN0YXRlLndyaXRlbGVuO1xuICBzdGF0ZS53cml0ZWxlbiA9IDA7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGUoc3RyZWFtLCBlcikge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3dyaXRhYmxlU3RhdGU7XG4gIHZhciBzeW5jID0gc3RhdGUuc3luYztcbiAgdmFyIGNiID0gc3RhdGUud3JpdGVjYjtcblxuICBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpO1xuXG4gIGlmIChlcikgb253cml0ZUVycm9yKHN0cmVhbSwgc3RhdGUsIHN5bmMsIGVyLCBjYik7ZWxzZSB7XG4gICAgLy8gQ2hlY2sgaWYgd2UncmUgYWN0dWFsbHkgcmVhZHkgdG8gZmluaXNoLCBidXQgZG9uJ3QgZW1pdCB5ZXRcbiAgICB2YXIgZmluaXNoZWQgPSBuZWVkRmluaXNoKHN0YXRlKTtcblxuICAgIGlmICghZmluaXNoZWQgJiYgIXN0YXRlLmNvcmtlZCAmJiAhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QpIHtcbiAgICAgIGNsZWFyQnVmZmVyKHN0cmVhbSwgc3RhdGUpO1xuICAgIH1cblxuICAgIGlmIChzeW5jKSB7XG4gICAgICAvKjxyZXBsYWNlbWVudD4qL1xuICAgICAgYXN5bmNXcml0ZShhZnRlcldyaXRlLCBzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpO1xuICAgICAgLyo8L3JlcGxhY2VtZW50PiovXG4gICAgfSBlbHNlIHtcbiAgICAgIGFmdGVyV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpIHtcbiAgaWYgKCFmaW5pc2hlZCkgb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpO1xuICBzdGF0ZS5wZW5kaW5nY2ItLTtcbiAgY2IoKTtcbiAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG59XG5cbi8vIE11c3QgZm9yY2UgY2FsbGJhY2sgdG8gYmUgY2FsbGVkIG9uIG5leHRUaWNrLCBzbyB0aGF0IHdlIGRvbid0XG4vLyBlbWl0ICdkcmFpbicgYmVmb3JlIHRoZSB3cml0ZSgpIGNvbnN1bWVyIGdldHMgdGhlICdmYWxzZScgcmV0dXJuXG4vLyB2YWx1ZSwgYW5kIGhhcyBhIGNoYW5jZSB0byBhdHRhY2ggYSAnZHJhaW4nIGxpc3RlbmVyLlxuZnVuY3Rpb24gb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5uZWVkRHJhaW4pIHtcbiAgICBzdGF0ZS5uZWVkRHJhaW4gPSBmYWxzZTtcbiAgICBzdHJlYW0uZW1pdCgnZHJhaW4nKTtcbiAgfVxufVxuXG4vLyBpZiB0aGVyZSdzIHNvbWV0aGluZyBpbiB0aGUgYnVmZmVyIHdhaXRpbmcsIHRoZW4gcHJvY2VzcyBpdFxuZnVuY3Rpb24gY2xlYXJCdWZmZXIoc3RyZWFtLCBzdGF0ZSkge1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gdHJ1ZTtcbiAgdmFyIGVudHJ5ID0gc3RhdGUuYnVmZmVyZWRSZXF1ZXN0O1xuXG4gIGlmIChzdHJlYW0uX3dyaXRldiAmJiBlbnRyeSAmJiBlbnRyeS5uZXh0KSB7XG4gICAgLy8gRmFzdCBjYXNlLCB3cml0ZSBldmVyeXRoaW5nIHVzaW5nIF93cml0ZXYoKVxuICAgIHZhciBsID0gc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQ7XG4gICAgdmFyIGJ1ZmZlciA9IG5ldyBBcnJheShsKTtcbiAgICB2YXIgaG9sZGVyID0gc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlO1xuICAgIGhvbGRlci5lbnRyeSA9IGVudHJ5O1xuXG4gICAgdmFyIGNvdW50ID0gMDtcbiAgICB2YXIgYWxsQnVmZmVycyA9IHRydWU7XG4gICAgd2hpbGUgKGVudHJ5KSB7XG4gICAgICBidWZmZXJbY291bnRdID0gZW50cnk7XG4gICAgICBpZiAoIWVudHJ5LmlzQnVmKSBhbGxCdWZmZXJzID0gZmFsc2U7XG4gICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7XG4gICAgICBjb3VudCArPSAxO1xuICAgIH1cbiAgICBidWZmZXIuYWxsQnVmZmVycyA9IGFsbEJ1ZmZlcnM7XG5cbiAgICBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIHRydWUsIHN0YXRlLmxlbmd0aCwgYnVmZmVyLCAnJywgaG9sZGVyLmZpbmlzaCk7XG5cbiAgICAvLyBkb1dyaXRlIGlzIGFsbW9zdCBhbHdheXMgYXN5bmMsIGRlZmVyIHRoZXNlIHRvIHNhdmUgYSBiaXQgb2YgdGltZVxuICAgIC8vIGFzIHRoZSBob3QgcGF0aCBlbmRzIHdpdGggZG9Xcml0ZVxuICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuICAgIGlmIChob2xkZXIubmV4dCkge1xuICAgICAgc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlID0gaG9sZGVyLm5leHQ7XG4gICAgICBob2xkZXIubmV4dCA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZSA9IG5ldyBDb3JrZWRSZXF1ZXN0KHN0YXRlKTtcbiAgICB9XG4gICAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQgPSAwO1xuICB9IGVsc2Uge1xuICAgIC8vIFNsb3cgY2FzZSwgd3JpdGUgY2h1bmtzIG9uZS1ieS1vbmVcbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIHZhciBjaHVuayA9IGVudHJ5LmNodW5rO1xuICAgICAgdmFyIGVuY29kaW5nID0gZW50cnkuZW5jb2Rpbmc7XG4gICAgICB2YXIgY2IgPSBlbnRyeS5jYWxsYmFjaztcbiAgICAgIHZhciBsZW4gPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcblxuICAgICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBmYWxzZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgICAgIGVudHJ5ID0gZW50cnkubmV4dDtcbiAgICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50LS07XG4gICAgICAvLyBpZiB3ZSBkaWRuJ3QgY2FsbCB0aGUgb253cml0ZSBpbW1lZGlhdGVseSwgdGhlblxuICAgICAgLy8gaXQgbWVhbnMgdGhhdCB3ZSBuZWVkIHRvIHdhaXQgdW50aWwgaXQgZG9lcy5cbiAgICAgIC8vIGFsc28sIHRoYXQgbWVhbnMgdGhhdCB0aGUgY2h1bmsgYW5kIGNiIGFyZSBjdXJyZW50bHlcbiAgICAgIC8vIGJlaW5nIHByb2Nlc3NlZCwgc28gbW92ZSB0aGUgYnVmZmVyIGNvdW50ZXIgcGFzdCB0aGVtLlxuICAgICAgaWYgKHN0YXRlLndyaXRpbmcpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVudHJ5ID09PSBudWxsKSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcbiAgfVxuXG4gIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9IGVudHJ5O1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gZmFsc2U7XG59XG5cbldyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjYihuZXcgRXJyb3IoJ193cml0ZSgpIGlzIG5vdCBpbXBsZW1lbnRlZCcpKTtcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGV2ID0gbnVsbDtcblxuV3JpdGFibGUucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG5cbiAgaWYgKHR5cGVvZiBjaHVuayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gY2h1bms7XG4gICAgY2h1bmsgPSBudWxsO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuXG4gIGlmIChjaHVuayAhPT0gbnVsbCAmJiBjaHVuayAhPT0gdW5kZWZpbmVkKSB0aGlzLndyaXRlKGNodW5rLCBlbmNvZGluZyk7XG5cbiAgLy8gLmVuZCgpIGZ1bGx5IHVuY29ya3NcbiAgaWYgKHN0YXRlLmNvcmtlZCkge1xuICAgIHN0YXRlLmNvcmtlZCA9IDE7XG4gICAgdGhpcy51bmNvcmsoKTtcbiAgfVxuXG4gIC8vIGlnbm9yZSB1bm5lY2Vzc2FyeSBlbmQoKSBjYWxscy5cbiAgaWYgKCFzdGF0ZS5lbmRpbmcgJiYgIXN0YXRlLmZpbmlzaGVkKSBlbmRXcml0YWJsZSh0aGlzLCBzdGF0ZSwgY2IpO1xufTtcblxuZnVuY3Rpb24gbmVlZEZpbmlzaChzdGF0ZSkge1xuICByZXR1cm4gc3RhdGUuZW5kaW5nICYmIHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QgPT09IG51bGwgJiYgIXN0YXRlLmZpbmlzaGVkICYmICFzdGF0ZS53cml0aW5nO1xufVxuZnVuY3Rpb24gY2FsbEZpbmFsKHN0cmVhbSwgc3RhdGUpIHtcbiAgc3RyZWFtLl9maW5hbChmdW5jdGlvbiAoZXJyKSB7XG4gICAgc3RhdGUucGVuZGluZ2NiLS07XG4gICAgaWYgKGVycikge1xuICAgICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICB9XG4gICAgc3RhdGUucHJlZmluaXNoZWQgPSB0cnVlO1xuICAgIHN0cmVhbS5lbWl0KCdwcmVmaW5pc2gnKTtcbiAgICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbiAgfSk7XG59XG5mdW5jdGlvbiBwcmVmaW5pc2goc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnByZWZpbmlzaGVkICYmICFzdGF0ZS5maW5hbENhbGxlZCkge1xuICAgIGlmICh0eXBlb2Ygc3RyZWFtLl9maW5hbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgc3RhdGUucGVuZGluZ2NiKys7XG4gICAgICBzdGF0ZS5maW5hbENhbGxlZCA9IHRydWU7XG4gICAgICBwbmEubmV4dFRpY2soY2FsbEZpbmFsLCBzdHJlYW0sIHN0YXRlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUucHJlZmluaXNoZWQgPSB0cnVlO1xuICAgICAgc3RyZWFtLmVtaXQoJ3ByZWZpbmlzaCcpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKSB7XG4gIHZhciBuZWVkID0gbmVlZEZpbmlzaChzdGF0ZSk7XG4gIGlmIChuZWVkKSB7XG4gICAgcHJlZmluaXNoKHN0cmVhbSwgc3RhdGUpO1xuICAgIGlmIChzdGF0ZS5wZW5kaW5nY2IgPT09IDApIHtcbiAgICAgIHN0YXRlLmZpbmlzaGVkID0gdHJ1ZTtcbiAgICAgIHN0cmVhbS5lbWl0KCdmaW5pc2gnKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5lZWQ7XG59XG5cbmZ1bmN0aW9uIGVuZFdyaXRhYmxlKHN0cmVhbSwgc3RhdGUsIGNiKSB7XG4gIHN0YXRlLmVuZGluZyA9IHRydWU7XG4gIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpO1xuICBpZiAoY2IpIHtcbiAgICBpZiAoc3RhdGUuZmluaXNoZWQpIHBuYS5uZXh0VGljayhjYik7ZWxzZSBzdHJlYW0ub25jZSgnZmluaXNoJywgY2IpO1xuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbiAgc3RyZWFtLndyaXRhYmxlID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIG9uQ29ya2VkRmluaXNoKGNvcmtSZXEsIHN0YXRlLCBlcnIpIHtcbiAgdmFyIGVudHJ5ID0gY29ya1JlcS5lbnRyeTtcbiAgY29ya1JlcS5lbnRyeSA9IG51bGw7XG4gIHdoaWxlIChlbnRyeSkge1xuICAgIHZhciBjYiA9IGVudHJ5LmNhbGxiYWNrO1xuICAgIHN0YXRlLnBlbmRpbmdjYi0tO1xuICAgIGNiKGVycik7XG4gICAgZW50cnkgPSBlbnRyeS5uZXh0O1xuICB9XG4gIGlmIChzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUpIHtcbiAgICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUubmV4dCA9IGNvcmtSZXE7XG4gIH0gZWxzZSB7XG4gICAgc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlID0gY29ya1JlcTtcbiAgfVxufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGUucHJvdG90eXBlLCAnZGVzdHJveWVkJywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5fd3JpdGFibGVTdGF0ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZDtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAvLyB3ZSBpZ25vcmUgdGhlIHZhbHVlIGlmIHRoZSBzdHJlYW1cbiAgICAvLyBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQgeWV0XG4gICAgaWYgKCF0aGlzLl93cml0YWJsZVN0YXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdGhlIHVzZXIgaXMgZXhwbGljaXRseVxuICAgIC8vIG1hbmFnaW5nIGRlc3Ryb3llZFxuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkID0gdmFsdWU7XG4gIH1cbn0pO1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuZGVzdHJveSA9IGRlc3Ryb3lJbXBsLmRlc3Ryb3k7XG5Xcml0YWJsZS5wcm90b3R5cGUuX3VuZGVzdHJveSA9IGRlc3Ryb3lJbXBsLnVuZGVzdHJveTtcbldyaXRhYmxlLnByb3RvdHlwZS5fZGVzdHJveSA9IGZ1bmN0aW9uIChlcnIsIGNiKSB7XG4gIHRoaXMuZW5kKCk7XG4gIGNiKGVycik7XG59OyIsIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cbmZ1bmN0aW9uIGNvcHlCdWZmZXIoc3JjLCB0YXJnZXQsIG9mZnNldCkge1xuICBzcmMuY29weSh0YXJnZXQsIG9mZnNldCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBCdWZmZXJMaXN0KCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBCdWZmZXJMaXN0KTtcblxuICAgIHRoaXMuaGVhZCA9IG51bGw7XG4gICAgdGhpcy50YWlsID0gbnVsbDtcbiAgICB0aGlzLmxlbmd0aCA9IDA7XG4gIH1cblxuICBCdWZmZXJMaXN0LnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24gcHVzaCh2KSB7XG4gICAgdmFyIGVudHJ5ID0geyBkYXRhOiB2LCBuZXh0OiBudWxsIH07XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gMCkgdGhpcy50YWlsLm5leHQgPSBlbnRyeTtlbHNlIHRoaXMuaGVhZCA9IGVudHJ5O1xuICAgIHRoaXMudGFpbCA9IGVudHJ5O1xuICAgICsrdGhpcy5sZW5ndGg7XG4gIH07XG5cbiAgQnVmZmVyTGlzdC5wcm90b3R5cGUudW5zaGlmdCA9IGZ1bmN0aW9uIHVuc2hpZnQodikge1xuICAgIHZhciBlbnRyeSA9IHsgZGF0YTogdiwgbmV4dDogdGhpcy5oZWFkIH07XG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSB0aGlzLnRhaWwgPSBlbnRyeTtcbiAgICB0aGlzLmhlYWQgPSBlbnRyeTtcbiAgICArK3RoaXMubGVuZ3RoO1xuICB9O1xuXG4gIEJ1ZmZlckxpc3QucHJvdG90eXBlLnNoaWZ0ID0gZnVuY3Rpb24gc2hpZnQoKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgdmFyIHJldCA9IHRoaXMuaGVhZC5kYXRhO1xuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMSkgdGhpcy5oZWFkID0gdGhpcy50YWlsID0gbnVsbDtlbHNlIHRoaXMuaGVhZCA9IHRoaXMuaGVhZC5uZXh0O1xuICAgIC0tdGhpcy5sZW5ndGg7XG4gICAgcmV0dXJuIHJldDtcbiAgfTtcblxuICBCdWZmZXJMaXN0LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uIGNsZWFyKCkge1xuICAgIHRoaXMuaGVhZCA9IHRoaXMudGFpbCA9IG51bGw7XG4gICAgdGhpcy5sZW5ndGggPSAwO1xuICB9O1xuXG4gIEJ1ZmZlckxpc3QucHJvdG90eXBlLmpvaW4gPSBmdW5jdGlvbiBqb2luKHMpIHtcbiAgICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybiAnJztcbiAgICB2YXIgcCA9IHRoaXMuaGVhZDtcbiAgICB2YXIgcmV0ID0gJycgKyBwLmRhdGE7XG4gICAgd2hpbGUgKHAgPSBwLm5leHQpIHtcbiAgICAgIHJldCArPSBzICsgcC5kYXRhO1xuICAgIH1yZXR1cm4gcmV0O1xuICB9O1xuXG4gIEJ1ZmZlckxpc3QucHJvdG90eXBlLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdChuKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gQnVmZmVyLmFsbG9jKDApO1xuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIHRoaXMuaGVhZC5kYXRhO1xuICAgIHZhciByZXQgPSBCdWZmZXIuYWxsb2NVbnNhZmUobiA+Pj4gMCk7XG4gICAgdmFyIHAgPSB0aGlzLmhlYWQ7XG4gICAgdmFyIGkgPSAwO1xuICAgIHdoaWxlIChwKSB7XG4gICAgICBjb3B5QnVmZmVyKHAuZGF0YSwgcmV0LCBpKTtcbiAgICAgIGkgKz0gcC5kYXRhLmxlbmd0aDtcbiAgICAgIHAgPSBwLm5leHQ7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG4gIH07XG5cbiAgcmV0dXJuIEJ1ZmZlckxpc3Q7XG59KCk7XG5cbmlmICh1dGlsICYmIHV0aWwuaW5zcGVjdCAmJiB1dGlsLmluc3BlY3QuY3VzdG9tKSB7XG4gIG1vZHVsZS5leHBvcnRzLnByb3RvdHlwZVt1dGlsLmluc3BlY3QuY3VzdG9tXSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgb2JqID0gdXRpbC5pbnNwZWN0KHsgbGVuZ3RoOiB0aGlzLmxlbmd0aCB9KTtcbiAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci5uYW1lICsgJyAnICsgb2JqO1xuICB9O1xufSIsIid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIHBuYSA9IHJlcXVpcmUoJ3Byb2Nlc3MtbmV4dGljay1hcmdzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLy8gdW5kb2N1bWVudGVkIGNiKCkgQVBJLCBuZWVkZWQgZm9yIGNvcmUsIG5vdCBmb3IgcHVibGljIEFQSVxuZnVuY3Rpb24gZGVzdHJveShlcnIsIGNiKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgdmFyIHJlYWRhYmxlRGVzdHJveWVkID0gdGhpcy5fcmVhZGFibGVTdGF0ZSAmJiB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZDtcbiAgdmFyIHdyaXRhYmxlRGVzdHJveWVkID0gdGhpcy5fd3JpdGFibGVTdGF0ZSAmJiB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZDtcblxuICBpZiAocmVhZGFibGVEZXN0cm95ZWQgfHwgd3JpdGFibGVEZXN0cm95ZWQpIHtcbiAgICBpZiAoY2IpIHtcbiAgICAgIGNiKGVycik7XG4gICAgfSBlbHNlIGlmIChlcnIgJiYgKCF0aGlzLl93cml0YWJsZVN0YXRlIHx8ICF0aGlzLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCkpIHtcbiAgICAgIHBuYS5uZXh0VGljayhlbWl0RXJyb3JOVCwgdGhpcywgZXJyKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyB3ZSBzZXQgZGVzdHJveWVkIHRvIHRydWUgYmVmb3JlIGZpcmluZyBlcnJvciBjYWxsYmFja3MgaW4gb3JkZXJcbiAgLy8gdG8gbWFrZSBpdCByZS1lbnRyYW5jZSBzYWZlIGluIGNhc2UgZGVzdHJveSgpIGlzIGNhbGxlZCB3aXRoaW4gY2FsbGJhY2tzXG5cbiAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUpIHtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZCA9IHRydWU7XG4gIH1cblxuICAvLyBpZiB0aGlzIGlzIGEgZHVwbGV4IHN0cmVhbSBtYXJrIHRoZSB3cml0YWJsZSBwYXJ0IGFzIGRlc3Ryb3llZCBhcyB3ZWxsXG4gIGlmICh0aGlzLl93cml0YWJsZVN0YXRlKSB7XG4gICAgdGhpcy5fd3JpdGFibGVTdGF0ZS5kZXN0cm95ZWQgPSB0cnVlO1xuICB9XG5cbiAgdGhpcy5fZGVzdHJveShlcnIgfHwgbnVsbCwgZnVuY3Rpb24gKGVycikge1xuICAgIGlmICghY2IgJiYgZXJyKSB7XG4gICAgICBwbmEubmV4dFRpY2soZW1pdEVycm9yTlQsIF90aGlzLCBlcnIpO1xuICAgICAgaWYgKF90aGlzLl93cml0YWJsZVN0YXRlKSB7XG4gICAgICAgIF90aGlzLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjYikge1xuICAgICAgY2IoZXJyKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiB0aGlzO1xufVxuXG5mdW5jdGlvbiB1bmRlc3Ryb3koKSB7XG4gIGlmICh0aGlzLl9yZWFkYWJsZVN0YXRlKSB7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmVuZGVkID0gZmFsc2U7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5lbmRFbWl0dGVkID0gZmFsc2U7XG4gIH1cblxuICBpZiAodGhpcy5fd3JpdGFibGVTdGF0ZSkge1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgdGhpcy5fd3JpdGFibGVTdGF0ZS5lbmRlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZW5kaW5nID0gZmFsc2U7XG4gICAgdGhpcy5fd3JpdGFibGVTdGF0ZS5maW5pc2hlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZXJyb3JFbWl0dGVkID0gZmFsc2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW1pdEVycm9yTlQoc2VsZiwgZXJyKSB7XG4gIHNlbGYuZW1pdCgnZXJyb3InLCBlcnIpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZGVzdHJveTogZGVzdHJveSxcbiAgdW5kZXN0cm95OiB1bmRlc3Ryb3lcbn07IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vcmVhZGFibGUnKS5QYXNzVGhyb3VnaFxuIiwiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV9yZWFkYWJsZS5qcycpO1xuZXhwb3J0cy5TdHJlYW0gPSBleHBvcnRzO1xuZXhwb3J0cy5SZWFkYWJsZSA9IGV4cG9ydHM7XG5leHBvcnRzLldyaXRhYmxlID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV93cml0YWJsZS5qcycpO1xuZXhwb3J0cy5EdXBsZXggPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX2R1cGxleC5qcycpO1xuZXhwb3J0cy5UcmFuc2Zvcm0gPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qcycpO1xuZXhwb3J0cy5QYXNzVGhyb3VnaCA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanMnKTtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9yZWFkYWJsZScpLlRyYW5zZm9ybVxuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzJyk7XG4iLCIndXNlIHN0cmljdCdcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXJcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBIYXNoQmFzZSA9IHJlcXVpcmUoJ2hhc2gtYmFzZScpXG5cbnZhciBBUlJBWTE2ID0gbmV3IEFycmF5KDE2KVxuXG52YXIgemwgPSBbXG4gIDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsXG4gIDcsIDQsIDEzLCAxLCAxMCwgNiwgMTUsIDMsIDEyLCAwLCA5LCA1LCAyLCAxNCwgMTEsIDgsXG4gIDMsIDEwLCAxNCwgNCwgOSwgMTUsIDgsIDEsIDIsIDcsIDAsIDYsIDEzLCAxMSwgNSwgMTIsXG4gIDEsIDksIDExLCAxMCwgMCwgOCwgMTIsIDQsIDEzLCAzLCA3LCAxNSwgMTQsIDUsIDYsIDIsXG4gIDQsIDAsIDUsIDksIDcsIDEyLCAyLCAxMCwgMTQsIDEsIDMsIDgsIDExLCA2LCAxNSwgMTNcbl1cblxudmFyIHpyID0gW1xuICA1LCAxNCwgNywgMCwgOSwgMiwgMTEsIDQsIDEzLCA2LCAxNSwgOCwgMSwgMTAsIDMsIDEyLFxuICA2LCAxMSwgMywgNywgMCwgMTMsIDUsIDEwLCAxNCwgMTUsIDgsIDEyLCA0LCA5LCAxLCAyLFxuICAxNSwgNSwgMSwgMywgNywgMTQsIDYsIDksIDExLCA4LCAxMiwgMiwgMTAsIDAsIDQsIDEzLFxuICA4LCA2LCA0LCAxLCAzLCAxMSwgMTUsIDAsIDUsIDEyLCAyLCAxMywgOSwgNywgMTAsIDE0LFxuICAxMiwgMTUsIDEwLCA0LCAxLCA1LCA4LCA3LCA2LCAyLCAxMywgMTQsIDAsIDMsIDksIDExXG5dXG5cbnZhciBzbCA9IFtcbiAgMTEsIDE0LCAxNSwgMTIsIDUsIDgsIDcsIDksIDExLCAxMywgMTQsIDE1LCA2LCA3LCA5LCA4LFxuICA3LCA2LCA4LCAxMywgMTEsIDksIDcsIDE1LCA3LCAxMiwgMTUsIDksIDExLCA3LCAxMywgMTIsXG4gIDExLCAxMywgNiwgNywgMTQsIDksIDEzLCAxNSwgMTQsIDgsIDEzLCA2LCA1LCAxMiwgNywgNSxcbiAgMTEsIDEyLCAxNCwgMTUsIDE0LCAxNSwgOSwgOCwgOSwgMTQsIDUsIDYsIDgsIDYsIDUsIDEyLFxuICA5LCAxNSwgNSwgMTEsIDYsIDgsIDEzLCAxMiwgNSwgMTIsIDEzLCAxNCwgMTEsIDgsIDUsIDZcbl1cblxudmFyIHNyID0gW1xuICA4LCA5LCA5LCAxMSwgMTMsIDE1LCAxNSwgNSwgNywgNywgOCwgMTEsIDE0LCAxNCwgMTIsIDYsXG4gIDksIDEzLCAxNSwgNywgMTIsIDgsIDksIDExLCA3LCA3LCAxMiwgNywgNiwgMTUsIDEzLCAxMSxcbiAgOSwgNywgMTUsIDExLCA4LCA2LCA2LCAxNCwgMTIsIDEzLCA1LCAxNCwgMTMsIDEzLCA3LCA1LFxuICAxNSwgNSwgOCwgMTEsIDE0LCAxNCwgNiwgMTQsIDYsIDksIDEyLCA5LCAxMiwgNSwgMTUsIDgsXG4gIDgsIDUsIDEyLCA5LCAxMiwgNSwgMTQsIDYsIDgsIDEzLCA2LCA1LCAxNSwgMTMsIDExLCAxMVxuXVxuXG52YXIgaGwgPSBbMHgwMDAwMDAwMCwgMHg1YTgyNzk5OSwgMHg2ZWQ5ZWJhMSwgMHg4ZjFiYmNkYywgMHhhOTUzZmQ0ZV1cbnZhciBociA9IFsweDUwYTI4YmU2LCAweDVjNGRkMTI0LCAweDZkNzAzZWYzLCAweDdhNmQ3NmU5LCAweDAwMDAwMDAwXVxuXG5mdW5jdGlvbiBSSVBFTUQxNjAgKCkge1xuICBIYXNoQmFzZS5jYWxsKHRoaXMsIDY0KVxuXG4gIC8vIHN0YXRlXG4gIHRoaXMuX2EgPSAweDY3NDUyMzAxXG4gIHRoaXMuX2IgPSAweGVmY2RhYjg5XG4gIHRoaXMuX2MgPSAweDk4YmFkY2ZlXG4gIHRoaXMuX2QgPSAweDEwMzI1NDc2XG4gIHRoaXMuX2UgPSAweGMzZDJlMWYwXG59XG5cbmluaGVyaXRzKFJJUEVNRDE2MCwgSGFzaEJhc2UpXG5cblJJUEVNRDE2MC5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHdvcmRzID0gQVJSQVkxNlxuICBmb3IgKHZhciBqID0gMDsgaiA8IDE2OyArK2opIHdvcmRzW2pdID0gdGhpcy5fYmxvY2sucmVhZEludDMyTEUoaiAqIDQpXG5cbiAgdmFyIGFsID0gdGhpcy5fYSB8IDBcbiAgdmFyIGJsID0gdGhpcy5fYiB8IDBcbiAgdmFyIGNsID0gdGhpcy5fYyB8IDBcbiAgdmFyIGRsID0gdGhpcy5fZCB8IDBcbiAgdmFyIGVsID0gdGhpcy5fZSB8IDBcblxuICB2YXIgYXIgPSB0aGlzLl9hIHwgMFxuICB2YXIgYnIgPSB0aGlzLl9iIHwgMFxuICB2YXIgY3IgPSB0aGlzLl9jIHwgMFxuICB2YXIgZHIgPSB0aGlzLl9kIHwgMFxuICB2YXIgZXIgPSB0aGlzLl9lIHwgMFxuXG4gIC8vIGNvbXB1dGF0aW9uXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgODA7IGkgKz0gMSkge1xuICAgIHZhciB0bFxuICAgIHZhciB0clxuICAgIGlmIChpIDwgMTYpIHtcbiAgICAgIHRsID0gZm4xKGFsLCBibCwgY2wsIGRsLCBlbCwgd29yZHNbemxbaV1dLCBobFswXSwgc2xbaV0pXG4gICAgICB0ciA9IGZuNShhciwgYnIsIGNyLCBkciwgZXIsIHdvcmRzW3pyW2ldXSwgaHJbMF0sIHNyW2ldKVxuICAgIH0gZWxzZSBpZiAoaSA8IDMyKSB7XG4gICAgICB0bCA9IGZuMihhbCwgYmwsIGNsLCBkbCwgZWwsIHdvcmRzW3psW2ldXSwgaGxbMV0sIHNsW2ldKVxuICAgICAgdHIgPSBmbjQoYXIsIGJyLCBjciwgZHIsIGVyLCB3b3Jkc1t6cltpXV0sIGhyWzFdLCBzcltpXSlcbiAgICB9IGVsc2UgaWYgKGkgPCA0OCkge1xuICAgICAgdGwgPSBmbjMoYWwsIGJsLCBjbCwgZGwsIGVsLCB3b3Jkc1t6bFtpXV0sIGhsWzJdLCBzbFtpXSlcbiAgICAgIHRyID0gZm4zKGFyLCBiciwgY3IsIGRyLCBlciwgd29yZHNbenJbaV1dLCBoclsyXSwgc3JbaV0pXG4gICAgfSBlbHNlIGlmIChpIDwgNjQpIHtcbiAgICAgIHRsID0gZm40KGFsLCBibCwgY2wsIGRsLCBlbCwgd29yZHNbemxbaV1dLCBobFszXSwgc2xbaV0pXG4gICAgICB0ciA9IGZuMihhciwgYnIsIGNyLCBkciwgZXIsIHdvcmRzW3pyW2ldXSwgaHJbM10sIHNyW2ldKVxuICAgIH0gZWxzZSB7IC8vIGlmIChpPDgwKSB7XG4gICAgICB0bCA9IGZuNShhbCwgYmwsIGNsLCBkbCwgZWwsIHdvcmRzW3psW2ldXSwgaGxbNF0sIHNsW2ldKVxuICAgICAgdHIgPSBmbjEoYXIsIGJyLCBjciwgZHIsIGVyLCB3b3Jkc1t6cltpXV0sIGhyWzRdLCBzcltpXSlcbiAgICB9XG5cbiAgICBhbCA9IGVsXG4gICAgZWwgPSBkbFxuICAgIGRsID0gcm90bChjbCwgMTApXG4gICAgY2wgPSBibFxuICAgIGJsID0gdGxcblxuICAgIGFyID0gZXJcbiAgICBlciA9IGRyXG4gICAgZHIgPSByb3RsKGNyLCAxMClcbiAgICBjciA9IGJyXG4gICAgYnIgPSB0clxuICB9XG5cbiAgLy8gdXBkYXRlIHN0YXRlXG4gIHZhciB0ID0gKHRoaXMuX2IgKyBjbCArIGRyKSB8IDBcbiAgdGhpcy5fYiA9ICh0aGlzLl9jICsgZGwgKyBlcikgfCAwXG4gIHRoaXMuX2MgPSAodGhpcy5fZCArIGVsICsgYXIpIHwgMFxuICB0aGlzLl9kID0gKHRoaXMuX2UgKyBhbCArIGJyKSB8IDBcbiAgdGhpcy5fZSA9ICh0aGlzLl9hICsgYmwgKyBjcikgfCAwXG4gIHRoaXMuX2EgPSB0XG59XG5cblJJUEVNRDE2MC5wcm90b3R5cGUuX2RpZ2VzdCA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gY3JlYXRlIHBhZGRpbmcgYW5kIGhhbmRsZSBibG9ja3NcbiAgdGhpcy5fYmxvY2tbdGhpcy5fYmxvY2tPZmZzZXQrK10gPSAweDgwXG4gIGlmICh0aGlzLl9ibG9ja09mZnNldCA+IDU2KSB7XG4gICAgdGhpcy5fYmxvY2suZmlsbCgwLCB0aGlzLl9ibG9ja09mZnNldCwgNjQpXG4gICAgdGhpcy5fdXBkYXRlKClcbiAgICB0aGlzLl9ibG9ja09mZnNldCA9IDBcbiAgfVxuXG4gIHRoaXMuX2Jsb2NrLmZpbGwoMCwgdGhpcy5fYmxvY2tPZmZzZXQsIDU2KVxuICB0aGlzLl9ibG9jay53cml0ZVVJbnQzMkxFKHRoaXMuX2xlbmd0aFswXSwgNTYpXG4gIHRoaXMuX2Jsb2NrLndyaXRlVUludDMyTEUodGhpcy5fbGVuZ3RoWzFdLCA2MClcbiAgdGhpcy5fdXBkYXRlKClcblxuICAvLyBwcm9kdWNlIHJlc3VsdFxuICB2YXIgYnVmZmVyID0gQnVmZmVyLmFsbG9jID8gQnVmZmVyLmFsbG9jKDIwKSA6IG5ldyBCdWZmZXIoMjApXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fYSwgMClcbiAgYnVmZmVyLndyaXRlSW50MzJMRSh0aGlzLl9iLCA0KVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2MsIDgpXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fZCwgMTIpXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fZSwgMTYpXG4gIHJldHVybiBidWZmZXJcbn1cblxuZnVuY3Rpb24gcm90bCAoeCwgbikge1xuICByZXR1cm4gKHggPDwgbikgfCAoeCA+Pj4gKDMyIC0gbikpXG59XG5cbmZ1bmN0aW9uIGZuMSAoYSwgYiwgYywgZCwgZSwgbSwgaywgcykge1xuICByZXR1cm4gKHJvdGwoKGEgKyAoYiBeIGMgXiBkKSArIG0gKyBrKSB8IDAsIHMpICsgZSkgfCAwXG59XG5cbmZ1bmN0aW9uIGZuMiAoYSwgYiwgYywgZCwgZSwgbSwgaywgcykge1xuICByZXR1cm4gKHJvdGwoKGEgKyAoKGIgJiBjKSB8ICgofmIpICYgZCkpICsgbSArIGspIHwgMCwgcykgKyBlKSB8IDBcbn1cblxuZnVuY3Rpb24gZm4zIChhLCBiLCBjLCBkLCBlLCBtLCBrLCBzKSB7XG4gIHJldHVybiAocm90bCgoYSArICgoYiB8ICh+YykpIF4gZCkgKyBtICsgaykgfCAwLCBzKSArIGUpIHwgMFxufVxuXG5mdW5jdGlvbiBmbjQgKGEsIGIsIGMsIGQsIGUsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKChiICYgZCkgfCAoYyAmICh+ZCkpKSArIG0gKyBrKSB8IDAsIHMpICsgZSkgfCAwXG59XG5cbmZ1bmN0aW9uIGZuNSAoYSwgYiwgYywgZCwgZSwgbSwgaywgcykge1xuICByZXR1cm4gKHJvdGwoKGEgKyAoYiBeIChjIHwgKH5kKSkpICsgbSArIGspIHwgMCwgcykgKyBlKSB8IDBcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSSVBFTUQxNjBcbiIsIi8qIGVzbGludC1kaXNhYmxlIG5vZGUvbm8tZGVwcmVjYXRlZC1hcGkgKi9cbnZhciBidWZmZXIgPSByZXF1aXJlKCdidWZmZXInKVxudmFyIEJ1ZmZlciA9IGJ1ZmZlci5CdWZmZXJcblxuLy8gYWx0ZXJuYXRpdmUgdG8gdXNpbmcgT2JqZWN0LmtleXMgZm9yIG9sZCBicm93c2Vyc1xuZnVuY3Rpb24gY29weVByb3BzIChzcmMsIGRzdCkge1xuICBmb3IgKHZhciBrZXkgaW4gc3JjKSB7XG4gICAgZHN0W2tleV0gPSBzcmNba2V5XVxuICB9XG59XG5pZiAoQnVmZmVyLmZyb20gJiYgQnVmZmVyLmFsbG9jICYmIEJ1ZmZlci5hbGxvY1Vuc2FmZSAmJiBCdWZmZXIuYWxsb2NVbnNhZmVTbG93KSB7XG4gIG1vZHVsZS5leHBvcnRzID0gYnVmZmVyXG59IGVsc2Uge1xuICAvLyBDb3B5IHByb3BlcnRpZXMgZnJvbSByZXF1aXJlKCdidWZmZXInKVxuICBjb3B5UHJvcHMoYnVmZmVyLCBleHBvcnRzKVxuICBleHBvcnRzLkJ1ZmZlciA9IFNhZmVCdWZmZXJcbn1cblxuZnVuY3Rpb24gU2FmZUJ1ZmZlciAoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIEJ1ZmZlcihhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuLy8gQ29weSBzdGF0aWMgbWV0aG9kcyBmcm9tIEJ1ZmZlclxuY29weVByb3BzKEJ1ZmZlciwgU2FmZUJ1ZmZlcilcblxuU2FmZUJ1ZmZlci5mcm9tID0gZnVuY3Rpb24gKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3Qgbm90IGJlIGEgbnVtYmVyJylcbiAgfVxuICByZXR1cm4gQnVmZmVyKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5TYWZlQnVmZmVyLmFsbG9jID0gZnVuY3Rpb24gKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgbnVtYmVyJylcbiAgfVxuICB2YXIgYnVmID0gQnVmZmVyKHNpemUpXG4gIGlmIChmaWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJykge1xuICAgICAgYnVmLmZpbGwoZmlsbCwgZW5jb2RpbmcpXG4gICAgfSBlbHNlIHtcbiAgICAgIGJ1Zi5maWxsKGZpbGwpXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGJ1Zi5maWxsKDApXG4gIH1cbiAgcmV0dXJuIGJ1ZlxufVxuXG5TYWZlQnVmZmVyLmFsbG9jVW5zYWZlID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9XG4gIHJldHVybiBCdWZmZXIoc2l6ZSlcbn1cblxuU2FmZUJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH1cbiAgcmV0dXJuIGJ1ZmZlci5TbG93QnVmZmVyKHNpemUpXG59XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCwgdW5kZWZpbmVkKSB7XG4gICAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgICBpZiAoZ2xvYmFsLnNldEltbWVkaWF0ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIG5leHRIYW5kbGUgPSAxOyAvLyBTcGVjIHNheXMgZ3JlYXRlciB0aGFuIHplcm9cbiAgICB2YXIgdGFza3NCeUhhbmRsZSA9IHt9O1xuICAgIHZhciBjdXJyZW50bHlSdW5uaW5nQVRhc2sgPSBmYWxzZTtcbiAgICB2YXIgZG9jID0gZ2xvYmFsLmRvY3VtZW50O1xuICAgIHZhciByZWdpc3RlckltbWVkaWF0ZTtcblxuICAgIGZ1bmN0aW9uIHNldEltbWVkaWF0ZShjYWxsYmFjaykge1xuICAgICAgLy8gQ2FsbGJhY2sgY2FuIGVpdGhlciBiZSBhIGZ1bmN0aW9uIG9yIGEgc3RyaW5nXG4gICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgY2FsbGJhY2sgPSBuZXcgRnVuY3Rpb24oXCJcIiArIGNhbGxiYWNrKTtcbiAgICAgIH1cbiAgICAgIC8vIENvcHkgZnVuY3Rpb24gYXJndW1lbnRzXG4gICAgICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoIC0gMSk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBhcmdzW2ldID0gYXJndW1lbnRzW2kgKyAxXTtcbiAgICAgIH1cbiAgICAgIC8vIFN0b3JlIGFuZCByZWdpc3RlciB0aGUgdGFza1xuICAgICAgdmFyIHRhc2sgPSB7IGNhbGxiYWNrOiBjYWxsYmFjaywgYXJnczogYXJncyB9O1xuICAgICAgdGFza3NCeUhhbmRsZVtuZXh0SGFuZGxlXSA9IHRhc2s7XG4gICAgICByZWdpc3RlckltbWVkaWF0ZShuZXh0SGFuZGxlKTtcbiAgICAgIHJldHVybiBuZXh0SGFuZGxlKys7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2xlYXJJbW1lZGlhdGUoaGFuZGxlKSB7XG4gICAgICAgIGRlbGV0ZSB0YXNrc0J5SGFuZGxlW2hhbmRsZV07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcnVuKHRhc2spIHtcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gdGFzay5jYWxsYmFjaztcbiAgICAgICAgdmFyIGFyZ3MgPSB0YXNrLmFyZ3M7XG4gICAgICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICBjYWxsYmFjayhhcmdzWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICBjYWxsYmFjayhhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICBjYWxsYmFjayhhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkodW5kZWZpbmVkLCBhcmdzKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcnVuSWZQcmVzZW50KGhhbmRsZSkge1xuICAgICAgICAvLyBGcm9tIHRoZSBzcGVjOiBcIldhaXQgdW50aWwgYW55IGludm9jYXRpb25zIG9mIHRoaXMgYWxnb3JpdGhtIHN0YXJ0ZWQgYmVmb3JlIHRoaXMgb25lIGhhdmUgY29tcGxldGVkLlwiXG4gICAgICAgIC8vIFNvIGlmIHdlJ3JlIGN1cnJlbnRseSBydW5uaW5nIGEgdGFzaywgd2UnbGwgbmVlZCB0byBkZWxheSB0aGlzIGludm9jYXRpb24uXG4gICAgICAgIGlmIChjdXJyZW50bHlSdW5uaW5nQVRhc2spIHtcbiAgICAgICAgICAgIC8vIERlbGF5IGJ5IGRvaW5nIGEgc2V0VGltZW91dC4gc2V0SW1tZWRpYXRlIHdhcyB0cmllZCBpbnN0ZWFkLCBidXQgaW4gRmlyZWZveCA3IGl0IGdlbmVyYXRlZCBhXG4gICAgICAgICAgICAvLyBcInRvbyBtdWNoIHJlY3Vyc2lvblwiIGVycm9yLlxuICAgICAgICAgICAgc2V0VGltZW91dChydW5JZlByZXNlbnQsIDAsIGhhbmRsZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgdGFzayA9IHRhc2tzQnlIYW5kbGVbaGFuZGxlXTtcbiAgICAgICAgICAgIGlmICh0YXNrKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudGx5UnVubmluZ0FUYXNrID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBydW4odGFzayk7XG4gICAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAgICAgY2xlYXJJbW1lZGlhdGUoaGFuZGxlKTtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudGx5UnVubmluZ0FUYXNrID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5zdGFsbE5leHRUaWNrSW1wbGVtZW50YXRpb24oKSB7XG4gICAgICAgIHJlZ2lzdGVySW1tZWRpYXRlID0gZnVuY3Rpb24oaGFuZGxlKSB7XG4gICAgICAgICAgICBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uICgpIHsgcnVuSWZQcmVzZW50KGhhbmRsZSk7IH0pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNhblVzZVBvc3RNZXNzYWdlKCkge1xuICAgICAgICAvLyBUaGUgdGVzdCBhZ2FpbnN0IGBpbXBvcnRTY3JpcHRzYCBwcmV2ZW50cyB0aGlzIGltcGxlbWVudGF0aW9uIGZyb20gYmVpbmcgaW5zdGFsbGVkIGluc2lkZSBhIHdlYiB3b3JrZXIsXG4gICAgICAgIC8vIHdoZXJlIGBnbG9iYWwucG9zdE1lc3NhZ2VgIG1lYW5zIHNvbWV0aGluZyBjb21wbGV0ZWx5IGRpZmZlcmVudCBhbmQgY2FuJ3QgYmUgdXNlZCBmb3IgdGhpcyBwdXJwb3NlLlxuICAgICAgICBpZiAoZ2xvYmFsLnBvc3RNZXNzYWdlICYmICFnbG9iYWwuaW1wb3J0U2NyaXB0cykge1xuICAgICAgICAgICAgdmFyIHBvc3RNZXNzYWdlSXNBc3luY2hyb25vdXMgPSB0cnVlO1xuICAgICAgICAgICAgdmFyIG9sZE9uTWVzc2FnZSA9IGdsb2JhbC5vbm1lc3NhZ2U7XG4gICAgICAgICAgICBnbG9iYWwub25tZXNzYWdlID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgcG9zdE1lc3NhZ2VJc0FzeW5jaHJvbm91cyA9IGZhbHNlO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGdsb2JhbC5wb3N0TWVzc2FnZShcIlwiLCBcIipcIik7XG4gICAgICAgICAgICBnbG9iYWwub25tZXNzYWdlID0gb2xkT25NZXNzYWdlO1xuICAgICAgICAgICAgcmV0dXJuIHBvc3RNZXNzYWdlSXNBc3luY2hyb25vdXM7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnN0YWxsUG9zdE1lc3NhZ2VJbXBsZW1lbnRhdGlvbigpIHtcbiAgICAgICAgLy8gSW5zdGFsbHMgYW4gZXZlbnQgaGFuZGxlciBvbiBgZ2xvYmFsYCBmb3IgdGhlIGBtZXNzYWdlYCBldmVudDogc2VlXG4gICAgICAgIC8vICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vRE9NL3dpbmRvdy5wb3N0TWVzc2FnZVxuICAgICAgICAvLyAqIGh0dHA6Ly93d3cud2hhdHdnLm9yZy9zcGVjcy93ZWItYXBwcy9jdXJyZW50LXdvcmsvbXVsdGlwYWdlL2NvbW1zLmh0bWwjY3Jvc3NEb2N1bWVudE1lc3NhZ2VzXG5cbiAgICAgICAgdmFyIG1lc3NhZ2VQcmVmaXggPSBcInNldEltbWVkaWF0ZSRcIiArIE1hdGgucmFuZG9tKCkgKyBcIiRcIjtcbiAgICAgICAgdmFyIG9uR2xvYmFsTWVzc2FnZSA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgICAgICBpZiAoZXZlbnQuc291cmNlID09PSBnbG9iYWwgJiZcbiAgICAgICAgICAgICAgICB0eXBlb2YgZXZlbnQuZGF0YSA9PT0gXCJzdHJpbmdcIiAmJlxuICAgICAgICAgICAgICAgIGV2ZW50LmRhdGEuaW5kZXhPZihtZXNzYWdlUHJlZml4KSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJ1bklmUHJlc2VudCgrZXZlbnQuZGF0YS5zbGljZShtZXNzYWdlUHJlZml4Lmxlbmd0aCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcikge1xuICAgICAgICAgICAgZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIG9uR2xvYmFsTWVzc2FnZSwgZmFsc2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2xvYmFsLmF0dGFjaEV2ZW50KFwib25tZXNzYWdlXCIsIG9uR2xvYmFsTWVzc2FnZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZWdpc3RlckltbWVkaWF0ZSA9IGZ1bmN0aW9uKGhhbmRsZSkge1xuICAgICAgICAgICAgZ2xvYmFsLnBvc3RNZXNzYWdlKG1lc3NhZ2VQcmVmaXggKyBoYW5kbGUsIFwiKlwiKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnN0YWxsTWVzc2FnZUNoYW5uZWxJbXBsZW1lbnRhdGlvbigpIHtcbiAgICAgICAgdmFyIGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgICAgdmFyIGhhbmRsZSA9IGV2ZW50LmRhdGE7XG4gICAgICAgICAgICBydW5JZlByZXNlbnQoaGFuZGxlKTtcbiAgICAgICAgfTtcblxuICAgICAgICByZWdpc3RlckltbWVkaWF0ZSA9IGZ1bmN0aW9uKGhhbmRsZSkge1xuICAgICAgICAgICAgY2hhbm5lbC5wb3J0Mi5wb3N0TWVzc2FnZShoYW5kbGUpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxSZWFkeVN0YXRlQ2hhbmdlSW1wbGVtZW50YXRpb24oKSB7XG4gICAgICAgIHZhciBodG1sID0gZG9jLmRvY3VtZW50RWxlbWVudDtcbiAgICAgICAgcmVnaXN0ZXJJbW1lZGlhdGUgPSBmdW5jdGlvbihoYW5kbGUpIHtcbiAgICAgICAgICAgIC8vIENyZWF0ZSBhIDxzY3JpcHQ+IGVsZW1lbnQ7IGl0cyByZWFkeXN0YXRlY2hhbmdlIGV2ZW50IHdpbGwgYmUgZmlyZWQgYXN5bmNocm9ub3VzbHkgb25jZSBpdCBpcyBpbnNlcnRlZFxuICAgICAgICAgICAgLy8gaW50byB0aGUgZG9jdW1lbnQuIERvIHNvLCB0aHVzIHF1ZXVpbmcgdXAgdGhlIHRhc2suIFJlbWVtYmVyIHRvIGNsZWFuIHVwIG9uY2UgaXQncyBiZWVuIGNhbGxlZC5cbiAgICAgICAgICAgIHZhciBzY3JpcHQgPSBkb2MuY3JlYXRlRWxlbWVudChcInNjcmlwdFwiKTtcbiAgICAgICAgICAgIHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcnVuSWZQcmVzZW50KGhhbmRsZSk7XG4gICAgICAgICAgICAgICAgc2NyaXB0Lm9ucmVhZHlzdGF0ZWNoYW5nZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgaHRtbC5yZW1vdmVDaGlsZChzY3JpcHQpO1xuICAgICAgICAgICAgICAgIHNjcmlwdCA9IG51bGw7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaHRtbC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxTZXRUaW1lb3V0SW1wbGVtZW50YXRpb24oKSB7XG4gICAgICAgIHJlZ2lzdGVySW1tZWRpYXRlID0gZnVuY3Rpb24oaGFuZGxlKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KHJ1bklmUHJlc2VudCwgMCwgaGFuZGxlKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBJZiBzdXBwb3J0ZWQsIHdlIHNob3VsZCBhdHRhY2ggdG8gdGhlIHByb3RvdHlwZSBvZiBnbG9iYWwsIHNpbmNlIHRoYXQgaXMgd2hlcmUgc2V0VGltZW91dCBldCBhbC4gbGl2ZS5cbiAgICB2YXIgYXR0YWNoVG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKGdsb2JhbCk7XG4gICAgYXR0YWNoVG8gPSBhdHRhY2hUbyAmJiBhdHRhY2hUby5zZXRUaW1lb3V0ID8gYXR0YWNoVG8gOiBnbG9iYWw7XG5cbiAgICAvLyBEb24ndCBnZXQgZm9vbGVkIGJ5IGUuZy4gYnJvd3NlcmlmeSBlbnZpcm9ubWVudHMuXG4gICAgaWYgKHt9LnRvU3RyaW5nLmNhbGwoZ2xvYmFsLnByb2Nlc3MpID09PSBcIltvYmplY3QgcHJvY2Vzc11cIikge1xuICAgICAgICAvLyBGb3IgTm9kZS5qcyBiZWZvcmUgMC45XG4gICAgICAgIGluc3RhbGxOZXh0VGlja0ltcGxlbWVudGF0aW9uKCk7XG5cbiAgICB9IGVsc2UgaWYgKGNhblVzZVBvc3RNZXNzYWdlKCkpIHtcbiAgICAgICAgLy8gRm9yIG5vbi1JRTEwIG1vZGVybiBicm93c2Vyc1xuICAgICAgICBpbnN0YWxsUG9zdE1lc3NhZ2VJbXBsZW1lbnRhdGlvbigpO1xuXG4gICAgfSBlbHNlIGlmIChnbG9iYWwuTWVzc2FnZUNoYW5uZWwpIHtcbiAgICAgICAgLy8gRm9yIHdlYiB3b3JrZXJzLCB3aGVyZSBzdXBwb3J0ZWRcbiAgICAgICAgaW5zdGFsbE1lc3NhZ2VDaGFubmVsSW1wbGVtZW50YXRpb24oKTtcblxuICAgIH0gZWxzZSBpZiAoZG9jICYmIFwib25yZWFkeXN0YXRlY2hhbmdlXCIgaW4gZG9jLmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIikpIHtcbiAgICAgICAgLy8gRm9yIElFIDbigJM4XG4gICAgICAgIGluc3RhbGxSZWFkeVN0YXRlQ2hhbmdlSW1wbGVtZW50YXRpb24oKTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEZvciBvbGRlciBicm93c2Vyc1xuICAgICAgICBpbnN0YWxsU2V0VGltZW91dEltcGxlbWVudGF0aW9uKCk7XG4gICAgfVxuXG4gICAgYXR0YWNoVG8uc2V0SW1tZWRpYXRlID0gc2V0SW1tZWRpYXRlO1xuICAgIGF0dGFjaFRvLmNsZWFySW1tZWRpYXRlID0gY2xlYXJJbW1lZGlhdGU7XG59KHR5cGVvZiBzZWxmID09PSBcInVuZGVmaW5lZFwiID8gdHlwZW9mIGdsb2JhbCA9PT0gXCJ1bmRlZmluZWRcIiA/IHRoaXMgOiBnbG9iYWwgOiBzZWxmKSk7XG4iLCJ2YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcblxuLy8gcHJvdG90eXBlIGNsYXNzIGZvciBoYXNoIGZ1bmN0aW9uc1xuZnVuY3Rpb24gSGFzaCAoYmxvY2tTaXplLCBmaW5hbFNpemUpIHtcbiAgdGhpcy5fYmxvY2sgPSBCdWZmZXIuYWxsb2MoYmxvY2tTaXplKVxuICB0aGlzLl9maW5hbFNpemUgPSBmaW5hbFNpemVcbiAgdGhpcy5fYmxvY2tTaXplID0gYmxvY2tTaXplXG4gIHRoaXMuX2xlbiA9IDBcbn1cblxuSGFzaC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGVuYykge1xuICBpZiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jID0gZW5jIHx8ICd1dGY4J1xuICAgIGRhdGEgPSBCdWZmZXIuZnJvbShkYXRhLCBlbmMpXG4gIH1cblxuICB2YXIgYmxvY2sgPSB0aGlzLl9ibG9ja1xuICB2YXIgYmxvY2tTaXplID0gdGhpcy5fYmxvY2tTaXplXG4gIHZhciBsZW5ndGggPSBkYXRhLmxlbmd0aFxuICB2YXIgYWNjdW0gPSB0aGlzLl9sZW5cblxuICBmb3IgKHZhciBvZmZzZXQgPSAwOyBvZmZzZXQgPCBsZW5ndGg7KSB7XG4gICAgdmFyIGFzc2lnbmVkID0gYWNjdW0gJSBibG9ja1NpemVcbiAgICB2YXIgcmVtYWluZGVyID0gTWF0aC5taW4obGVuZ3RoIC0gb2Zmc2V0LCBibG9ja1NpemUgLSBhc3NpZ25lZClcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVtYWluZGVyOyBpKyspIHtcbiAgICAgIGJsb2NrW2Fzc2lnbmVkICsgaV0gPSBkYXRhW29mZnNldCArIGldXG4gICAgfVxuXG4gICAgYWNjdW0gKz0gcmVtYWluZGVyXG4gICAgb2Zmc2V0ICs9IHJlbWFpbmRlclxuXG4gICAgaWYgKChhY2N1bSAlIGJsb2NrU2l6ZSkgPT09IDApIHtcbiAgICAgIHRoaXMuX3VwZGF0ZShibG9jaylcbiAgICB9XG4gIH1cblxuICB0aGlzLl9sZW4gKz0gbGVuZ3RoXG4gIHJldHVybiB0aGlzXG59XG5cbkhhc2gucHJvdG90eXBlLmRpZ2VzdCA9IGZ1bmN0aW9uIChlbmMpIHtcbiAgdmFyIHJlbSA9IHRoaXMuX2xlbiAlIHRoaXMuX2Jsb2NrU2l6ZVxuXG4gIHRoaXMuX2Jsb2NrW3JlbV0gPSAweDgwXG5cbiAgLy8gemVybyAocmVtICsgMSkgdHJhaWxpbmcgYml0cywgd2hlcmUgKHJlbSArIDEpIGlzIHRoZSBzbWFsbGVzdFxuICAvLyBub24tbmVnYXRpdmUgc29sdXRpb24gdG8gdGhlIGVxdWF0aW9uIChsZW5ndGggKyAxICsgKHJlbSArIDEpKSA9PT0gZmluYWxTaXplIG1vZCBibG9ja1NpemVcbiAgdGhpcy5fYmxvY2suZmlsbCgwLCByZW0gKyAxKVxuXG4gIGlmIChyZW0gPj0gdGhpcy5fZmluYWxTaXplKSB7XG4gICAgdGhpcy5fdXBkYXRlKHRoaXMuX2Jsb2NrKVxuICAgIHRoaXMuX2Jsb2NrLmZpbGwoMClcbiAgfVxuXG4gIHZhciBiaXRzID0gdGhpcy5fbGVuICogOFxuXG4gIC8vIHVpbnQzMlxuICBpZiAoYml0cyA8PSAweGZmZmZmZmZmKSB7XG4gICAgdGhpcy5fYmxvY2sud3JpdGVVSW50MzJCRShiaXRzLCB0aGlzLl9ibG9ja1NpemUgLSA0KVxuXG4gIC8vIHVpbnQ2NFxuICB9IGVsc2Uge1xuICAgIHZhciBsb3dCaXRzID0gKGJpdHMgJiAweGZmZmZmZmZmKSA+Pj4gMFxuICAgIHZhciBoaWdoQml0cyA9IChiaXRzIC0gbG93Qml0cykgLyAweDEwMDAwMDAwMFxuXG4gICAgdGhpcy5fYmxvY2sud3JpdGVVSW50MzJCRShoaWdoQml0cywgdGhpcy5fYmxvY2tTaXplIC0gOClcbiAgICB0aGlzLl9ibG9jay53cml0ZVVJbnQzMkJFKGxvd0JpdHMsIHRoaXMuX2Jsb2NrU2l6ZSAtIDQpXG4gIH1cblxuICB0aGlzLl91cGRhdGUodGhpcy5fYmxvY2spXG4gIHZhciBoYXNoID0gdGhpcy5faGFzaCgpXG5cbiAgcmV0dXJuIGVuYyA/IGhhc2gudG9TdHJpbmcoZW5jKSA6IGhhc2hcbn1cblxuSGFzaC5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdfdXBkYXRlIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3MnKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEhhc2hcbiIsInZhciBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTSEEgKGFsZ29yaXRobSkge1xuICBhbGdvcml0aG0gPSBhbGdvcml0aG0udG9Mb3dlckNhc2UoKVxuXG4gIHZhciBBbGdvcml0aG0gPSBleHBvcnRzW2FsZ29yaXRobV1cbiAgaWYgKCFBbGdvcml0aG0pIHRocm93IG5ldyBFcnJvcihhbGdvcml0aG0gKyAnIGlzIG5vdCBzdXBwb3J0ZWQgKHdlIGFjY2VwdCBwdWxsIHJlcXVlc3RzKScpXG5cbiAgcmV0dXJuIG5ldyBBbGdvcml0aG0oKVxufVxuXG5leHBvcnRzLnNoYSA9IHJlcXVpcmUoJy4vc2hhJylcbmV4cG9ydHMuc2hhMSA9IHJlcXVpcmUoJy4vc2hhMScpXG5leHBvcnRzLnNoYTIyNCA9IHJlcXVpcmUoJy4vc2hhMjI0JylcbmV4cG9ydHMuc2hhMjU2ID0gcmVxdWlyZSgnLi9zaGEyNTYnKVxuZXhwb3J0cy5zaGEzODQgPSByZXF1aXJlKCcuL3NoYTM4NCcpXG5leHBvcnRzLnNoYTUxMiA9IHJlcXVpcmUoJy4vc2hhNTEyJylcbiIsIi8qXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFNlY3VyZSBIYXNoIEFsZ29yaXRobSwgU0hBLTAsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgUFVCIDE4MC0xXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGRlcml2ZWQgZnJvbSBzaGExLmpzIG9mIHRoZSBzYW1lIHJlcG9zaXRvcnkuXG4gKiBUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIFNIQS0wIGFuZCBTSEEtMSBpcyBqdXN0IGEgYml0d2lzZSByb3RhdGUgbGVmdFxuICogb3BlcmF0aW9uIHdhcyBhZGRlZC5cbiAqL1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgSGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcblxudmFyIEsgPSBbXG4gIDB4NWE4Mjc5OTksIDB4NmVkOWViYTEsIDB4OGYxYmJjZGMgfCAwLCAweGNhNjJjMWQ2IHwgMFxuXVxuXG52YXIgVyA9IG5ldyBBcnJheSg4MClcblxuZnVuY3Rpb24gU2hhICgpIHtcbiAgdGhpcy5pbml0KClcbiAgdGhpcy5fdyA9IFdcblxuICBIYXNoLmNhbGwodGhpcywgNjQsIDU2KVxufVxuXG5pbmhlcml0cyhTaGEsIEhhc2gpXG5cblNoYS5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fYSA9IDB4Njc0NTIzMDFcbiAgdGhpcy5fYiA9IDB4ZWZjZGFiODlcbiAgdGhpcy5fYyA9IDB4OThiYWRjZmVcbiAgdGhpcy5fZCA9IDB4MTAzMjU0NzZcbiAgdGhpcy5fZSA9IDB4YzNkMmUxZjBcblxuICByZXR1cm4gdGhpc1xufVxuXG5mdW5jdGlvbiByb3RsNSAobnVtKSB7XG4gIHJldHVybiAobnVtIDw8IDUpIHwgKG51bSA+Pj4gMjcpXG59XG5cbmZ1bmN0aW9uIHJvdGwzMCAobnVtKSB7XG4gIHJldHVybiAobnVtIDw8IDMwKSB8IChudW0gPj4+IDIpXG59XG5cbmZ1bmN0aW9uIGZ0IChzLCBiLCBjLCBkKSB7XG4gIGlmIChzID09PSAwKSByZXR1cm4gKGIgJiBjKSB8ICgofmIpICYgZClcbiAgaWYgKHMgPT09IDIpIHJldHVybiAoYiAmIGMpIHwgKGIgJiBkKSB8IChjICYgZClcbiAgcmV0dXJuIGIgXiBjIF4gZFxufVxuXG5TaGEucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoTSkge1xuICB2YXIgVyA9IHRoaXMuX3dcblxuICB2YXIgYSA9IHRoaXMuX2EgfCAwXG4gIHZhciBiID0gdGhpcy5fYiB8IDBcbiAgdmFyIGMgPSB0aGlzLl9jIHwgMFxuICB2YXIgZCA9IHRoaXMuX2QgfCAwXG4gIHZhciBlID0gdGhpcy5fZSB8IDBcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyArK2kpIFdbaV0gPSBNLnJlYWRJbnQzMkJFKGkgKiA0KVxuICBmb3IgKDsgaSA8IDgwOyArK2kpIFdbaV0gPSBXW2kgLSAzXSBeIFdbaSAtIDhdIF4gV1tpIC0gMTRdIF4gV1tpIC0gMTZdXG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCA4MDsgKytqKSB7XG4gICAgdmFyIHMgPSB+fihqIC8gMjApXG4gICAgdmFyIHQgPSAocm90bDUoYSkgKyBmdChzLCBiLCBjLCBkKSArIGUgKyBXW2pdICsgS1tzXSkgfCAwXG5cbiAgICBlID0gZFxuICAgIGQgPSBjXG4gICAgYyA9IHJvdGwzMChiKVxuICAgIGIgPSBhXG4gICAgYSA9IHRcbiAgfVxuXG4gIHRoaXMuX2EgPSAoYSArIHRoaXMuX2EpIHwgMFxuICB0aGlzLl9iID0gKGIgKyB0aGlzLl9iKSB8IDBcbiAgdGhpcy5fYyA9IChjICsgdGhpcy5fYykgfCAwXG4gIHRoaXMuX2QgPSAoZCArIHRoaXMuX2QpIHwgMFxuICB0aGlzLl9lID0gKGUgKyB0aGlzLl9lKSB8IDBcbn1cblxuU2hhLnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBCdWZmZXIuYWxsb2NVbnNhZmUoMjApXG5cbiAgSC53cml0ZUludDMyQkUodGhpcy5fYSB8IDAsIDApXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2IgfCAwLCA0KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9jIHwgMCwgOClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZCB8IDAsIDEyKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9lIHwgMCwgMTYpXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGFcbiIsIi8qXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFNlY3VyZSBIYXNoIEFsZ29yaXRobSwgU0hBLTEsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgUFVCIDE4MC0xXG4gKiBWZXJzaW9uIDIuMWEgQ29weXJpZ2h0IFBhdWwgSm9obnN0b24gMjAwMCAtIDIwMDIuXG4gKiBPdGhlciBjb250cmlidXRvcnM6IEdyZWcgSG9sdCwgQW5kcmV3IEtlcGVydCwgWWRuYXIsIExvc3RpbmV0XG4gKiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQlNEIExpY2Vuc2VcbiAqIFNlZSBodHRwOi8vcGFqaG9tZS5vcmcudWsvY3J5cHQvbWQ1IGZvciBkZXRhaWxzLlxuICovXG5cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBIYXNoID0gcmVxdWlyZSgnLi9oYXNoJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxuXG52YXIgSyA9IFtcbiAgMHg1YTgyNzk5OSwgMHg2ZWQ5ZWJhMSwgMHg4ZjFiYmNkYyB8IDAsIDB4Y2E2MmMxZDYgfCAwXG5dXG5cbnZhciBXID0gbmV3IEFycmF5KDgwKVxuXG5mdW5jdGlvbiBTaGExICgpIHtcbiAgdGhpcy5pbml0KClcbiAgdGhpcy5fdyA9IFdcblxuICBIYXNoLmNhbGwodGhpcywgNjQsIDU2KVxufVxuXG5pbmhlcml0cyhTaGExLCBIYXNoKVxuXG5TaGExLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9hID0gMHg2NzQ1MjMwMVxuICB0aGlzLl9iID0gMHhlZmNkYWI4OVxuICB0aGlzLl9jID0gMHg5OGJhZGNmZVxuICB0aGlzLl9kID0gMHgxMDMyNTQ3NlxuICB0aGlzLl9lID0gMHhjM2QyZTFmMFxuXG4gIHJldHVybiB0aGlzXG59XG5cbmZ1bmN0aW9uIHJvdGwxIChudW0pIHtcbiAgcmV0dXJuIChudW0gPDwgMSkgfCAobnVtID4+PiAzMSlcbn1cblxuZnVuY3Rpb24gcm90bDUgKG51bSkge1xuICByZXR1cm4gKG51bSA8PCA1KSB8IChudW0gPj4+IDI3KVxufVxuXG5mdW5jdGlvbiByb3RsMzAgKG51bSkge1xuICByZXR1cm4gKG51bSA8PCAzMCkgfCAobnVtID4+PiAyKVxufVxuXG5mdW5jdGlvbiBmdCAocywgYiwgYywgZCkge1xuICBpZiAocyA9PT0gMCkgcmV0dXJuIChiICYgYykgfCAoKH5iKSAmIGQpXG4gIGlmIChzID09PSAyKSByZXR1cm4gKGIgJiBjKSB8IChiICYgZCkgfCAoYyAmIGQpXG4gIHJldHVybiBiIF4gYyBeIGRcbn1cblxuU2hhMS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChNKSB7XG4gIHZhciBXID0gdGhpcy5fd1xuXG4gIHZhciBhID0gdGhpcy5fYSB8IDBcbiAgdmFyIGIgPSB0aGlzLl9iIHwgMFxuICB2YXIgYyA9IHRoaXMuX2MgfCAwXG4gIHZhciBkID0gdGhpcy5fZCB8IDBcbiAgdmFyIGUgPSB0aGlzLl9lIHwgMFxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7ICsraSkgV1tpXSA9IE0ucmVhZEludDMyQkUoaSAqIDQpXG4gIGZvciAoOyBpIDwgODA7ICsraSkgV1tpXSA9IHJvdGwxKFdbaSAtIDNdIF4gV1tpIC0gOF0gXiBXW2kgLSAxNF0gXiBXW2kgLSAxNl0pXG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCA4MDsgKytqKSB7XG4gICAgdmFyIHMgPSB+fihqIC8gMjApXG4gICAgdmFyIHQgPSAocm90bDUoYSkgKyBmdChzLCBiLCBjLCBkKSArIGUgKyBXW2pdICsgS1tzXSkgfCAwXG5cbiAgICBlID0gZFxuICAgIGQgPSBjXG4gICAgYyA9IHJvdGwzMChiKVxuICAgIGIgPSBhXG4gICAgYSA9IHRcbiAgfVxuXG4gIHRoaXMuX2EgPSAoYSArIHRoaXMuX2EpIHwgMFxuICB0aGlzLl9iID0gKGIgKyB0aGlzLl9iKSB8IDBcbiAgdGhpcy5fYyA9IChjICsgdGhpcy5fYykgfCAwXG4gIHRoaXMuX2QgPSAoZCArIHRoaXMuX2QpIHwgMFxuICB0aGlzLl9lID0gKGUgKyB0aGlzLl9lKSB8IDBcbn1cblxuU2hhMS5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gQnVmZmVyLmFsbG9jVW5zYWZlKDIwKVxuXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2EgfCAwLCAwKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9iIHwgMCwgNClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYyB8IDAsIDgpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2QgfCAwLCAxMilcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZSB8IDAsIDE2KVxuXG4gIHJldHVybiBIXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2hhMVxuIiwiLyoqXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFNlY3VyZSBIYXNoIEFsZ29yaXRobSwgU0hBLTI1NiwgYXMgZGVmaW5lZFxuICogaW4gRklQUyAxODAtMlxuICogVmVyc2lvbiAyLjItYmV0YSBDb3B5cmlnaHQgQW5nZWwgTWFyaW4sIFBhdWwgSm9obnN0b24gMjAwMCAtIDIwMDkuXG4gKiBPdGhlciBjb250cmlidXRvcnM6IEdyZWcgSG9sdCwgQW5kcmV3IEtlcGVydCwgWWRuYXIsIExvc3RpbmV0XG4gKlxuICovXG5cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBTaGEyNTYgPSByZXF1aXJlKCcuL3NoYTI1NicpXG52YXIgSGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcblxudmFyIFcgPSBuZXcgQXJyYXkoNjQpXG5cbmZ1bmN0aW9uIFNoYTIyNCAoKSB7XG4gIHRoaXMuaW5pdCgpXG5cbiAgdGhpcy5fdyA9IFcgLy8gbmV3IEFycmF5KDY0KVxuXG4gIEhhc2guY2FsbCh0aGlzLCA2NCwgNTYpXG59XG5cbmluaGVyaXRzKFNoYTIyNCwgU2hhMjU2KVxuXG5TaGEyMjQucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2EgPSAweGMxMDU5ZWQ4XG4gIHRoaXMuX2IgPSAweDM2N2NkNTA3XG4gIHRoaXMuX2MgPSAweDMwNzBkZDE3XG4gIHRoaXMuX2QgPSAweGY3MGU1OTM5XG4gIHRoaXMuX2UgPSAweGZmYzAwYjMxXG4gIHRoaXMuX2YgPSAweDY4NTgxNTExXG4gIHRoaXMuX2cgPSAweDY0Zjk4ZmE3XG4gIHRoaXMuX2ggPSAweGJlZmE0ZmE0XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuU2hhMjI0LnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBCdWZmZXIuYWxsb2NVbnNhZmUoMjgpXG5cbiAgSC53cml0ZUludDMyQkUodGhpcy5fYSwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiwgNClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYywgOClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UsIDE2KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9mLCAyMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZywgMjQpXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGEyMjRcbiIsIi8qKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0yNTYsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgMTgwLTJcbiAqIFZlcnNpb24gMi4yLWJldGEgQ29weXJpZ2h0IEFuZ2VsIE1hcmluLCBQYXVsIEpvaG5zdG9uIDIwMDAgLSAyMDA5LlxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxuICpcbiAqL1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgSGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcblxudmFyIEsgPSBbXG4gIDB4NDI4QTJGOTgsIDB4NzEzNzQ0OTEsIDB4QjVDMEZCQ0YsIDB4RTlCNURCQTUsXG4gIDB4Mzk1NkMyNUIsIDB4NTlGMTExRjEsIDB4OTIzRjgyQTQsIDB4QUIxQzVFRDUsXG4gIDB4RDgwN0FBOTgsIDB4MTI4MzVCMDEsIDB4MjQzMTg1QkUsIDB4NTUwQzdEQzMsXG4gIDB4NzJCRTVENzQsIDB4ODBERUIxRkUsIDB4OUJEQzA2QTcsIDB4QzE5QkYxNzQsXG4gIDB4RTQ5QjY5QzEsIDB4RUZCRTQ3ODYsIDB4MEZDMTlEQzYsIDB4MjQwQ0ExQ0MsXG4gIDB4MkRFOTJDNkYsIDB4NEE3NDg0QUEsIDB4NUNCMEE5REMsIDB4NzZGOTg4REEsXG4gIDB4OTgzRTUxNTIsIDB4QTgzMUM2NkQsIDB4QjAwMzI3QzgsIDB4QkY1OTdGQzcsXG4gIDB4QzZFMDBCRjMsIDB4RDVBNzkxNDcsIDB4MDZDQTYzNTEsIDB4MTQyOTI5NjcsXG4gIDB4MjdCNzBBODUsIDB4MkUxQjIxMzgsIDB4NEQyQzZERkMsIDB4NTMzODBEMTMsXG4gIDB4NjUwQTczNTQsIDB4NzY2QTBBQkIsIDB4ODFDMkM5MkUsIDB4OTI3MjJDODUsXG4gIDB4QTJCRkU4QTEsIDB4QTgxQTY2NEIsIDB4QzI0QjhCNzAsIDB4Qzc2QzUxQTMsXG4gIDB4RDE5MkU4MTksIDB4RDY5OTA2MjQsIDB4RjQwRTM1ODUsIDB4MTA2QUEwNzAsXG4gIDB4MTlBNEMxMTYsIDB4MUUzNzZDMDgsIDB4Mjc0ODc3NEMsIDB4MzRCMEJDQjUsXG4gIDB4MzkxQzBDQjMsIDB4NEVEOEFBNEEsIDB4NUI5Q0NBNEYsIDB4NjgyRTZGRjMsXG4gIDB4NzQ4RjgyRUUsIDB4NzhBNTYzNkYsIDB4ODRDODc4MTQsIDB4OENDNzAyMDgsXG4gIDB4OTBCRUZGRkEsIDB4QTQ1MDZDRUIsIDB4QkVGOUEzRjcsIDB4QzY3MTc4RjJcbl1cblxudmFyIFcgPSBuZXcgQXJyYXkoNjQpXG5cbmZ1bmN0aW9uIFNoYTI1NiAoKSB7XG4gIHRoaXMuaW5pdCgpXG5cbiAgdGhpcy5fdyA9IFcgLy8gbmV3IEFycmF5KDY0KVxuXG4gIEhhc2guY2FsbCh0aGlzLCA2NCwgNTYpXG59XG5cbmluaGVyaXRzKFNoYTI1NiwgSGFzaClcblxuU2hhMjU2LnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9hID0gMHg2YTA5ZTY2N1xuICB0aGlzLl9iID0gMHhiYjY3YWU4NVxuICB0aGlzLl9jID0gMHgzYzZlZjM3MlxuICB0aGlzLl9kID0gMHhhNTRmZjUzYVxuICB0aGlzLl9lID0gMHg1MTBlNTI3ZlxuICB0aGlzLl9mID0gMHg5YjA1Njg4Y1xuICB0aGlzLl9nID0gMHgxZjgzZDlhYlxuICB0aGlzLl9oID0gMHg1YmUwY2QxOVxuXG4gIHJldHVybiB0aGlzXG59XG5cbmZ1bmN0aW9uIGNoICh4LCB5LCB6KSB7XG4gIHJldHVybiB6IF4gKHggJiAoeSBeIHopKVxufVxuXG5mdW5jdGlvbiBtYWogKHgsIHksIHopIHtcbiAgcmV0dXJuICh4ICYgeSkgfCAoeiAmICh4IHwgeSkpXG59XG5cbmZ1bmN0aW9uIHNpZ21hMCAoeCkge1xuICByZXR1cm4gKHggPj4+IDIgfCB4IDw8IDMwKSBeICh4ID4+PiAxMyB8IHggPDwgMTkpIF4gKHggPj4+IDIyIHwgeCA8PCAxMClcbn1cblxuZnVuY3Rpb24gc2lnbWExICh4KSB7XG4gIHJldHVybiAoeCA+Pj4gNiB8IHggPDwgMjYpIF4gKHggPj4+IDExIHwgeCA8PCAyMSkgXiAoeCA+Pj4gMjUgfCB4IDw8IDcpXG59XG5cbmZ1bmN0aW9uIGdhbW1hMCAoeCkge1xuICByZXR1cm4gKHggPj4+IDcgfCB4IDw8IDI1KSBeICh4ID4+PiAxOCB8IHggPDwgMTQpIF4gKHggPj4+IDMpXG59XG5cbmZ1bmN0aW9uIGdhbW1hMSAoeCkge1xuICByZXR1cm4gKHggPj4+IDE3IHwgeCA8PCAxNSkgXiAoeCA+Pj4gMTkgfCB4IDw8IDEzKSBeICh4ID4+PiAxMClcbn1cblxuU2hhMjU2LnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKE0pIHtcbiAgdmFyIFcgPSB0aGlzLl93XG5cbiAgdmFyIGEgPSB0aGlzLl9hIHwgMFxuICB2YXIgYiA9IHRoaXMuX2IgfCAwXG4gIHZhciBjID0gdGhpcy5fYyB8IDBcbiAgdmFyIGQgPSB0aGlzLl9kIHwgMFxuICB2YXIgZSA9IHRoaXMuX2UgfCAwXG4gIHZhciBmID0gdGhpcy5fZiB8IDBcbiAgdmFyIGcgPSB0aGlzLl9nIHwgMFxuICB2YXIgaCA9IHRoaXMuX2ggfCAwXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgKytpKSBXW2ldID0gTS5yZWFkSW50MzJCRShpICogNClcbiAgZm9yICg7IGkgPCA2NDsgKytpKSBXW2ldID0gKGdhbW1hMShXW2kgLSAyXSkgKyBXW2kgLSA3XSArIGdhbW1hMChXW2kgLSAxNV0pICsgV1tpIC0gMTZdKSB8IDBcblxuICBmb3IgKHZhciBqID0gMDsgaiA8IDY0OyArK2opIHtcbiAgICB2YXIgVDEgPSAoaCArIHNpZ21hMShlKSArIGNoKGUsIGYsIGcpICsgS1tqXSArIFdbal0pIHwgMFxuICAgIHZhciBUMiA9IChzaWdtYTAoYSkgKyBtYWooYSwgYiwgYykpIHwgMFxuXG4gICAgaCA9IGdcbiAgICBnID0gZlxuICAgIGYgPSBlXG4gICAgZSA9IChkICsgVDEpIHwgMFxuICAgIGQgPSBjXG4gICAgYyA9IGJcbiAgICBiID0gYVxuICAgIGEgPSAoVDEgKyBUMikgfCAwXG4gIH1cblxuICB0aGlzLl9hID0gKGEgKyB0aGlzLl9hKSB8IDBcbiAgdGhpcy5fYiA9IChiICsgdGhpcy5fYikgfCAwXG4gIHRoaXMuX2MgPSAoYyArIHRoaXMuX2MpIHwgMFxuICB0aGlzLl9kID0gKGQgKyB0aGlzLl9kKSB8IDBcbiAgdGhpcy5fZSA9IChlICsgdGhpcy5fZSkgfCAwXG4gIHRoaXMuX2YgPSAoZiArIHRoaXMuX2YpIHwgMFxuICB0aGlzLl9nID0gKGcgKyB0aGlzLl9nKSB8IDBcbiAgdGhpcy5faCA9IChoICsgdGhpcy5faCkgfCAwXG59XG5cblNoYTI1Ni5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gQnVmZmVyLmFsbG9jVW5zYWZlKDMyKVxuXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2EsIDApXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2IsIDQpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2MsIDgpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2QsIDEyKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9lLCAxNilcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZiwgMjApXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2csIDI0KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9oLCAyOClcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYTI1NlxuIiwidmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIFNIQTUxMiA9IHJlcXVpcmUoJy4vc2hhNTEyJylcbnZhciBIYXNoID0gcmVxdWlyZSgnLi9oYXNoJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxuXG52YXIgVyA9IG5ldyBBcnJheSgxNjApXG5cbmZ1bmN0aW9uIFNoYTM4NCAoKSB7XG4gIHRoaXMuaW5pdCgpXG4gIHRoaXMuX3cgPSBXXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDEyOCwgMTEyKVxufVxuXG5pbmhlcml0cyhTaGEzODQsIFNIQTUxMilcblxuU2hhMzg0LnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9haCA9IDB4Y2JiYjlkNWRcbiAgdGhpcy5fYmggPSAweDYyOWEyOTJhXG4gIHRoaXMuX2NoID0gMHg5MTU5MDE1YVxuICB0aGlzLl9kaCA9IDB4MTUyZmVjZDhcbiAgdGhpcy5fZWggPSAweDY3MzMyNjY3XG4gIHRoaXMuX2ZoID0gMHg4ZWI0NGE4N1xuICB0aGlzLl9naCA9IDB4ZGIwYzJlMGRcbiAgdGhpcy5faGggPSAweDQ3YjU0ODFkXG5cbiAgdGhpcy5fYWwgPSAweGMxMDU5ZWQ4XG4gIHRoaXMuX2JsID0gMHgzNjdjZDUwN1xuICB0aGlzLl9jbCA9IDB4MzA3MGRkMTdcbiAgdGhpcy5fZGwgPSAweGY3MGU1OTM5XG4gIHRoaXMuX2VsID0gMHhmZmMwMGIzMVxuICB0aGlzLl9mbCA9IDB4Njg1ODE1MTFcbiAgdGhpcy5fZ2wgPSAweDY0Zjk4ZmE3XG4gIHRoaXMuX2hsID0gMHhiZWZhNGZhNFxuXG4gIHJldHVybiB0aGlzXG59XG5cblNoYTM4NC5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gQnVmZmVyLmFsbG9jVW5zYWZlKDQ4KVxuXG4gIGZ1bmN0aW9uIHdyaXRlSW50NjRCRSAoaCwgbCwgb2Zmc2V0KSB7XG4gICAgSC53cml0ZUludDMyQkUoaCwgb2Zmc2V0KVxuICAgIEgud3JpdGVJbnQzMkJFKGwsIG9mZnNldCArIDQpXG4gIH1cblxuICB3cml0ZUludDY0QkUodGhpcy5fYWgsIHRoaXMuX2FsLCAwKVxuICB3cml0ZUludDY0QkUodGhpcy5fYmgsIHRoaXMuX2JsLCA4KVxuICB3cml0ZUludDY0QkUodGhpcy5fY2gsIHRoaXMuX2NsLCAxNilcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2RoLCB0aGlzLl9kbCwgMjQpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9laCwgdGhpcy5fZWwsIDMyKVxuICB3cml0ZUludDY0QkUodGhpcy5fZmgsIHRoaXMuX2ZsLCA0MClcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYTM4NFxuIiwidmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG5cbnZhciBLID0gW1xuICAweDQyOGEyZjk4LCAweGQ3MjhhZTIyLCAweDcxMzc0NDkxLCAweDIzZWY2NWNkLFxuICAweGI1YzBmYmNmLCAweGVjNGQzYjJmLCAweGU5YjVkYmE1LCAweDgxODlkYmJjLFxuICAweDM5NTZjMjViLCAweGYzNDhiNTM4LCAweDU5ZjExMWYxLCAweGI2MDVkMDE5LFxuICAweDkyM2Y4MmE0LCAweGFmMTk0ZjliLCAweGFiMWM1ZWQ1LCAweGRhNmQ4MTE4LFxuICAweGQ4MDdhYTk4LCAweGEzMDMwMjQyLCAweDEyODM1YjAxLCAweDQ1NzA2ZmJlLFxuICAweDI0MzE4NWJlLCAweDRlZTRiMjhjLCAweDU1MGM3ZGMzLCAweGQ1ZmZiNGUyLFxuICAweDcyYmU1ZDc0LCAweGYyN2I4OTZmLCAweDgwZGViMWZlLCAweDNiMTY5NmIxLFxuICAweDliZGMwNmE3LCAweDI1YzcxMjM1LCAweGMxOWJmMTc0LCAweGNmNjkyNjk0LFxuICAweGU0OWI2OWMxLCAweDllZjE0YWQyLCAweGVmYmU0Nzg2LCAweDM4NGYyNWUzLFxuICAweDBmYzE5ZGM2LCAweDhiOGNkNWI1LCAweDI0MGNhMWNjLCAweDc3YWM5YzY1LFxuICAweDJkZTkyYzZmLCAweDU5MmIwMjc1LCAweDRhNzQ4NGFhLCAweDZlYTZlNDgzLFxuICAweDVjYjBhOWRjLCAweGJkNDFmYmQ0LCAweDc2Zjk4OGRhLCAweDgzMTE1M2I1LFxuICAweDk4M2U1MTUyLCAweGVlNjZkZmFiLCAweGE4MzFjNjZkLCAweDJkYjQzMjEwLFxuICAweGIwMDMyN2M4LCAweDk4ZmIyMTNmLCAweGJmNTk3ZmM3LCAweGJlZWYwZWU0LFxuICAweGM2ZTAwYmYzLCAweDNkYTg4ZmMyLCAweGQ1YTc5MTQ3LCAweDkzMGFhNzI1LFxuICAweDA2Y2E2MzUxLCAweGUwMDM4MjZmLCAweDE0MjkyOTY3LCAweDBhMGU2ZTcwLFxuICAweDI3YjcwYTg1LCAweDQ2ZDIyZmZjLCAweDJlMWIyMTM4LCAweDVjMjZjOTI2LFxuICAweDRkMmM2ZGZjLCAweDVhYzQyYWVkLCAweDUzMzgwZDEzLCAweDlkOTViM2RmLFxuICAweDY1MGE3MzU0LCAweDhiYWY2M2RlLCAweDc2NmEwYWJiLCAweDNjNzdiMmE4LFxuICAweDgxYzJjOTJlLCAweDQ3ZWRhZWU2LCAweDkyNzIyYzg1LCAweDE0ODIzNTNiLFxuICAweGEyYmZlOGExLCAweDRjZjEwMzY0LCAweGE4MWE2NjRiLCAweGJjNDIzMDAxLFxuICAweGMyNGI4YjcwLCAweGQwZjg5NzkxLCAweGM3NmM1MWEzLCAweDA2NTRiZTMwLFxuICAweGQxOTJlODE5LCAweGQ2ZWY1MjE4LCAweGQ2OTkwNjI0LCAweDU1NjVhOTEwLFxuICAweGY0MGUzNTg1LCAweDU3NzEyMDJhLCAweDEwNmFhMDcwLCAweDMyYmJkMWI4LFxuICAweDE5YTRjMTE2LCAweGI4ZDJkMGM4LCAweDFlMzc2YzA4LCAweDUxNDFhYjUzLFxuICAweDI3NDg3NzRjLCAweGRmOGVlYjk5LCAweDM0YjBiY2I1LCAweGUxOWI0OGE4LFxuICAweDM5MWMwY2IzLCAweGM1Yzk1YTYzLCAweDRlZDhhYTRhLCAweGUzNDE4YWNiLFxuICAweDViOWNjYTRmLCAweDc3NjNlMzczLCAweDY4MmU2ZmYzLCAweGQ2YjJiOGEzLFxuICAweDc0OGY4MmVlLCAweDVkZWZiMmZjLCAweDc4YTU2MzZmLCAweDQzMTcyZjYwLFxuICAweDg0Yzg3ODE0LCAweGExZjBhYjcyLCAweDhjYzcwMjA4LCAweDFhNjQzOWVjLFxuICAweDkwYmVmZmZhLCAweDIzNjMxZTI4LCAweGE0NTA2Y2ViLCAweGRlODJiZGU5LFxuICAweGJlZjlhM2Y3LCAweGIyYzY3OTE1LCAweGM2NzE3OGYyLCAweGUzNzI1MzJiLFxuICAweGNhMjczZWNlLCAweGVhMjY2MTljLCAweGQxODZiOGM3LCAweDIxYzBjMjA3LFxuICAweGVhZGE3ZGQ2LCAweGNkZTBlYjFlLCAweGY1N2Q0ZjdmLCAweGVlNmVkMTc4LFxuICAweDA2ZjA2N2FhLCAweDcyMTc2ZmJhLCAweDBhNjM3ZGM1LCAweGEyYzg5OGE2LFxuICAweDExM2Y5ODA0LCAweGJlZjkwZGFlLCAweDFiNzEwYjM1LCAweDEzMWM0NzFiLFxuICAweDI4ZGI3N2Y1LCAweDIzMDQ3ZDg0LCAweDMyY2FhYjdiLCAweDQwYzcyNDkzLFxuICAweDNjOWViZTBhLCAweDE1YzliZWJjLCAweDQzMWQ2N2M0LCAweDljMTAwZDRjLFxuICAweDRjYzVkNGJlLCAweGNiM2U0MmI2LCAweDU5N2YyOTljLCAweGZjNjU3ZTJhLFxuICAweDVmY2I2ZmFiLCAweDNhZDZmYWVjLCAweDZjNDQxOThjLCAweDRhNDc1ODE3XG5dXG5cbnZhciBXID0gbmV3IEFycmF5KDE2MClcblxuZnVuY3Rpb24gU2hhNTEyICgpIHtcbiAgdGhpcy5pbml0KClcbiAgdGhpcy5fdyA9IFdcblxuICBIYXNoLmNhbGwodGhpcywgMTI4LCAxMTIpXG59XG5cbmluaGVyaXRzKFNoYTUxMiwgSGFzaClcblxuU2hhNTEyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9haCA9IDB4NmEwOWU2NjdcbiAgdGhpcy5fYmggPSAweGJiNjdhZTg1XG4gIHRoaXMuX2NoID0gMHgzYzZlZjM3MlxuICB0aGlzLl9kaCA9IDB4YTU0ZmY1M2FcbiAgdGhpcy5fZWggPSAweDUxMGU1MjdmXG4gIHRoaXMuX2ZoID0gMHg5YjA1Njg4Y1xuICB0aGlzLl9naCA9IDB4MWY4M2Q5YWJcbiAgdGhpcy5faGggPSAweDViZTBjZDE5XG5cbiAgdGhpcy5fYWwgPSAweGYzYmNjOTA4XG4gIHRoaXMuX2JsID0gMHg4NGNhYTczYlxuICB0aGlzLl9jbCA9IDB4ZmU5NGY4MmJcbiAgdGhpcy5fZGwgPSAweDVmMWQzNmYxXG4gIHRoaXMuX2VsID0gMHhhZGU2ODJkMVxuICB0aGlzLl9mbCA9IDB4MmIzZTZjMWZcbiAgdGhpcy5fZ2wgPSAweGZiNDFiZDZiXG4gIHRoaXMuX2hsID0gMHgxMzdlMjE3OVxuXG4gIHJldHVybiB0aGlzXG59XG5cbmZ1bmN0aW9uIENoICh4LCB5LCB6KSB7XG4gIHJldHVybiB6IF4gKHggJiAoeSBeIHopKVxufVxuXG5mdW5jdGlvbiBtYWogKHgsIHksIHopIHtcbiAgcmV0dXJuICh4ICYgeSkgfCAoeiAmICh4IHwgeSkpXG59XG5cbmZ1bmN0aW9uIHNpZ21hMCAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAyOCB8IHhsIDw8IDQpIF4gKHhsID4+PiAyIHwgeCA8PCAzMCkgXiAoeGwgPj4+IDcgfCB4IDw8IDI1KVxufVxuXG5mdW5jdGlvbiBzaWdtYTEgKHgsIHhsKSB7XG4gIHJldHVybiAoeCA+Pj4gMTQgfCB4bCA8PCAxOCkgXiAoeCA+Pj4gMTggfCB4bCA8PCAxNCkgXiAoeGwgPj4+IDkgfCB4IDw8IDIzKVxufVxuXG5mdW5jdGlvbiBHYW1tYTAgKHgsIHhsKSB7XG4gIHJldHVybiAoeCA+Pj4gMSB8IHhsIDw8IDMxKSBeICh4ID4+PiA4IHwgeGwgPDwgMjQpIF4gKHggPj4+IDcpXG59XG5cbmZ1bmN0aW9uIEdhbW1hMGwgKHgsIHhsKSB7XG4gIHJldHVybiAoeCA+Pj4gMSB8IHhsIDw8IDMxKSBeICh4ID4+PiA4IHwgeGwgPDwgMjQpIF4gKHggPj4+IDcgfCB4bCA8PCAyNSlcbn1cblxuZnVuY3Rpb24gR2FtbWExICh4LCB4bCkge1xuICByZXR1cm4gKHggPj4+IDE5IHwgeGwgPDwgMTMpIF4gKHhsID4+PiAyOSB8IHggPDwgMykgXiAoeCA+Pj4gNilcbn1cblxuZnVuY3Rpb24gR2FtbWExbCAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxOSB8IHhsIDw8IDEzKSBeICh4bCA+Pj4gMjkgfCB4IDw8IDMpIF4gKHggPj4+IDYgfCB4bCA8PCAyNilcbn1cblxuZnVuY3Rpb24gZ2V0Q2FycnkgKGEsIGIpIHtcbiAgcmV0dXJuIChhID4+PiAwKSA8IChiID4+PiAwKSA/IDEgOiAwXG59XG5cblNoYTUxMi5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChNKSB7XG4gIHZhciBXID0gdGhpcy5fd1xuXG4gIHZhciBhaCA9IHRoaXMuX2FoIHwgMFxuICB2YXIgYmggPSB0aGlzLl9iaCB8IDBcbiAgdmFyIGNoID0gdGhpcy5fY2ggfCAwXG4gIHZhciBkaCA9IHRoaXMuX2RoIHwgMFxuICB2YXIgZWggPSB0aGlzLl9laCB8IDBcbiAgdmFyIGZoID0gdGhpcy5fZmggfCAwXG4gIHZhciBnaCA9IHRoaXMuX2doIHwgMFxuICB2YXIgaGggPSB0aGlzLl9oaCB8IDBcblxuICB2YXIgYWwgPSB0aGlzLl9hbCB8IDBcbiAgdmFyIGJsID0gdGhpcy5fYmwgfCAwXG4gIHZhciBjbCA9IHRoaXMuX2NsIHwgMFxuICB2YXIgZGwgPSB0aGlzLl9kbCB8IDBcbiAgdmFyIGVsID0gdGhpcy5fZWwgfCAwXG4gIHZhciBmbCA9IHRoaXMuX2ZsIHwgMFxuICB2YXIgZ2wgPSB0aGlzLl9nbCB8IDBcbiAgdmFyIGhsID0gdGhpcy5faGwgfCAwXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAzMjsgaSArPSAyKSB7XG4gICAgV1tpXSA9IE0ucmVhZEludDMyQkUoaSAqIDQpXG4gICAgV1tpICsgMV0gPSBNLnJlYWRJbnQzMkJFKGkgKiA0ICsgNClcbiAgfVxuICBmb3IgKDsgaSA8IDE2MDsgaSArPSAyKSB7XG4gICAgdmFyIHhoID0gV1tpIC0gMTUgKiAyXVxuICAgIHZhciB4bCA9IFdbaSAtIDE1ICogMiArIDFdXG4gICAgdmFyIGdhbW1hMCA9IEdhbW1hMCh4aCwgeGwpXG4gICAgdmFyIGdhbW1hMGwgPSBHYW1tYTBsKHhsLCB4aClcblxuICAgIHhoID0gV1tpIC0gMiAqIDJdXG4gICAgeGwgPSBXW2kgLSAyICogMiArIDFdXG4gICAgdmFyIGdhbW1hMSA9IEdhbW1hMSh4aCwgeGwpXG4gICAgdmFyIGdhbW1hMWwgPSBHYW1tYTFsKHhsLCB4aClcblxuICAgIC8vIFdbaV0gPSBnYW1tYTAgKyBXW2kgLSA3XSArIGdhbW1hMSArIFdbaSAtIDE2XVxuICAgIHZhciBXaTdoID0gV1tpIC0gNyAqIDJdXG4gICAgdmFyIFdpN2wgPSBXW2kgLSA3ICogMiArIDFdXG5cbiAgICB2YXIgV2kxNmggPSBXW2kgLSAxNiAqIDJdXG4gICAgdmFyIFdpMTZsID0gV1tpIC0gMTYgKiAyICsgMV1cblxuICAgIHZhciBXaWwgPSAoZ2FtbWEwbCArIFdpN2wpIHwgMFxuICAgIHZhciBXaWggPSAoZ2FtbWEwICsgV2k3aCArIGdldENhcnJ5KFdpbCwgZ2FtbWEwbCkpIHwgMFxuICAgIFdpbCA9IChXaWwgKyBnYW1tYTFsKSB8IDBcbiAgICBXaWggPSAoV2loICsgZ2FtbWExICsgZ2V0Q2FycnkoV2lsLCBnYW1tYTFsKSkgfCAwXG4gICAgV2lsID0gKFdpbCArIFdpMTZsKSB8IDBcbiAgICBXaWggPSAoV2loICsgV2kxNmggKyBnZXRDYXJyeShXaWwsIFdpMTZsKSkgfCAwXG5cbiAgICBXW2ldID0gV2loXG4gICAgV1tpICsgMV0gPSBXaWxcbiAgfVxuXG4gIGZvciAodmFyIGogPSAwOyBqIDwgMTYwOyBqICs9IDIpIHtcbiAgICBXaWggPSBXW2pdXG4gICAgV2lsID0gV1tqICsgMV1cblxuICAgIHZhciBtYWpoID0gbWFqKGFoLCBiaCwgY2gpXG4gICAgdmFyIG1hamwgPSBtYWooYWwsIGJsLCBjbClcblxuICAgIHZhciBzaWdtYTBoID0gc2lnbWEwKGFoLCBhbClcbiAgICB2YXIgc2lnbWEwbCA9IHNpZ21hMChhbCwgYWgpXG4gICAgdmFyIHNpZ21hMWggPSBzaWdtYTEoZWgsIGVsKVxuICAgIHZhciBzaWdtYTFsID0gc2lnbWExKGVsLCBlaClcblxuICAgIC8vIHQxID0gaCArIHNpZ21hMSArIGNoICsgS1tqXSArIFdbal1cbiAgICB2YXIgS2loID0gS1tqXVxuICAgIHZhciBLaWwgPSBLW2ogKyAxXVxuXG4gICAgdmFyIGNoaCA9IENoKGVoLCBmaCwgZ2gpXG4gICAgdmFyIGNobCA9IENoKGVsLCBmbCwgZ2wpXG5cbiAgICB2YXIgdDFsID0gKGhsICsgc2lnbWExbCkgfCAwXG4gICAgdmFyIHQxaCA9IChoaCArIHNpZ21hMWggKyBnZXRDYXJyeSh0MWwsIGhsKSkgfCAwXG4gICAgdDFsID0gKHQxbCArIGNobCkgfCAwXG4gICAgdDFoID0gKHQxaCArIGNoaCArIGdldENhcnJ5KHQxbCwgY2hsKSkgfCAwXG4gICAgdDFsID0gKHQxbCArIEtpbCkgfCAwXG4gICAgdDFoID0gKHQxaCArIEtpaCArIGdldENhcnJ5KHQxbCwgS2lsKSkgfCAwXG4gICAgdDFsID0gKHQxbCArIFdpbCkgfCAwXG4gICAgdDFoID0gKHQxaCArIFdpaCArIGdldENhcnJ5KHQxbCwgV2lsKSkgfCAwXG5cbiAgICAvLyB0MiA9IHNpZ21hMCArIG1halxuICAgIHZhciB0MmwgPSAoc2lnbWEwbCArIG1hamwpIHwgMFxuICAgIHZhciB0MmggPSAoc2lnbWEwaCArIG1hamggKyBnZXRDYXJyeSh0MmwsIHNpZ21hMGwpKSB8IDBcblxuICAgIGhoID0gZ2hcbiAgICBobCA9IGdsXG4gICAgZ2ggPSBmaFxuICAgIGdsID0gZmxcbiAgICBmaCA9IGVoXG4gICAgZmwgPSBlbFxuICAgIGVsID0gKGRsICsgdDFsKSB8IDBcbiAgICBlaCA9IChkaCArIHQxaCArIGdldENhcnJ5KGVsLCBkbCkpIHwgMFxuICAgIGRoID0gY2hcbiAgICBkbCA9IGNsXG4gICAgY2ggPSBiaFxuICAgIGNsID0gYmxcbiAgICBiaCA9IGFoXG4gICAgYmwgPSBhbFxuICAgIGFsID0gKHQxbCArIHQybCkgfCAwXG4gICAgYWggPSAodDFoICsgdDJoICsgZ2V0Q2FycnkoYWwsIHQxbCkpIHwgMFxuICB9XG5cbiAgdGhpcy5fYWwgPSAodGhpcy5fYWwgKyBhbCkgfCAwXG4gIHRoaXMuX2JsID0gKHRoaXMuX2JsICsgYmwpIHwgMFxuICB0aGlzLl9jbCA9ICh0aGlzLl9jbCArIGNsKSB8IDBcbiAgdGhpcy5fZGwgPSAodGhpcy5fZGwgKyBkbCkgfCAwXG4gIHRoaXMuX2VsID0gKHRoaXMuX2VsICsgZWwpIHwgMFxuICB0aGlzLl9mbCA9ICh0aGlzLl9mbCArIGZsKSB8IDBcbiAgdGhpcy5fZ2wgPSAodGhpcy5fZ2wgKyBnbCkgfCAwXG4gIHRoaXMuX2hsID0gKHRoaXMuX2hsICsgaGwpIHwgMFxuXG4gIHRoaXMuX2FoID0gKHRoaXMuX2FoICsgYWggKyBnZXRDYXJyeSh0aGlzLl9hbCwgYWwpKSB8IDBcbiAgdGhpcy5fYmggPSAodGhpcy5fYmggKyBiaCArIGdldENhcnJ5KHRoaXMuX2JsLCBibCkpIHwgMFxuICB0aGlzLl9jaCA9ICh0aGlzLl9jaCArIGNoICsgZ2V0Q2FycnkodGhpcy5fY2wsIGNsKSkgfCAwXG4gIHRoaXMuX2RoID0gKHRoaXMuX2RoICsgZGggKyBnZXRDYXJyeSh0aGlzLl9kbCwgZGwpKSB8IDBcbiAgdGhpcy5fZWggPSAodGhpcy5fZWggKyBlaCArIGdldENhcnJ5KHRoaXMuX2VsLCBlbCkpIHwgMFxuICB0aGlzLl9maCA9ICh0aGlzLl9maCArIGZoICsgZ2V0Q2FycnkodGhpcy5fZmwsIGZsKSkgfCAwXG4gIHRoaXMuX2doID0gKHRoaXMuX2doICsgZ2ggKyBnZXRDYXJyeSh0aGlzLl9nbCwgZ2wpKSB8IDBcbiAgdGhpcy5faGggPSAodGhpcy5faGggKyBoaCArIGdldENhcnJ5KHRoaXMuX2hsLCBobCkpIHwgMFxufVxuXG5TaGE1MTIucHJvdG90eXBlLl9oYXNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgSCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSg2NClcblxuICBmdW5jdGlvbiB3cml0ZUludDY0QkUgKGgsIGwsIG9mZnNldCkge1xuICAgIEgud3JpdGVJbnQzMkJFKGgsIG9mZnNldClcbiAgICBILndyaXRlSW50MzJCRShsLCBvZmZzZXQgKyA0KVxuICB9XG5cbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2FoLCB0aGlzLl9hbCwgMClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2JoLCB0aGlzLl9ibCwgOClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2NoLCB0aGlzLl9jbCwgMTYpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9kaCwgdGhpcy5fZGwsIDI0KVxuICB3cml0ZUludDY0QkUodGhpcy5fZWgsIHRoaXMuX2VsLCAzMilcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2ZoLCB0aGlzLl9mbCwgNDApXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9naCwgdGhpcy5fZ2wsIDQ4KVxuICB3cml0ZUludDY0QkUodGhpcy5faGgsIHRoaXMuX2hsLCA1NilcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYTUxMlxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbm1vZHVsZS5leHBvcnRzID0gU3RyZWFtO1xuXG52YXIgRUUgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG5pbmhlcml0cyhTdHJlYW0sIEVFKTtcblN0cmVhbS5SZWFkYWJsZSA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbS9yZWFkYWJsZS5qcycpO1xuU3RyZWFtLldyaXRhYmxlID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL3dyaXRhYmxlLmpzJyk7XG5TdHJlYW0uRHVwbGV4ID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL2R1cGxleC5qcycpO1xuU3RyZWFtLlRyYW5zZm9ybSA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbS90cmFuc2Zvcm0uanMnKTtcblN0cmVhbS5QYXNzVGhyb3VnaCA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbS9wYXNzdGhyb3VnaC5qcycpO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjQueFxuU3RyZWFtLlN0cmVhbSA9IFN0cmVhbTtcblxuXG5cbi8vIG9sZC1zdHlsZSBzdHJlYW1zLiAgTm90ZSB0aGF0IHRoZSBwaXBlIG1ldGhvZCAodGhlIG9ubHkgcmVsZXZhbnRcbi8vIHBhcnQgb2YgdGhpcyBjbGFzcykgaXMgb3ZlcnJpZGRlbiBpbiB0aGUgUmVhZGFibGUgY2xhc3MuXG5cbmZ1bmN0aW9uIFN0cmVhbSgpIHtcbiAgRUUuY2FsbCh0aGlzKTtcbn1cblxuU3RyZWFtLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24oZGVzdCwgb3B0aW9ucykge1xuICB2YXIgc291cmNlID0gdGhpcztcblxuICBmdW5jdGlvbiBvbmRhdGEoY2h1bmspIHtcbiAgICBpZiAoZGVzdC53cml0YWJsZSkge1xuICAgICAgaWYgKGZhbHNlID09PSBkZXN0LndyaXRlKGNodW5rKSAmJiBzb3VyY2UucGF1c2UpIHtcbiAgICAgICAgc291cmNlLnBhdXNlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc291cmNlLm9uKCdkYXRhJywgb25kYXRhKTtcblxuICBmdW5jdGlvbiBvbmRyYWluKCkge1xuICAgIGlmIChzb3VyY2UucmVhZGFibGUgJiYgc291cmNlLnJlc3VtZSkge1xuICAgICAgc291cmNlLnJlc3VtZSgpO1xuICAgIH1cbiAgfVxuXG4gIGRlc3Qub24oJ2RyYWluJywgb25kcmFpbik7XG5cbiAgLy8gSWYgdGhlICdlbmQnIG9wdGlvbiBpcyBub3Qgc3VwcGxpZWQsIGRlc3QuZW5kKCkgd2lsbCBiZSBjYWxsZWQgd2hlblxuICAvLyBzb3VyY2UgZ2V0cyB0aGUgJ2VuZCcgb3IgJ2Nsb3NlJyBldmVudHMuICBPbmx5IGRlc3QuZW5kKCkgb25jZS5cbiAgaWYgKCFkZXN0Ll9pc1N0ZGlvICYmICghb3B0aW9ucyB8fCBvcHRpb25zLmVuZCAhPT0gZmFsc2UpKSB7XG4gICAgc291cmNlLm9uKCdlbmQnLCBvbmVuZCk7XG4gICAgc291cmNlLm9uKCdjbG9zZScsIG9uY2xvc2UpO1xuICB9XG5cbiAgdmFyIGRpZE9uRW5kID0gZmFsc2U7XG4gIGZ1bmN0aW9uIG9uZW5kKCkge1xuICAgIGlmIChkaWRPbkVuZCkgcmV0dXJuO1xuICAgIGRpZE9uRW5kID0gdHJ1ZTtcblxuICAgIGRlc3QuZW5kKCk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIG9uY2xvc2UoKSB7XG4gICAgaWYgKGRpZE9uRW5kKSByZXR1cm47XG4gICAgZGlkT25FbmQgPSB0cnVlO1xuXG4gICAgaWYgKHR5cGVvZiBkZXN0LmRlc3Ryb3kgPT09ICdmdW5jdGlvbicpIGRlc3QuZGVzdHJveSgpO1xuICB9XG5cbiAgLy8gZG9uJ3QgbGVhdmUgZGFuZ2xpbmcgcGlwZXMgd2hlbiB0aGVyZSBhcmUgZXJyb3JzLlxuICBmdW5jdGlvbiBvbmVycm9yKGVyKSB7XG4gICAgY2xlYW51cCgpO1xuICAgIGlmIChFRS5saXN0ZW5lckNvdW50KHRoaXMsICdlcnJvcicpID09PSAwKSB7XG4gICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkIHN0cmVhbSBlcnJvciBpbiBwaXBlLlxuICAgIH1cbiAgfVxuXG4gIHNvdXJjZS5vbignZXJyb3InLCBvbmVycm9yKTtcbiAgZGVzdC5vbignZXJyb3InLCBvbmVycm9yKTtcblxuICAvLyByZW1vdmUgYWxsIHRoZSBldmVudCBsaXN0ZW5lcnMgdGhhdCB3ZXJlIGFkZGVkLlxuICBmdW5jdGlvbiBjbGVhbnVwKCkge1xuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZGF0YScsIG9uZGF0YSk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZHJhaW4nLCBvbmRyYWluKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25lbmQpO1xuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuXG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBjbGVhbnVwKTtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgY2xlYW51cCk7XG5cbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIGNsZWFudXApO1xuICB9XG5cbiAgc291cmNlLm9uKCdlbmQnLCBjbGVhbnVwKTtcbiAgc291cmNlLm9uKCdjbG9zZScsIGNsZWFudXApO1xuXG4gIGRlc3Qub24oJ2Nsb3NlJywgY2xlYW51cCk7XG5cbiAgZGVzdC5lbWl0KCdwaXBlJywgc291cmNlKTtcblxuICAvLyBBbGxvdyBmb3IgdW5peC1saWtlIHVzYWdlOiBBLnBpcGUoQikucGlwZShDKVxuICByZXR1cm4gZGVzdDtcbn07XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuJ3VzZSBzdHJpY3QnO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXI7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIGlzRW5jb2RpbmcgPSBCdWZmZXIuaXNFbmNvZGluZyB8fCBmdW5jdGlvbiAoZW5jb2RpbmcpIHtcbiAgZW5jb2RpbmcgPSAnJyArIGVuY29kaW5nO1xuICBzd2l0Y2ggKGVuY29kaW5nICYmIGVuY29kaW5nLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOmNhc2UgJ3V0ZjgnOmNhc2UgJ3V0Zi04JzpjYXNlICdhc2NpaSc6Y2FzZSAnYmluYXJ5JzpjYXNlICdiYXNlNjQnOmNhc2UgJ3VjczInOmNhc2UgJ3Vjcy0yJzpjYXNlICd1dGYxNmxlJzpjYXNlICd1dGYtMTZsZSc6Y2FzZSAncmF3JzpcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIF9ub3JtYWxpemVFbmNvZGluZyhlbmMpIHtcbiAgaWYgKCFlbmMpIHJldHVybiAndXRmOCc7XG4gIHZhciByZXRyaWVkO1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIHN3aXRjaCAoZW5jKSB7XG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuICd1dGY4JztcbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiAndXRmMTZsZSc7XG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuICdsYXRpbjEnO1xuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBlbmM7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAocmV0cmllZCkgcmV0dXJuOyAvLyB1bmRlZmluZWRcbiAgICAgICAgZW5jID0gKCcnICsgZW5jKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICByZXRyaWVkID0gdHJ1ZTtcbiAgICB9XG4gIH1cbn07XG5cbi8vIERvIG5vdCBjYWNoZSBgQnVmZmVyLmlzRW5jb2RpbmdgIHdoZW4gY2hlY2tpbmcgZW5jb2RpbmcgbmFtZXMgYXMgc29tZVxuLy8gbW9kdWxlcyBtb25rZXktcGF0Y2ggaXQgdG8gc3VwcG9ydCBhZGRpdGlvbmFsIGVuY29kaW5nc1xuZnVuY3Rpb24gbm9ybWFsaXplRW5jb2RpbmcoZW5jKSB7XG4gIHZhciBuZW5jID0gX25vcm1hbGl6ZUVuY29kaW5nKGVuYyk7XG4gIGlmICh0eXBlb2YgbmVuYyAhPT0gJ3N0cmluZycgJiYgKEJ1ZmZlci5pc0VuY29kaW5nID09PSBpc0VuY29kaW5nIHx8ICFpc0VuY29kaW5nKGVuYykpKSB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmMpO1xuICByZXR1cm4gbmVuYyB8fCBlbmM7XG59XG5cbi8vIFN0cmluZ0RlY29kZXIgcHJvdmlkZXMgYW4gaW50ZXJmYWNlIGZvciBlZmZpY2llbnRseSBzcGxpdHRpbmcgYSBzZXJpZXMgb2Zcbi8vIGJ1ZmZlcnMgaW50byBhIHNlcmllcyBvZiBKUyBzdHJpbmdzIHdpdGhvdXQgYnJlYWtpbmcgYXBhcnQgbXVsdGktYnl0ZVxuLy8gY2hhcmFjdGVycy5cbmV4cG9ydHMuU3RyaW5nRGVjb2RlciA9IFN0cmluZ0RlY29kZXI7XG5mdW5jdGlvbiBTdHJpbmdEZWNvZGVyKGVuY29kaW5nKSB7XG4gIHRoaXMuZW5jb2RpbmcgPSBub3JtYWxpemVFbmNvZGluZyhlbmNvZGluZyk7XG4gIHZhciBuYjtcbiAgc3dpdGNoICh0aGlzLmVuY29kaW5nKSB7XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICB0aGlzLnRleHQgPSB1dGYxNlRleHQ7XG4gICAgICB0aGlzLmVuZCA9IHV0ZjE2RW5kO1xuICAgICAgbmIgPSA0O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndXRmOCc6XG4gICAgICB0aGlzLmZpbGxMYXN0ID0gdXRmOEZpbGxMYXN0O1xuICAgICAgbmIgPSA0O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIHRoaXMudGV4dCA9IGJhc2U2NFRleHQ7XG4gICAgICB0aGlzLmVuZCA9IGJhc2U2NEVuZDtcbiAgICAgIG5iID0gMztcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aGlzLndyaXRlID0gc2ltcGxlV3JpdGU7XG4gICAgICB0aGlzLmVuZCA9IHNpbXBsZUVuZDtcbiAgICAgIHJldHVybjtcbiAgfVxuICB0aGlzLmxhc3ROZWVkID0gMDtcbiAgdGhpcy5sYXN0VG90YWwgPSAwO1xuICB0aGlzLmxhc3RDaGFyID0gQnVmZmVyLmFsbG9jVW5zYWZlKG5iKTtcbn1cblxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAoYnVmKSB7XG4gIGlmIChidWYubGVuZ3RoID09PSAwKSByZXR1cm4gJyc7XG4gIHZhciByO1xuICB2YXIgaTtcbiAgaWYgKHRoaXMubGFzdE5lZWQpIHtcbiAgICByID0gdGhpcy5maWxsTGFzdChidWYpO1xuICAgIGlmIChyID09PSB1bmRlZmluZWQpIHJldHVybiAnJztcbiAgICBpID0gdGhpcy5sYXN0TmVlZDtcbiAgICB0aGlzLmxhc3ROZWVkID0gMDtcbiAgfSBlbHNlIHtcbiAgICBpID0gMDtcbiAgfVxuICBpZiAoaSA8IGJ1Zi5sZW5ndGgpIHJldHVybiByID8gciArIHRoaXMudGV4dChidWYsIGkpIDogdGhpcy50ZXh0KGJ1ZiwgaSk7XG4gIHJldHVybiByIHx8ICcnO1xufTtcblxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZW5kID0gdXRmOEVuZDtcblxuLy8gUmV0dXJucyBvbmx5IGNvbXBsZXRlIGNoYXJhY3RlcnMgaW4gYSBCdWZmZXJcblN0cmluZ0RlY29kZXIucHJvdG90eXBlLnRleHQgPSB1dGY4VGV4dDtcblxuLy8gQXR0ZW1wdHMgdG8gY29tcGxldGUgYSBwYXJ0aWFsIG5vbi1VVEYtOCBjaGFyYWN0ZXIgdXNpbmcgYnl0ZXMgZnJvbSBhIEJ1ZmZlclxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZmlsbExhc3QgPSBmdW5jdGlvbiAoYnVmKSB7XG4gIGlmICh0aGlzLmxhc3ROZWVkIDw9IGJ1Zi5sZW5ndGgpIHtcbiAgICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCB0aGlzLmxhc3RUb3RhbCAtIHRoaXMubGFzdE5lZWQsIDAsIHRoaXMubGFzdE5lZWQpO1xuICAgIHJldHVybiB0aGlzLmxhc3RDaGFyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcsIDAsIHRoaXMubGFzdFRvdGFsKTtcbiAgfVxuICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCB0aGlzLmxhc3RUb3RhbCAtIHRoaXMubGFzdE5lZWQsIDAsIGJ1Zi5sZW5ndGgpO1xuICB0aGlzLmxhc3ROZWVkIC09IGJ1Zi5sZW5ndGg7XG59O1xuXG4vLyBDaGVja3MgdGhlIHR5cGUgb2YgYSBVVEYtOCBieXRlLCB3aGV0aGVyIGl0J3MgQVNDSUksIGEgbGVhZGluZyBieXRlLCBvciBhXG4vLyBjb250aW51YXRpb24gYnl0ZS4gSWYgYW4gaW52YWxpZCBieXRlIGlzIGRldGVjdGVkLCAtMiBpcyByZXR1cm5lZC5cbmZ1bmN0aW9uIHV0ZjhDaGVja0J5dGUoYnl0ZSkge1xuICBpZiAoYnl0ZSA8PSAweDdGKSByZXR1cm4gMDtlbHNlIGlmIChieXRlID4+IDUgPT09IDB4MDYpIHJldHVybiAyO2Vsc2UgaWYgKGJ5dGUgPj4gNCA9PT0gMHgwRSkgcmV0dXJuIDM7ZWxzZSBpZiAoYnl0ZSA+PiAzID09PSAweDFFKSByZXR1cm4gNDtcbiAgcmV0dXJuIGJ5dGUgPj4gNiA9PT0gMHgwMiA/IC0xIDogLTI7XG59XG5cbi8vIENoZWNrcyBhdCBtb3N0IDMgYnl0ZXMgYXQgdGhlIGVuZCBvZiBhIEJ1ZmZlciBpbiBvcmRlciB0byBkZXRlY3QgYW5cbi8vIGluY29tcGxldGUgbXVsdGktYnl0ZSBVVEYtOCBjaGFyYWN0ZXIuIFRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgKDIsIDMsIG9yIDQpXG4vLyBuZWVkZWQgdG8gY29tcGxldGUgdGhlIFVURi04IGNoYXJhY3RlciAoaWYgYXBwbGljYWJsZSkgYXJlIHJldHVybmVkLlxuZnVuY3Rpb24gdXRmOENoZWNrSW5jb21wbGV0ZShzZWxmLCBidWYsIGkpIHtcbiAgdmFyIGogPSBidWYubGVuZ3RoIC0gMTtcbiAgaWYgKGogPCBpKSByZXR1cm4gMDtcbiAgdmFyIG5iID0gdXRmOENoZWNrQnl0ZShidWZbal0pO1xuICBpZiAobmIgPj0gMCkge1xuICAgIGlmIChuYiA+IDApIHNlbGYubGFzdE5lZWQgPSBuYiAtIDE7XG4gICAgcmV0dXJuIG5iO1xuICB9XG4gIGlmICgtLWogPCBpIHx8IG5iID09PSAtMikgcmV0dXJuIDA7XG4gIG5iID0gdXRmOENoZWNrQnl0ZShidWZbal0pO1xuICBpZiAobmIgPj0gMCkge1xuICAgIGlmIChuYiA+IDApIHNlbGYubGFzdE5lZWQgPSBuYiAtIDI7XG4gICAgcmV0dXJuIG5iO1xuICB9XG4gIGlmICgtLWogPCBpIHx8IG5iID09PSAtMikgcmV0dXJuIDA7XG4gIG5iID0gdXRmOENoZWNrQnl0ZShidWZbal0pO1xuICBpZiAobmIgPj0gMCkge1xuICAgIGlmIChuYiA+IDApIHtcbiAgICAgIGlmIChuYiA9PT0gMikgbmIgPSAwO2Vsc2Ugc2VsZi5sYXN0TmVlZCA9IG5iIC0gMztcbiAgICB9XG4gICAgcmV0dXJuIG5iO1xuICB9XG4gIHJldHVybiAwO1xufVxuXG4vLyBWYWxpZGF0ZXMgYXMgbWFueSBjb250aW51YXRpb24gYnl0ZXMgZm9yIGEgbXVsdGktYnl0ZSBVVEYtOCBjaGFyYWN0ZXIgYXNcbi8vIG5lZWRlZCBvciBhcmUgYXZhaWxhYmxlLiBJZiB3ZSBzZWUgYSBub24tY29udGludWF0aW9uIGJ5dGUgd2hlcmUgd2UgZXhwZWN0XG4vLyBvbmUsIHdlIFwicmVwbGFjZVwiIHRoZSB2YWxpZGF0ZWQgY29udGludWF0aW9uIGJ5dGVzIHdlJ3ZlIHNlZW4gc28gZmFyIHdpdGhcbi8vIGEgc2luZ2xlIFVURi04IHJlcGxhY2VtZW50IGNoYXJhY3RlciAoJ1xcdWZmZmQnKSwgdG8gbWF0Y2ggdjgncyBVVEYtOCBkZWNvZGluZ1xuLy8gYmVoYXZpb3IuIFRoZSBjb250aW51YXRpb24gYnl0ZSBjaGVjayBpcyBpbmNsdWRlZCB0aHJlZSB0aW1lcyBpbiB0aGUgY2FzZVxuLy8gd2hlcmUgYWxsIG9mIHRoZSBjb250aW51YXRpb24gYnl0ZXMgZm9yIGEgY2hhcmFjdGVyIGV4aXN0IGluIHRoZSBzYW1lIGJ1ZmZlci5cbi8vIEl0IGlzIGFsc28gZG9uZSB0aGlzIHdheSBhcyBhIHNsaWdodCBwZXJmb3JtYW5jZSBpbmNyZWFzZSBpbnN0ZWFkIG9mIHVzaW5nIGFcbi8vIGxvb3AuXG5mdW5jdGlvbiB1dGY4Q2hlY2tFeHRyYUJ5dGVzKHNlbGYsIGJ1ZiwgcCkge1xuICBpZiAoKGJ1ZlswXSAmIDB4QzApICE9PSAweDgwKSB7XG4gICAgc2VsZi5sYXN0TmVlZCA9IDA7XG4gICAgcmV0dXJuICdcXHVmZmZkJztcbiAgfVxuICBpZiAoc2VsZi5sYXN0TmVlZCA+IDEgJiYgYnVmLmxlbmd0aCA+IDEpIHtcbiAgICBpZiAoKGJ1ZlsxXSAmIDB4QzApICE9PSAweDgwKSB7XG4gICAgICBzZWxmLmxhc3ROZWVkID0gMTtcbiAgICAgIHJldHVybiAnXFx1ZmZmZCc7XG4gICAgfVxuICAgIGlmIChzZWxmLmxhc3ROZWVkID4gMiAmJiBidWYubGVuZ3RoID4gMikge1xuICAgICAgaWYgKChidWZbMl0gJiAweEMwKSAhPT0gMHg4MCkge1xuICAgICAgICBzZWxmLmxhc3ROZWVkID0gMjtcbiAgICAgICAgcmV0dXJuICdcXHVmZmZkJztcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLy8gQXR0ZW1wdHMgdG8gY29tcGxldGUgYSBtdWx0aS1ieXRlIFVURi04IGNoYXJhY3RlciB1c2luZyBieXRlcyBmcm9tIGEgQnVmZmVyLlxuZnVuY3Rpb24gdXRmOEZpbGxMYXN0KGJ1Zikge1xuICB2YXIgcCA9IHRoaXMubGFzdFRvdGFsIC0gdGhpcy5sYXN0TmVlZDtcbiAgdmFyIHIgPSB1dGY4Q2hlY2tFeHRyYUJ5dGVzKHRoaXMsIGJ1ZiwgcCk7XG4gIGlmIChyICE9PSB1bmRlZmluZWQpIHJldHVybiByO1xuICBpZiAodGhpcy5sYXN0TmVlZCA8PSBidWYubGVuZ3RoKSB7XG4gICAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgcCwgMCwgdGhpcy5sYXN0TmVlZCk7XG4gICAgcmV0dXJuIHRoaXMubGFzdENoYXIudG9TdHJpbmcodGhpcy5lbmNvZGluZywgMCwgdGhpcy5sYXN0VG90YWwpO1xuICB9XG4gIGJ1Zi5jb3B5KHRoaXMubGFzdENoYXIsIHAsIDAsIGJ1Zi5sZW5ndGgpO1xuICB0aGlzLmxhc3ROZWVkIC09IGJ1Zi5sZW5ndGg7XG59XG5cbi8vIFJldHVybnMgYWxsIGNvbXBsZXRlIFVURi04IGNoYXJhY3RlcnMgaW4gYSBCdWZmZXIuIElmIHRoZSBCdWZmZXIgZW5kZWQgb24gYVxuLy8gcGFydGlhbCBjaGFyYWN0ZXIsIHRoZSBjaGFyYWN0ZXIncyBieXRlcyBhcmUgYnVmZmVyZWQgdW50aWwgdGhlIHJlcXVpcmVkXG4vLyBudW1iZXIgb2YgYnl0ZXMgYXJlIGF2YWlsYWJsZS5cbmZ1bmN0aW9uIHV0ZjhUZXh0KGJ1ZiwgaSkge1xuICB2YXIgdG90YWwgPSB1dGY4Q2hlY2tJbmNvbXBsZXRlKHRoaXMsIGJ1ZiwgaSk7XG4gIGlmICghdGhpcy5sYXN0TmVlZCkgcmV0dXJuIGJ1Zi50b1N0cmluZygndXRmOCcsIGkpO1xuICB0aGlzLmxhc3RUb3RhbCA9IHRvdGFsO1xuICB2YXIgZW5kID0gYnVmLmxlbmd0aCAtICh0b3RhbCAtIHRoaXMubGFzdE5lZWQpO1xuICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCAwLCBlbmQpO1xuICByZXR1cm4gYnVmLnRvU3RyaW5nKCd1dGY4JywgaSwgZW5kKTtcbn1cblxuLy8gRm9yIFVURi04LCBhIHJlcGxhY2VtZW50IGNoYXJhY3RlciBpcyBhZGRlZCB3aGVuIGVuZGluZyBvbiBhIHBhcnRpYWxcbi8vIGNoYXJhY3Rlci5cbmZ1bmN0aW9uIHV0ZjhFbmQoYnVmKSB7XG4gIHZhciByID0gYnVmICYmIGJ1Zi5sZW5ndGggPyB0aGlzLndyaXRlKGJ1ZikgOiAnJztcbiAgaWYgKHRoaXMubGFzdE5lZWQpIHJldHVybiByICsgJ1xcdWZmZmQnO1xuICByZXR1cm4gcjtcbn1cblxuLy8gVVRGLTE2TEUgdHlwaWNhbGx5IG5lZWRzIHR3byBieXRlcyBwZXIgY2hhcmFjdGVyLCBidXQgZXZlbiBpZiB3ZSBoYXZlIGFuIGV2ZW5cbi8vIG51bWJlciBvZiBieXRlcyBhdmFpbGFibGUsIHdlIG5lZWQgdG8gY2hlY2sgaWYgd2UgZW5kIG9uIGEgbGVhZGluZy9oaWdoXG4vLyBzdXJyb2dhdGUuIEluIHRoYXQgY2FzZSwgd2UgbmVlZCB0byB3YWl0IGZvciB0aGUgbmV4dCB0d28gYnl0ZXMgaW4gb3JkZXIgdG9cbi8vIGRlY29kZSB0aGUgbGFzdCBjaGFyYWN0ZXIgcHJvcGVybHkuXG5mdW5jdGlvbiB1dGYxNlRleHQoYnVmLCBpKSB7XG4gIGlmICgoYnVmLmxlbmd0aCAtIGkpICUgMiA9PT0gMCkge1xuICAgIHZhciByID0gYnVmLnRvU3RyaW5nKCd1dGYxNmxlJywgaSk7XG4gICAgaWYgKHIpIHtcbiAgICAgIHZhciBjID0gci5jaGFyQ29kZUF0KHIubGVuZ3RoIC0gMSk7XG4gICAgICBpZiAoYyA+PSAweEQ4MDAgJiYgYyA8PSAweERCRkYpIHtcbiAgICAgICAgdGhpcy5sYXN0TmVlZCA9IDI7XG4gICAgICAgIHRoaXMubGFzdFRvdGFsID0gNDtcbiAgICAgICAgdGhpcy5sYXN0Q2hhclswXSA9IGJ1ZltidWYubGVuZ3RoIC0gMl07XG4gICAgICAgIHRoaXMubGFzdENoYXJbMV0gPSBidWZbYnVmLmxlbmd0aCAtIDFdO1xuICAgICAgICByZXR1cm4gci5zbGljZSgwLCAtMSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByO1xuICB9XG4gIHRoaXMubGFzdE5lZWQgPSAxO1xuICB0aGlzLmxhc3RUb3RhbCA9IDI7XG4gIHRoaXMubGFzdENoYXJbMF0gPSBidWZbYnVmLmxlbmd0aCAtIDFdO1xuICByZXR1cm4gYnVmLnRvU3RyaW5nKCd1dGYxNmxlJywgaSwgYnVmLmxlbmd0aCAtIDEpO1xufVxuXG4vLyBGb3IgVVRGLTE2TEUgd2UgZG8gbm90IGV4cGxpY2l0bHkgYXBwZW5kIHNwZWNpYWwgcmVwbGFjZW1lbnQgY2hhcmFjdGVycyBpZiB3ZVxuLy8gZW5kIG9uIGEgcGFydGlhbCBjaGFyYWN0ZXIsIHdlIHNpbXBseSBsZXQgdjggaGFuZGxlIHRoYXQuXG5mdW5jdGlvbiB1dGYxNkVuZChidWYpIHtcbiAgdmFyIHIgPSBidWYgJiYgYnVmLmxlbmd0aCA/IHRoaXMud3JpdGUoYnVmKSA6ICcnO1xuICBpZiAodGhpcy5sYXN0TmVlZCkge1xuICAgIHZhciBlbmQgPSB0aGlzLmxhc3RUb3RhbCAtIHRoaXMubGFzdE5lZWQ7XG4gICAgcmV0dXJuIHIgKyB0aGlzLmxhc3RDaGFyLnRvU3RyaW5nKCd1dGYxNmxlJywgMCwgZW5kKTtcbiAgfVxuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gYmFzZTY0VGV4dChidWYsIGkpIHtcbiAgdmFyIG4gPSAoYnVmLmxlbmd0aCAtIGkpICUgMztcbiAgaWYgKG4gPT09IDApIHJldHVybiBidWYudG9TdHJpbmcoJ2Jhc2U2NCcsIGkpO1xuICB0aGlzLmxhc3ROZWVkID0gMyAtIG47XG4gIHRoaXMubGFzdFRvdGFsID0gMztcbiAgaWYgKG4gPT09IDEpIHtcbiAgICB0aGlzLmxhc3RDaGFyWzBdID0gYnVmW2J1Zi5sZW5ndGggLSAxXTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmxhc3RDaGFyWzBdID0gYnVmW2J1Zi5sZW5ndGggLSAyXTtcbiAgICB0aGlzLmxhc3RDaGFyWzFdID0gYnVmW2J1Zi5sZW5ndGggLSAxXTtcbiAgfVxuICByZXR1cm4gYnVmLnRvU3RyaW5nKCdiYXNlNjQnLCBpLCBidWYubGVuZ3RoIC0gbik7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NEVuZChidWYpIHtcbiAgdmFyIHIgPSBidWYgJiYgYnVmLmxlbmd0aCA/IHRoaXMud3JpdGUoYnVmKSA6ICcnO1xuICBpZiAodGhpcy5sYXN0TmVlZCkgcmV0dXJuIHIgKyB0aGlzLmxhc3RDaGFyLnRvU3RyaW5nKCdiYXNlNjQnLCAwLCAzIC0gdGhpcy5sYXN0TmVlZCk7XG4gIHJldHVybiByO1xufVxuXG4vLyBQYXNzIGJ5dGVzIG9uIHRocm91Z2ggZm9yIHNpbmdsZS1ieXRlIGVuY29kaW5ncyAoZS5nLiBhc2NpaSwgbGF0aW4xLCBoZXgpXG5mdW5jdGlvbiBzaW1wbGVXcml0ZShidWYpIHtcbiAgcmV0dXJuIGJ1Zi50b1N0cmluZyh0aGlzLmVuY29kaW5nKTtcbn1cblxuZnVuY3Rpb24gc2ltcGxlRW5kKGJ1Zikge1xuICByZXR1cm4gYnVmICYmIGJ1Zi5sZW5ndGggPyB0aGlzLndyaXRlKGJ1ZikgOiAnJztcbn0iLCJ2YXIgc2NvcGUgPSAodHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBnbG9iYWwpIHx8XG4gICAgICAgICAgICAodHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgJiYgc2VsZikgfHxcbiAgICAgICAgICAgIHdpbmRvdztcbnZhciBhcHBseSA9IEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseTtcblxuLy8gRE9NIEFQSXMsIGZvciBjb21wbGV0ZW5lc3NcblxuZXhwb3J0cy5zZXRUaW1lb3V0ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBuZXcgVGltZW91dChhcHBseS5jYWxsKHNldFRpbWVvdXQsIHNjb3BlLCBhcmd1bWVudHMpLCBjbGVhclRpbWVvdXQpO1xufTtcbmV4cG9ydHMuc2V0SW50ZXJ2YWwgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIG5ldyBUaW1lb3V0KGFwcGx5LmNhbGwoc2V0SW50ZXJ2YWwsIHNjb3BlLCBhcmd1bWVudHMpLCBjbGVhckludGVydmFsKTtcbn07XG5leHBvcnRzLmNsZWFyVGltZW91dCA9XG5leHBvcnRzLmNsZWFySW50ZXJ2YWwgPSBmdW5jdGlvbih0aW1lb3V0KSB7XG4gIGlmICh0aW1lb3V0KSB7XG4gICAgdGltZW91dC5jbG9zZSgpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBUaW1lb3V0KGlkLCBjbGVhckZuKSB7XG4gIHRoaXMuX2lkID0gaWQ7XG4gIHRoaXMuX2NsZWFyRm4gPSBjbGVhckZuO1xufVxuVGltZW91dC5wcm90b3R5cGUudW5yZWYgPSBUaW1lb3V0LnByb3RvdHlwZS5yZWYgPSBmdW5jdGlvbigpIHt9O1xuVGltZW91dC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5fY2xlYXJGbi5jYWxsKHNjb3BlLCB0aGlzLl9pZCk7XG59O1xuXG4vLyBEb2VzIG5vdCBzdGFydCB0aGUgdGltZSwganVzdCBzZXRzIHVwIHRoZSBtZW1iZXJzIG5lZWRlZC5cbmV4cG9ydHMuZW5yb2xsID0gZnVuY3Rpb24oaXRlbSwgbXNlY3MpIHtcbiAgY2xlYXJUaW1lb3V0KGl0ZW0uX2lkbGVUaW1lb3V0SWQpO1xuICBpdGVtLl9pZGxlVGltZW91dCA9IG1zZWNzO1xufTtcblxuZXhwb3J0cy51bmVucm9sbCA9IGZ1bmN0aW9uKGl0ZW0pIHtcbiAgY2xlYXJUaW1lb3V0KGl0ZW0uX2lkbGVUaW1lb3V0SWQpO1xuICBpdGVtLl9pZGxlVGltZW91dCA9IC0xO1xufTtcblxuZXhwb3J0cy5fdW5yZWZBY3RpdmUgPSBleHBvcnRzLmFjdGl2ZSA9IGZ1bmN0aW9uKGl0ZW0pIHtcbiAgY2xlYXJUaW1lb3V0KGl0ZW0uX2lkbGVUaW1lb3V0SWQpO1xuXG4gIHZhciBtc2VjcyA9IGl0ZW0uX2lkbGVUaW1lb3V0O1xuICBpZiAobXNlY3MgPj0gMCkge1xuICAgIGl0ZW0uX2lkbGVUaW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uIG9uVGltZW91dCgpIHtcbiAgICAgIGlmIChpdGVtLl9vblRpbWVvdXQpXG4gICAgICAgIGl0ZW0uX29uVGltZW91dCgpO1xuICAgIH0sIG1zZWNzKTtcbiAgfVxufTtcblxuLy8gc2V0aW1tZWRpYXRlIGF0dGFjaGVzIGl0c2VsZiB0byB0aGUgZ2xvYmFsIG9iamVjdFxucmVxdWlyZShcInNldGltbWVkaWF0ZVwiKTtcbi8vIE9uIHNvbWUgZXhvdGljIGVudmlyb25tZW50cywgaXQncyBub3QgY2xlYXIgd2hpY2ggb2JqZWN0IGBzZXRpbW1lZGlhdGVgIHdhc1xuLy8gYWJsZSB0byBpbnN0YWxsIG9udG8uICBTZWFyY2ggZWFjaCBwb3NzaWJpbGl0eSBpbiB0aGUgc2FtZSBvcmRlciBhcyB0aGVcbi8vIGBzZXRpbW1lZGlhdGVgIGxpYnJhcnkuXG5leHBvcnRzLnNldEltbWVkaWF0ZSA9ICh0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiAmJiBzZWxmLnNldEltbWVkaWF0ZSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgKHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgJiYgZ2xvYmFsLnNldEltbWVkaWF0ZSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgKHRoaXMgJiYgdGhpcy5zZXRJbW1lZGlhdGUpO1xuZXhwb3J0cy5jbGVhckltbWVkaWF0ZSA9ICh0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiAmJiBzZWxmLmNsZWFySW1tZWRpYXRlKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICh0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiICYmIGdsb2JhbC5jbGVhckltbWVkaWF0ZSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAodGhpcyAmJiB0aGlzLmNsZWFySW1tZWRpYXRlKTtcbiIsIlxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRlcHJlY2F0ZTtcblxuLyoqXG4gKiBNYXJrIHRoYXQgYSBtZXRob2Qgc2hvdWxkIG5vdCBiZSB1c2VkLlxuICogUmV0dXJucyBhIG1vZGlmaWVkIGZ1bmN0aW9uIHdoaWNoIHdhcm5zIG9uY2UgYnkgZGVmYXVsdC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLm5vRGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gaXQgaXMgYSBuby1vcC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLnRocm93RGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gZGVwcmVjYXRlZCBmdW5jdGlvbnNcbiAqIHdpbGwgdGhyb3cgYW4gRXJyb3Igd2hlbiBpbnZva2VkLlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2UudHJhY2VEZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBkZXByZWNhdGVkIGZ1bmN0aW9uc1xuICogd2lsbCBpbnZva2UgYGNvbnNvbGUudHJhY2UoKWAgaW5zdGVhZCBvZiBgY29uc29sZS5lcnJvcigpYC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB0byBkZXByZWNhdGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgLSB0aGUgc3RyaW5nIHRvIHByaW50IHRvIHRoZSBjb25zb2xlIHdoZW4gYGZuYCBpcyBpbnZva2VkXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IGEgbmV3IFwiZGVwcmVjYXRlZFwiIHZlcnNpb24gb2YgYGZuYFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkZXByZWNhdGUgKGZuLCBtc2cpIHtcbiAgaWYgKGNvbmZpZygnbm9EZXByZWNhdGlvbicpKSB7XG4gICAgcmV0dXJuIGZuO1xuICB9XG5cbiAgdmFyIHdhcm5lZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBkZXByZWNhdGVkKCkge1xuICAgIGlmICghd2FybmVkKSB7XG4gICAgICBpZiAoY29uZmlnKCd0aHJvd0RlcHJlY2F0aW9uJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICB9IGVsc2UgaWYgKGNvbmZpZygndHJhY2VEZXByZWNhdGlvbicpKSB7XG4gICAgICAgIGNvbnNvbGUudHJhY2UobXNnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2Fybihtc2cpO1xuICAgICAgfVxuICAgICAgd2FybmVkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICByZXR1cm4gZGVwcmVjYXRlZDtcbn1cblxuLyoqXG4gKiBDaGVja3MgYGxvY2FsU3RvcmFnZWAgZm9yIGJvb2xlYW4gdmFsdWVzIGZvciB0aGUgZ2l2ZW4gYG5hbWVgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGNvbmZpZyAobmFtZSkge1xuICAvLyBhY2Nlc3NpbmcgZ2xvYmFsLmxvY2FsU3RvcmFnZSBjYW4gdHJpZ2dlciBhIERPTUV4Y2VwdGlvbiBpbiBzYW5kYm94ZWQgaWZyYW1lc1xuICB0cnkge1xuICAgIGlmICghZ2xvYmFsLmxvY2FsU3RvcmFnZSkgcmV0dXJuIGZhbHNlO1xuICB9IGNhdGNoIChfKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciB2YWwgPSBnbG9iYWwubG9jYWxTdG9yYWdlW25hbWVdO1xuICBpZiAobnVsbCA9PSB2YWwpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIFN0cmluZyh2YWwpLnRvTG93ZXJDYXNlKCkgPT09ICd0cnVlJztcbn1cbiIsInZhciBpbmRleE9mID0gZnVuY3Rpb24gKHhzLCBpdGVtKSB7XG4gICAgaWYgKHhzLmluZGV4T2YpIHJldHVybiB4cy5pbmRleE9mKGl0ZW0pO1xuICAgIGVsc2UgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoeHNbaV0gPT09IGl0ZW0pIHJldHVybiBpO1xuICAgIH1cbiAgICByZXR1cm4gLTE7XG59O1xudmFyIE9iamVjdF9rZXlzID0gZnVuY3Rpb24gKG9iaikge1xuICAgIGlmIChPYmplY3Qua2V5cykgcmV0dXJuIE9iamVjdC5rZXlzKG9iailcbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIHJlcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSByZXMucHVzaChrZXkpXG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxufTtcblxudmFyIGZvckVhY2ggPSBmdW5jdGlvbiAoeHMsIGZuKSB7XG4gICAgaWYgKHhzLmZvckVhY2gpIHJldHVybiB4cy5mb3JFYWNoKGZuKVxuICAgIGVsc2UgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBmbih4c1tpXSwgaSwgeHMpO1xuICAgIH1cbn07XG5cbnZhciBkZWZpbmVQcm9wID0gKGZ1bmN0aW9uKCkge1xuICAgIHRyeSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7fSwgJ18nLCB7fSk7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihvYmosIG5hbWUsIHZhbHVlKSB7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBuYW1lLCB7XG4gICAgICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfTtcbiAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iaiwgbmFtZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIG9ialtuYW1lXSA9IHZhbHVlO1xuICAgICAgICB9O1xuICAgIH1cbn0oKSk7XG5cbnZhciBnbG9iYWxzID0gWydBcnJheScsICdCb29sZWFuJywgJ0RhdGUnLCAnRXJyb3InLCAnRXZhbEVycm9yJywgJ0Z1bmN0aW9uJyxcbidJbmZpbml0eScsICdKU09OJywgJ01hdGgnLCAnTmFOJywgJ051bWJlcicsICdPYmplY3QnLCAnUmFuZ2VFcnJvcicsXG4nUmVmZXJlbmNlRXJyb3InLCAnUmVnRXhwJywgJ1N0cmluZycsICdTeW50YXhFcnJvcicsICdUeXBlRXJyb3InLCAnVVJJRXJyb3InLFxuJ2RlY29kZVVSSScsICdkZWNvZGVVUklDb21wb25lbnQnLCAnZW5jb2RlVVJJJywgJ2VuY29kZVVSSUNvbXBvbmVudCcsICdlc2NhcGUnLFxuJ2V2YWwnLCAnaXNGaW5pdGUnLCAnaXNOYU4nLCAncGFyc2VGbG9hdCcsICdwYXJzZUludCcsICd1bmRlZmluZWQnLCAndW5lc2NhcGUnXTtcblxuZnVuY3Rpb24gQ29udGV4dCgpIHt9XG5Db250ZXh0LnByb3RvdHlwZSA9IHt9O1xuXG52YXIgU2NyaXB0ID0gZXhwb3J0cy5TY3JpcHQgPSBmdW5jdGlvbiBOb2RlU2NyaXB0IChjb2RlKSB7XG4gICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNjcmlwdCkpIHJldHVybiBuZXcgU2NyaXB0KGNvZGUpO1xuICAgIHRoaXMuY29kZSA9IGNvZGU7XG59O1xuXG5TY3JpcHQucHJvdG90eXBlLnJ1bkluQ29udGV4dCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgaWYgKCEoY29udGV4dCBpbnN0YW5jZW9mIENvbnRleHQpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJuZWVkcyBhICdjb250ZXh0JyBhcmd1bWVudC5cIik7XG4gICAgfVxuICAgIFxuICAgIHZhciBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICBpZiAoIWlmcmFtZS5zdHlsZSkgaWZyYW1lLnN0eWxlID0ge307XG4gICAgaWZyYW1lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgXG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuICAgIFxuICAgIHZhciB3aW4gPSBpZnJhbWUuY29udGVudFdpbmRvdztcbiAgICB2YXIgd0V2YWwgPSB3aW4uZXZhbCwgd0V4ZWNTY3JpcHQgPSB3aW4uZXhlY1NjcmlwdDtcblxuICAgIGlmICghd0V2YWwgJiYgd0V4ZWNTY3JpcHQpIHtcbiAgICAgICAgLy8gd2luLmV2YWwoKSBtYWdpY2FsbHkgYXBwZWFycyB3aGVuIHRoaXMgaXMgY2FsbGVkIGluIElFOlxuICAgICAgICB3RXhlY1NjcmlwdC5jYWxsKHdpbiwgJ251bGwnKTtcbiAgICAgICAgd0V2YWwgPSB3aW4uZXZhbDtcbiAgICB9XG4gICAgXG4gICAgZm9yRWFjaChPYmplY3Rfa2V5cyhjb250ZXh0KSwgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICB3aW5ba2V5XSA9IGNvbnRleHRba2V5XTtcbiAgICB9KTtcbiAgICBmb3JFYWNoKGdsb2JhbHMsIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgaWYgKGNvbnRleHRba2V5XSkge1xuICAgICAgICAgICAgd2luW2tleV0gPSBjb250ZXh0W2tleV07XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBcbiAgICB2YXIgd2luS2V5cyA9IE9iamVjdF9rZXlzKHdpbik7XG5cbiAgICB2YXIgcmVzID0gd0V2YWwuY2FsbCh3aW4sIHRoaXMuY29kZSk7XG4gICAgXG4gICAgZm9yRWFjaChPYmplY3Rfa2V5cyh3aW4pLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIC8vIEF2b2lkIGNvcHlpbmcgY2lyY3VsYXIgb2JqZWN0cyBsaWtlIGB0b3BgIGFuZCBgd2luZG93YCBieSBvbmx5XG4gICAgICAgIC8vIHVwZGF0aW5nIGV4aXN0aW5nIGNvbnRleHQgcHJvcGVydGllcyBvciBuZXcgcHJvcGVydGllcyBpbiB0aGUgYHdpbmBcbiAgICAgICAgLy8gdGhhdCB3YXMgb25seSBpbnRyb2R1Y2VkIGFmdGVyIHRoZSBldmFsLlxuICAgICAgICBpZiAoa2V5IGluIGNvbnRleHQgfHwgaW5kZXhPZih3aW5LZXlzLCBrZXkpID09PSAtMSkge1xuICAgICAgICAgICAgY29udGV4dFtrZXldID0gd2luW2tleV07XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIGZvckVhY2goZ2xvYmFscywgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBpZiAoIShrZXkgaW4gY29udGV4dCkpIHtcbiAgICAgICAgICAgIGRlZmluZVByb3AoY29udGV4dCwga2V5LCB3aW5ba2V5XSk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBcbiAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGlmcmFtZSk7XG4gICAgXG4gICAgcmV0dXJuIHJlcztcbn07XG5cblNjcmlwdC5wcm90b3R5cGUucnVuSW5UaGlzQ29udGV4dCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZXZhbCh0aGlzLmNvZGUpOyAvLyBtYXliZS4uLlxufTtcblxuU2NyaXB0LnByb3RvdHlwZS5ydW5Jbk5ld0NvbnRleHQgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHZhciBjdHggPSBTY3JpcHQuY3JlYXRlQ29udGV4dChjb250ZXh0KTtcbiAgICB2YXIgcmVzID0gdGhpcy5ydW5JbkNvbnRleHQoY3R4KTtcblxuICAgIGlmIChjb250ZXh0KSB7XG4gICAgICAgIGZvckVhY2goT2JqZWN0X2tleXMoY3R4KSwgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgY29udGV4dFtrZXldID0gY3R4W2tleV07XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiByZXM7XG59O1xuXG5mb3JFYWNoKE9iamVjdF9rZXlzKFNjcmlwdC5wcm90b3R5cGUpLCBmdW5jdGlvbiAobmFtZSkge1xuICAgIGV4cG9ydHNbbmFtZV0gPSBTY3JpcHRbbmFtZV0gPSBmdW5jdGlvbiAoY29kZSkge1xuICAgICAgICB2YXIgcyA9IFNjcmlwdChjb2RlKTtcbiAgICAgICAgcmV0dXJuIHNbbmFtZV0uYXBwbHkocywgW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKTtcbiAgICB9O1xufSk7XG5cbmV4cG9ydHMuaXNDb250ZXh0ID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICByZXR1cm4gY29udGV4dCBpbnN0YW5jZW9mIENvbnRleHQ7XG59O1xuXG5leHBvcnRzLmNyZWF0ZVNjcmlwdCA9IGZ1bmN0aW9uIChjb2RlKSB7XG4gICAgcmV0dXJuIGV4cG9ydHMuU2NyaXB0KGNvZGUpO1xufTtcblxuZXhwb3J0cy5jcmVhdGVDb250ZXh0ID0gU2NyaXB0LmNyZWF0ZUNvbnRleHQgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHZhciBjb3B5ID0gbmV3IENvbnRleHQoKTtcbiAgICBpZih0eXBlb2YgY29udGV4dCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgZm9yRWFjaChPYmplY3Rfa2V5cyhjb250ZXh0KSwgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgY29weVtrZXldID0gY29udGV4dFtrZXldO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGNvcHk7XG59O1xuIiwidmFyIGc7XG5cbi8vIFRoaXMgd29ya3MgaW4gbm9uLXN0cmljdCBtb2RlXG5nID0gKGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gdGhpcztcbn0pKCk7XG5cbnRyeSB7XG5cdC8vIFRoaXMgd29ya3MgaWYgZXZhbCBpcyBhbGxvd2VkIChzZWUgQ1NQKVxuXHRnID0gZyB8fCBuZXcgRnVuY3Rpb24oXCJyZXR1cm4gdGhpc1wiKSgpO1xufSBjYXRjaCAoZSkge1xuXHQvLyBUaGlzIHdvcmtzIGlmIHRoZSB3aW5kb3cgcmVmZXJlbmNlIGlzIGF2YWlsYWJsZVxuXHRpZiAodHlwZW9mIHdpbmRvdyA9PT0gXCJvYmplY3RcIikgZyA9IHdpbmRvdztcbn1cblxuLy8gZyBjYW4gc3RpbGwgYmUgdW5kZWZpbmVkLCBidXQgbm90aGluZyB0byBkbyBhYm91dCBpdC4uLlxuLy8gV2UgcmV0dXJuIHVuZGVmaW5lZCwgaW5zdGVhZCBvZiBub3RoaW5nIGhlcmUsIHNvIGl0J3Ncbi8vIGVhc2llciB0byBoYW5kbGUgdGhpcyBjYXNlLiBpZighZ2xvYmFsKSB7IC4uLn1cblxubW9kdWxlLmV4cG9ydHMgPSBnO1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihtb2R1bGUpIHtcblx0aWYgKCFtb2R1bGUud2VicGFja1BvbHlmaWxsKSB7XG5cdFx0bW9kdWxlLmRlcHJlY2F0ZSA9IGZ1bmN0aW9uKCkge307XG5cdFx0bW9kdWxlLnBhdGhzID0gW107XG5cdFx0Ly8gbW9kdWxlLnBhcmVudCA9IHVuZGVmaW5lZCBieSBkZWZhdWx0XG5cdFx0aWYgKCFtb2R1bGUuY2hpbGRyZW4pIG1vZHVsZS5jaGlsZHJlbiA9IFtdO1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2R1bGUsIFwibG9hZGVkXCIsIHtcblx0XHRcdGVudW1lcmFibGU6IHRydWUsXG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gbW9kdWxlLmw7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZSwgXCJpZFwiLCB7XG5cdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuXHRcdFx0Z2V0OiBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuIG1vZHVsZS5pO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHRcdG1vZHVsZS53ZWJwYWNrUG9seWZpbGwgPSAxO1xuXHR9XG5cdHJldHVybiBtb2R1bGU7XG59O1xuIiwiaW1wb3J0IHsgUmVmZXJlbmNlUG9pbnRlciwgUERGRG9jdW1lbnRQYXJzZXIsIFBhZ2UsIEFubm90YXRpb24gfSBmcm9tICcuL3BhcnNlcic7XG5pbXBvcnQgeyBCb3JkZXIsIENvbG9yLCBCYXNlQW5ub3RhdGlvbiB9IGZyb20gJy4vYW5ub3RhdGlvbnMvYW5ub3RhdGlvbl90eXBlcyc7XG5pbXBvcnQgeyBUZXh0QW5ub3RhdGlvbk9iaiB9IGZyb20gJy4vYW5ub3RhdGlvbnMvdGV4dF9hbm5vdGF0aW9uJztcbmltcG9ydCB7IEhpZ2hsaWdodEFubm90YXRpb25PYmosIFVuZGVybGluZUFubm90YXRpb25PYmosIFNxdWlnZ2x5QW5ub3RhdGlvbk9iaiwgU3RyaWtlT3V0QW5ub3RhdGlvbk9iaiB9IGZyb20gJy4vYW5ub3RhdGlvbnMvdGV4dF9tYXJrdXBfYW5ub3RhdGlvbic7XG5pbXBvcnQgeyBGcmVlVGV4dEFubm90YXRpb25PYmogfSBmcm9tICcuL2Fubm90YXRpb25zL2ZyZWV0ZXh0X2Fubm90YXRpb24nO1xuaW1wb3J0IHsgU3F1YXJlQW5ub3RhdGlvbk9iaiwgQ2lyY2xlQW5ub3RhdGlvbk9iaiB9IGZyb20gJy4vYW5ub3RhdGlvbnMvY2lyY2xlX3NxdWFyZV9hbm5vdGF0aW9uJztcbmltcG9ydCB7IFBvbHlnb25Bbm5vdGF0aW9uT2JqLCBQb2x5TGluZUFubm90YXRpb25PYmogfSBmcm9tICcuL2Fubm90YXRpb25zL3BvbHlnb25fcG9seWxpbmVfYW5ub3RhdGlvbic7XG5pbXBvcnQgeyBJbmtBbm5vdGF0aW9uT2JqIH0gZnJvbSAnLi9hbm5vdGF0aW9ucy9pbmtfYW5ub3RhdGlvbic7XG5pbXBvcnQgeyBVdGlsIH0gZnJvbSAnLi91dGlsJztcbmltcG9ydCB7IFdyaXRlciB9IGZyb20gJy4vd3JpdGVyJztcblxuZXhwb3J0IGNsYXNzIFBhcmFtZXRlclBhcnNlciB7XG4gICAgLyoqXG4gICAgICogUGFyc2VzIGFuZCBjaGVja3MgdGhlIHBhcmFtZXRlci4gVGhpcyBpcyBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSBhbmQgdG8gc3VwcG9ydCBhcmJpdHJhcnkgYW5ub3RhdGlvbiBwYXJhbWV0ZXJzXG4gICAgICogKi9cbiAgICBzdGF0aWMgcGFyc2VQYXJhbWV0ZXJzKHZhbHVlcyA6IGFueVtdKSB7XG4gICAgICAgIGlmICh2YWx1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcIk5vIHBhcmFtZXRlcnMgcHJvdmlkZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBpID0gMFxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlc1tpXSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIGxldCByZXRfdmFsIDogYW55ID0ge31cbiAgICAgICAgICAgIHJldF92YWwucGFnZSA9IHZhbHVlc1tpKytdXG4gICAgICAgICAgICByZXRfdmFsLnJlY3QgPSB2YWx1ZXNbaSsrXVxuXG4gICAgICAgICAgICByZXRfdmFsLmNvbnRlbnRzID0gdmFsdWVzW2krK11cbiAgICAgICAgICAgIGlmKHR5cGVvZiByZXRfdmFsLmNvbnRlbnRzICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFwiSW52YWxpZCBjb250ZW50cyBwYXJhbWV0ZXJcIilcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0X3ZhbC5hdXRob3IgPSB2YWx1ZXNbaSsrXVxuICAgICAgICAgICAgaWYodHlwZW9mIHJldF92YWwuYXV0aG9yICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFwiSW52YWxpZCBhdXRob3IgcGFyYW1ldGVyXCIpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpID49IHZhbHVlcy5sZW5ndGgpIHJldHVybiByZXRfdmFsXG5cbiAgICAgICAgICAgIGlmIChcInJcIiBpbiB2YWx1ZXNbaV0gJiYgXCJnXCIgaW4gdmFsdWVzW2ldICYmIFwiYlwiIGluIHZhbHVlc1tpXSkge1xuICAgICAgICAgICAgICAgIHJldF92YWwuY29sb3IgPSB2YWx1ZXNbaSsrXVxuICAgICAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHZhbHVlc1tpXSkgJiYgdmFsdWVzW2ldLmxlbmd0aCA+IDAgJiYgdHlwZW9mIHZhbHVlc1tpXVswXSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICByZXRfdmFsLnZlcnRpY2VzID0gdmFsdWVzW2krK11cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZXNbaV0pICYmIHZhbHVlc1tpXS5sZW5ndGggPiAwICYmIEFycmF5LmlzQXJyYXkodmFsdWVzW2ldWzBdKSkge1xuICAgICAgICAgICAgICAgIHJldF92YWwuaW5rTGlzdCA9IHZhbHVlc1tpKytdXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFwiSW52YWxpZCBwYXJhbWV0ZXIgcHJvdmlkZWQgLSBpcyBuZWl0aGVyIGNvbG9yLCBub3IgcXVhZHBvaW50cyBhcnJheSBvciBhbiBpbmtsaXN0XCIpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpID49IHZhbHVlcy5sZW5ndGgpIHJldHVybiByZXRfdmFsXG5cbiAgICAgICAgICAgIGlmIChcInJcIiBpbiB2YWx1ZXNbaV0gJiYgXCJnXCIgaW4gdmFsdWVzW2ldICYmIFwiYlwiIGluIHZhbHVlc1tpXSkge1xuICAgICAgICAgICAgICAgIGlmIChyZXRfdmFsLmNvbG9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldF92YWwuZmlsbCA9IHZhbHVlc1tpKytdXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0X3ZhbC5jb2xvciA9IHZhbHVlc1tpKytdXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHZhbHVlc1tpXSkgJiYgdmFsdWVzW2ldLmxlbmd0aCA+IDAgJiYgdHlwZW9mIHZhbHVlc1tpXVswXSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICByZXRfdmFsLnF1YWRQb2ludHMgPSB2YWx1ZXNbaSsrXVxuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWVzW2ldID09PSAnb2JqZWN0Jyl7XG4gICAgICAgICAgICAgICAgcmV0X3ZhbC5jb25maWcgPSB0cnVlXG4gICAgICAgICAgICAgICAgcmV0X3ZhbCA9ICg8YW55Pk9iamVjdCkuYXNzaWduKHJldF92YWwsIHZhbHVlc1tpKytdKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihcIkludmFsaWQgcGFyYW1ldGVyIHByb3ZpZGVkXCIpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpID49IHZhbHVlcy5sZW5ndGgpIHJldHVybiByZXRfdmFsXG5cbiAgICAgICAgICAgIGlmICghcmV0X3ZhbC5jb25maWcgJiYgdHlwZW9mIHZhbHVlc1tpXSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICByZXRfdmFsID0gKDxhbnk+T2JqZWN0KS5hc3NpZ24ocmV0X3ZhbCwgdmFsdWVzW2krK10pXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFwiSW52YWxpZCBjb25maWd1cmF0aW9uIHByb3ZpZGVkXCIpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByZXRfdmFsXG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlc1tpXSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZXNbMF1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiSW52YWxpZCBjb25maWd1cmF0aW9uIG9iamVjdFwiKVxuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqIFRoZSBhbm5vdGF0aW9uIGZhY3RvcnkgcHJvdmlkZXMgbWV0aG9kcyB0byBjcmVhdGUgYW5ub3RhdGlvbnMuIFRob3NlIGFyZSBzdG9yZWQgdGVtcG9yYXJpbHlcbiAqIGFuZCB0aGFuIGVuY29kZWQgaW50byBQREYgY29kZSB3aGVuIHRoZSBQREYgZG9jdW1lbnQgaXMgd3JpdHRlbi5cbiAqICovXG5leHBvcnQgY2xhc3MgQW5ub3RhdGlvbkZhY3Rvcnkge1xuICAgIHByaXZhdGUgYW5ub3RhdGlvbnM6IEFubm90YXRpb25bXSA9IFtdXG5cbiAgICBwcml2YXRlIHRvRGVsZXRlOiBBbm5vdGF0aW9uW10gPSBbXVxuXG4gICAgcHJpdmF0ZSBwYXJzZXI6IFBERkRvY3VtZW50UGFyc2VyXG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGRhdGE6IFVpbnQ4QXJyYXksIHByaXZhdGUgdXNlclBhc3N3b3JkOiBzdHJpbmcgPSBcIlwiLCBwcml2YXRlIG93bmVyUGFzc3dvcmQgOiBzdHJpbmcgPSBcIlwiKSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGFcbiAgICAgICAgdGhpcy5wYXJzZXIgPSBuZXcgUERGRG9jdW1lbnRQYXJzZXIodGhpcy5kYXRhLCB0aGlzLnVzZXJQYXNzd29yZCwgdGhpcy5vd25lclBhc3N3b3JkKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBhbm5vdGF0aW9ucyB0aGF0IHdpbGwgYmUgYWRkZWQgdG8gdGhlIFBERiBkb2N1bWVudFxuICAgICAqICovXG4gICAgZ2V0QW5ub3RhdGlvbkNvdW50KCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLmFubm90YXRpb25zLmxlbmd0aFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExvYWQgYSBQREYgZmlsZSByZWZlcmVuY2VkIGJ5IHRoZSBnaXZlbiAncGF0aCdcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgbG9hZEZpbGUocGF0aDogc3RyaW5nLCB1c2VyUGFzc3dvcmQ6IHN0cmluZyA9IFwiXCIsIG93bmVyUGFzc3dvcmQgOiBzdHJpbmcgPSBcIlwiKTogUHJvbWlzZTxBbm5vdGF0aW9uRmFjdG9yeT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8QW5ub3RhdGlvbkZhY3Rvcnk+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHsgLy8gYnJvd3NlciBlbnZpcm9ubWVudFxuICAgICAgICAgICAgICAgIGZldGNoKHBhdGgpLnRoZW4oKHIpID0+IHIuYmxvYigpKS50aGVuKChkYXRhKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxldCByZWFkZXI6IGFueSA9IG5ldyBGaWxlUmVhZGVyKClcblxuICAgICAgICAgICAgICAgICAgICByZWFkZXIub25sb2FkID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQW5ub3RhdGlvbkZhY3RvcnkocmVhZGVyLnJlc3VsdCwgdXNlclBhc3N3b3JkLCBvd25lclBhc3N3b3JkKSlcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihkYXRhKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBwcm9jZXNzID09PSAnb2JqZWN0JykgeyAvLyBub2RlIGVudmlyb25tZW50XG4gICAgICAgICAgICAgICAgbGV0IGZzID0gcmVxdWlyZSgnZnMnKVxuICAgICAgICAgICAgICAgIGxldCBkYXRhID0gZnMucmVhZEZpbGVTeW5jKHBhdGgpXG5cbiAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBBbm5vdGF0aW9uRmFjdG9yeShkYXRhLCB1c2VyUGFzc3dvcmQsIG93bmVyUGFzc3dvcmQpKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihcIlVuc3VwcG9ydGVkIGVudmlyb25tZW50XCIpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2VuZXJhdGVzIGEgdW5pcXVlIGlkZW50aWZpZXIgbmVjZXNzYXJ5IGZvciBjcmVhdGluZyB0aGUgYW5ub3RhdGlvblxuICAgICAqICovXG4gICAgcHJpdmF0ZSBnZW5lcmF0ZVVuaXF1ZUlkZW50aWZpZXIoKSB7XG4gICAgICAgIHJldHVybiBcInBkZkFubm90YXRlLVwiICsgVXRpbC5jb252ZXJ0RGF0ZVRvUERGRGF0ZShuZXcgRGF0ZSgpKS5zbGljZSgzLCAxNykgKyBcIi1cIiArIHRoaXMuYW5ub3RhdGlvbnMubGVuZ3RoXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2VuZXJhdGVzIGEgZGVmYXVsdCBib3JkZXJcbiAgICAgKiAqL1xuICAgIHByaXZhdGUgY3JlYXRlRGVmYXVsdEJvcmRlcigpOiBCb3JkZXIge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmVydGljYWxfY29ybmVyX3JhZGl1czogMCxcbiAgICAgICAgICAgIGhvcml6b250YWxfY29ybmVyX3JhZGl1czogMCxcbiAgICAgICAgICAgIGJvcmRlcl93aWR0aDogMVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV3JpdGVzIHRoZSBjcmVhdGVkIGFubm90YXRpb25zIGludG8gYSBieXRlc3RyZWFtXG4gICAgICogKi9cbiAgICB3cml0ZSgpOiBVaW50OEFycmF5IHtcbiAgICAgICAgaWYgKHRoaXMuYW5ub3RhdGlvbnMubGVuZ3RoID09PSAwICYmIHRoaXMudG9EZWxldGUubGVuZ3RoID09PSAwKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF0YVxuXG4gICAgICAgIGxldCB3cml0ZXI6IFdyaXRlciA9IG5ldyBXcml0ZXIodGhpcy5kYXRhLCB0aGlzLmFubm90YXRpb25zLCB0aGlzLnRvRGVsZXRlLCB0aGlzLnBhcnNlcilcblxuICAgICAgICByZXR1cm4gd3JpdGVyLndyaXRlKClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgdGhlICdyZWN0JyBwYXJhbWV0ZXIsIHdoZXRoZXIgYWxsIHRoZSBlbnRyaWVzIGFyZSBvZiB0eXBlIG51bWJlciBhbmQgaWYgdGhlIHRoZSBudW1iZXIgb2YgZW50cmllcyBpcyBjb3JyZWN0XG4gICAgICogKi9cbiAgICBwcml2YXRlIGNoZWNrUmVjdChucjogbnVtYmVyLCByZWN0OiBudW1iZXJbXSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkocmVjdCkpIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiaW52YWxpZCByZWN0IHBhcmFtZXRlclwiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJlY3QubGVuZ3RoICE9PSBucilcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiUmVjdCBoYXMgaW52YWxpZCBudW1iZXIgb2YgZW50cmllczogXCIgKyByZWN0ICsgXCIgaGFzIFwiICsgcmVjdC5sZW5ndGggKyBcIiBlbnRyaWVzLCBidXQgc2hvdWxkIGhhdmUgXCIgKyBuciArIFwiIGVudHJpZXNcIilcblxuICAgICAgICByZWN0LmZvckVhY2goKGEpID0+IHtcbiAgICAgICAgICAgIGlmICgnbnVtYmVyJyAhPT0gdHlwZW9mIGEpXG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJSZWN0IFwiICsgcmVjdCArIFwiIGhhcyBpbnZhbGlkIGVudHJ5OiBcIiArIGEpXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGJhc2UgYW5ub3RhdGlvbiB0aGF0IG1lYW5zIHRoZSByYXcgb2JqZWN0IG9mIGFubm90YXRpb24gb3IgdGhvc2UgcGFydHMgdGhhdCBleGlzdFxuICAgICAqIGluIGVxdWFsIGZvcm0gaW4gYWxsIHR5cGVzIG9mIGFubm90YXRpb25zXG4gICAgICogKi9cbiAgICBjcmVhdGVCYXNlQW5ub3RhdGlvbihwYWdlIDogbnVtYmVyKTogQmFzZUFubm90YXRpb24ge1xuICAgICAgICBpZiAocGFnZSA8IDApIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKGBJbnZhbGlkIHBhZ2UgbnVtYmVyOiAke3BhZ2V9YClcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBhbm5vdDogQmFzZUFubm90YXRpb24gPSB7XG4gICAgICAgICAgICBvYmplY3RfaWQ6IHRoaXMucGFyc2VyLmdldEZyZWVPYmplY3RJZCgpLFxuICAgICAgICAgICAgaWQ6IHRoaXMuZ2VuZXJhdGVVbmlxdWVJZGVudGlmaWVyKCksXG4gICAgICAgICAgICBwYWdlUmVmZXJlbmNlOiB0aGlzLnBhcnNlci5nZXRQYWdlKHBhZ2UpLFxuICAgICAgICAgICAgdXBkYXRlRGF0ZTogVXRpbC5jb252ZXJ0RGF0ZVRvUERGRGF0ZShuZXcgRGF0ZSgpKSxcbiAgICAgICAgICAgIGJvcmRlcjogdGhpcy5jcmVhdGVEZWZhdWx0Qm9yZGVyKCksXG4gICAgICAgICAgICBwYWdlOiBwYWdlLCByZWN0OiBbXVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFubm90XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgdGV4dCBhbm5vdGF0aW9uXG4gICAgICogcGFnZSA6IHRoZSBudW1iZXIgb2YgdGhlIFBERiBkb2N1bWVudCBwYWdlLCB3aGVyZSB0aGUgYW5ub3RhdGlvbiBtdXN0IGJlIGF0dGFjaGVkXG4gICAgICogcmVjdCA6IHRoZSBwb3NpdGlvbiBvZiB0aGUgYW5ub3RhdGlvbiBvbiB0aGUgcGFnZVxuICAgICAqIGNvbnRlbnRzIDogdGhlIGNvbnRlbnQgb2YgdGhlIGFubm90YXRpb25cbiAgICAgKiBhdXRob3IgOiB0aGUgYXV0aG9yIG9mIHRoZSBhbm5vdGF0aW9uXG4gICAgICogY29sb3IgOiB0aGUgY29sb3Igb2YgdGhlIGFubm90YXRpb24gaW4gcmdiLiBDYW4gYmUgb2YgZG9tYWluIDAgLSAyNTUgb3IgMCAtIDFcbiAgICAgKiBvcHRpb25zIDogZGljdGlvbmFyeSBjb250YWluaW5nIGFkZGl0aW9uYWwgY29uZmlndXJhdGlvbiB2YWx1ZXMsIHNlZSBkb2N1bWVudGF0aW9uXG4gICAgICogKi9cbiAgICBjcmVhdGVUZXh0QW5ub3RhdGlvbiguLi52YWx1ZXMgOiBhbnlbXSkge1xuICAgICAgICBsZXQgcGFyYW1zID0gUGFyYW1ldGVyUGFyc2VyLnBhcnNlUGFyYW1ldGVycyh2YWx1ZXMpXG5cbiAgICAgICAgbGV0IGFubm90IDogVGV4dEFubm90YXRpb25PYmogPSBuZXcgVGV4dEFubm90YXRpb25PYmooKVxuICAgICAgICBhbm5vdCA9ICg8YW55Pk9iamVjdCkuYXNzaWduKGFubm90LCB0aGlzLmNyZWF0ZUJhc2VBbm5vdGF0aW9uKHBhcmFtcy5wYWdlKSlcbiAgICAgICAgYW5ub3QgPSAoPGFueT5PYmplY3QpLmFzc2lnbihhbm5vdCwgcGFyYW1zKVxuXG4gICAgICAgIGFubm90LnZhbGlkYXRlKClcblxuICAgICAgICB0aGlzLmFubm90YXRpb25zLnB1c2goYW5ub3QpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGhpZ2hsaWdodCBhbm5vdGF0aW9uXG4gICAgICogcGFnZSA6IHRoZSBudW1iZXIgb2YgdGhlIFBERiBkb2N1bWVudCBwYWdlLCB3aGVyZSB0aGUgYW5ub3RhdGlvbiBtdXN0IGJlIGF0dGFjaGVkXG4gICAgICogcmVjdCA6IHRoZSBwb3NpdGlvbiBvZiB0aGUgYW5ub3RhdGlvbiBvbiB0aGUgcGFnZVxuICAgICAqIGNvbnRlbnRzIDogdGhlIGNvbnRlbnQgb2YgdGhlIGFubm90YXRpb25cbiAgICAgKiBhdXRob3IgOiB0aGUgYXV0aG9yIG9mIHRoZSBhbm5vdGF0aW9uXG4gICAgICogY29sb3IgOiB0aGUgY29sb3Igb2YgdGhlIGFubm90YXRpb24gaW4gcmdiLiBDYW4gYmUgb2YgZG9tYWluIDAgLSAyNTUgb3IgMCAtIDFcbiAgICAgKiBxdWFkUG9pbnRzIDogcmVnaW9ucyB0byBtYXJrIHdpdGggdGhlIGhpZ2hsaWdodFxuICAgICAqICovXG4gICAgY3JlYXRlSGlnaGxpZ2h0QW5ub3RhdGlvbiguLi52YWx1ZXMgOiBhbnlbXSkge1xuICAgICAgICBsZXQgcGFyYW1zID0gUGFyYW1ldGVyUGFyc2VyLnBhcnNlUGFyYW1ldGVycyh2YWx1ZXMpXG5cbiAgICAgICAgbGV0IGFubm90IDogSGlnaGxpZ2h0QW5ub3RhdGlvbk9iaiA9IG5ldyBIaWdobGlnaHRBbm5vdGF0aW9uT2JqKClcbiAgICAgICAgYW5ub3QgPSAoPGFueT5PYmplY3QpLmFzc2lnbihhbm5vdCwgdGhpcy5jcmVhdGVCYXNlQW5ub3RhdGlvbihwYXJhbXMucGFnZSkpXG4gICAgICAgIGFubm90ID0gKDxhbnk+T2JqZWN0KS5hc3NpZ24oYW5ub3QsIHBhcmFtcylcblxuICAgICAgICBhbm5vdC52YWxpZGF0ZSgpXG5cbiAgICAgICAgdGhpcy5hbm5vdGF0aW9ucy5wdXNoKGFubm90KVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gdW5kZXJsaW5lIGFubm90YXRpb25cbiAgICAgKiBwYWdlIDogdGhlIG51bWJlciBvZiB0aGUgUERGIGRvY3VtZW50IHBhZ2UsIHdoZXJlIHRoZSBhbm5vdGF0aW9uIG11c3QgYmUgYXR0YWNoZWRcbiAgICAgKiByZWN0IDogdGhlIHBvc2l0aW9uIG9mIHRoZSBhbm5vdGF0aW9uIG9uIHRoZSBwYWdlXG4gICAgICogY29udGVudHMgOiB0aGUgY29udGVudCBvZiB0aGUgYW5ub3RhdGlvblxuICAgICAqIGF1dGhvciA6IHRoZSBhdXRob3Igb2YgdGhlIGFubm90YXRpb25cbiAgICAgKiBjb2xvciA6IHRoZSBjb2xvciBvZiB0aGUgYW5ub3RhdGlvbiBpbiByZ2IuIENhbiBiZSBvZiBkb21haW4gMCAtIDI1NSBvciAwIC0gMVxuICAgICAqIHF1YWRQb2ludHMgOiByZWdpb25zIHRvIG1hcmsgd2l0aCB0aGUgaGlnaGxpZ2h0XG4gICAgICogKi9cbiAgICBjcmVhdGVVbmRlcmxpbmVBbm5vdGF0aW9uKC4uLnZhbHVlcyA6IGFueVtdKSB7XG4gICAgICAgIGxldCBwYXJhbXMgPSBQYXJhbWV0ZXJQYXJzZXIucGFyc2VQYXJhbWV0ZXJzKHZhbHVlcylcblxuICAgICAgICBsZXQgYW5ub3QgOiBVbmRlcmxpbmVBbm5vdGF0aW9uT2JqID0gbmV3IFVuZGVybGluZUFubm90YXRpb25PYmooKVxuICAgICAgICBhbm5vdCA9ICg8YW55Pk9iamVjdCkuYXNzaWduKGFubm90LCB0aGlzLmNyZWF0ZUJhc2VBbm5vdGF0aW9uKHBhcmFtcy5wYWdlKSlcbiAgICAgICAgYW5ub3QgPSAoPGFueT5PYmplY3QpLmFzc2lnbihhbm5vdCwgcGFyYW1zKVxuXG4gICAgICAgIGFubm90LnZhbGlkYXRlKClcblxuICAgICAgICB0aGlzLmFubm90YXRpb25zLnB1c2goYW5ub3QpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNxdWlnZ2xlIGFubm90YXRpb25cbiAgICAgKiBwYWdlIDogdGhlIG51bWJlciBvZiB0aGUgUERGIGRvY3VtZW50IHBhZ2UsIHdoZXJlIHRoZSBhbm5vdGF0aW9uIG11c3QgYmUgYXR0YWNoZWRcbiAgICAgKiByZWN0IDogdGhlIHBvc2l0aW9uIG9mIHRoZSBhbm5vdGF0aW9uIG9uIHRoZSBwYWdlXG4gICAgICogY29udGVudHMgOiB0aGUgY29udGVudCBvZiB0aGUgYW5ub3RhdGlvblxuICAgICAqIGF1dGhvciA6IHRoZSBhdXRob3Igb2YgdGhlIGFubm90YXRpb25cbiAgICAgKiBjb2xvciA6IHRoZSBjb2xvciBvZiB0aGUgYW5ub3RhdGlvbiBpbiByZ2IuIENhbiBiZSBvZiBkb21haW4gMCAtIDI1NSBvciAwIC0gMVxuICAgICAqIHF1YWRQb2ludHMgOiByZWdpb25zIHRvIG1hcmsgd2l0aCB0aGUgaGlnaGxpZ2h0XG4gICAgICogKi9cbiAgICBjcmVhdGVTcXVpZ2dseUFubm90YXRpb24oLi4udmFsdWVzIDogYW55W10pIHtcbiAgICAgICAgbGV0IHBhcmFtcyA9IFBhcmFtZXRlclBhcnNlci5wYXJzZVBhcmFtZXRlcnModmFsdWVzKVxuXG4gICAgICAgIGxldCBhbm5vdCA6IFNxdWlnZ2x5QW5ub3RhdGlvbk9iaiA9IG5ldyBTcXVpZ2dseUFubm90YXRpb25PYmooKVxuICAgICAgICBhbm5vdCA9ICg8YW55Pk9iamVjdCkuYXNzaWduKGFubm90LCB0aGlzLmNyZWF0ZUJhc2VBbm5vdGF0aW9uKHBhcmFtcy5wYWdlKSlcbiAgICAgICAgYW5ub3QgPSAoPGFueT5PYmplY3QpLmFzc2lnbihhbm5vdCwgcGFyYW1zKVxuXG4gICAgICAgIGFubm90LnZhbGlkYXRlKClcblxuICAgICAgICB0aGlzLmFubm90YXRpb25zLnB1c2goYW5ub3QpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHN0cmlrZSBvdXQgYW5ub3RhdGlvblxuICAgICAqIHBhZ2UgOiB0aGUgbnVtYmVyIG9mIHRoZSBQREYgZG9jdW1lbnQgcGFnZSwgd2hlcmUgdGhlIGFubm90YXRpb24gbXVzdCBiZSBhdHRhY2hlZFxuICAgICAqIHJlY3QgOiB0aGUgcG9zaXRpb24gb2YgdGhlIGFubm90YXRpb24gb24gdGhlIHBhZ2VcbiAgICAgKiBjb250ZW50cyA6IHRoZSBjb250ZW50IG9mIHRoZSBhbm5vdGF0aW9uXG4gICAgICogYXV0aG9yIDogdGhlIGF1dGhvciBvZiB0aGUgYW5ub3RhdGlvblxuICAgICAqIGNvbG9yIDogdGhlIGNvbG9yIG9mIHRoZSBhbm5vdGF0aW9uIGluIHJnYi4gQ2FuIGJlIG9mIGRvbWFpbiAwIC0gMjU1IG9yIDAgLSAxXG4gICAgICogcXVhZFBvaW50cyA6IHJlZ2lvbnMgdG8gbWFyayB3aXRoIHRoZSBoaWdobGlnaHRcbiAgICAgKiAqL1xuICAgIGNyZWF0ZVN0cmlrZU91dEFubm90YXRpb24oLi4udmFsdWVzIDogYW55W10pIHtcbiAgICAgICAgbGV0IHBhcmFtcyA9IFBhcmFtZXRlclBhcnNlci5wYXJzZVBhcmFtZXRlcnModmFsdWVzKVxuXG4gICAgICAgIGxldCBhbm5vdCA6IFN0cmlrZU91dEFubm90YXRpb25PYmogPSBuZXcgU3RyaWtlT3V0QW5ub3RhdGlvbk9iaigpXG4gICAgICAgIGFubm90ID0gKDxhbnk+T2JqZWN0KS5hc3NpZ24oYW5ub3QsIHRoaXMuY3JlYXRlQmFzZUFubm90YXRpb24ocGFyYW1zLnBhZ2UpKVxuICAgICAgICBhbm5vdCA9ICg8YW55Pk9iamVjdCkuYXNzaWduKGFubm90LCBwYXJhbXMpXG5cbiAgICAgICAgYW5ub3QudmFsaWRhdGUoKVxuXG4gICAgICAgIHRoaXMuYW5ub3RhdGlvbnMucHVzaChhbm5vdClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnJlZSB0ZXh0IGFubm90YXRpb25cbiAgICAgKiBwYWdlIDogdGhlIG51bWJlciBvZiB0aGUgUERGIGRvY3VtZW50IHBhZ2UsIHdoZXJlIHRoZSBhbm5vdGF0aW9uIG11c3QgYmUgYXR0YWNoZWRcbiAgICAgKiByZWN0IDogdGhlIHBvc2l0aW9uIG9mIHRoZSBhbm5vdGF0aW9uIG9uIHRoZSBwYWdlXG4gICAgICogY29udGVudHMgOiB0aGUgY29udGVudCBvZiB0aGUgYW5ub3RhdGlvblxuICAgICAqIGF1dGhvciA6IHRoZSBhdXRob3Igb2YgdGhlIGFubm90YXRpb25cbiAgICAgKiBjb2xvciA6IHRoZSBjb2xvciBvZiB0aGUgYW5ub3RhdGlvbiBpbiByZ2IuIENhbiBiZSBvZiBkb21haW4gMCAtIDI1NSBvciAwIC0gMVxuICAgICAqICovXG4gICAgY3JlYXRlRnJlZVRleHRBbm5vdGF0aW9uKC4uLnZhbHVlcyA6IGFueVtdKSB7XG4gICAgICAgIGxldCBwYXJhbXMgPSBQYXJhbWV0ZXJQYXJzZXIucGFyc2VQYXJhbWV0ZXJzKHZhbHVlcylcblxuICAgICAgICBsZXQgYW5ub3QgOiBGcmVlVGV4dEFubm90YXRpb25PYmogPSBuZXcgRnJlZVRleHRBbm5vdGF0aW9uT2JqKClcbiAgICAgICAgYW5ub3QgPSAoPGFueT5PYmplY3QpLmFzc2lnbihhbm5vdCwgdGhpcy5jcmVhdGVCYXNlQW5ub3RhdGlvbihwYXJhbXMucGFnZSkpXG4gICAgICAgIGFubm90ID0gKDxhbnk+T2JqZWN0KS5hc3NpZ24oYW5ub3QsIHBhcmFtcylcblxuICAgICAgICBhbm5vdC52YWxpZGF0ZSgpXG5cbiAgICAgICAgdGhpcy5hbm5vdGF0aW9ucy5wdXNoKGFubm90KVxuICAgIH1cblxuICAgIGNyZWF0ZUxpbmVBbm5vdGF0aW9uKCkge1xuICAgICAgICB0aHJvdyBFcnJvcihcIk5vIHlldCBpbXBsZW1lbnRlZFwiKVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNxdWFyZSBhbm5vdGF0aW9uXG4gICAgICogcGFnZSA6IHRoZSBudW1iZXIgb2YgdGhlIFBERiBkb2N1bWVudCBwYWdlLCB3aGVyZSB0aGUgYW5ub3RhdGlvbiBtdXN0IGJlIGF0dGFjaGVkXG4gICAgICogcmVjdCA6IHRoZSBwb3NpdGlvbiBvZiB0aGUgYW5ub3RhdGlvbiBvbiB0aGUgcGFnZVxuICAgICAqIGNvbnRlbnRzIDogdGhlIGNvbnRlbnQgb2YgdGhlIGFubm90YXRpb25cbiAgICAgKiBhdXRob3IgOiB0aGUgYXV0aG9yIG9mIHRoZSBhbm5vdGF0aW9uXG4gICAgICogY29sb3IgOiB0aGUgY29sb3Igb2YgdGhlIGFubm90YXRpb24gaW4gcmdiLiBDYW4gYmUgb2YgZG9tYWluIDAgLSAyNTUgb3IgMCAtIDFcbiAgICAgKiBmaWxsIDogdGhlIGZpbGxpbmcgY29sb3Igb2YgIHRoZSBhbm5vdGF0aW9uIGluIHJnYi4gQ2FuIGJlIG9mIGRvbWFpbiAwIC0gMjU1IG9yIDAgLSAxXG4gICAgICogKi9cbiAgICBjcmVhdGVTcXVhcmVBbm5vdGF0aW9uKC4uLnZhbHVlcyA6IGFueVtdKSB7XG4gICAgICAgIGxldCBwYXJhbXMgPSBQYXJhbWV0ZXJQYXJzZXIucGFyc2VQYXJhbWV0ZXJzKHZhbHVlcylcblxuICAgICAgICBsZXQgYW5ub3QgOiBTcXVhcmVBbm5vdGF0aW9uT2JqID0gbmV3IFNxdWFyZUFubm90YXRpb25PYmooKVxuICAgICAgICBhbm5vdCA9ICg8YW55Pk9iamVjdCkuYXNzaWduKGFubm90LCB0aGlzLmNyZWF0ZUJhc2VBbm5vdGF0aW9uKHBhcmFtcy5wYWdlKSlcbiAgICAgICAgYW5ub3QgPSAoPGFueT5PYmplY3QpLmFzc2lnbihhbm5vdCwgcGFyYW1zKVxuXG4gICAgICAgIGFubm90LnZhbGlkYXRlKClcblxuICAgICAgICB0aGlzLmFubm90YXRpb25zLnB1c2goYW5ub3QpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNpcmNsZSBhbm5vdGF0aW9uXG4gICAgICogcGFnZSA6IHRoZSBudW1iZXIgb2YgdGhlIFBERiBkb2N1bWVudCBwYWdlLCB3aGVyZSB0aGUgYW5ub3RhdGlvbiBtdXN0IGJlIGF0dGFjaGVkXG4gICAgICogcmVjdCA6IHRoZSBwb3NpdGlvbiBvZiB0aGUgYW5ub3RhdGlvbiBvbiB0aGUgcGFnZVxuICAgICAqIGNvbnRlbnRzIDogdGhlIGNvbnRlbnQgb2YgdGhlIGFubm90YXRpb25cbiAgICAgKiBhdXRob3IgOiB0aGUgYXV0aG9yIG9mIHRoZSBhbm5vdGF0aW9uXG4gICAgICogY29sb3IgOiB0aGUgY29sb3Igb2YgdGhlIGFubm90YXRpb24gaW4gcmdiLiBDYW4gYmUgb2YgZG9tYWluIDAgLSAyNTUgb3IgMCAtIDFcbiAgICAgKiBmaWxsIDogdGhlIGZpbGxpbmcgY29sb3Igb2YgIHRoZSBhbm5vdGF0aW9uIGluIHJnYi4gQ2FuIGJlIG9mIGRvbWFpbiAwIC0gMjU1IG9yIDAgLSAxXG4gICAgICogKi9cbiAgICBjcmVhdGVDaXJjbGVBbm5vdGF0aW9uKC4uLnZhbHVlcyA6IGFueVtdKSB7XG4gICAgICAgIGxldCBwYXJhbXMgPSBQYXJhbWV0ZXJQYXJzZXIucGFyc2VQYXJhbWV0ZXJzKHZhbHVlcylcblxuICAgICAgICBsZXQgYW5ub3QgOiBDaXJjbGVBbm5vdGF0aW9uT2JqID0gbmV3IENpcmNsZUFubm90YXRpb25PYmooKVxuICAgICAgICBhbm5vdCA9ICg8YW55Pk9iamVjdCkuYXNzaWduKGFubm90LCB0aGlzLmNyZWF0ZUJhc2VBbm5vdGF0aW9uKHBhcmFtcy5wYWdlKSlcbiAgICAgICAgYW5ub3QgPSAoPGFueT5PYmplY3QpLmFzc2lnbihhbm5vdCwgcGFyYW1zKVxuXG4gICAgICAgIGFubm90LnZhbGlkYXRlKClcblxuICAgICAgICB0aGlzLmFubm90YXRpb25zLnB1c2goYW5ub3QpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBvbHlnb24gYW5ub3RhdGlvblxuICAgICAqIHBhZ2UgOiB0aGUgbnVtYmVyIG9mIHRoZSBQREYgZG9jdW1lbnQgcGFnZSwgd2hlcmUgdGhlIGFubm90YXRpb24gbXVzdCBiZSBhdHRhY2hlZFxuICAgICAqIHJlY3QgOiB0aGUgcG9zaXRpb24gb2YgdGhlIGFubm90YXRpb24gb24gdGhlIHBhZ2VcbiAgICAgKiBjb250ZW50cyA6IHRoZSBjb250ZW50IG9mIHRoZSBhbm5vdGF0aW9uXG4gICAgICogYXV0aG9yIDogdGhlIGF1dGhvciBvZiB0aGUgYW5ub3RhdGlvblxuICAgICAqIHZlcnRpY2VzIDogdGhlIHZlcnRpY2VzIGRlZmluaW5nIHRoZSBhcnJhbmdlbWVudCBvZiB0aGUgb2JqZWN0XG4gICAgICogY29sb3IgOiB0aGUgY29sb3Igb2YgdGhlIGFubm90YXRpb24gaW4gcmdiLiBDYW4gYmUgb2YgZG9tYWluIDAgLSAyNTUgb3IgMCAtIDFcbiAgICAgKiAqL1xuICAgIGNyZWF0ZVBvbHlnb25Bbm5vdGF0aW9uKC4uLnZhbHVlcyA6IGFueVtdKSB7XG4gICAgICAgIGxldCBwYXJhbXMgPSBQYXJhbWV0ZXJQYXJzZXIucGFyc2VQYXJhbWV0ZXJzKHZhbHVlcylcblxuICAgICAgICBsZXQgYW5ub3QgOiBQb2x5Z29uQW5ub3RhdGlvbk9iaiA9IG5ldyBQb2x5Z29uQW5ub3RhdGlvbk9iaigpXG4gICAgICAgIGFubm90ID0gKDxhbnk+T2JqZWN0KS5hc3NpZ24oYW5ub3QsIHRoaXMuY3JlYXRlQmFzZUFubm90YXRpb24ocGFyYW1zLnBhZ2UpKVxuICAgICAgICBhbm5vdCA9ICg8YW55Pk9iamVjdCkuYXNzaWduKGFubm90LCBwYXJhbXMpXG5cbiAgICAgICAgYW5ub3QudmFsaWRhdGUoKVxuXG4gICAgICAgIHRoaXMuYW5ub3RhdGlvbnMucHVzaChhbm5vdClcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwb2x5bGluZSBhbm5vdGF0aW9uXG4gICAgICogcGFnZSA6IHRoZSBudW1iZXIgb2YgdGhlIFBERiBkb2N1bWVudCBwYWdlLCB3aGVyZSB0aGUgYW5ub3RhdGlvbiBtdXN0IGJlIGF0dGFjaGVkXG4gICAgICogcmVjdCA6IHRoZSBwb3NpdGlvbiBvZiB0aGUgYW5ub3RhdGlvbiBvbiB0aGUgcGFnZVxuICAgICAqIGNvbnRlbnRzIDogdGhlIGNvbnRlbnQgb2YgdGhlIGFubm90YXRpb25cbiAgICAgKiBhdXRob3IgOiB0aGUgYXV0aG9yIG9mIHRoZSBhbm5vdGF0aW9uXG4gICAgICogdmVydGljZXMgOiB0aGUgdmVydGljZXMgZGVmaW5pbmcgdGhlIGFycmFuZ2VtZW50IG9mIHRoZSBvYmplY3RcbiAgICAgKiBjb2xvciA6IHRoZSBjb2xvciBvZiB0aGUgYW5ub3RhdGlvbiBpbiByZ2IuIENhbiBiZSBvZiBkb21haW4gMCAtIDI1NSBvciAwIC0gMVxuICAgICAqICovXG4gICAgY3JlYXRlUG9seUxpbmVBbm5vdGF0aW9uKC4uLnZhbHVlcyA6IGFueVtdKSB7XG4gICAgICAgIGxldCBwYXJhbXMgPSBQYXJhbWV0ZXJQYXJzZXIucGFyc2VQYXJhbWV0ZXJzKHZhbHVlcylcblxuICAgICAgICBsZXQgYW5ub3QgOiBQb2x5TGluZUFubm90YXRpb25PYmogPSBuZXcgUG9seUxpbmVBbm5vdGF0aW9uT2JqKClcbiAgICAgICAgYW5ub3QgPSAoPGFueT5PYmplY3QpLmFzc2lnbihhbm5vdCwgdGhpcy5jcmVhdGVCYXNlQW5ub3RhdGlvbihwYXJhbXMucGFnZSkpXG4gICAgICAgIGFubm90ID0gKDxhbnk+T2JqZWN0KS5hc3NpZ24oYW5ub3QsIHBhcmFtcylcblxuICAgICAgICBhbm5vdC52YWxpZGF0ZSgpXG5cbiAgICAgICAgdGhpcy5hbm5vdGF0aW9ucy5wdXNoKGFubm90KVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5rIGFubm90YXRpb25cbiAgICAgKiBwYWdlIDogdGhlIG51bWJlciBvZiB0aGUgUERGIGRvY3VtZW50IHBhZ2UsIHdoZXJlIHRoZSBhbm5vdGF0aW9uIG11c3QgYmUgYXR0YWNoZWRcbiAgICAgKiByZWN0IDogdGhlIHBvc2l0aW9uIG9mIHRoZSBhbm5vdGF0aW9uIG9uIHRoZSBwYWdlXG4gICAgICogY29udGVudHMgOiB0aGUgY29udGVudCBvZiB0aGUgYW5ub3RhdGlvblxuICAgICAqIGF1dGhvciA6IHRoZSBhdXRob3Igb2YgdGhlIGFubm90YXRpb25cbiAgICAgKiBpbmtMaXN0IDogYSBsaXN0IG9mIGxpc3QgY29udGFpbmluZyB0aGUgcG9pbnRzIGZvciBkcmF3aW5nIHRoZSBsaW5lc1xuICAgICAqIGNvbG9yIDogdGhlIGNvbG9yIG9mIHRoZSBhbm5vdGF0aW9uIGluIHJnYi4gQ2FuIGJlIG9mIGRvbWFpbiAwIC0gMjU1IG9yIDAgLSAxXG4gICAgICogKi9cbiAgICBjcmVhdGVJbmtBbm5vdGF0aW9uKC4uLnZhbHVlcyA6IGFueVtdKSB7XG4gICAgICAgIGxldCBwYXJhbXMgPSBQYXJhbWV0ZXJQYXJzZXIucGFyc2VQYXJhbWV0ZXJzKHZhbHVlcylcblxuICAgICAgICBsZXQgYW5ub3QgOiBJbmtBbm5vdGF0aW9uT2JqID0gbmV3IElua0Fubm90YXRpb25PYmooKVxuICAgICAgICBhbm5vdCA9ICg8YW55Pk9iamVjdCkuYXNzaWduKGFubm90LCB0aGlzLmNyZWF0ZUJhc2VBbm5vdGF0aW9uKHBhcmFtcy5wYWdlKSlcbiAgICAgICAgYW5ub3QgPSAoPGFueT5PYmplY3QpLmFzc2lnbihhbm5vdCwgcGFyYW1zKVxuXG4gICAgICAgIGFubm90LnZhbGlkYXRlKClcblxuICAgICAgICB0aGlzLmFubm90YXRpb25zLnB1c2goYW5ub3QpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHN0YW1wIGFubm90YXRpb24uIFRoZXJlIGV4aXN0cyBhIG51bWJlciBvZiBwcmVkaWZpbmVkIHN0YW1wcyB0aGF0IGNhbiBiZSBhdHRhY2hlZCB0byBQREYgZG9jdW1lbnRzLlxuICAgICAqIHBhZ2UgOiB0aGUgbnVtYmVyIG9mIHRoZSBQREYgZG9jdW1lbnQgcGFnZSwgd2hlcmUgdGhlIGFubm90YXRpb24gbXVzdCBiZSBhdHRhY2hlZFxuICAgICAqIGNvbnRlbnRzIDogdGhlIGNvbnRlbnQgb2YgdGhlIGFubm90YXRpb25cbiAgICAgKiBhdXRob3IgOiB0aGUgYXV0aG9yIG9mIHRoZSBhbm5vdGF0aW9uXG4gICAgICogc3RhbXBUeXBlIDogdGhlIG5hbWUgb2YgdGhlIHVzZWQgc3RhbXAgdHlwZS4gQ2FuIGJlOiBbQXBwcm92ZWQsIEV4cGVyaW1lbnRhbCwgTm90QXBwcm92ZWQsIEFzSXMsIEV4cGlyZWQsIE5vdEZvclB1YmxpY1JlbGVhc2UsIENvbmZpZGVudGlhbCwgRmluYWwsIFNvbGQsIERlcGFydG1lbnRhbCwgRm9yQ29tbWVudCwgVG9wU2VjcmV0LCBEcmFmdCwgRm9yUHVibGljUmVsZWFzZV1cbiAgICAgKiBjb2xvciA6IHRoZSBjb2xvciBvZiB0aGUgYW5ub3RhdGlvbiBpbiByZ2IuIENhbiBiZSBvZiBkb21haW4gMCAtIDI1NSBvciAwIC0gMVxuICAgICAqICovXG4gICAgY3JlYXRlU3RhbXBBbm5vdGF0aW9uKC4uLnZhbHVlcyA6IGFueVtdKSB7XG4gICAgICAgIGxldCBwYXJhbXMgPSBQYXJhbWV0ZXJQYXJzZXIucGFyc2VQYXJhbWV0ZXJzKHZhbHVlcylcbiAgICAgICAgbGV0IGFubm90OiBBbm5vdGF0aW9uID0gKDxhbnk+T2JqZWN0KS5hc3NpZ24odGhpcy5jcmVhdGVCYXNlQW5ub3RhdGlvbihwYXJhbXMucGFnZSksIHtcbiAgICAgICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgICAgICBpbml0aWFsbHlPcGVuOiBmYWxzZSxcbiAgICAgICAgICAgIGFubm90YXRpb25fZmxhZzogNCxcbiAgICAgICAgICAgIGNvbG9yOiBwYXJhbXMuY29sb3IsXG4gICAgICAgICAgICBzdGFtcFR5cGU6IHBhcmFtcy5zdGFtcFR5cGVcbiAgICAgICAgfSlcblxuICAgICAgICBhbm5vdC50eXBlID0gXCIvU3RhbXBcIlxuXG4gICAgICAgIHRoaXMuYW5ub3RhdGlvbnMucHVzaChhbm5vdClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgdmlzdWFsIHN5bWJvbCB0aGF0IGluZGNhdGVzIHRoZSBleGlzdGFuY2Ugb2YgdGV4dCBlZGl0cy5cbiAgICAgKiBwYWdlIDogdGhlIG51bWJlciBvZiB0aGUgUERGIGRvY3VtZW50IHBhZ2UsIHdoZXJlIHRoZSBhbm5vdGF0aW9uIG11c3QgYmUgYXR0YWNoZWRcbiAgICAgKiBjb250ZW50cyA6IHRoZSBjb250ZW50IG9mIHRoZSBhbm5vdGF0aW9uXG4gICAgICogYXV0aG9yIDogdGhlIGF1dGhvciBvZiB0aGUgYW5ub3RhdGlvblxuICAgICAqIGNhcmV0U3ltYm9sIDogTm9uZSBvciBQLCB3aXRoIFAgZm9yIHVzaW5nIHRoZSBwYXJhZ3JhcGggc3ltYm9sIGFzIGNhcmV0XG4gICAgICogY29sb3IgOiB0aGUgY29sb3Igb2YgdGhlIGFubm90YXRpb24gaW4gcmdiLiBDYW4gYmUgb2YgZG9tYWluIDAgLSAyNTUgb3IgMCAtIDFcbiAgICAgKiAqL1xuICAgIGNyZWF0ZUNhcmV0QW5ub3RhdGlvbiguLi52YWx1ZXMgOiBhbnlbXSkge1xuICAgICAgICBsZXQgcGFyYW1zID0gUGFyYW1ldGVyUGFyc2VyLnBhcnNlUGFyYW1ldGVycyh2YWx1ZXMpXG4gICAgICAgIGxldCBhbm5vdDogQW5ub3RhdGlvbiA9ICg8YW55Pk9iamVjdCkuYXNzaWduKHRoaXMuY3JlYXRlQmFzZUFubm90YXRpb24ocGFyYW1zLnBhZ2UpLCB7XG4gICAgICAgICAgICBvcGFjaXR5OiAxLFxuICAgICAgICAgICAgaW5pdGlhbGx5T3BlbjogZmFsc2UsXG4gICAgICAgICAgICBhbm5vdGF0aW9uX2ZsYWc6IDQsXG4gICAgICAgICAgICBjb2xvcjogcGFyYW1zLmNvbG9yLFxuICAgICAgICAgICAgY2FyZXRTeW1ib2w6IHBhcmFtcy5jYXJldFN5bWJvbFxuICAgICAgICB9KVxuXG4gICAgICAgIGFubm90LnR5cGUgPSBcIi9DYXJldFwiXG5cbiAgICAgICAgdGhpcy5hbm5vdGF0aW9ucy5wdXNoKGFubm90KVxuICAgIH1cblxuICAgIGNyZWF0ZVBvcHVwQW5ub3RhdGlvbigpIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoXCJObyB5ZXQgaW1wbGVtZW50ZWRcIilcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWxldGVzIHRoZSBhbm5vdGF0aW9uIHdpdGggdGhlIGdpdmVuIGlkIG9yIHRoZSBnaXZlbiByZWZlcmVuY2Ugb2JqZWN0XG4gICAgICogKi9cbiAgICBkZWxldGVBbm5vdGF0aW9uKGlkOiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcblxuICAgICAgICAgICAgLy8gZGVsZXRlIGlmIGl0IHdhcyBqdXN0IGNyZWF0ZWQgYnV0IGlzIG5vdCBpbiB0aGUgcGRmIGRvY3VtZW50XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYW5ub3RhdGlvbnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICBpZiAoJ3N0cmluZycgPT09IHR5cGVvZiBpZCAmJiB0aGlzLmFubm90YXRpb25zW2ldLmlkID09PSBpZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFubm90YXRpb25zID0gdGhpcy5hbm5vdGF0aW9ucy5zbGljZShpLCAxKVxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMudG9EZWxldGUpXG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaWQub2JqICYmIHRoaXMuYW5ub3RhdGlvbnNbaV0ub2JqZWN0X2lkICYmIGlkLm9iaiA9PT0gKDxhbnk+dGhpcy5hbm5vdGF0aW9uc1tpXS5vYmplY3RfaWQpLm9iaiAmJiBpZC5nZW5lcmF0aW9uICYmIGlkLmdlbmVyYXRpb24gPT09ICg8YW55PnRoaXMuYW5ub3RhdGlvbnNbaV0ub2JqZWN0X2lkKS5nZW5lcmF0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYW5ub3RhdGlvbnMgPSB0aGlzLmFubm90YXRpb25zLnNsaWNlKGksIDEpXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUodGhpcy50b0RlbGV0ZSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmdldEFubm90YXRpb25zKCkudGhlbigoYW5ub3RzKSA9PiB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgX2Fubm90cyBvZiBhbm5vdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgYW5ub3Qgb2YgX2Fubm90cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCdzdHJpbmcnID09PSB0eXBlb2YgaWQgJiYgYW5ub3QuaWQgPT09IGlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50b0RlbGV0ZS5wdXNoKGFubm90KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUodGhpcy50b0RlbGV0ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaWQub2JqICYmIGFubm90Lm9iamVjdF9pZCAmJiBpZC5vYmogPT09IGFubm90Lm9iamVjdF9pZC5vYmogJiYgaWQuZ2VuZXJhdGlvbiAmJiBpZC5nZW5lcmF0aW9uID09PSBhbm5vdC5vYmplY3RfaWQuZ2VuZXJhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudG9EZWxldGUucHVzaChhbm5vdClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMudG9EZWxldGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHByb21pc2Ugd2l0aCBhbGwgdGhlIGFubm90YXRpb25zIHRoYXQgYXJlIHBhcnQgb2YgdGhlIGRvY3VtZW50LiBUaGlzXG4gICAgICogY29tcHJpc2VzIGFubm90YXRpb25zLCB0aGF0IGFyZSBhbHJlYWR5IHBhcnQgb2YgdGhlIHBhcnNlZCBkb2N1bWVudCBhbmQgdGhvc2UgdGhhdCB3ZXJlIGNyZWF0ZWQgdXNpbmcgdGhpcyBsaWJyYXJ5IGFuZFxuICAgICAqIG5vdCB5ZXQgYXBwZW5kZWQgdG8gdGhlIGRvY3VtZW50LlxuICAgICAqICovXG4gICAgZ2V0QW5ub3RhdGlvbnMoKTogUHJvbWlzZTxBbm5vdGF0aW9uW11bXT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIGxldCBleGlzdGluZ0Fubm90cyA9IHRoaXMucGFyc2VyLmV4dHJhY3RBbm5vdGF0aW9ucygpXG4gICAgICAgICAgICBmb3IgKGxldCBuZXdBbm5vdCBvZiB0aGlzLmFubm90YXRpb25zKSB7XG4gICAgICAgICAgICAgICAgZXhpc3RpbmdBbm5vdHNbbmV3QW5ub3QucGFnZV0ucHVzaChuZXdBbm5vdClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc29sdmUoZXhpc3RpbmdBbm5vdHMpXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRG93bmxvYWRzIHRoZSBhZGFwdGVkIFBERiBkb2N1bWVudFxuICAgICAqICovXG4gICAgZG93bmxvYWQoZmlsZU5hbWU6IHN0cmluZyA9IFwib3V0cHV0LnBkZlwiKSB7XG4gICAgICAgIGxldCBhOiBhbnkgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYVwiKTtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChhKTtcbiAgICAgICAgYS5zdHlsZSA9IFwiZGlzcGxheTogbm9uZVwiO1xuXG4gICAgICAgIGxldCBleHRlbmRlZF9wZGYgPSB0aGlzLndyaXRlKClcbiAgICAgICAgbGV0IGJsb2IgPSBuZXcgQmxvYihbZXh0ZW5kZWRfcGRmXSwgeyB0eXBlOiBcImFwcGxpY2F0aW9uL3BkZlwiIH0pXG4gICAgICAgIGxldCB1cmwgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKVxuICAgICAgICBhLmhyZWYgPSB1cmxcbiAgICAgICAgYS5kb3dubG9hZCA9IGZpbGVOYW1lXG4gICAgICAgIGEuY2xpY2soKVxuICAgICAgICBhLnJlbW92ZSgpXG4gICAgICAgIHdpbmRvdy5VUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2F2ZXMgdGhlIGFkYXB0ZWQgUERGIGRvY3VtZW50IGluIGEgbm9kZWpzIGVudmlyb25tZW50IGFuZCBkb3dubG9hZHMgaXQgaW4gYSBicm93c2VyIGVudmlyb25tZW50LlxuICAgICAqICovXG4gICAgc2F2ZShmaWxlTmFtZTogc3RyaW5nID0gXCJvdXRwdXQucGRmXCIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7IC8vIGJyb3dzZXIgZW52aXJvbm1lbnRcbiAgICAgICAgICAgIHRoaXMuZG93bmxvYWQoZmlsZU5hbWUpXG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHByb2Nlc3MgPT09ICdvYmplY3QnKSB7IC8vIG5vZGUgZW52aXJvbm1lbnRcbiAgICAgICAgICAgIGNvbnN0IGZzID0gcmVxdWlyZSgnZnMnKVxuICAgICAgICAgICAgbGV0IGRhdGEgPSB0aGlzLndyaXRlKClcbiAgICAgICAgICAgIGZzLndyaXRlRmlsZShmaWxlTmFtZSwgQnVmZmVyLmZyb20obmV3IFVpbnQ4QXJyYXkoZGF0YSkpLCAoZXJyOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IEVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiVW5zdXBwb3J0ZWQgZW52aXJvbm1lbnRcIilcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImV4cG9ydCBjbGFzcyBJbnZhbGlkQW5ub3RhdGlvblR5cGVFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgbWVzc2FnZSA6IHN0cmluZykge1xuICAgICAgICBzdXBlcihtZXNzYWdlKVxuICAgICAgICB0aGlzLm5hbWUgPSBcIkludmFsaWRBbm5vdGF0aW9uVHlwZUVycm9yXCJcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBJbnZhbGlkT3BhY2l0eUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKHB1YmxpYyBtZXNzYWdlIDogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpXG4gICAgICAgIHRoaXMubmFtZSA9IFwiSW52YWxpZE9wYWNpdHlFcnJvclwiXG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgSW52YWxpZENvbG9yRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgY29uc3RydWN0b3IocHVibGljIG1lc3NhZ2UgOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIobWVzc2FnZSlcbiAgICAgICAgdGhpcy5uYW1lID0gXCJJbnZhbGlkQ29sb3JFcnJvclwiXG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ29sb3JPdXRPZlJhbmdlRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgY29uc3RydWN0b3IocHVibGljIG1lc3NhZ2UgOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIobWVzc2FnZSlcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDb2xvck91dE9mUmFuZ2VFcnJvclwiXG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgSW52YWxpZFJlZmVyZW5jZVBvaW50ZXJFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgbWVzc2FnZSA6IHN0cmluZykge1xuICAgICAgICBzdXBlcihtZXNzYWdlKVxuICAgICAgICB0aGlzLm5hbWUgPSBcIkludmFsaWRSZWZlcmVuY2VQb2ludGVyRXJyb3JcIlxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEludmFsaWREYXRlRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgY29uc3RydWN0b3IocHVibGljIG1lc3NhZ2UgOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIobWVzc2FnZSlcbiAgICAgICAgdGhpcy5uYW1lID0gXCJJbnZhbGlkRGF0ZUVycm9yXCJcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBJbnZhbGlkUmVjdEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKHB1YmxpYyBtZXNzYWdlIDogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpXG4gICAgICAgIHRoaXMubmFtZSA9IFwiSW52YWxpZFJlY3RFcnJvclwiXG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgSW52YWxpZElERXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgY29uc3RydWN0b3IocHVibGljIG1lc3NhZ2UgOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIobWVzc2FnZSlcbiAgICAgICAgdGhpcy5uYW1lID0gXCJJbnZhbGlkSURFcnJvclwiXG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgSW52YWxpZFN0YXRlRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgY29uc3RydWN0b3IocHVibGljIG1lc3NhZ2UgOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIobWVzc2FnZSlcbiAgICAgICAgdGhpcy5uYW1lID0gXCJJbnZhbGlkU3RhdGVFcnJvclwiXG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgSW52YWxpZFF1YWRQb2ludEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKHB1YmxpYyBtZXNzYWdlIDogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpXG4gICAgICAgIHRoaXMubmFtZSA9IFwiSW52YWxpZFF1YWRQb2ludEVycm9yXCJcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBJbnZhbGlkVmVydGljZXNFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgbWVzc2FnZSA6IHN0cmluZykge1xuICAgICAgICBzdXBlcihtZXNzYWdlKVxuICAgICAgICB0aGlzLm5hbWUgPSBcIkludmFsaWRWZXJ0aWNlc0Vycm9yXCJcbiAgICB9XG59XG5cbmV4cG9ydCB0eXBlIEVycm9yTGlzdCA9IChFcnJvciB8IENvbG9yT3V0T2ZSYW5nZUVycm9yIHwgSW52YWxpZFJlZmVyZW5jZVBvaW50ZXJFcnJvciB8IEludmFsaWREYXRlRXJyb3IgfCBJbnZhbGlkUmVjdEVycm9yIHwgSW52YWxpZElERXJyb3IgfCBJbnZhbGlkQ29sb3JFcnJvciB8IEludmFsaWRPcGFjaXR5RXJyb3IgfCBJbnZhbGlkQW5ub3RhdGlvblR5cGVFcnJvciB8IEludmFsaWRTdGF0ZUVycm9yIHwgSW52YWxpZFF1YWRQb2ludEVycm9yIHwgSW52YWxpZFZlcnRpY2VzRXJyb3IpW11cbiIsImltcG9ydCB7IFBhZ2UsIFJlZmVyZW5jZVBvaW50ZXIsIENyeXB0b0ludGVyZmFjZSB9IGZyb20gJy4uL3BhcnNlcic7XG5pbXBvcnQgeyBVdGlsIH0gZnJvbSAnLi4vdXRpbCc7XG5pbXBvcnQgeyBFcnJvckxpc3QsIEludmFsaWRPcGFjaXR5RXJyb3IsIEludmFsaWRSZWN0RXJyb3IsIEludmFsaWREYXRlRXJyb3IsIEludmFsaWRSZWZlcmVuY2VQb2ludGVyRXJyb3IsIENvbG9yT3V0T2ZSYW5nZUVycm9yLCBJbnZhbGlkQ29sb3JFcnJvciwgSW52YWxpZElERXJyb3IgfSBmcm9tICcuL2Fubm90YXRpb25fZXJyb3JzJztcbmltcG9ydCB7IFdyaXRlclV0aWwgfSBmcm9tICcuLi93cml0ZXItdXRpbCc7XG5cbmV4cG9ydCBlbnVtIExpbmVFbmRpbmdTdHlsZSB7XG4gICAgU3F1YXJlLCBDaXJjbGUsIERpYW1vbmQsIE9wZW5BcnJvdywgQ2xvc2VkQXJyb3csIEJ1dHQsIFJPcGVuQXJyb3csIFJDbG9zZWRBcnJvdywgU2xhc2gsIE5vbmVcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb2xvciB7XG4gICAgcjogbnVtYmVyXG4gICAgZzogbnVtYmVyXG4gICAgYjogbnVtYmVyXG59XG5cbmV4cG9ydCBlbnVtIEJvcmRlclN0eWxlcyB7XG4gICAgU29saWQsIERhc2hlZCwgQmV2ZWxlZCwgSW5zZXQsIFVuZGVybGluZVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJvcmRlciB7XG4gICAgaG9yaXpvbnRhbF9jb3JuZXJfcmFkaXVzPzogbnVtYmVyXG4gICAgdmVydGljYWxfY29ybmVyX3JhZGl1cz86IG51bWJlclxuICAgIGJvcmRlcl93aWR0aD86IG51bWJlclxuICAgIGRhc2hfcGF0dGVybj86IG51bWJlcltdXG4gICAgYm9yZGVyX3N0eWxlPzogQm9yZGVyU3R5bGVzXG4gICAgY2xvdWR5PzogYm9vbGVhblxuICAgIGNsb3VkX2ludGVuc2l0eT86IG51bWJlclxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFubm90YXRpb25GbGFncyB7XG4gICAgaW52aXNpYmxlPzogYm9vbGVhblxuICAgIGhpZGRlbj86IGJvb2xlYW5cbiAgICBwcmludD86IGJvb2xlYW5cbiAgICBub1pvb20/OiBib29sZWFuXG4gICAgbm9Sb3RhdGU/OiBib29sZWFuXG4gICAgbm9WaWV3PzogYm9vbGVhblxuICAgIHJlYWRPbmx5PzogYm9vbGVhblxuICAgIGxvY2tlZD86IGJvb2xlYW5cbiAgICB0b2dnbGVOb1ZpZXc/OiBib29sZWFuXG4gICAgbG9ja2VkQ29udGVudHM/OiBib29sZWFuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXBwZWFyYW5jZVN0cmVhbSB7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3B0aW9uYWxDb250ZW50IHtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCYXNlQW5ub3RhdGlvbiB7XG4gICAgcGFnZTogbnVtYmVyXG4gICAgcGFnZVJlZmVyZW5jZTogUGFnZSB8IHVuZGVmaW5lZCAvLyBUaGUgcmVmZXJlbmNlIHRvIHRoZSBwYWdlIG9iamVjdCB0byB3aGljaCB0aGUgYW5ub3RhdGlvbiBpcyBhZGRlZFxuICAgIG9iamVjdF9pZDogUmVmZXJlbmNlUG9pbnRlciB8IHVuZGVmaW5lZCAvLyBhbiB1bnVzZWQgb2JqZWN0IGlkXG4gICAgdHlwZT86IHN0cmluZ1xuICAgIHJlY3Q6IG51bWJlcltdXG4gICAgY29udGVudHM/OiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgICBpZDogc3RyaW5nIC8vIC9OTVxuICAgIHVwZGF0ZURhdGU6IHN0cmluZyB8IERhdGUvLyAvTVxuICAgIGFubm90YXRpb25GbGFncz86IEFubm90YXRpb25GbGFncyB8IHVuZGVmaW5lZCAvLyAvRlxuICAgIGFwcGVhcmFuY2VTdHJlYW0/OiBBcHBlYXJhbmNlU3RyZWFtIHwgdW5kZWZpbmVkIC8vIC9BUFxuICAgIGFwcGVhcmFuY2VTdHJlYW1TZWxlY3Rvcj86IHN0cmluZyB8IHVuZGVmaW5lZCAvLyAvQVNcbiAgICBib3JkZXI/OiBCb3JkZXIgfCB1bmRlZmluZWRcbiAgICBjb2xvcj86IENvbG9yIHwgdW5kZWZpbmVkIC8vIC9DXG4gICAgc3RydWN0UGFyZW50PzogbnVtYmVyIHwgdW5kZWZpbmVkIC8vIC9TdHJ1Y3RQYXJlbnRcbiAgICBvcHRpb25hbENvbnRlbnQ/OiBPcHRpb25hbENvbnRlbnQgfCB1bmRlZmluZWQgLy8gL09DXG4gICAgaXNfZGVsZXRlZD86IGJvb2xlYW4gLy8gaW50ZXJuYWwgZmxhZyB0byBkZXRlcm1pbmUgd2hldGhlciB0aGUgYW5ub3RhdGlvbiB3YXMgZGVsZXRlZFxufVxuXG5leHBvcnQgY2xhc3MgQmFzZUFubm90YXRpb25PYmogaW1wbGVtZW50cyBCYXNlQW5ub3RhdGlvbiB7XG4gICAgb2JqZWN0X2lkOiBSZWZlcmVuY2VQb2ludGVyIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkLy8gYW4gdW51c2VkIG9iamVjdCBpZFxuICAgIGlzX2RlbGV0ZWQ6IGJvb2xlYW4gPSBmYWxzZS8vIGludGVybmFsIGZsYWcgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGFubm90YXRpb24gd2FzIGRlbGV0ZWRcblxuICAgIHJhd19wYXJhbWV0ZXJzOiBudW1iZXJbXVtdIHwgdW5kZWZpbmVkXG5cbiAgICBwYWdlOiBudW1iZXIgPSAtMVxuICAgIHBhZ2VSZWZlcmVuY2U6IFBhZ2UgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQvLyBUaGUgcmVmZXJlbmNlIHRvIHRoZSBwYWdlIG9iamVjdCB0byB3aGljaCB0aGUgYW5ub3RhdGlvbiBpcyBhZGRlZFxuICAgIHR5cGU6IHN0cmluZyA9IFwiXCJcbiAgICB0eXBlX2VuY29kZWQ6IG51bWJlcltdID0gW11cbiAgICByZWN0OiBudW1iZXJbXSA9IFtdXG4gICAgY29udGVudHM6IHN0cmluZyA9IFwiXCJcbiAgICBpZDogc3RyaW5nID0gXCJcIi8vIC9OTVxuICAgIHVwZGF0ZURhdGU6IHN0cmluZyB8IERhdGUgPSBcIlwiLy8gL01cbiAgICBhbm5vdGF0aW9uRmxhZ3M6IEFubm90YXRpb25GbGFncyB8IHVuZGVmaW5lZCAvLyAvRlxuICAgIGJvcmRlcjogQm9yZGVyIHwgdW5kZWZpbmVkXG4gICAgY29sb3I6IENvbG9yIHwgdW5kZWZpbmVkIC8vIC9DXG5cbiAgICBvcHRpb25hbENvbnRlbnQ6IE9wdGlvbmFsQ29udGVudCB8IHVuZGVmaW5lZCAvLyAvT0NcbiAgICBzdHJ1Y3RQYXJlbnQ6IG51bWJlciB8IHVuZGVmaW5lZCAvLyAvU3RydWN0UGFyZW50XG4gICAgYXBwZWFyYW5jZVN0cmVhbTogQXBwZWFyYW5jZVN0cmVhbSB8IHVuZGVmaW5lZCAvLyAvQVBcbiAgICBhcHBlYXJhbmNlU3RyZWFtU2VsZWN0b3I6IHN0cmluZyB8IHVuZGVmaW5lZCAvLyAvQVNcblxuICAgIGNvbnN0cnVjdG9yKCkgeyB9XG5cbiAgICBwdWJsaWMgd3JpdGVBbm5vdGF0aW9uUHJlYW1ibGUoKSA6IG51bWJlcltdIHtcbiAgICAgICAgbGV0IHJldDogbnVtYmVyW10gPSBXcml0ZXJVdGlsLndyaXRlUmVmZXJlbmNlUG9pbnRlcih0aGlzLm9iamVjdF9pZCEpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC5PQkopXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQ1IpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuTEYpXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC5ESUNUX1NUQVJUKVxuXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC5UWVBFX0FOTk9UKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuXG4gICAgICAgIHJldHVybiByZXRcbiAgICB9XG5cbiAgICBwdWJsaWMgd3JpdGVBbm5vdGF0aW9uT2JqZWN0KGNyeXB0b0ludGVyZmFjZSA6IENyeXB0b0ludGVyZmFjZSkgOiBudW1iZXJbXSB7XG4gICAgICAgIGxldCByZXQgOiBudW1iZXJbXSA9IFtdXG5cbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLlBBR0VfUkVGRVJFTkNFKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwud3JpdGVSZWZlcmVuY2VQb2ludGVyKHRoaXMucGFnZVJlZmVyZW5jZSEub2JqZWN0X2lkISwgdHJ1ZSkpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG5cbiAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLlNVQlRZUEUpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQodGhpcy50eXBlX2VuY29kZWQpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG5cbiAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLlJFQ1QpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC53cml0ZU51bWJlckFycmF5KHRoaXMucmVjdCkpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG5cbiAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLkNPTlRFTlRTKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLkJSQUNLRVRfU1RBUlQpXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQoQXJyYXkuZnJvbShVdGlsLmVzY2FwZVN0cmluZyhjcnlwdG9JbnRlcmZhY2UuZW5jcnlwdChuZXcgVWludDhBcnJheShVdGlsLmNvbnZlcnRTdHJpbmdUb0FzY2lpKHRoaXMuY29udGVudHMpKSwgdGhpcy5vYmplY3RfaWQpKSkpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQlJBQ0tFVF9FTkQpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG5cbiAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLklEKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLkJSQUNLRVRfU1RBUlQpXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQoQXJyYXkuZnJvbShVdGlsLmVzY2FwZVN0cmluZyhjcnlwdG9JbnRlcmZhY2UuZW5jcnlwdChuZXcgVWludDhBcnJheShVdGlsLmNvbnZlcnRTdHJpbmdUb0FzY2lpKHRoaXMuaWQpKSwgdGhpcy5vYmplY3RfaWQpKSkpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQlJBQ0tFVF9FTkQpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG5cbiAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLlVQREFURV9EQVRFKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLkJSQUNLRVRfU1RBUlQpXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQoQXJyYXkuZnJvbShVdGlsLmVzY2FwZVN0cmluZyhjcnlwdG9JbnRlcmZhY2UuZW5jcnlwdChuZXcgVWludDhBcnJheShVdGlsLmNvbnZlcnRTdHJpbmdUb0FzY2lpKHRoaXMudXBkYXRlRGF0ZSBhcyBzdHJpbmcpKSwgdGhpcy5vYmplY3RfaWQpKSkpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQlJBQ0tFVF9FTkQpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG5cbiAgICAgICAgaWYgKHRoaXMuYW5ub3RhdGlvbkZsYWdzKSB7XG4gICAgICAgICAgICBsZXQgZmxhZ3NfdmFsdWUgOiBudW1iZXIgPSB0aGlzLmVuY29kZUFubm90YXRpb25GbGFncygpXG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuRkxBRylcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFV0aWwuY29udmVydE51bWJlclRvQ2hhckFycmF5KGZsYWdzX3ZhbHVlKSlcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5ib3JkZXIpIHtcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuQk9SREVSKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC53cml0ZU51bWJlckFycmF5KFt0aGlzLmJvcmRlci5ob3Jpem9udGFsX2Nvcm5lcl9yYWRpdXMgfHwgMCwgdGhpcy5ib3JkZXIudmVydGljYWxfY29ybmVyX3JhZGl1cyB8fCAwLCB0aGlzLmJvcmRlci5ib3JkZXJfd2lkdGggfHwgMV0pKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmNvbG9yKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5jb2xvci5yID4gMSkgdGhpcy5jb2xvci5yIC89IDI1NVxuICAgICAgICAgICAgaWYgKHRoaXMuY29sb3IuZyA+IDEpIHRoaXMuY29sb3IuZyAvPSAyNTVcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbG9yLmIgPiAxKSB0aGlzLmNvbG9yLmIgLz0gMjU1XG5cbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuQ09MT1IpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLndyaXRlTnVtYmVyQXJyYXkoW3RoaXMuY29sb3IuciwgdGhpcy5jb2xvci5nLCB0aGlzLmNvbG9yLmJdKSlcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5yYXdfcGFyYW1ldGVycyAmJiB0aGlzLnJhd19wYXJhbWV0ZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGZvcihsZXQgaSBvZiB0aGlzLnJhd19wYXJhbWV0ZXJzKSB7XG4gICAgICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KGkpXG4gICAgICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXRcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgY29udmVydExpbmVFbmRpbmdTdHlsZShsbmUgOiBMaW5lRW5kaW5nU3R5bGUpIDogbnVtYmVyW10ge1xuICAgICAgICBzd2l0Y2gobG5lKSB7XG4gICAgICAgICAgICBjYXNlIExpbmVFbmRpbmdTdHlsZS5TcXVhcmU6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0aWwuY29udmVydFN0cmluZ1RvQXNjaWkoXCIvU3F1YXJlXCIpXG4gICAgICAgICAgICBjYXNlIExpbmVFbmRpbmdTdHlsZS5DaXJjbGU6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0aWwuY29udmVydFN0cmluZ1RvQXNjaWkoXCIvQ2lyY2xlXCIpXG4gICAgICAgICAgICBjYXNlIExpbmVFbmRpbmdTdHlsZS5EaWFtb25kOlxuICAgICAgICAgICAgICAgIHJldHVybiBVdGlsLmNvbnZlcnRTdHJpbmdUb0FzY2lpKFwiL0RpYW1vbmRcIilcbiAgICAgICAgICAgIGNhc2UgTGluZUVuZGluZ1N0eWxlLk9wZW5BcnJvdzpcbiAgICAgICAgICAgICAgICByZXR1cm4gVXRpbC5jb252ZXJ0U3RyaW5nVG9Bc2NpaShcIi9PcGVuQXJyb3dcIilcbiAgICAgICAgICAgIGNhc2UgTGluZUVuZGluZ1N0eWxlLkNsb3NlZEFycm93OlxuICAgICAgICAgICAgICAgIHJldHVybiBVdGlsLmNvbnZlcnRTdHJpbmdUb0FzY2lpKFwiL0Nsb3NlZEFycm93XCIpXG4gICAgICAgICAgICBjYXNlIExpbmVFbmRpbmdTdHlsZS5CdXR0OlxuICAgICAgICAgICAgICAgIHJldHVybiBVdGlsLmNvbnZlcnRTdHJpbmdUb0FzY2lpKFwiL0J1dHRcIilcbiAgICAgICAgICAgIGNhc2UgTGluZUVuZGluZ1N0eWxlLlJPcGVuQXJyb3c6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0aWwuY29udmVydFN0cmluZ1RvQXNjaWkoXCIvUk9wZW5BcnJvd1wiKVxuICAgICAgICAgICAgY2FzZSBMaW5lRW5kaW5nU3R5bGUuUkNsb3NlZEFycm93OlxuICAgICAgICAgICAgICAgIHJldHVybiBVdGlsLmNvbnZlcnRTdHJpbmdUb0FzY2lpKFwiL1JDbG9zZWRBcnJvd1wiKVxuICAgICAgICAgICAgY2FzZSBMaW5lRW5kaW5nU3R5bGUuU2xhc2g6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0aWwuY29udmVydFN0cmluZ1RvQXNjaWkoXCIvU2xhc2hcIilcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0aWwuY29udmVydFN0cmluZ1RvQXNjaWkoXCIvTm9uZVwiKVxuICAgICAgICB9XG5cbiAgICB9XG5cbiAgICBwdWJsaWMgd3JpdGVBbm5vdGF0aW9uUG9zdGFtYmxlKCkgOiBudW1iZXJbXSB7XG4gICAgICAgIGxldCByZXQgOiBudW1iZXJbXSA9IFdyaXRlclV0aWwuRElDVF9FTkRcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5DUilcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5MRilcblxuICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuRU5ET0JKKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLkNSKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLkxGKVxuXG4gICAgICAgIHJldHVybiByZXRcbiAgICB9XG5cbiAgICBwdWJsaWMgZW5jb2RlQW5ub3RhdGlvbkZsYWdzKCkgOiBudW1iZXIge1xuICAgICAgICBpZiAoIXRoaXMuYW5ub3RhdGlvbkZsYWdzKSB7XG4gICAgICAgICAgICByZXR1cm4gMFxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHZhbCA9IDBcblxuICAgICAgICBpZiAodGhpcy5hbm5vdGF0aW9uRmxhZ3MuaW52aXNpYmxlKSB7XG4gICAgICAgICAgICB2YWwgfD0gMVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmFubm90YXRpb25GbGFncy5oaWRkZW4pIHtcbiAgICAgICAgICAgIHZhbCB8PSAyXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuYW5ub3RhdGlvbkZsYWdzLnByaW50KSB7XG4gICAgICAgICAgICB2YWwgfD0gNFxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmFubm90YXRpb25GbGFncy5ub1pvb20pIHtcbiAgICAgICAgICAgIHZhbCB8PSA4XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuYW5ub3RhdGlvbkZsYWdzLm5vUm90YXRlKSB7XG4gICAgICAgICAgICB2YWwgfD0gMTZcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5hbm5vdGF0aW9uRmxhZ3Mubm9WaWV3KSB7XG4gICAgICAgICAgICB2YWwgfD0gMzJcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5hbm5vdGF0aW9uRmxhZ3MucmVhZE9ubHkpIHtcbiAgICAgICAgICAgIHZhbCB8PSA2NFxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmFubm90YXRpb25GbGFncy5sb2NrZWQpIHtcbiAgICAgICAgICAgIHZhbCB8PSAxMjhcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5hbm5vdGF0aW9uRmxhZ3MudG9nZ2xlTm9WaWV3KSB7XG4gICAgICAgICAgICB2YWwgfD0gMjU2XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuYW5ub3RhdGlvbkZsYWdzLmxvY2tlZENvbnRlbnRzKSB7XG4gICAgICAgICAgICB2YWwgfD0gNTEyXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdmFsXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSWYgZW5hY3QgaXMgdHJ1ZSwgdGhlIGVycm9yIHdpbGwgYmUgdGhyb3duIGRpcmVjdGx5LCBvdGhlcndpc2UgdGhlIGVycm9ycyBhcmUgY29sbGVjdGVkXG4gICAgICogYW5kIHJldHVybmVkIGFzIGVycm9yIGxpc3QuXG4gICAgICogKi9cbiAgICBwdWJsaWMgdmFsaWRhdGUoZW5hY3QgOiBib29sZWFuID0gdHJ1ZSkgOiBFcnJvckxpc3Qge1xuICAgICAgICBsZXQgZXJyb3JMaXN0IDogRXJyb3JMaXN0ID0gdGhpcy5jaGVja1JlY3QoNCwgdGhpcy5yZWN0KVxuXG4gICAgICAgIGVycm9yTGlzdCA9IGVycm9yTGlzdC5jb25jYXQodGhpcy5jaGVja1JlZmVyZW5jZVBvaW50ZXIodGhpcy5vYmplY3RfaWQpKVxuXG4gICAgICAgIGlmKCF0aGlzLnBhZ2VSZWZlcmVuY2UgfHwgdHlwZW9mIHRoaXMucGFnZVJlZmVyZW5jZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGVycm9yTGlzdC5wdXNoKG5ldyBJbnZhbGlkUmVmZXJlbmNlUG9pbnRlckVycm9yKFwiSW5hbGlkIHBhZ2UgcmVmZXJlbmNlXCIpKVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHJlcyA9IHRoaXMuY2hlY2tEYXRlKHRoaXMudXBkYXRlRGF0ZSlcbiAgICAgICAgaWYgKHJlc1sxXSkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVEYXRlID0gcmVzWzFdXG4gICAgICAgIH1cbiAgICAgICAgZXJyb3JMaXN0ID0gZXJyb3JMaXN0LmNvbmNhdChyZXNbMF0pXG5cbiAgICAgICAgZXJyb3JMaXN0ID0gZXJyb3JMaXN0LmNvbmNhdCh0aGlzLmNoZWNrQ29sb3IodGhpcy5jb2xvcikpXG5cbiAgICAgICAgaWYgKCF0aGlzLmlkIHx8IHRoaXMuaWQgPT09IFwiXCIpIHtcbiAgICAgICAgICAgIGVycm9yTGlzdC5wdXNoKG5ldyBJbnZhbGlkSURFcnJvcihcIkludmFsaWQgSUQgcHJvdmlkZWRcIikpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZW5hY3QpIHtcbiAgICAgICAgICAgIGZvcihsZXQgZXJyb3Igb2YgZXJyb3JMaXN0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyb3JcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlcnJvckxpc3RcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgY2hlY2tDb2xvcihjb2xvciA6IENvbG9yIHwgdW5kZWZpbmVkKSA6IEVycm9yTGlzdCB7XG4gICAgICAgIGxldCBlcnJvckxpc3QgOiBFcnJvckxpc3QgPSBbXVxuXG4gICAgICAgIGlmICghY29sb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBlcnJvckxpc3RcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghKGNvbG9yICYmIFwiclwiIGluIGNvbG9yICYmIFwiZ1wiIGluIGNvbG9yICYmIFwiYlwiIGluIGNvbG9yKSkge1xuICAgICAgICAgICAgZXJyb3JMaXN0LnB1c2gobmV3IEludmFsaWRDb2xvckVycm9yKFwiTm90IHtyOiA8cj4sIGc6IDxnPiwgYjogPGI+fVwiKSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb2xvciEuciA+IDI1NSB8fCBjb2xvciEuciA8IDApIHtcbiAgICAgICAgICAgIGVycm9yTGlzdC5wdXNoKG5ldyBDb2xvck91dE9mUmFuZ2VFcnJvcihcIlJlZCB2YWx1ZSBvdXQgb2YgcmFuZ2VcIikpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29sb3IhLmcgPiAyNTUgfHwgY29sb3IhLmcgPCAwKSB7XG4gICAgICAgICAgICBlcnJvckxpc3QucHVzaChuZXcgQ29sb3JPdXRPZlJhbmdlRXJyb3IoXCJHcmVlbiB2YWx1ZSBvdXQgb2YgcmFuZ2VcIikpXG4gICAgICAgIH1cblxuICAgICAgICBpZihjb2xvciEuYiA+IDI1NSAmJiBjb2xvciEuYiA8IDApIHtcbiAgICAgICAgICAgIGVycm9yTGlzdC5wdXNoKG5ldyBDb2xvck91dE9mUmFuZ2VFcnJvcihcIkJsdWUgdmFsdWUgb3V0IG9mIHJhbmdlXCIpKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVycm9yTGlzdFxuICAgIH1cblxuICAgIHByb3RlY3RlZCBjaGVja1JlZmVyZW5jZVBvaW50ZXIocHRyIDogUmVmZXJlbmNlUG9pbnRlciB8IHVuZGVmaW5lZCkgOiBFcnJvckxpc3Qge1xuICAgICAgICBsZXQgZXJyb3JMaXN0IDogRXJyb3JMaXN0ID0gW11cbiAgICAgICAgaWYoIShwdHIgJiYgXCJvYmpcIiBpbiBwdHIgJiYgcHRyLm9iaiA+PSAwICYmIFwiZ2VuZXJhdGlvblwiIGluIHB0ciAmJiBwdHIuZ2VuZXJhdGlvbiA+PSAwKSkge1xuICAgICAgICAgICAgZXJyb3JMaXN0LnB1c2gobmV3IEludmFsaWRSZWZlcmVuY2VQb2ludGVyRXJyb3IoXCJJbnZhbGlkIHJlZmVyZW5jZSBwb2ludGVyXCIpKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVycm9yTGlzdFxuICAgIH1cblxuICAgIHByb3RlY3RlZCBjaGVja0RhdGUoZGF0ZSA6IHN0cmluZyB8IERhdGUpIDogW0Vycm9yTGlzdCwgc3RyaW5nIHwgdW5kZWZpbmVkXSB7XG4gICAgICAgIGlmICh0eXBlb2YgZGF0ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBbW10sIGRhdGVdXG4gICAgICAgIH1cbiAgICAgICAgbGV0IGVycm9yTGlzdCA6IEVycm9yTGlzdCA9IFtdXG4gICAgICAgIGxldCByZXRfdmFsIDogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXRfdmFsID0gVXRpbC5jb252ZXJ0RGF0ZVRvUERGRGF0ZShkYXRlIGFzIERhdGUpXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGVycm9yTGlzdC5wdXNoKG5ldyBJbnZhbGlkRGF0ZUVycm9yKFwiSW52YWxpZCB1cGRhdGUgZGF0ZSBwcm92aWRlZFwiKSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBbZXJyb3JMaXN0LCByZXRfdmFsXVxuICAgIH1cblxuICAgIHByb3RlY3RlZCBjaGVja1JlY3QobnI6IG51bWJlciwgcmVjdDogbnVtYmVyW10pIDogRXJyb3JMaXN0IHtcbiAgICAgICAgbGV0IGVycm9yTGlzdCA6IEVycm9yTGlzdCA9IFtdXG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShyZWN0KSkge1xuICAgICAgICAgICAgZXJyb3JMaXN0LnB1c2gobmV3IEludmFsaWRSZWN0RXJyb3IoXCJpbnZhbGlkIHJlY3QgcGFyYW1ldGVyXCIpKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJlY3QubGVuZ3RoICE9PSBucikge1xuICAgICAgICAgICAgZXJyb3JMaXN0LnB1c2gobmV3IEludmFsaWRSZWN0RXJyb3IoXCJSZWN0IGhhcyBpbnZhbGlkIG51bWJlciBvZiBlbnRyaWVzOiBcIiArIHJlY3QgKyBcIiBoYXMgXCIgKyByZWN0Lmxlbmd0aCArIFwiIGVudHJpZXMsIGJ1dCBzaG91bGQgaGF2ZSBcIiArIG5yICsgXCIgZW50cmllc1wiKSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJlY3QuZm9yRWFjaCgoYSkgPT4ge1xuICAgICAgICAgICAgaWYgKCdudW1iZXInICE9PSB0eXBlb2YgYSkge1xuICAgICAgICAgICAgICAgIGVycm9yTGlzdC5wdXNoKG5ldyBJbnZhbGlkUmVjdEVycm9yKFwiUmVjdCBcIiArIHJlY3QgKyBcIiBoYXMgaW52YWxpZCBlbnRyeTogXCIgKyBhKSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgICByZXR1cm4gZXJyb3JMaXN0XG4gICAgfVxufVxuXG5leHBvcnQgZW51bSBSZXBseVR5cGVzIHtcbiAgICBSZXBseSwgR3JvdXBcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJblJlcGx5VG8ge31cblxuZXhwb3J0IGludGVyZmFjZSBNYXJrdXBBbm5vdGF0aW9uIGV4dGVuZHMgQmFzZUFubm90YXRpb24ge1xuICAgIGF1dGhvcj86IHN0cmluZyAvLyAvVFxuICAgIG9wYWNpdHk/OiBudW1iZXIgLy8gL0NBXG4gICAgcmljaHRleHRTdHJpbmc/OiBzdHJpbmcgLy8gL1JDXG4gICAgY3JlYXRpb25EYXRlPzogc3RyaW5nIHwgRGF0ZSAvLyAvQ3JlYXRpb25EYXRlXG4gICAgaW5SZXBseVRvPzogSW5SZXBseVRvIC8vIC9JUlRcbiAgICBzdWJqZWN0Pzogc3RyaW5nIC8vIC9TdWJqXG4gICAgcmVwbHlUeXBlPzogUmVwbHlUeXBlcyAvLyAvUlRcbn1cblxuZXhwb3J0IGNsYXNzIE1hcmt1cEFubm90YXRpb25PYmogZXh0ZW5kcyBCYXNlQW5ub3RhdGlvbk9iaiBpbXBsZW1lbnRzIE1hcmt1cEFubm90YXRpb24ge1xuICAgIGF1dGhvcjogc3RyaW5nID0gXCJcIlxuICAgIG9wYWNpdHk/OiBudW1iZXIgPSAxLy8gL0NBXG4gICAgY3JlYXRpb25EYXRlPzogc3RyaW5nIHwgRGF0ZSAvLyAvQ3JlYXRpb25EYXRlXG4gICAgc3ViamVjdCA6IHN0cmluZyA9IFwiXCJcbiAgICByaWNodGV4dFN0cmluZz86IHN0cmluZ1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKClcbiAgICB9XG5cbiAgICBwdWJsaWMgd3JpdGVBbm5vdGF0aW9uT2JqZWN0KGNyeXB0b0ludGVyZmFjZSA6IENyeXB0b0ludGVyZmFjZSkgOiBudW1iZXJbXSB7XG4gICAgICAgIGxldCByZXQgOiBudW1iZXJbXSA9IHN1cGVyLndyaXRlQW5ub3RhdGlvbk9iamVjdChjcnlwdG9JbnRlcmZhY2UpXG5cbiAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLkFVVEhPUilcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5CUkFDS0VUX1NUQVJUKVxuICAgICAgICByZXQgPSByZXQuY29uY2F0KEFycmF5LmZyb20oVXRpbC5lc2NhcGVTdHJpbmcoY3J5cHRvSW50ZXJmYWNlLmVuY3J5cHQobmV3IFVpbnQ4QXJyYXkoVXRpbC5jb252ZXJ0U3RyaW5nVG9Bc2NpaSh0aGlzLmF1dGhvcikpLCB0aGlzLm9iamVjdF9pZCkpKSlcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5CUkFDS0VUX0VORClcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcblxuICAgICAgICBpZiAodGhpcy5vcGFjaXR5KSB7XG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuT1BBQ0lUWSlcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFV0aWwuY29udmVydE51bWJlclRvQ2hhckFycmF5KHRoaXMub3BhY2l0eSkpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuY3JlYXRpb25EYXRlKSB7XG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuQ1JFQVRJT05fREFURSlcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLkJSQUNLRVRfU1RBUlQpXG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KEFycmF5LmZyb20oVXRpbC5lc2NhcGVTdHJpbmcoY3J5cHRvSW50ZXJmYWNlLmVuY3J5cHQobmV3IFVpbnQ4QXJyYXkoVXRpbC5jb252ZXJ0U3RyaW5nVG9Bc2NpaSh0aGlzLmNyZWF0aW9uRGF0ZSBhcyBzdHJpbmcpKSwgdGhpcy5vYmplY3RfaWQpKSkpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLkJSQUNLRVRfRU5EKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnN1YmplY3QgIT09IFwiXCIpIHtcbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC5TVUJKKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQlJBQ0tFVF9TVEFSVClcbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoQXJyYXkuZnJvbShVdGlsLmVzY2FwZVN0cmluZyhjcnlwdG9JbnRlcmZhY2UuZW5jcnlwdChuZXcgVWludDhBcnJheShVdGlsLmNvbnZlcnRTdHJpbmdUb0FzY2lpKHRoaXMuc3ViamVjdCkpLCB0aGlzLm9iamVjdF9pZCkpKSlcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQlJBQ0tFVF9FTkQpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMucmljaHRleHRTdHJpbmcpIHtcbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC5SQylcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLkJSQUNLRVRfU1RBUlQpXG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KEFycmF5LmZyb20oVXRpbC5lc2NhcGVTdHJpbmcoY3J5cHRvSW50ZXJmYWNlLmVuY3J5cHQobmV3IFVpbnQ4QXJyYXkoVXRpbC5jb252ZXJ0U3RyaW5nVG9Bc2NpaSh0aGlzLnJpY2h0ZXh0U3RyaW5nISkpLCB0aGlzLm9iamVjdF9pZCkpKSlcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQlJBQ0tFVF9FTkQpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJldFxuICAgIH1cblxuICAgIHB1YmxpYyB2YWxpZGF0ZShlbmFjdCA6IGJvb2xlYW4gPSB0cnVlKSA6IEVycm9yTGlzdCB7XG4gICAgICAgIGxldCBlcnJvckxpc3QgOiBFcnJvckxpc3QgPSBzdXBlci52YWxpZGF0ZShmYWxzZSlcblxuICAgICAgICBpZiAodGhpcy5vcGFjaXR5KSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BhY2l0eSA9ICt0aGlzLm9wYWNpdHlcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBlcnJvckxpc3QucHVzaChuZXcgSW52YWxpZE9wYWNpdHlFcnJvcihcIk9wYWNpdHkgbm8gbnVtZXJpY2FsIHZhbHVlXCIpKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5vcGFjaXR5IDwgMCB8fCB0aGlzLm9wYWNpdHkgPiAyNTUpIHtcbiAgICAgICAgICAgICAgICBlcnJvckxpc3QucHVzaChuZXcgSW52YWxpZE9wYWNpdHlFcnJvcihcIk9wYWNpdHkgb3V0IG9mIHJhbmdlXCIpKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuY3JlYXRpb25EYXRlKSB7XG4gICAgICAgICAgICBsZXQgcmVzID0gdGhpcy5jaGVja0RhdGUodGhpcy5jcmVhdGlvbkRhdGUpXG4gICAgICAgICAgICB0aGlzLmNyZWF0aW9uRGF0ZSA9IHJlc1sxXVxuXG4gICAgICAgICAgICBlcnJvckxpc3QgPSBlcnJvckxpc3QuY29uY2F0KHJlc1swXSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbmFjdCkge1xuICAgICAgICAgICAgZm9yKGxldCBlcnJvciBvZiBlcnJvckxpc3QpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvclxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVycm9yTGlzdFxuICAgIH1cbn1cbiIsImltcG9ydCB7IE1hcmt1cEFubm90YXRpb24sIE1hcmt1cEFubm90YXRpb25PYmosIENvbG9yIH0gZnJvbSAnLi9hbm5vdGF0aW9uX3R5cGVzJztcbmltcG9ydCB7IEVycm9yTGlzdCwgSW52YWxpZEFubm90YXRpb25UeXBlRXJyb3IgfSBmcm9tICcuL2Fubm90YXRpb25fZXJyb3JzJztcbmltcG9ydCB7IENyeXB0b0ludGVyZmFjZSB9IGZyb20gJy4uL3BhcnNlcic7XG5pbXBvcnQgeyBXcml0ZXJVdGlsIH0gZnJvbSAnLi4vd3JpdGVyLXV0aWwnO1xuXG5leHBvcnQgaW50ZXJmYWNlIENpcmNsZVNxdWFyZUFubm90YXRpb24gZXh0ZW5kcyBNYXJrdXBBbm5vdGF0aW9uIHtcbiAgICBib3JkZXJTdHlsZT86IGFueSAvLyAvQlNcbiAgICBmaWxsPzogQ29sb3IgLy8gL0lDXG4gICAgYm9yZGVyRWZmZWN0PyA6IGFueSAvLyAvQkVcbiAgICBkaWZmZXJlbmNlUmVjdGFuZ2xlPzogbnVtYmVyW10gLy8gL1JEXG59XG5cbmV4cG9ydCBjbGFzcyBDaXJjbGVTcXVhcmVBbm5vdGF0aW9uT2JqIGV4dGVuZHMgTWFya3VwQW5ub3RhdGlvbk9iaiBpbXBsZW1lbnRzIENpcmNsZVNxdWFyZUFubm90YXRpb24ge1xuICAgIGZpbGwgOiBDb2xvciB8IHVuZGVmaW5lZFxuICAgIGRpZmZlcmVuY2VSZWN0YW5nbGUgOiBudW1iZXJbXSA9IFtdXG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKVxuICAgIH1cblxuICAgIHB1YmxpYyB3cml0ZUFubm90YXRpb25PYmplY3QoY3J5cHRvSW50ZXJmYWNlIDogQ3J5cHRvSW50ZXJmYWNlKSA6IG51bWJlcltdIHtcbiAgICAgICAgbGV0IHJldCA6IG51bWJlcltdID0gc3VwZXIud3JpdGVBbm5vdGF0aW9uT2JqZWN0KGNyeXB0b0ludGVyZmFjZSlcblxuICAgICAgICBpZiAodGhpcy5maWxsKSB7XG4gICAgICAgICAgICBsZXQgZmlsbCA6IENvbG9yID0gdGhpcy5maWxsXG4gICAgICAgICAgICBpZiAoZmlsbC5yID4gMSkgZmlsbC5yIC89IDI1NVxuICAgICAgICAgICAgaWYgKGZpbGwuZyA+IDEpIGZpbGwuZyAvPSAyNTVcbiAgICAgICAgICAgIGlmIChmaWxsLmIgPiAxKSBmaWxsLmIgLz0gMjU1XG5cbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuRklMTClcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwud3JpdGVOdW1iZXJBcnJheShbZmlsbC5yLCBmaWxsLmcsIGZpbGwuYl0pKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmRpZmZlcmVuY2VSZWN0YW5nbGUgJiYgdGhpcy5kaWZmZXJlbmNlUmVjdGFuZ2xlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC5ESUZGRVJFTkNFX1JFQ1RBTkdMRSlcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwud3JpdGVOdW1iZXJBcnJheSh0aGlzLmRpZmZlcmVuY2VSZWN0YW5nbGUpKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXRcbiAgICB9XG5cbiAgICBwdWJsaWMgdmFsaWRhdGUoZW5hY3QgOiBib29sZWFuID0gdHJ1ZSkgOiBFcnJvckxpc3Qge1xuICAgICAgICBsZXQgZXJyb3JMaXN0IDogRXJyb3JMaXN0ID0gc3VwZXIudmFsaWRhdGUoZmFsc2UpXG5cbiAgICAgICAgaWYgKHRoaXMuZmlsbCkge1xuICAgICAgICAgICAgZXJyb3JMaXN0ID0gZXJyb3JMaXN0LmNvbmNhdCh0aGlzLmNoZWNrQ29sb3IodGhpcy5maWxsKSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbmFjdCkge1xuICAgICAgICAgICAgZm9yKGxldCBlcnJvciBvZiBlcnJvckxpc3QpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvclxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVycm9yTGlzdFxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIENpcmNsZUFubm90YXRpb25PYmogZXh0ZW5kcyBDaXJjbGVTcXVhcmVBbm5vdGF0aW9uT2JqIHtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpXG4gICAgICAgIHRoaXMudHlwZSA9IFwiL0NpcmNsZVwiXG4gICAgICAgIHRoaXMudHlwZV9lbmNvZGVkID0gWzQ3LCA2NywgMTA1LCAxMTQsIDk5LCAxMDgsIDEwMV0gLy8gPSAnL0NpcmNsZSdcbiAgICB9XG5cbiAgICBwdWJsaWMgdmFsaWRhdGUoZW5hY3QgOiBib29sZWFuID0gdHJ1ZSkgOiBFcnJvckxpc3Qge1xuICAgICAgICBsZXQgZXJyb3JMaXN0IDogRXJyb3JMaXN0ID0gc3VwZXIudmFsaWRhdGUoZmFsc2UpXG5cbiAgICAgICAgaWYgKHRoaXMudHlwZSAhPT0gXCIvQ2lyY2xlXCIpIHtcbiAgICAgICAgICAgIGVycm9yTGlzdC5wdXNoKG5ldyBJbnZhbGlkQW5ub3RhdGlvblR5cGVFcnJvcihgSW52YWxpZCBhbm5vdGF0aW9uIHR5cGUgJHt0aGlzLnR5cGV9YCkpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZW5hY3QpIHtcbiAgICAgICAgICAgIGZvcihsZXQgZXJyb3Igb2YgZXJyb3JMaXN0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyb3JcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlcnJvckxpc3RcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTcXVhcmVBbm5vdGF0aW9uT2JqIGV4dGVuZHMgQ2lyY2xlU3F1YXJlQW5ub3RhdGlvbk9iaiB7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKVxuICAgICAgICB0aGlzLnR5cGUgPSBcIi9TcXVhcmVcIlxuICAgICAgICB0aGlzLnR5cGVfZW5jb2RlZCA9ICBbNDcsIDgzLCAxMTMsIDExNywgOTcsIDExNCwgMTAxXSAvLyA9ICcvU3F1YXJlJ1xuICAgIH1cblxuICAgIHB1YmxpYyB2YWxpZGF0ZShlbmFjdCA6IGJvb2xlYW4gPSB0cnVlKSA6IEVycm9yTGlzdCB7XG4gICAgICAgIGxldCBlcnJvckxpc3QgOiBFcnJvckxpc3QgPSBzdXBlci52YWxpZGF0ZShmYWxzZSlcblxuICAgICAgICBpZiAodGhpcy50eXBlICE9PSBcIi9TcXVhcmVcIikge1xuICAgICAgICAgICAgZXJyb3JMaXN0LnB1c2gobmV3IEludmFsaWRBbm5vdGF0aW9uVHlwZUVycm9yKGBJbnZhbGlkIGFubm90YXRpb24gdHlwZSAke3RoaXMudHlwZX1gKSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbmFjdCkge1xuICAgICAgICAgICAgZm9yKGxldCBlcnJvciBvZiBlcnJvckxpc3QpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvclxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVycm9yTGlzdFxuICAgIH1cbn1cbiIsImltcG9ydCB7IE1hcmt1cEFubm90YXRpb24sIE1hcmt1cEFubm90YXRpb25PYmosIExpbmVFbmRpbmdTdHlsZSB9IGZyb20gJy4vYW5ub3RhdGlvbl90eXBlcyc7XG5pbXBvcnQgeyBFcnJvckxpc3QsIEludmFsaWRBbm5vdGF0aW9uVHlwZUVycm9yIH0gZnJvbSAnLi9hbm5vdGF0aW9uX2Vycm9ycyc7XG5pbXBvcnQgeyBDcnlwdG9JbnRlcmZhY2UgfSBmcm9tICcuLi9wYXJzZXInO1xuaW1wb3J0IHsgV3JpdGVyVXRpbCB9IGZyb20gJy4uL3dyaXRlci11dGlsJztcbmltcG9ydCB7IFV0aWwgfSBmcm9tICcuLi91dGlsJ1xuXG5leHBvcnQgZW51bSBUZXh0SnVzdGlmaWNhdGlvbiB7XG4gICAgTGVmdCwgQ2VudGVyZWQsIFJpZ2h0XG59XG5cbmV4cG9ydCBlbnVtIEZyZWVUZXh0VHlwZSB7XG4gICAgRnJlZVRleHQsIEZyZWVUZXh0Q2FsbG91dCwgRnJlZVRleHRUeXBlV3JpdGVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRnJlZVRleHRBbm5vdGF0aW9uIGV4dGVuZHMgTWFya3VwQW5ub3RhdGlvbiB7XG4gICAgdGV4dEp1c3RpZmljYXRpb24/OiBUZXh0SnVzdGlmaWNhdGlvbiAvLyAvUVxuICAgIGRlZmF1bHRBcHBlYXJhbmNlOiBzdHJpbmcgLy8gL0RBXG4gICAgZGVmYXVsdFN0eWxlU3RyaW5nPzogc3RyaW5nIC8vIC9EU1xuICAgIGNhbGxvdXRMaW5lPzogbnVtYmVyW10gLy8gL0NMXG4gICAgZnJlZVRleHRUeXBlPzogRnJlZVRleHRUeXBlIC8vIC9JVFxuICAgIGJvcmRlckVmZmVjdD86IGFueSAvLyAvQkVcbiAgICBib3JkZXJTdHlsZT86IGFueSAvLyAvQlNcbiAgICBkaWZmZXJlbmNlUmVjdGFuZ2xlPzogbnVtYmVyW10gLy8gL1JEXG4gICAgbGluZUVuZGluZ1N0eWxlPzogTGluZUVuZGluZ1N0eWxlIC8vIExFXG59XG5cbmV4cG9ydCBjbGFzcyBGcmVlVGV4dEFubm90YXRpb25PYmogZXh0ZW5kcyBNYXJrdXBBbm5vdGF0aW9uT2JqIGltcGxlbWVudHMgRnJlZVRleHRBbm5vdGF0aW9uIHtcbiAgICBkZWZhdWx0QXBwZWFyYW5jZSA6IHN0cmluZyA9IFwiL0ludmFsaWRfZm9udCA5IFRmXCIgLy8gL0RBXG4gICAgZGVmYXVsdFN0eWxlU3RyaW5nIDogc3RyaW5nIHwgdW5kZWZpbmVkXG4gICAgZGlmZmVyZW5jZVJlY3RhbmdsZSA6IG51bWJlcltdID0gW11cbiAgICB0ZXh0SnVzdGlmaWNhdGlvbiA6IFRleHRKdXN0aWZpY2F0aW9uID0gVGV4dEp1c3RpZmljYXRpb24uTGVmdCAvLyAvUVxuICAgIGNhbGxvdXRMaW5lOiBudW1iZXJbXSA9IFtdXG4gICAgZnJlZVRleHRUeXBlOiBGcmVlVGV4dFR5cGUgPSBGcmVlVGV4dFR5cGUuRnJlZVRleHRcbiAgICBsaW5lRW5kaW5nU3R5bGUgOiBMaW5lRW5kaW5nU3R5bGUgPSBMaW5lRW5kaW5nU3R5bGUuTm9uZVxuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKClcbiAgICAgICAgdGhpcy50eXBlID0gXCIvRnJlZVRleHRcIlxuICAgICAgICB0aGlzLnR5cGVfZW5jb2RlZCA9IFs0NywgNzAsIDExNCwgMTAxLCAxMDEsIDg0LCAxMDEsIDEyMCwgMTE2XSAvLyA9ICcvRnJlZVRleHQnXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb252ZXJ0SnVzdGlmaWNhdGlvbihqdXN0IDogVGV4dEp1c3RpZmljYXRpb24pIDogbnVtYmVyIHtcbiAgICAgICAgc3dpdGNoIChqdXN0KSB7XG4gICAgICAgICAgICBjYXNlIFRleHRKdXN0aWZpY2F0aW9uLkxlZnQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIDBcbiAgICAgICAgICAgIGNhc2UgVGV4dEp1c3RpZmljYXRpb24uQ2VudGVyZWQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIDFcbiAgICAgICAgICAgIGNhc2UgVGV4dEp1c3RpZmljYXRpb24uUmlnaHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIDJcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIDBcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgY29udmVydEZyZWVUZXh0VHlwZShmdCA6IEZyZWVUZXh0VHlwZSkgOiBudW1iZXJbXSB7XG4gICAgICAgIHN3aXRjaCAoZnQpIHtcbiAgICAgICAgICAgIGNhc2UgRnJlZVRleHRUeXBlLkZyZWVUZXh0OlxuICAgICAgICAgICAgICAgIHJldHVybiBVdGlsLmNvbnZlcnRTdHJpbmdUb0FzY2lpKFwiL0ZyZWVUZXh0XCIpXG4gICAgICAgICAgICBjYXNlIEZyZWVUZXh0VHlwZS5GcmVlVGV4dENhbGxvdXQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0aWwuY29udmVydFN0cmluZ1RvQXNjaWkoXCIvRnJlZVRleHRDYWxsb3V0XCIpXG4gICAgICAgICAgICBjYXNlIEZyZWVUZXh0VHlwZS5GcmVlVGV4dFR5cGVXcml0ZXI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0aWwuY29udmVydFN0cmluZ1RvQXNjaWkoXCIvRnJlZVRleHRUeXBlV3JpdGVyXCIpXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBVdGlsLmNvbnZlcnRTdHJpbmdUb0FzY2lpKFwiL0ZyZWVUZXh0XCIpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgd3JpdGVBbm5vdGF0aW9uT2JqZWN0KGNyeXB0b0ludGVyZmFjZSA6IENyeXB0b0ludGVyZmFjZSkgOiBudW1iZXJbXSB7XG4gICAgICAgIGxldCByZXQgOiBudW1iZXJbXSA9IHN1cGVyLndyaXRlQW5ub3RhdGlvbk9iamVjdChjcnlwdG9JbnRlcmZhY2UpXG5cbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLkRFRkFVTFRfQVBQRUFSQU5DRSlcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5CUkFDS0VUX1NUQVJUKVxuICAgICAgICByZXQgPSByZXQuY29uY2F0KFV0aWwuY29udmVydFN0cmluZ1RvQXNjaWkodGhpcy5kZWZhdWx0QXBwZWFyYW5jZSkpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQlJBQ0tFVF9FTkQpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG5cbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLlRFWFRfSlVTVElGSUNBVElPTilcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChVdGlsLmNvbnZlcnROdW1iZXJUb0NoYXJBcnJheSh0aGlzLmNvbnZlcnRKdXN0aWZpY2F0aW9uKHRoaXMudGV4dEp1c3RpZmljYXRpb24pKSlcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcblxuICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuSVQpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQodGhpcy5jb252ZXJ0RnJlZVRleHRUeXBlKHRoaXMuZnJlZVRleHRUeXBlKSlcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcblxuICAgICAgICBpZiAodGhpcy5jYWxsb3V0TGluZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuQ0FMTE9VVF9MSU5FKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC53cml0ZU51bWJlckFycmF5KHRoaXMuY2FsbG91dExpbmUpKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmxpbmVFbmRpbmdTdHlsZSAhPT0gTGluZUVuZGluZ1N0eWxlLk5vbmUpIHtcbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC5MSU5FX0VORElORylcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KHRoaXMuY29udmVydExpbmVFbmRpbmdTdHlsZSh0aGlzLmxpbmVFbmRpbmdTdHlsZSkpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuZGVmYXVsdFN0eWxlU3RyaW5nICYmIHRoaXMuZGVmYXVsdFN0eWxlU3RyaW5nICE9PSBcIlwiKSB7XG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuREVGQVVMVF9TVFlMRV9TVFJJTkcpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5CUkFDS0VUX1NUQVJUKVxuICAgICAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChVdGlsLmNvbnZlcnRTdHJpbmdUb0FzY2lpKHRoaXMuZGVmYXVsdFN0eWxlU3RyaW5nKSlcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQlJBQ0tFVF9FTkQpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuZGlmZmVyZW5jZVJlY3RhbmdsZSAmJiB0aGlzLmRpZmZlcmVuY2VSZWN0YW5nbGUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLkRJRkZFUkVOQ0VfUkVDVEFOR0xFKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC53cml0ZU51bWJlckFycmF5KHRoaXMuZGlmZmVyZW5jZVJlY3RhbmdsZSkpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJldFxuICAgIH1cblxuICAgIHB1YmxpYyB2YWxpZGF0ZShlbmFjdCA6IGJvb2xlYW4gPSB0cnVlKSA6IEVycm9yTGlzdCB7XG4gICAgICAgIGxldCBlcnJvckxpc3QgOiBFcnJvckxpc3QgPSBzdXBlci52YWxpZGF0ZShmYWxzZSlcblxuICAgICAgICBpZiAodGhpcy50eXBlICE9PSBcIi9GcmVlVGV4dFwiKSB7XG4gICAgICAgICAgICBlcnJvckxpc3QucHVzaChuZXcgSW52YWxpZEFubm90YXRpb25UeXBlRXJyb3IoYEludmFsaWQgYW5ub3RhdGlvbiB0eXBlICR7dGhpcy50eXBlfWApKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuY2FsbG91dExpbmUgJiYgdGhpcy5jYWxsb3V0TGluZS5sZW5ndGggPiAwICYmIHRoaXMuZnJlZVRleHRUeXBlICE9PSBGcmVlVGV4dFR5cGUuRnJlZVRleHRDYWxsb3V0KSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcIldhcm5pbmc6IENhbGxvdXQgbGluZSBvbmx5IHJlbGV2YW50IGZvciBmcmVlIHRleHQgdHlwZTogJ0NhbGxvdXQnXCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZW5hY3QpIHtcbiAgICAgICAgICAgIGZvcihsZXQgZXJyb3Igb2YgZXJyb3JMaXN0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyb3JcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlcnJvckxpc3RcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBNYXJrdXBBbm5vdGF0aW9uLCBNYXJrdXBBbm5vdGF0aW9uT2JqIH0gZnJvbSAnLi9hbm5vdGF0aW9uX3R5cGVzJztcbmltcG9ydCB7IEVycm9yTGlzdCwgSW52YWxpZEFubm90YXRpb25UeXBlRXJyb3IgfSBmcm9tICcuL2Fubm90YXRpb25fZXJyb3JzJztcbmltcG9ydCB7IENyeXB0b0ludGVyZmFjZSB9IGZyb20gJy4uL3BhcnNlcic7XG5pbXBvcnQgeyBXcml0ZXJVdGlsIH0gZnJvbSAnLi4vd3JpdGVyLXV0aWwnO1xuXG5leHBvcnQgaW50ZXJmYWNlIElua0Fubm90YXRpb24gZXh0ZW5kcyBNYXJrdXBBbm5vdGF0aW9uIHtcbiAgICBpbmtMaXN0OiBudW1iZXJbXVtdIC8vIC9JbmtMaXN0XG4gICAgYm9yZGVyU3R5bGU/OiBhbnkgLy8gL0JTXG59XG5cbmV4cG9ydCBjbGFzcyBJbmtBbm5vdGF0aW9uT2JqIGV4dGVuZHMgTWFya3VwQW5ub3RhdGlvbk9iaiBpbXBsZW1lbnRzIElua0Fubm90YXRpb24ge1xuICAgIGlua0xpc3Q6IG51bWJlcltdW10gPSBbXVxuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKClcbiAgICAgICAgdGhpcy50eXBlID0gXCIvSW5rXCJcbiAgICAgICAgdGhpcy50eXBlX2VuY29kZWQgPSBbNDcsIDczLCAxMTAsIDEwN10gLy8gPSAnL0luaydcbiAgICB9XG5cbiAgICBwdWJsaWMgd3JpdGVBbm5vdGF0aW9uT2JqZWN0KGNyeXB0b0ludGVyZmFjZSA6IENyeXB0b0ludGVyZmFjZSkgOiBudW1iZXJbXSB7XG4gICAgICAgIGxldCByZXQgOiBudW1iZXJbXSA9IHN1cGVyLndyaXRlQW5ub3RhdGlvbk9iamVjdChjcnlwdG9JbnRlcmZhY2UpXG5cbiAgICAgICAgaWYgKHRoaXMuaW5rTGlzdCAmJiB0aGlzLmlua0xpc3QubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLklOS0xJU1QpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLndyaXRlTmVzdGVkTnVtYmVyQXJyYXkodGhpcy5pbmtMaXN0KSlcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmV0XG4gICAgfVxuXG4gICAgcHVibGljIHZhbGlkYXRlKGVuYWN0IDogYm9vbGVhbiA9IHRydWUpIDogRXJyb3JMaXN0IHtcbiAgICAgICAgbGV0IGVycm9yTGlzdCA6IEVycm9yTGlzdCA9IHN1cGVyLnZhbGlkYXRlKGZhbHNlKVxuXG4gICAgICAgIGlmICh0aGlzLnR5cGUgIT09IFwiL0lua1wiKSB7XG4gICAgICAgICAgICBlcnJvckxpc3QucHVzaChuZXcgSW52YWxpZEFubm90YXRpb25UeXBlRXJyb3IoYEludmFsaWQgYW5ub3RhdGlvbiB0eXBlICR7dGhpcy50eXBlfWApKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCdudW1iZXInID09PSB0eXBlb2YgdGhpcy5pbmtMaXN0WzBdKSB7XG4gICAgICAgICAgICB0aGlzLmlua0xpc3QgPSBbdGhpcy5pbmtMaXN0XSBhcyBhbnlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbmFjdCkge1xuICAgICAgICAgICAgZm9yKGxldCBlcnJvciBvZiBlcnJvckxpc3QpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvclxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVycm9yTGlzdFxuICAgIH1cbn1cbiIsImltcG9ydCB7IE1hcmt1cEFubm90YXRpb24sIE1hcmt1cEFubm90YXRpb25PYmosIENvbG9yLCBMaW5lRW5kaW5nU3R5bGUgfSBmcm9tICcuL2Fubm90YXRpb25fdHlwZXMnO1xuaW1wb3J0IHsgRXJyb3JMaXN0LCBJbnZhbGlkQW5ub3RhdGlvblR5cGVFcnJvciwgSW52YWxpZFZlcnRpY2VzRXJyb3IgfSBmcm9tICcuL2Fubm90YXRpb25fZXJyb3JzJztcbmltcG9ydCB7IENyeXB0b0ludGVyZmFjZSB9IGZyb20gJy4uL3BhcnNlcic7XG5pbXBvcnQgeyBXcml0ZXJVdGlsIH0gZnJvbSAnLi4vd3JpdGVyLXV0aWwnO1xuXG5leHBvcnQgZW51bSBQb2x5Z29uUG9seUxpbmVJbnRlbnQge1xuICAgIFBvbHlnb25DbG91ZCwgUG9seUxpbmVEaW1lbnNpb24sIFBvbHlnb25EaW1lbnNpb25cbn1cblxuZXhwb3J0IGludGVyZmFjZSBQb2x5Z29uUG9seUxpbmVBbm5vdGF0aW9uIGV4dGVuZHMgTWFya3VwQW5ub3RhdGlvbiB7XG4gICAgdmVydGljZXM6IG51bWJlcltdXG4gICAgYm9yZGVyU3R5bGU/IDogYW55XG4gICAgZmlsbD86IENvbG9yXG4gICAgaW50ZW50PzogUG9seWdvblBvbHlMaW5lSW50ZW50XG4gICAgbWVhc3VyZT8gOiBhbnlcbn1cblxuZXhwb3J0IGNsYXNzIFBvbHlnb25Qb2x5TGluZUFubm90YXRpb25PYmogZXh0ZW5kcyBNYXJrdXBBbm5vdGF0aW9uT2JqIGltcGxlbWVudHMgUG9seWdvblBvbHlMaW5lQW5ub3RhdGlvbiB7XG4gICAgZmlsbCA6IENvbG9yIHwgdW5kZWZpbmVkXG4gICAgdmVydGljZXM6IG51bWJlcltdID0gW11cblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpXG4gICAgfVxuXG4gICAgcHVibGljIHdyaXRlQW5ub3RhdGlvbk9iamVjdChjcnlwdG9JbnRlcmZhY2UgOiBDcnlwdG9JbnRlcmZhY2UpIDogbnVtYmVyW10ge1xuICAgICAgICBsZXQgcmV0IDogbnVtYmVyW10gPSBzdXBlci53cml0ZUFubm90YXRpb25PYmplY3QoY3J5cHRvSW50ZXJmYWNlKVxuXG4gICAgICAgIGlmICh0aGlzLmZpbGwpIHtcbiAgICAgICAgICAgIGxldCBmaWxsIDogQ29sb3IgPSB0aGlzLmZpbGxcbiAgICAgICAgICAgIGlmIChmaWxsLnIgPiAxKSBmaWxsLnIgLz0gMjU1XG4gICAgICAgICAgICBpZiAoZmlsbC5nID4gMSkgZmlsbC5nIC89IDI1NVxuICAgICAgICAgICAgaWYgKGZpbGwuYiA+IDEpIGZpbGwuYiAvPSAyNTVcblxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC5GSUxMKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC53cml0ZU51bWJlckFycmF5KFtmaWxsLnIsIGZpbGwuZywgZmlsbC5iXSkpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLlZFUlRJQ0VTKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwud3JpdGVOdW1iZXJBcnJheSh0aGlzLnZlcnRpY2VzKSlcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcblxuXG4gICAgICAgIHJldHVybiByZXRcbiAgICB9XG5cbiAgICBwdWJsaWMgdmFsaWRhdGUoZW5hY3QgOiBib29sZWFuID0gdHJ1ZSkgOiBFcnJvckxpc3Qge1xuICAgICAgICBsZXQgZXJyb3JMaXN0IDogRXJyb3JMaXN0ID0gc3VwZXIudmFsaWRhdGUoZmFsc2UpXG5cbiAgICAgICAgaWYgKHRoaXMuZmlsbCkge1xuICAgICAgICAgICAgZXJyb3JMaXN0ID0gZXJyb3JMaXN0LmNvbmNhdCh0aGlzLmNoZWNrQ29sb3IodGhpcy5maWxsKSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy52ZXJ0aWNlcyB8fCB0aGlzLnZlcnRpY2VzLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgICBlcnJvckxpc3QucHVzaChuZXcgSW52YWxpZFZlcnRpY2VzRXJyb3IoXCJObyB2ZXJ0aWNlcyBwcm92aWRlZFwiKSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnZlcnRpY2VzLmxlbmd0aCAlIDIgIT09IDApIHtcbiAgICAgICAgICAgIGVycm9yTGlzdC5wdXNoKG5ldyBJbnZhbGlkVmVydGljZXNFcnJvcihcIm51bWJlciBvZiB2ZXJ0aWNlcyBtdXN0IGJlIGFuIGV2ZW4gbnVtYmVyXCIpKVxuICAgICAgICB9XG5cblxuICAgICAgICBpZiAoZW5hY3QpIHtcbiAgICAgICAgICAgIGZvcihsZXQgZXJyb3Igb2YgZXJyb3JMaXN0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyb3JcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlcnJvckxpc3RcbiAgICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUG9seUxpbmVBbm5vdGF0aW9uIGV4dGVuZHMgUG9seWdvblBvbHlMaW5lQW5ub3RhdGlvbiB7XG4gICAgbGluZUVuZGluZ1N0eWxlcz8gOiBMaW5lRW5kaW5nU3R5bGVbXSAvLyAvTEVcbn1cblxuZXhwb3J0IGNsYXNzIFBvbHlMaW5lQW5ub3RhdGlvbk9iaiBleHRlbmRzIFBvbHlnb25Qb2x5TGluZUFubm90YXRpb25PYmogaW1wbGVtZW50cyBQb2x5TGluZUFubm90YXRpb24ge1xuICAgIGxpbmVFbmRpbmdTdHlsZXMgOiBMaW5lRW5kaW5nU3R5bGVbXSA9IFtdXG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKVxuICAgICAgICB0aGlzLnR5cGUgPSBcIi9Qb2x5TGluZVwiXG4gICAgICAgIHRoaXMudHlwZV9lbmNvZGVkID0gWzQ3LCA4MCwgMTExLCAxMDgsIDEyMSwgNzYsIDEwNSwgMTEwLCAxMDFdIC8vICcvUG9seUxpbmVcbiAgICB9XG5cbiAgICBwdWJsaWMgd3JpdGVBbm5vdGF0aW9uT2JqZWN0KGNyeXB0b0ludGVyZmFjZSA6IENyeXB0b0ludGVyZmFjZSkgOiBudW1iZXJbXSB7XG4gICAgICAgIGxldCByZXQgOiBudW1iZXJbXSA9IHN1cGVyLndyaXRlQW5ub3RhdGlvbk9iamVjdChjcnlwdG9JbnRlcmZhY2UpXG5cbiAgICAgICAgaWYgKHRoaXMubGluZUVuZGluZ1N0eWxlcyAmJiB0aGlzLmxpbmVFbmRpbmdTdHlsZXMubGVuZ3RoID49IDIpIHtcbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC5MSU5FX0VORElORylcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLkFSUkFZX1NUQVJUKVxuICAgICAgICAgICAgcmV0ID0gcmV0LmNvbmNhdCh0aGlzLmNvbnZlcnRMaW5lRW5kaW5nU3R5bGUodGhpcy5saW5lRW5kaW5nU3R5bGVzWzBdKSlcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KHRoaXMuY29udmVydExpbmVFbmRpbmdTdHlsZSh0aGlzLmxpbmVFbmRpbmdTdHlsZXNbMV0pKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQVJSQVlfRU5EKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXRcbiAgICB9XG5cbiAgICBwdWJsaWMgdmFsaWRhdGUoZW5hY3QgOiBib29sZWFuID0gdHJ1ZSkgOiBFcnJvckxpc3Qge1xuICAgICAgICBsZXQgZXJyb3JMaXN0IDogRXJyb3JMaXN0ID0gc3VwZXIudmFsaWRhdGUoZmFsc2UpXG5cbiAgICAgICAgaWYgKHRoaXMudHlwZSAhPT0gXCIvUG9seUxpbmVcIikge1xuICAgICAgICAgICAgZXJyb3JMaXN0LnB1c2gobmV3IEludmFsaWRBbm5vdGF0aW9uVHlwZUVycm9yKGBJbnZhbGlkIGFubm90YXRpb24gdHlwZSAke3RoaXMudHlwZX1gKSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbmFjdCkge1xuICAgICAgICAgICAgZm9yKGxldCBlcnJvciBvZiBlcnJvckxpc3QpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvclxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVycm9yTGlzdFxuICAgIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBQb2x5Z29uQW5ub3RhdGlvbiBleHRlbmRzIFBvbHlnb25Qb2x5TGluZUFubm90YXRpb24ge1xuICAgIGJvcmRlckVmZmVjdD86IGFueVxufVxuXG5leHBvcnQgY2xhc3MgUG9seWdvbkFubm90YXRpb25PYmogZXh0ZW5kcyBQb2x5Z29uUG9seUxpbmVBbm5vdGF0aW9uT2JqIGltcGxlbWVudHMgUG9seWdvbkFubm90YXRpb24ge1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKClcbiAgICAgICAgdGhpcy50eXBlID0gXCIvUG9seWdvblwiXG4gICAgICAgIHRoaXMudHlwZV9lbmNvZGVkID0gWzQ3LCA4MCwgMTExLCAxMDgsIDEyMSwgMTAzLCAxMTEsIDExMF0gLy8gPSAnL1BvbHlnb25cbiAgICB9XG5cbiAgICBwdWJsaWMgdmFsaWRhdGUoZW5hY3QgOiBib29sZWFuID0gdHJ1ZSkgOiBFcnJvckxpc3Qge1xuICAgICAgICBsZXQgZXJyb3JMaXN0IDogRXJyb3JMaXN0ID0gc3VwZXIudmFsaWRhdGUoZmFsc2UpXG5cbiAgICAgICAgaWYgKHRoaXMudHlwZSAhPT0gXCIvUG9seWdvblwiKSB7XG4gICAgICAgICAgICBlcnJvckxpc3QucHVzaChuZXcgSW52YWxpZEFubm90YXRpb25UeXBlRXJyb3IoYEludmFsaWQgYW5ub3RhdGlvbiB0eXBlICR7dGhpcy50eXBlfWApKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVuYWN0KSB7XG4gICAgICAgICAgICBmb3IobGV0IGVycm9yIG9mIGVycm9yTGlzdCkge1xuICAgICAgICAgICAgICAgIHRocm93IGVycm9yXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZXJyb3JMaXN0XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgTWFya3VwQW5ub3RhdGlvbiwgTWFya3VwQW5ub3RhdGlvbk9iaiB9IGZyb20gJy4vYW5ub3RhdGlvbl90eXBlcyc7XG5pbXBvcnQgeyBDcnlwdG9JbnRlcmZhY2UgfSBmcm9tICcuLi9wYXJzZXInO1xuaW1wb3J0IHsgRXJyb3JMaXN0LCBJbnZhbGlkQW5ub3RhdGlvblR5cGVFcnJvciwgSW52YWxpZFN0YXRlRXJyb3IgfSBmcm9tICcuL2Fubm90YXRpb25fZXJyb3JzJztcbmltcG9ydCB7IFdyaXRlclV0aWwgfSBmcm9tICcuLi93cml0ZXItdXRpbCc7XG5pbXBvcnQgeyBVdGlsIH0gZnJvbSAnLi4vdXRpbCdcblxuZXhwb3J0IGVudW0gQW5ub3RhdGlvbkljb24ge1xuICAgIENvbW1lbnQsIEtleSwgTm90ZSwgSGVscCwgTmV3UGFyYWdyYXBoLCBQYXJhZ3JhcGgsIEluc2VydFxufVxuXG5leHBvcnQgZW51bSBBbm5vdGF0aW9uU3RhdGVNb2RlbCB7XG4gICAgTWFya2VkLCBSZXZpZXdcbn1cblxuZXhwb3J0IGVudW0gQW5ub3RhdGlvblN0YXRlIHtcbiAgICBNYXJrZWQsIFVubWFya2VkLCBBY2NlcHRlZCwgUmVqZWN0ZWQsIENhbmNlbGxlZCwgQ29tcGxldGVkLCBOb25lXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dEFubm90YXRpb24gZXh0ZW5kcyBNYXJrdXBBbm5vdGF0aW9uIHtcbiAgICBvcGVuOiBib29sZWFuXG4gICAgaWNvbjogQW5ub3RhdGlvbkljb25cbiAgICBzdGF0ZTogQW5ub3RhdGlvblN0YXRlIHwgdW5kZWZpbmVkXG4gICAgc3RhdGVNb2RlbD8gOiBBbm5vdGF0aW9uU3RhdGVNb2RlbFxufVxuXG5leHBvcnQgY2xhc3MgVGV4dEFubm90YXRpb25PYmogZXh0ZW5kcyBNYXJrdXBBbm5vdGF0aW9uT2JqIGltcGxlbWVudHMgVGV4dEFubm90YXRpb24ge1xuICAgIG9wZW46IGJvb2xlYW4gPSBmYWxzZVxuICAgIGljb246IEFubm90YXRpb25JY29uID0gQW5ub3RhdGlvbkljb24uTm90ZVxuICAgIHN0YXRlOiBBbm5vdGF0aW9uU3RhdGUgfCB1bmRlZmluZWQgPSB1bmRlZmluZWRcbiAgICBzdGF0ZU1vZGVsPyA6IEFubm90YXRpb25TdGF0ZU1vZGVsXG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKVxuICAgICAgICB0aGlzLnR5cGUgPSBcIi9UZXh0XCJcbiAgICAgICAgdGhpcy50eXBlX2VuY29kZWQgPSBbNDcsIDg0LCAxMDEsIDEyMCwgMTE2XSAvLyA9ICcvVGV4dCdcbiAgICAgICAgLy8gZGVtYW5kZWQgYnkgUERGIHNwZWNpZmljYXRpb24gKHAuIDM5NCAtIDEyLjUuNi40IFRleHQgQW5ub3RhdGlvbnMpXG4gICAgICAgIHRoaXMuYW5ub3RhdGlvbkZsYWdzID0ge25vWm9vbTogdHJ1ZSwgbm9Sb3RhdGU6IHRydWV9XG4gICAgfVxuXG4gICAgY29udmVydEFubm90YXRpb25JY29uKGljb24gOiBBbm5vdGF0aW9uSWNvbikgOiBudW1iZXJbXSB7XG4gICAgICAgIHN3aXRjaChpY29uKSB7XG4gICAgICAgICAgICBjYXNlIEFubm90YXRpb25JY29uLkNvbW1lbnQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFs0NywgNjcsIDExMSwgMTA5LCAxMDksIDEwMSwgMTEwLCAxMTZdIC8vID0gJy9Db21tZW50J1xuICAgICAgICAgICAgY2FzZSBBbm5vdGF0aW9uSWNvbi5LZXk6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFs0NywgNzUsIDEwMSwgMTIxXSAvLyA9ICcvS2V5J1xuICAgICAgICAgICAgY2FzZSBBbm5vdGF0aW9uSWNvbi5Ob3RlOlxuICAgICAgICAgICAgICAgIHJldHVybiBbNDcsIDc4LCAxMTEsIDExNiwgMTAxXSAvLyA9ICcvTm90ZSdcbiAgICAgICAgICAgIGNhc2UgQW5ub3RhdGlvbkljb24uSGVscDpcbiAgICAgICAgICAgICAgICByZXR1cm4gWzQ3LCA3MiwgMTAxLCAxMDgsIDExMl0gLy8gPSAnL0hlbHAnXG4gICAgICAgICAgICBjYXNlIEFubm90YXRpb25JY29uLk5ld1BhcmFncmFwaDpcbiAgICAgICAgICAgICAgICByZXR1cm4gWzQ3LCA3OCwgMTAxLCAxMTksIDgwLCA5NywgMTE0LCA5NywgMTAzLCAxMTQsIDk3LCAxMTIsIDEwNF0gLy8gPSAnL05ld1BhcmFncmFwaCdcbiAgICAgICAgICAgIGNhc2UgQW5ub3RhdGlvbkljb24uUGFyYWdyYXBoOlxuICAgICAgICAgICAgICAgIHJldHVybiBbNDcsIDgwLCA5NywgMTE0LCA5NywgMTAzLCAxMTQsIDk3LCAxMTIsIDEwNF0gLy8gPSAnL1BhcmFncmFwaCdcbiAgICAgICAgICAgIGNhc2UgQW5ub3RhdGlvbkljb24uSW5zZXJ0OlxuICAgICAgICAgICAgICAgIHJldHVybiBbNDcsIDczLCAxMTAsIDExNSwgMTAxLCAxMTQsIDExNl0gLy8gPSAnL0luc2VydCdcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBbXVxuICAgIH1cblxuICAgIGNvbnZlcnRTdGF0ZShzdGF0ZSA6IEFubm90YXRpb25TdGF0ZSkgOiBudW1iZXJbXSB7XG4gICAgICAgIHN3aXRjaChzdGF0ZSkge1xuICAgICAgICAgICAgY2FzZSBBbm5vdGF0aW9uU3RhdGUuTWFya2VkOlxuICAgICAgICAgICAgICAgIHJldHVybiBVdGlsLmNvbnZlcnRTdHJpbmdUb0FzY2lpKFwiL01hcmtlZFwiKVxuICAgICAgICAgICAgY2FzZSBBbm5vdGF0aW9uU3RhdGUuVW5tYXJrZWQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0aWwuY29udmVydFN0cmluZ1RvQXNjaWkoXCIvVW5tYXJrZWRcIilcbiAgICAgICAgICAgIGNhc2UgQW5ub3RhdGlvblN0YXRlLkFjY2VwdGVkOlxuICAgICAgICAgICAgICAgIHJldHVybiBVdGlsLmNvbnZlcnRTdHJpbmdUb0FzY2lpKFwiL0FjY2VwdGVkXCIpXG4gICAgICAgICAgICBjYXNlIEFubm90YXRpb25TdGF0ZS5SZWplY3RlZDpcbiAgICAgICAgICAgICAgICByZXR1cm4gVXRpbC5jb252ZXJ0U3RyaW5nVG9Bc2NpaShcIi9SZWplY3RlZFwiKVxuICAgICAgICAgICAgY2FzZSBBbm5vdGF0aW9uU3RhdGUuQ2FuY2VsbGVkOlxuICAgICAgICAgICAgICAgIHJldHVybiBVdGlsLmNvbnZlcnRTdHJpbmdUb0FzY2lpKFwiL0NhbmNlbGxlZFwiKVxuICAgICAgICAgICAgY2FzZSBBbm5vdGF0aW9uU3RhdGUuQ29tcGxldGVkOlxuICAgICAgICAgICAgICAgIHJldHVybiBVdGlsLmNvbnZlcnRTdHJpbmdUb0FzY2lpKFwiL0NvbXBsZXRlZFwiKVxuICAgICAgICAgICAgY2FzZSBBbm5vdGF0aW9uU3RhdGUuTm9uZTpcbiAgICAgICAgICAgICAgICByZXR1cm4gVXRpbC5jb252ZXJ0U3RyaW5nVG9Bc2NpaShcIi9Ob25lXCIpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtdXG4gICAgfVxuXG4gICAgY29udmVydFN0YXRlTW9kZWwoc3RhdGVNb2RlbCA6IEFubm90YXRpb25TdGF0ZU1vZGVsKSA6IG51bWJlcltdIHtcbiAgICAgICAgc3dpdGNoKHN0YXRlTW9kZWwpIHtcbiAgICAgICAgICAgIGNhc2UgQW5ub3RhdGlvblN0YXRlTW9kZWwuTWFya2VkOlxuICAgICAgICAgICAgICAgIHJldHVybiBVdGlsLmNvbnZlcnRTdHJpbmdUb0FzY2lpKFwiL01hcmtlZFwiKVxuICAgICAgICAgICAgY2FzZSBBbm5vdGF0aW9uU3RhdGVNb2RlbC5SZXZpZXc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFV0aWwuY29udmVydFN0cmluZ1RvQXNjaWkoXCIvUmV2aWV3XCIpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gW11cbiAgICB9XG5cblxuICAgIHB1YmxpYyB3cml0ZUFubm90YXRpb25PYmplY3QoY3J5cHRvSW50ZXJmYWNlIDogQ3J5cHRvSW50ZXJmYWNlKSA6IG51bWJlcltdIHtcbiAgICAgICAgbGV0IHJldCA6IG51bWJlcltdID0gc3VwZXIud3JpdGVBbm5vdGF0aW9uT2JqZWN0KGNyeXB0b0ludGVyZmFjZSlcblxuICAgICAgICBpZiAodGhpcy5vcGVuKSB7XG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuT1BFTilcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuVFJVRSlcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5pY29uKSB7XG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuTkFNRSlcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KHRoaXMuY29udmVydEFubm90YXRpb25JY29uKHRoaXMuaWNvbikpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUpIHtcbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC5TVEFURSlcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KHRoaXMuY29udmVydFN0YXRlKHRoaXMuc3RhdGUpKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlTW9kZWwpIHtcbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC5TVEFURU1PREVMKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQodGhpcy5jb252ZXJ0U3RhdGVNb2RlbCh0aGlzLnN0YXRlTW9kZWwpKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXRcbiAgICB9XG5cbiAgICBwdWJsaWMgdmFsaWRhdGUoZW5hY3QgOiBib29sZWFuID0gdHJ1ZSkgOiBFcnJvckxpc3Qge1xuICAgICAgICBsZXQgZXJyb3JMaXN0IDogRXJyb3JMaXN0ID0gc3VwZXIudmFsaWRhdGUoZmFsc2UpXG5cbiAgICAgICAgaWYgKHRoaXMudHlwZSAhPT0gXCIvVGV4dFwiKSB7XG4gICAgICAgICAgICBlcnJvckxpc3QucHVzaChuZXcgSW52YWxpZEFubm90YXRpb25UeXBlRXJyb3IoYEludmFsaWQgYW5ub3RhdGlvbiB0eXBlICR7dGhpcy50eXBlfWApKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgJiYgIXRoaXMuc3RhdGVNb2RlbCkge1xuICAgICAgICAgICAgZXJyb3JMaXN0LnB1c2gobmV3IEludmFsaWRTdGF0ZUVycm9yKFwiWW91IG5lZWQgdG8gc3BlY2lmeSBhIHN0YXRlIG1vZGVsLCB3aGVuIHNwZWNpZnlpbmcgYSBzdGF0ZVwiKSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlTW9kZWwgJiYgIXRoaXMuc3RhdGUpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlTW9kZWwudmFsdWVPZigpID09PSBBbm5vdGF0aW9uU3RhdGVNb2RlbC5NYXJrZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gQW5ub3RhdGlvblN0YXRlLlVubWFya2VkXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGVNb2RlbC52YWx1ZU9mKCkgPT09IEFubm90YXRpb25TdGF0ZU1vZGVsLlJldmlldykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBBbm5vdGF0aW9uU3RhdGUuTm9uZVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBlcnJvckxpc3QucHVzaChuZXcgSW52YWxpZFN0YXRlRXJyb3IoXCJJbnZhbGlkIHN0YXRlIG1vZGVsIHNlbGVjdGVkXCIpKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgJiYgdGhpcy5zdGF0ZU1vZGVsKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZU1vZGVsLnZhbHVlT2YoKSA9PT0gQW5ub3RhdGlvblN0YXRlTW9kZWwuTWFya2VkKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUudmFsdWVPZigpICE9PSBBbm5vdGF0aW9uU3RhdGUuTWFya2VkICYmIHRoaXMuc3RhdGUudmFsdWVPZigpICE9PSBBbm5vdGF0aW9uU3RhdGUuVW5tYXJrZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JMaXN0LnB1c2gobmV3IEludmFsaWRTdGF0ZUVycm9yKFwiSW52YWxpZCBhbm5vdGF0aW9uIHN0YXRlIGZvciBzdGF0ZSBtb2RlbCAnTWFya2VkJyBvbmx5ICdNYXJrZWQnIGFuZCAnVW5tYXJrZWQnIGFyZSBsZWdhbCB2YWx1ZXNcIikpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlTW9kZWwudmFsdWVPZigpID09PSBBbm5vdGF0aW9uU3RhdGVNb2RlbC5SZXZpZXcpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS52YWx1ZU9mKCkgIT09IEFubm90YXRpb25TdGF0ZS5BY2NlcHRlZCAmJiB0aGlzLnN0YXRlLnZhbHVlT2YoKSAhPT0gQW5ub3RhdGlvblN0YXRlLlJlamVjdGVkICYmXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUudmFsdWVPZigpICE9PSBBbm5vdGF0aW9uU3RhdGUuQ2FuY2VsbGVkICYmIHRoaXMuc3RhdGUudmFsdWVPZigpICE9PSBBbm5vdGF0aW9uU3RhdGUuQ29tcGxldGVkICYmXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUudmFsdWVPZigpICE9PSBBbm5vdGF0aW9uU3RhdGUuTm9uZSkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckxpc3QucHVzaChuZXcgSW52YWxpZFN0YXRlRXJyb3IoXCJJbnZhbGlkIGFubm90YXRpb24gc3RhdGUgZm9yIHN0YXRlIG1vZGVsICdSZXZpZXcnIG9ubHkgJ0FjY2VwdGVkJywgJ1JlamVjdGVkJywgJ0NhbmNlbGxlZCcsICdDb21wbGV0ZWQnIGFuZCAnTm9uZScgYXJlIGxlZ2FsIHZhbHVlc1wiKSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGVycm9yTGlzdC5wdXNoKG5ldyBJbnZhbGlkU3RhdGVFcnJvcihcIkludmFsaWQgc3RhdGUgbW9kZWwgc2VsZWN0ZWRcIikpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZW5hY3QpIHtcbiAgICAgICAgICAgIGZvcihsZXQgZXJyb3Igb2YgZXJyb3JMaXN0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyb3JcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlcnJvckxpc3RcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBNYXJrdXBBbm5vdGF0aW9uLCBNYXJrdXBBbm5vdGF0aW9uT2JqIH0gZnJvbSAnLi9hbm5vdGF0aW9uX3R5cGVzJztcbmltcG9ydCB7IENyeXB0b0ludGVyZmFjZSB9IGZyb20gJy4uL3BhcnNlcic7XG5pbXBvcnQgeyBFcnJvckxpc3QsIEludmFsaWRSZWN0RXJyb3IsIEludmFsaWRBbm5vdGF0aW9uVHlwZUVycm9yLCBJbnZhbGlkUXVhZFBvaW50RXJyb3IgfSBmcm9tICcuL2Fubm90YXRpb25fZXJyb3JzJztcbmltcG9ydCB7IFdyaXRlclV0aWwgfSBmcm9tICcuLi93cml0ZXItdXRpbCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dE1hcmt1cEFubm90YXRpb24gZXh0ZW5kcyBNYXJrdXBBbm5vdGF0aW9uIHtcbiAgICBxdWFkUG9pbnRzOiBudW1iZXJbXSAvLyBzcGVjaWZpZXMgaG93IHRoZSBhbm5vdGF0aW9uIGdvZXMgYXJyb3VuZCB0aGUgdGV4dFxufVxuXG5leHBvcnQgY2xhc3MgVGV4dE1hcmt1cEFubm90YXRpb25PYmogZXh0ZW5kcyBNYXJrdXBBbm5vdGF0aW9uT2JqIGltcGxlbWVudHMgVGV4dE1hcmt1cEFubm90YXRpb24ge1xuICAgIHF1YWRQb2ludHM6IG51bWJlcltdID0gW11cblxuICAgIHB1YmxpYyB3cml0ZUFubm90YXRpb25PYmplY3QoY3J5cHRvSW50ZXJmYWNlIDogQ3J5cHRvSW50ZXJmYWNlKSA6IG51bWJlcltdIHtcbiAgICAgICAgbGV0IHJldCA6IG51bWJlcltdID0gc3VwZXIud3JpdGVBbm5vdGF0aW9uT2JqZWN0KGNyeXB0b0ludGVyZmFjZSlcblxuICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuUVVBRFBPSU5UUylcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLndyaXRlTnVtYmVyQXJyYXkodGhpcy5xdWFkUG9pbnRzKSlcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcblxuICAgICAgICByZXR1cm4gcmV0XG4gICAgfVxuXG4gICAgcHVibGljIHZhbGlkYXRlKGVuYWN0IDogYm9vbGVhbiA9IHRydWUpIDogRXJyb3JMaXN0IHtcbiAgICAgICAgbGV0IGVycm9yTGlzdCA6IEVycm9yTGlzdCA9IHN1cGVyLnZhbGlkYXRlKGZhbHNlKVxuXG4gICAgICAgIGlmIChlcnJvckxpc3QubGVuZ3RoID09PSAxICYmIGVycm9yTGlzdFswXSBpbnN0YW5jZW9mIEludmFsaWRSZWN0RXJyb3IpIHtcbiAgICAgICAgICAgIGlmKHRoaXMucXVhZFBvaW50cyAmJiB0aGlzLnF1YWRQb2ludHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMucmVjdCA9IHRoaXMuZXh0cmFjdFJlY3RGcm9tUXVhZFBvaW50cyh0aGlzLnF1YWRQb2ludHMpXG4gICAgICAgICAgICAgICAgZXJyb3JMaXN0ID0gdGhpcy5jaGVja1JlY3QoNCwgdGhpcy5yZWN0KVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLnF1YWRQb2ludHMgfHwgdGhpcy5xdWFkUG9pbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgbGV0IHJlY3QgPSB0aGlzLnJlY3RcbiAgICAgICAgICAgIHRoaXMucXVhZFBvaW50cyA9IFtyZWN0WzBdLCByZWN0WzNdLCByZWN0WzJdLCByZWN0WzNdLCByZWN0WzBdLCByZWN0WzFdLCByZWN0WzJdLCByZWN0WzFdXVxuICAgICAgICB9XG5cblxuICAgICAgICBlcnJvckxpc3QgPSBlcnJvckxpc3QuY29uY2F0KHRoaXMuY2hlY2tRdWFkUG9pbnRzKHRoaXMucXVhZFBvaW50cykpXG5cbiAgICAgICAgaWYgKGVuYWN0KSB7XG4gICAgICAgICAgICBmb3IobGV0IGVycm9yIG9mIGVycm9yTGlzdCkge1xuICAgICAgICAgICAgICAgIHRocm93IGVycm9yXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZXJyb3JMaXN0XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdHMgdGhlIHJlY3Rhbmd1bGFyIGh1bGwgZnJvbSBhIHF1YWRQb2ludCBkZWZpbml0aW9uXG4gICAgICogKi9cbiAgICBwcml2YXRlIGV4dHJhY3RSZWN0RnJvbVF1YWRQb2ludHMocXVhZFBvaW50czogbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gICAgICAgIGxldCB4X3ZhbHVlcyA9IHF1YWRQb2ludHMuZmlsdGVyKChlbGVtZW50LCBpbmRleCkgPT4gaW5kZXggJSAyID09PSAwKVxuICAgICAgICBsZXQgeV92YWx1ZXMgPSBxdWFkUG9pbnRzLmZpbHRlcigoZWxlbWVudCwgaW5kZXgpID0+IGluZGV4ICUgMiAhPT0gMClcblxuICAgICAgICByZXR1cm4gW01hdGgubWluKC4uLnhfdmFsdWVzKSwgTWF0aC5taW4oLi4ueV92YWx1ZXMpLCBNYXRoLm1heCguLi54X3ZhbHVlcyksIE1hdGgubWF4KC4uLnlfdmFsdWVzKV1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgdGhlICdxdWFkUG9pbnRzJyBwYXJhbWV0ZXJcbiAgICAgKiAqL1xuICAgIHByaXZhdGUgY2hlY2tRdWFkUG9pbnRzKHF1YWRQb2ludHM6IG51bWJlcltdKSA6IEVycm9yTGlzdCB7XG4gICAgICAgIGxldCBlcnJvckxpc3QgOiBFcnJvckxpc3QgPSBbXVxuICAgICAgICBpZiAocXVhZFBvaW50cy5sZW5ndGggJSA4ICE9PSAwKVxuICAgICAgICAgICAgZXJyb3JMaXN0LnB1c2gobmV3IEludmFsaWRRdWFkUG9pbnRFcnJvcihgUXVhZHBvaW50cyBhcnJheSBoYXMgbGVuZ3RoICR7cXVhZFBvaW50cy5sZW5ndGh9IGJ1dCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgOGApKVxuXG4gICAgICAgIHF1YWRQb2ludHMuZm9yRWFjaCgoYSkgPT4ge1xuICAgICAgICAgICAgaWYgKCdudW1iZXInICE9PSB0eXBlb2YgYSlcbiAgICAgICAgICAgICAgICBlcnJvckxpc3QucHVzaChuZXcgSW52YWxpZFF1YWRQb2ludEVycm9yKFwiUXVhZHBvaW50IFwiICsgcXVhZFBvaW50cyArIFwiIGhhcyBpbnZhbGlkIGVudHJ5OiBcIiArIGEpKVxuICAgICAgICB9KVxuXG4gICAgICAgIHJldHVybiBlcnJvckxpc3RcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBIaWdobGlnaHRBbm5vdGF0aW9uT2JqIGV4dGVuZHMgVGV4dE1hcmt1cEFubm90YXRpb25PYmoge1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKClcbiAgICAgICAgdGhpcy50eXBlID0gXCIvSGlnaGxpZ2h0XCJcbiAgICAgICAgdGhpcy50eXBlX2VuY29kZWQgPSBbNDcsIDcyLCAxMDUsIDEwMywgMTA0LCAxMDgsIDEwNSwgMTAzLCAxMDQsIDExNl0gLy8gPSAnL0hpZ2hsaWdodCdcbiAgICB9XG5cbiAgICBwdWJsaWMgdmFsaWRhdGUoZW5hY3QgOiBib29sZWFuID0gdHJ1ZSkgOiBFcnJvckxpc3Qge1xuICAgICAgICBsZXQgZXJyb3JMaXN0IDogRXJyb3JMaXN0ID0gc3VwZXIudmFsaWRhdGUoZmFsc2UpXG5cbiAgICAgICAgaWYgKHRoaXMudHlwZSAhPT0gXCIvSGlnaGxpZ2h0XCIpIHtcbiAgICAgICAgICAgIGVycm9yTGlzdC5wdXNoKG5ldyBJbnZhbGlkQW5ub3RhdGlvblR5cGVFcnJvcihgSW52YWxpZCBhbm5vdGF0aW9uIHR5cGUgJHt0aGlzLnR5cGV9YCkpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZW5hY3QpIHtcbiAgICAgICAgICAgIGZvcihsZXQgZXJyb3Igb2YgZXJyb3JMaXN0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyb3JcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlcnJvckxpc3RcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBVbmRlcmxpbmVBbm5vdGF0aW9uT2JqIGV4dGVuZHMgVGV4dE1hcmt1cEFubm90YXRpb25PYmoge1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKClcbiAgICAgICAgdGhpcy50eXBlID0gXCIvVW5kZXJsaW5lXCJcbiAgICAgICAgdGhpcy50eXBlX2VuY29kZWQgPSBbNDcsIDg1LCAxMTAsIDEwMCwgMTAxLCAxMTQsIDEwOCwgMTA1LCAxMTAsIDEwMV0gLy8gPSAnL1VuZGVybGluZSdcbiAgICB9XG5cbiAgICBwdWJsaWMgdmFsaWRhdGUoZW5hY3QgOiBib29sZWFuID0gdHJ1ZSkgOiBFcnJvckxpc3Qge1xuICAgICAgICBsZXQgZXJyb3JMaXN0IDogRXJyb3JMaXN0ID0gc3VwZXIudmFsaWRhdGUoZmFsc2UpXG5cbiAgICAgICAgaWYgKHRoaXMudHlwZSAhPT0gXCIvVW5kZXJsaW5lXCIpIHtcbiAgICAgICAgICAgIGVycm9yTGlzdC5wdXNoKG5ldyBJbnZhbGlkQW5ub3RhdGlvblR5cGVFcnJvcihgSW52YWxpZCBhbm5vdGF0aW9uIHR5cGUgJHt0aGlzLnR5cGV9YCkpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZW5hY3QpIHtcbiAgICAgICAgICAgIGZvcihsZXQgZXJyb3Igb2YgZXJyb3JMaXN0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyb3JcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlcnJvckxpc3RcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTcXVpZ2dseUFubm90YXRpb25PYmogZXh0ZW5kcyBUZXh0TWFya3VwQW5ub3RhdGlvbk9iaiB7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKVxuICAgICAgICB0aGlzLnR5cGUgPSBcIi9TcXVpZ2dseVwiXG4gICAgICAgIHRoaXMudHlwZV9lbmNvZGVkID0gWzQ3LCA4MywgMTEzLCAxMTcsIDEwNSwgMTAzLCAxMDMsIDEwOCwgMTIxXSAvLyA9ICcvU3F1aWdnbHknXG4gICAgfVxuXG4gICAgcHVibGljIHZhbGlkYXRlKGVuYWN0IDogYm9vbGVhbiA9IHRydWUpIDogRXJyb3JMaXN0IHtcbiAgICAgICAgbGV0IGVycm9yTGlzdCA6IEVycm9yTGlzdCA9IHN1cGVyLnZhbGlkYXRlKGZhbHNlKVxuXG4gICAgICAgIGlmICh0aGlzLnR5cGUgIT09IFwiL1NxdWlnZ2x5XCIpIHtcbiAgICAgICAgICAgIGVycm9yTGlzdC5wdXNoKG5ldyBJbnZhbGlkQW5ub3RhdGlvblR5cGVFcnJvcihgSW52YWxpZCBhbm5vdGF0aW9uIHR5cGUgJHt0aGlzLnR5cGV9YCkpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZW5hY3QpIHtcbiAgICAgICAgICAgIGZvcihsZXQgZXJyb3Igb2YgZXJyb3JMaXN0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyb3JcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlcnJvckxpc3RcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTdHJpa2VPdXRBbm5vdGF0aW9uT2JqIGV4dGVuZHMgVGV4dE1hcmt1cEFubm90YXRpb25PYmoge1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKClcbiAgICAgICAgdGhpcy50eXBlID0gXCIvU3RyaWtlT3V0XCJcbiAgICAgICAgdGhpcy50eXBlX2VuY29kZWQgPSBbNDcsIDgzLCAxMTYsIDExNCwgMTA1LCAxMDcsIDEwMSwgNzksIDExNywgMTE2XSAvLyA9ICcvU3RyaWtlT3V0J1xuICAgIH1cblxuICAgIHB1YmxpYyB2YWxpZGF0ZShlbmFjdCA6IGJvb2xlYW4gPSB0cnVlKSA6IEVycm9yTGlzdCB7XG4gICAgICAgIGxldCBlcnJvckxpc3QgOiBFcnJvckxpc3QgPSBzdXBlci52YWxpZGF0ZShmYWxzZSlcblxuICAgICAgICBpZiAodGhpcy50eXBlICE9PSBcIi9TdHJpa2VPdXRcIikge1xuICAgICAgICAgICAgZXJyb3JMaXN0LnB1c2gobmV3IEludmFsaWRBbm5vdGF0aW9uVHlwZUVycm9yKGBJbnZhbGlkIGFubm90YXRpb24gdHlwZSAke3RoaXMudHlwZX1gKSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbmFjdCkge1xuICAgICAgICAgICAgZm9yKGxldCBlcnJvciBvZiBlcnJvckxpc3QpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvclxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVycm9yTGlzdFxuICAgIH1cbn1cbiIsImltcG9ydCB7IFV0aWwsIEV4dHJhY3Rpb25SZXN1bHQgfSBmcm9tICcuL3V0aWwnXG5pbXBvcnQgeyBPYmplY3RVdGlsIH0gZnJvbSAnLi9vYmplY3QtdXRpbCdcbi8qKlxuICogSG9sZHMgdGhlIGxvZ2ljIGZvciBleHRyYWN0aW5nIGFycmF5c1xuICogKi9cbmV4cG9ydCBjbGFzcyBBcnJheVV0aWwge1xuICAgIC8qKlxuICAgICAqIEV4dHJhY3RzIGFycmF5IG9mIG51bWJlcnMgYW5kIGFycmF5cyBvZiByZWZlcmVuY2VzXG4gICAgICpcbiAgICAgKiBUaGUgZnVuY3Rpb24gc3VwcG9ydHMgYXJiaXRyYXJpbHkgbmVzdGluZyBvZiBhcnJheXMgYW5kIG11bHRpcGxlIHR5cGVzLlxuICAgICAqICovXG4gICAgcHVibGljIHN0YXRpYyBleHRyYWN0QXJyYXkoZGF0YTogVWludDhBcnJheSwgcHRyOiBudW1iZXIpOiBFeHRyYWN0aW9uUmVzdWx0IHtcbiAgICAgICAgcHRyID0gVXRpbC5za2lwU3BhY2VzKGRhdGEsIHB0cilcbiAgICAgICAgbGV0IHN0YXJ0X2luZGV4ID0gcHRyXG5cbiAgICAgICAgaWYgKGRhdGFbcHRyXSAhPT0gVXRpbC5BUlJBWV9TVEFSVFswXSlcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiSW52YWxpZCBhcnJheSBzZXF1ZW5jZSAtLSBkb2VzIG5vdCBzdGFydCB3aXRoICdbJ1wiKVxuXG4gICAgICAgIHB0ciArPSAxXG5cbiAgICAgICAgbGV0IG5leHQgPSBVdGlsLnJlYWROZXh0V29yZChkYXRhLCBwdHIpXG4gICAgICAgIGxldCBuZXh0X3N0cmluZzogVWludDhBcnJheSB8IHVuZGVmaW5lZCA9IG5leHQucmVzdWx0XG4gICAgICAgIHB0ciA9IG5leHQuc3RhcnRfaW5kZXhcblxuICAgICAgICBsZXQgcmV0X2xpc3Q6IGFueVtdID0gW11cblxuICAgICAgICB3aGlsZSAobmV4dF9zdHJpbmcpIHtcbiAgICAgICAgICAgIGlmIChuZXh0X3N0cmluZ1swXSA9PT0gVXRpbC5BUlJBWV9TVEFSVFswXSkge1xuICAgICAgICAgICAgICAgIGxldCBzdWJfYXJyYXkgPSBBcnJheVV0aWwuZXh0cmFjdEFycmF5KGRhdGEsIHB0cilcbiAgICAgICAgICAgICAgICBwdHIgPSBzdWJfYXJyYXkuZW5kX2luZGV4XG4gICAgICAgICAgICAgICAgcmV0X2xpc3QucHVzaChzdWJfYXJyYXkucmVzdWx0KVxuICAgICAgICAgICAgfSBlbHNlIGlmIChVdGlsLmFyZUFycmF5c0VxdWFsKG5leHRfc3RyaW5nLCBVdGlsLk5VTEwpKSB7XG4gICAgICAgICAgICAgICAgcmV0X2xpc3QucHVzaChcIm51bGxcIilcbiAgICAgICAgICAgICAgICBwdHIgKz0gbmV4dF9zdHJpbmcubGVuZ3RoIC0gMVxuICAgICAgICAgICAgfSBlbHNlIGlmIChuZXh0X3N0cmluZ1swXSA9PT0gVXRpbC5MSVRFUkFMX1NUUklOR19FTkRbMF0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyByZXN1bHQ6IHJldF9saXN0LCBzdGFydF9pbmRleDogc3RhcnRfaW5kZXgsIGVuZF9pbmRleDogbmV4dC5lbmRfaW5kZXggfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChuZXh0X3N0cmluZ1swXSA9PT0gVXRpbC5MSVRFUkFMX1NUUklOR19TVEFSVFswXSkge1xuICAgICAgICAgICAgICAgIGxldCBleHRyYWN0ZWRfc3RyaW5nID0gVXRpbC5leHRyYWN0U3RyaW5nKGRhdGEsIHB0cilcbiAgICAgICAgICAgICAgICByZXRfbGlzdC5wdXNoKGV4dHJhY3RlZF9zdHJpbmcucmVzdWx0KVxuICAgICAgICAgICAgICAgIHB0ciA9IGV4dHJhY3RlZF9zdHJpbmcuZW5kX2luZGV4XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG5leHRfc3RyaW5nWzBdID09PSBVdGlsLkRJQ1RfU1RBUlRbMF0pIHsgLy8gPFxuICAgICAgICAgICAgICAgIGxldCBsb29rdXBfd29yZCA9IFV0aWwucmVhZE5leHRXb3JkKGRhdGEsIG5leHQuZW5kX2luZGV4ICsgMSlcbiAgICAgICAgICAgICAgICBpZiAobG9va3VwX3dvcmQucmVzdWx0ICYmIGxvb2t1cF93b3JkLnJlc3VsdFswXSA9PT0gVXRpbC5ESUNUX1NUQVJUWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBkaWN0ID0ge31cbiAgICAgICAgICAgICAgICAgICAgcHRyID0gT2JqZWN0VXRpbC5leHRyYWN0RGljdFZhbHVlUmVjKGRhdGEsIHB0ciwgZGljdClcbiAgICAgICAgICAgICAgICAgICAgcmV0X2xpc3QucHVzaChkaWN0KVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBoZXhfc3RyaW5nID0gVXRpbC5leHRyYWN0SGV4U3RyaW5nKGRhdGEsIHB0cilcbiAgICAgICAgICAgICAgICAgICAgcmV0X2xpc3QucHVzaChoZXhfc3RyaW5nLnJlc3VsdClcbiAgICAgICAgICAgICAgICAgICAgcHRyID0gaGV4X3N0cmluZy5lbmRfaW5kZXhcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG5leHRfc3RyaW5nWzBdID09PSA0NykgeyAvLyAvXG4gICAgICAgICAgICAgICAgbGV0IG9wdF92YWx1ZSA9IFV0aWwuZXh0cmFjdE9wdGlvblZhbHVlKGRhdGEsIHB0cilcbiAgICAgICAgICAgICAgICByZXRfbGlzdC5wdXNoKFwiL1wiICsgb3B0X3ZhbHVlLnJlc3VsdClcbiAgICAgICAgICAgICAgICBwdHIgPSBvcHRfdmFsdWUuZW5kX2luZGV4XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG5leHRfc3RyaW5nWzBdID09PSBVdGlsLlJbMF0pIHsgLy8gUmVmZXJlbmNlIHBvaW50ZXJcbiAgICAgICAgICAgICAgICBsZXQgb2JqID0gcmV0X2xpc3RbcmV0X2xpc3QubGVuZ3RoIC0gMl1cbiAgICAgICAgICAgICAgICBsZXQgZ2VuZXJhdGlvbiA9IHJldF9saXN0W3JldF9saXN0Lmxlbmd0aCAtIDFdXG4gICAgICAgICAgICAgICAgcmV0X2xpc3QgPSByZXRfbGlzdC5zbGljZSgwLCByZXRfbGlzdC5sZW5ndGggLSAyKVxuICAgICAgICAgICAgICAgIHJldF9saXN0LnB1c2goeyBvYmo6IG9iaiwgZ2VuZXJhdGlvbjogZ2VuZXJhdGlvbiB9KVxuICAgICAgICAgICAgICAgIHB0ciA9IG5leHQuZW5kX2luZGV4XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG5leHRfc3RyaW5nWzBdID09PSBVdGlsLkFSUkFZX0VORFswXSkge1xuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxldCBuYnIgPSBVdGlsLmV4dHJhY3ROdW1iZXIoZGF0YSwgcHRyKVxuICAgICAgICAgICAgICAgIHJldF9saXN0LnB1c2gobmJyLnJlc3VsdClcbiAgICAgICAgICAgICAgICBwdHIgPSBuYnIuZW5kX2luZGV4XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICsrcHRyXG4gICAgICAgICAgICBwdHIgPSBVdGlsLnNraXBTcGFjZXMoZGF0YSwgcHRyKVxuICAgICAgICAgICAgbmV4dCA9IFV0aWwucmVhZE5leHRXb3JkKGRhdGEsIHB0cilcbiAgICAgICAgICAgIG5leHRfc3RyaW5nID0gbmV4dC5yZXN1bHRcbiAgICAgICAgICAgIHB0ciA9IG5leHQuc3RhcnRfaW5kZXhcblxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHsgcmVzdWx0OiByZXRfbGlzdCwgc3RhcnRfaW5kZXg6IHN0YXJ0X2luZGV4LCBlbmRfaW5kZXg6IG5leHQuZW5kX2luZGV4IH1cbiAgICB9XG59XG4iLCJpbXBvcnQgeyBVdGlsIH0gZnJvbSAnLi91dGlsJztcbmltcG9ydCAqIGFzIGNyeXB0byBmcm9tIFwiY3J5cHRvLWpzXCI7XG5cbmV4cG9ydCB0eXBlIFdvcmRBcnJheSA9IGNyeXB0by5saWIuV29yZEFycmF5XG5cbmV4cG9ydCBjbGFzcyBDcnlwdG9VdGlsIHtcbiAgICBwdWJsaWMgc3RhdGljIFBBRERJTkdfU1RSSU5HIDogbnVtYmVyW10gPSBbXG4gICAgICAgIDB4MjgsXG4gICAgICAgIDB4QkYsXG4gICAgICAgIDB4NEUsXG4gICAgICAgIDB4NUUsXG4gICAgICAgIDB4NEUsXG4gICAgICAgIDB4NzUsXG4gICAgICAgIDB4OEEsXG4gICAgICAgIDB4NDEsXG4gICAgICAgIDB4NjQsXG4gICAgICAgIDB4MDAsXG4gICAgICAgIDB4NEUsXG4gICAgICAgIDB4NTYsXG4gICAgICAgIDB4RkYsXG4gICAgICAgIDB4RkEsXG4gICAgICAgIDB4MDEsXG4gICAgICAgIDB4MDgsXG4gICAgICAgIDB4MkUsXG4gICAgICAgIDB4MkUsXG4gICAgICAgIDB4MDAsXG4gICAgICAgIDB4QjYsXG4gICAgICAgIDB4RDAsXG4gICAgICAgIDB4NjgsXG4gICAgICAgIDB4M0UsXG4gICAgICAgIDB4ODAsXG4gICAgICAgIDB4MkYsXG4gICAgICAgIDB4MEMsXG4gICAgICAgIDB4QTksXG4gICAgICAgIDB4RkUsXG4gICAgICAgIDB4NjQsXG4gICAgICAgIDB4NTMsXG4gICAgICAgIDB4NjksXG4gICAgICAgIDB4N0FdXG5cbiAgICAvKipcbiAgICAgKiBUcmFuc2Zvcm1zIGEgdWludDhhcnJheSBpbnRvIGEgY3J5cHRvLWpzIHdvcmQgYXJyYXlcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY29udmVydFRvV29yZEFycmF5KGFyciA6IFVpbnQ4QXJyYXkpIDogV29yZEFycmF5IHtcbiAgICAgICAgbGV0IG5ld192YWxfaW50MzIgPSBVdGlsLmNvbnZlcnRVaW50OEFycmF5VG9JbnQzMkFycmF5KGFycilcbiAgICAgICAgcmV0dXJuIGNyeXB0by5saWIuV29yZEFycmF5LmNyZWF0ZShBcnJheS5mcm9tKG5ld192YWxfaW50MzIpLCBhcnIubGVuZ3RoKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGEgZ2l2ZW4gd29yZCBhcnJheSBpbnRvIGEgdWludDggYXJyYXlcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY29udmVydFdvcmRBcnJheVRvQnl0ZUFycmF5KGFyciA6IFdvcmRBcnJheSkgOiBVaW50OEFycmF5IHtcbiAgICAgICAgcmV0dXJuIFV0aWwuY29udmVydEludDMyQXJyYXlUb1VpbnQ4QXJyYXkoYXJyLndvcmRzKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGEgbnVtYmVyIGludG8gYSBsaXR0bGUgZW5kaWFuIGJ5dGUgYXJyYXlcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY29udmVydE51bWJlclRvTGl0dGxlRW5kaWFuQnl0ZUFycmF5KG5iciA6IG51bWJlcikgOiBVaW50OEFycmF5IHtcbiAgICAgICAgcmV0dXJuIFV0aWwuY29udmVydEludDMyQXJyYXlUb1VpbnQ4QXJyYXkobmV3IEludDMyQXJyYXkoW25icl0pKS5yZXZlcnNlKClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBNRDUgaGFzaFxuICAgICAqICovXG4gICAgcHVibGljIHN0YXRpYyBNRDUoZGF0YSA6IFdvcmRBcnJheSB8IFVpbnQ4QXJyYXkpIDogV29yZEFycmF5IHtcbiAgICAgICAgaWYgKGRhdGEgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgICAgICBkYXRhID0gQ3J5cHRvVXRpbC5jb252ZXJ0VG9Xb3JkQXJyYXkoZGF0YSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjcnlwdG8uTUQ1KGRhdGEpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgTUQ1IGhhc2ggYXMgYnl0ZSBhcnJheVxuICAgICAqICovXG4gICAgcHVibGljIHN0YXRpYyBNRDVBc0J5dGVBcnJheShkYXRhIDogV29yZEFycmF5IHwgVWludDhBcnJheSkgOiBVaW50OEFycmF5IHtcbiAgICAgICAgaWYgKGRhdGEgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgICAgICBkYXRhID0gQ3J5cHRvVXRpbC5jb252ZXJ0VG9Xb3JkQXJyYXkoZGF0YSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBDcnlwdG9VdGlsLmNvbnZlcnRXb3JkQXJyYXlUb0J5dGVBcnJheShjcnlwdG8uTUQ1KGRhdGEpKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIE1ENSBoYXNoIGFzIGhleCBzdHJpbmdcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgTUQ1SGV4KGRhdGEgOiBXb3JkQXJyYXkgfCBVaW50OEFycmF5KSA6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBDcnlwdG9VdGlsLk1ENShkYXRhKS50b1N0cmluZyhjcnlwdG8uZW5jLkhleClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBSQzQgZW5jcnlwdGVkIGRhdGFcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgUkM0KGRhdGEgOiBXb3JkQXJyYXkgfCBVaW50OEFycmF5LCBrZXkgOiBXb3JkQXJyYXkgfCBVaW50OEFycmF5KSA6IFdvcmRBcnJheSB7XG4gICAgICAgIGlmIChkYXRhIGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgICAgICAgICAgZGF0YSA9IENyeXB0b1V0aWwuY29udmVydFRvV29yZEFycmF5KGRhdGEpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoa2V5IGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgICAgICAgICAga2V5ID0gQ3J5cHRvVXRpbC5jb252ZXJ0VG9Xb3JkQXJyYXkoa2V5KVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNyeXB0by5SQzQuZW5jcnlwdChkYXRhLCBrZXkpLmNpcGhlcnRleHRcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBSQzQgZW5jcnlwdGVkIGRhdGEgYXMgaGV4IHN0cmluZ1xuICAgICAqICovXG4gICAgcHVibGljIHN0YXRpYyBSQzRIZXgoZGF0YSA6IFdvcmRBcnJheSB8IFVpbnQ4QXJyYXksIGtleSA6IFdvcmRBcnJheSB8IFVpbnQ4QXJyYXkpIDogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIENyeXB0b1V0aWwuUkM0KGRhdGEsIGtleSkudG9TdHJpbmcoY3J5cHRvLmVuYy5IZXgpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFkcyB0aGUgcHJvdmlkZWQgcGFzc3dvcmQgc3RyaW5nXG4gICAgICogKi9cbiAgICBwdWJsaWMgc3RhdGljIHBhZFBhc3N3b3J0U3RyaW5nKHBhc3N3b3JkIDogVWludDhBcnJheSB8IHN0cmluZykgOiBVaW50OEFycmF5IHtcbiAgICAgICAgaWYgKHR5cGVvZiBwYXNzd29yZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHBhc3N3b3JkID0gbmV3IFVpbnQ4QXJyYXkoVXRpbC5jb252ZXJ0U3RyaW5nVG9Bc2NpaShwYXNzd29yZCkpXG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcmV0X3ZhbCA9IG5ldyBVaW50OEFycmF5KDMyKVxuICAgICAgICByZXRfdmFsLnNldChwYXNzd29yZC5zbGljZSgwLCAzMikpXG5cbiAgICAgICAgaWYgKHBhc3N3b3JkLmxlbmd0aCA8IDMyKSB7XG4gICAgICAgICAgICByZXRfdmFsLnNldChDcnlwdG9VdGlsLlBBRERJTkdfU1RSSU5HLnNsaWNlKDAsIDMyIC0gcGFzc3dvcmQubGVuZ3RoKSwgcGFzc3dvcmQubGVuZ3RoKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJldF92YWxcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBYb3JzIGV2ZXJ5IGJ5dGUgb2YgdGhlIHByb3ZpZGVkIF9ieXRlX2FycmF5IHdpdGggdGhlIHZhbHVlIF9rXG4gICAgICogKi9cbiAgICBwdWJsaWMgc3RhdGljIHhvckJ5dGVzKF9ieXRlX2FycmF5IDogVWludDhBcnJheSwgX2sgOiBudW1iZXIpIDogV29yZEFycmF5IHtcbiAgICAgICAgbGV0IF9yZXRfdmFsIDogbnVtYmVyW10gPSBbXVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IF9ieXRlX2FycmF5Lmxlbmd0aDsgKytpKXtcbiAgICAgICAgICAgIF9yZXRfdmFsLnB1c2goX2J5dGVfYXJyYXlbaV0gXiBfaylcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBDcnlwdG9VdGlsLmNvbnZlcnRUb1dvcmRBcnJheShuZXcgVWludDhBcnJheShfcmV0X3ZhbCkpXG4gICAgfVxufVxuIiwiaW1wb3J0IHsgVXRpbCB9IGZyb20gJy4vdXRpbCc7XG5pbXBvcnQge1JlZmVyZW5jZVBvaW50ZXJ9IGZyb20gJy4vcGFyc2VyJ1xuaW1wb3J0IHsgQ3J5cHRvVXRpbCB9IGZyb20gJy4vY3J5cHRvLXV0aWwnO1xuXG5leHBvcnQgY29uc3QgUkM0XzQwX0JJVCA6IGJvb2xlYW4gPSB0cnVlO1xuXG5leHBvcnQgaW50ZXJmYWNlIENyeXB0b0NvbmZpZ3VyYXRpb24ge1xuICAgIHZlcnNpb24gOiBudW1iZXIgfCB1bmRlZmluZWQgLy8gL1YgcGFyYW1ldGVyXG4gICAgcmV2aXNpb24gOiBudW1iZXIgfCB1bmRlZmluZWQgLy8gL1IgcmV2aXNpb24gbnVtYmVyXG4gICAgZmlsdGVyIDogc3RyaW5nIHwgdW5kZWZpbmVkIC8vIFRoZSBzZWxlY3RlZCBmaWx0ZXJcbiAgICB1c2VyX3B3ZF9jIDogVWludDhBcnJheSB8IHVuZGVmaW5lZCAvLyAvVSBUaGUgdXNlciBwYXNzd29yZCBoYXNoXG4gICAgb3duZXJfcHdkX2MgOiBVaW50OEFycmF5IHwgdW5kZWZpbmVkIC8vIC9PIFRoZSBvd25lciBwYXNzd29yZCBoYXNoXG4gICAgbGVuZ3RoIDogbnVtYmVyIHwgdW5kZWZpbmVkIC8vIC9MZW5ndGggdmFsdWVcbiAgICBwZXJtaXNzaW9ucyA6IG51bWJlciB8IHVuZGVmaW5lZCAvLyAvUCBwZXJtaXNzaW9uc1xuXG4gICAgdXNlcl9wd2Q6IHN0cmluZyAvLyB0aGUgdXNlciBwYXNzd29yZFxuICAgIG93bmVyX3B3ZDogc3RyaW5nIC8vIHRoZSBvd25lciBwYXNzd29yZFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENyeXB0b0VuZ2luZSB7XG4gICAgZW5jcnlwdChkYXRhIDogVWludDhBcnJheSwgcmVmZXJlbmNlIDogUmVmZXJlbmNlUG9pbnRlciB8IHVuZGVmaW5lZCkgOiBVaW50OEFycmF5O1xuICAgIGRlY3J5cHQoZGF0YSA6IFVpbnQ4QXJyYXksIHJlZmVyZW5jZSA6IFJlZmVyZW5jZVBvaW50ZXIgfCB1bmRlZmluZWQpIDogVWludDhBcnJheTtcblxuICAgIGlzVXNlclBhc3N3b3JkQ29ycmVjdCgpIDogYm9vbGVhbjtcbiAgICBpc093bmVyUGFzc3dvcmRDb3JyZWN0KCkgOiBib29sZWFuO1xufVxuXG5leHBvcnQgY2xhc3MgSWRlbnRpdHlFbmdpbmUgaW1wbGVtZW50cyBDcnlwdG9FbmdpbmUge1xuICAgIGVuY3J5cHQoZGF0YSA6IFVpbnQ4QXJyYXksIHJlZmVyZW5jZSA6IFJlZmVyZW5jZVBvaW50ZXIgfCB1bmRlZmluZWQpIDogVWludDhBcnJheSB7XG4gICAgICAgIHJldHVybiBkYXRhXG4gICAgfVxuXG4gICAgZGVjcnlwdChkYXRhIDogVWludDhBcnJheSwgcmVmZXJlbmNlIDogUmVmZXJlbmNlUG9pbnRlciB8IHVuZGVmaW5lZCkgOiBVaW50OEFycmF5IHtcbiAgICAgICAgcmV0dXJuIGRhdGFcbiAgICB9XG5cbiAgICBpc1VzZXJQYXNzd29yZENvcnJlY3QoKSA6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIGlzT3duZXJQYXNzd29yZENvcnJlY3QoKSA6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFJDNENyeXB0b0VuZ2luZSBpbXBsZW1lbnRzIENyeXB0b0VuZ2luZSB7XG4gICAgcHJpdmF0ZSBlbmNyeXB0aW9uS2V5IDogVWludDhBcnJheSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZFxuICAgIHByaXZhdGUgY29tcHV0ZWRfdXNlcl9wYXNzd29yZCA6IFVpbnQ4QXJyYXkgfCB1bmRlZmluZWQgPSB1bmRlZmluZWRcbiAgICBwcml2YXRlIGNvbXB1dGVkX293bmVyX3Bhc3N3b3JkIDogVWludDhBcnJheSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZFxuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBjcnlwdG9Db25maWd1cmF0aW9uOiBDcnlwdG9Db25maWd1cmF0aW9uLCBwcml2YXRlIGZpbGVfaWQgOiBVaW50OEFycmF5W10gfCB1bmRlZmluZWQsIHByaXZhdGUgcmM0XzQwX2JpdCA6IGJvb2xlYW4gPSBmYWxzZSkgeyB9XG5cbiAgICBlbmNyeXB0KGRhdGEgOiBVaW50OEFycmF5LCByZWZlcmVuY2UgOiBSZWZlcmVuY2VQb2ludGVyIHwgdW5kZWZpbmVkKSA6IFVpbnQ4QXJyYXkge1xuICAgICAgICBpZiAoIXJlZmVyZW5jZSlcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiVW5kZWZpbmVkIHJlZmVyZW5jZSBwb2ludGVyIG9mIGVuY3J5cHRlZCBvYmplY3RcIilcblxuICAgICAgICBsZXQgZW5jcnlwdGlvbktleSA9IHRoaXMuY29tcHV0ZUVuY3J5cHRpb25LZXkoKVxuXG4gICAgICAgIGxldCBhZGFwdGVkX2tleSA9IG5ldyBVaW50OEFycmF5KGVuY3J5cHRpb25LZXkubGVuZ3RoICsgNSlcbiAgICAgICAgYWRhcHRlZF9rZXkuc2V0KGVuY3J5cHRpb25LZXksIDApXG4gICAgICAgIGxldCBvYmogPSBDcnlwdG9VdGlsLmNvbnZlcnROdW1iZXJUb0xpdHRsZUVuZGlhbkJ5dGVBcnJheShyZWZlcmVuY2Uub2JqKVxuICAgICAgICBhZGFwdGVkX2tleS5zZXQob2JqLnNsaWNlKDAsIDMpLCBlbmNyeXB0aW9uS2V5Lmxlbmd0aClcbiAgICAgICAgbGV0IGdlbiA9IENyeXB0b1V0aWwuY29udmVydE51bWJlclRvTGl0dGxlRW5kaWFuQnl0ZUFycmF5KHJlZmVyZW5jZS5nZW5lcmF0aW9uKVxuICAgICAgICBhZGFwdGVkX2tleS5zZXQoZ2VuLnNsaWNlKDAsIDIpLCBlbmNyeXB0aW9uS2V5Lmxlbmd0aCArIDMpXG5cbiAgICAgICAgbGV0IGtleV9oYXNoID0gQ3J5cHRvVXRpbC5NRDVBc0J5dGVBcnJheShhZGFwdGVkX2tleSlcblxuICAgICAgICBsZXQgZW5jcnlwdGVkID0gQ3J5cHRvVXRpbC5SQzQoZGF0YSwga2V5X2hhc2guc2xpY2UoMCwgTWF0aC5taW4oZW5jcnlwdGlvbktleS5sZW5ndGggKyA1LCAxNikpKVxuXG4gICAgICAgIHJldHVybiBDcnlwdG9VdGlsLmNvbnZlcnRXb3JkQXJyYXlUb0J5dGVBcnJheShlbmNyeXB0ZWQpXG4gICAgfVxuXG4gICAgZGVjcnlwdChkYXRhIDogVWludDhBcnJheSwgcmVmZXJlbmNlIDogUmVmZXJlbmNlUG9pbnRlciB8IHVuZGVmaW5lZCkgOiBVaW50OEFycmF5IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5jcnlwdChkYXRhLCByZWZlcmVuY2UpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgdGhlIFJDNCBlbmNyeXB0aW9uIGtleVxuICAgICAqICovXG4gICAgY29tcHV0ZUVuY3J5cHRpb25LZXkoKSA6IFVpbnQ4QXJyYXkge1xuICAgICAgICBpZiAodGhpcy5lbmNyeXB0aW9uS2V5KVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5jcnlwdGlvbktleVxuXG4gICAgICAgIGxldCB1c2VycHdkID0gQ3J5cHRvVXRpbC5wYWRQYXNzd29ydFN0cmluZyh0aGlzLmNyeXB0b0NvbmZpZ3VyYXRpb24udXNlcl9wd2QpXG5cbiAgICAgICAgaWYoIXRoaXMuY3J5cHRvQ29uZmlndXJhdGlvbi5vd25lcl9wd2RfYylcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiSW52YWxpZCAvTyB2YWx1ZSAob3duZXIgcGFzc3dvcmQpXCIpXG5cbiAgICAgICAgbGV0IG9WYWx1ZSA6IFVpbnQ4QXJyYXkgPSB0aGlzLmNyeXB0b0NvbmZpZ3VyYXRpb24ub3duZXJfcHdkX2NcblxuICAgICAgICBpZiAob1ZhbHVlLmxlbmd0aCAhPT0gMzIpXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihgSW52YWxpZCBsZW5ndGggb2Ygb3duZXIgdmFsdWUuIElzICR7b1ZhbHVlLmxlbmd0aH0gYnV0IG11c3QgYmUgMzIuYClcblxuICAgICAgICBpZiAoIXRoaXMuY3J5cHRvQ29uZmlndXJhdGlvbi5wZXJtaXNzaW9ucylcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiUGVybWlzc2lvbnMgbm90IHNldFwiKVxuXG4gICAgICAgIGxldCBwZXJtaXNzaW9ucyA9IENyeXB0b1V0aWwuY29udmVydE51bWJlclRvTGl0dGxlRW5kaWFuQnl0ZUFycmF5KHRoaXMuY3J5cHRvQ29uZmlndXJhdGlvbi5wZXJtaXNzaW9ucylcblxuICAgICAgICBpZiAoIXRoaXMuZmlsZV9pZCB8fCB0aGlzLmZpbGVfaWQubGVuZ3RoID09PSAwKVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJGaWxlIElEIG5vdCBzZXRcIilcblxuICAgICAgICBsZXQga2V5bGVuZ3RoID0gNDBcbiAgICAgICAgaWYgKHRoaXMuY3J5cHRvQ29uZmlndXJhdGlvbi5sZW5ndGgpXG4gICAgICAgICAgICBrZXlsZW5ndGggPSB0aGlzLmNyeXB0b0NvbmZpZ3VyYXRpb24ubGVuZ3RoXG5cbiAgICAgICAgbGV0IGZpbGVfaWQgOiBVaW50OEFycmF5ID0gdGhpcy5maWxlX2lkWzBdXG5cbiAgICAgICAgbGV0IHN0dWZmID0gbmV3IFVpbnQ4QXJyYXkodXNlcnB3ZC5sZW5ndGggKyBvVmFsdWUubGVuZ3RoICsgcGVybWlzc2lvbnMubGVuZ3RoICsgZmlsZV9pZC5sZW5ndGgpXG4gICAgICAgIHN0dWZmLnNldCh1c2VycHdkLCAwKVxuICAgICAgICBzdHVmZi5zZXQob1ZhbHVlLCB1c2VycHdkLmxlbmd0aClcbiAgICAgICAgc3R1ZmYuc2V0KHBlcm1pc3Npb25zLCB1c2VycHdkLmxlbmd0aCArIG9WYWx1ZS5sZW5ndGgpXG4gICAgICAgIHN0dWZmLnNldChmaWxlX2lkLCB1c2VycHdkLmxlbmd0aCArIG9WYWx1ZS5sZW5ndGggKyBwZXJtaXNzaW9ucy5sZW5ndGgpXG5cbiAgICAgICAgbGV0IGggPSBDcnlwdG9VdGlsLk1ENUFzQnl0ZUFycmF5KHN0dWZmKVxuICAgICAgICBrZXlsZW5ndGggPSBrZXlsZW5ndGggPj4gM1xuXG4gICAgICAgIGlmICh0aGlzLmNyeXB0b0NvbmZpZ3VyYXRpb24ucmV2aXNpb24gJiYgdGhpcy5jcnlwdG9Db25maWd1cmF0aW9uLnJldmlzaW9uID49IDMpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNTA7ICsraSkge1xuICAgICAgICAgICAgICAgIGggPSBDcnlwdG9VdGlsLk1ENUFzQnl0ZUFycmF5KGguc2xpY2UoMCwga2V5bGVuZ3RoKSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnJjNF80MF9iaXQpIHtcbiAgICAgICAgICAgIHRoaXMuZW5jcnlwdGlvbktleSA9IGguc2xpY2UoMCwgNSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZW5jcnlwdGlvbktleSA9IGhcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLmVuY3J5cHRpb25LZXlcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXJpdmVzIHRoZSB1c2VyIHBhc3N3b3JkICgvVSkgdmFsdWVcbiAgICAgKiAqL1xuICAgIGNvbXB1dGVVc2VyUGFzc3dvcmQoKSA6IFVpbnQ4QXJyYXkge1xuICAgICAgICBpZiAodGhpcy5jb21wdXRlZF91c2VyX3Bhc3N3b3JkKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcHV0ZWRfdXNlcl9wYXNzd29yZFxuXG4gICAgICAgIGlmICh0aGlzLmNyeXB0b0NvbmZpZ3VyYXRpb24ucmV2aXNpb24gJiYgdGhpcy5jcnlwdG9Db25maWd1cmF0aW9uLnJldmlzaW9uID49IDMpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbXB1dGVVc2VyUGFzc3dvcmRSZXZpc2lvbjNPckdyZWF0ZXIoKVxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuY3J5cHRvQ29uZmlndXJhdGlvbi5yZXZpc2lvbiA9PT0gMikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcHV0ZVVzZXJQYXNzd29yZFJldmlzaW9uMigpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoW10pXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgdGhlIHVzZXIgcGFzc3dvcmQgZm9yIHNlY3VyaXR5IGhhbmRsZXJzIG9mIHJldmlzaW9uIDJcbiAgICAgKiAqL1xuICAgIGNvbXB1dGVVc2VyUGFzc3dvcmRSZXZpc2lvbjIoKSA6IFVpbnQ4QXJyYXkge1xuICAgICAgICBsZXQgcGFkZGluZ19zdHIgOiBVaW50OEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoQ3J5cHRvVXRpbC5QQURESU5HX1NUUklORylcbiAgICAgICAgbGV0IGVuY19rZXkgPSB0aGlzLmNvbXB1dGVFbmNyeXB0aW9uS2V5KClcblxuICAgICAgICBsZXQgeCA9IENyeXB0b1V0aWwuUkM0KHBhZGRpbmdfc3RyLCBlbmNfa2V5KVxuXG4gICAgICAgIHRoaXMuY29tcHV0ZWRfdXNlcl9wYXNzd29yZCA9IENyeXB0b1V0aWwuY29udmVydFdvcmRBcnJheVRvQnl0ZUFycmF5KHgpXG5cbiAgICAgICAgcmV0dXJuIHRoaXMuY29tcHV0ZWRfdXNlcl9wYXNzd29yZFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVzIHRoZSB1c2VyIHBhc3N3b3JkIGZvciBzZWN1cml0eSBoYW5kbGVycyBvZiByZXZpc2lvbiAzIG9yIGhpZ2hlclxuICAgICAqICovXG4gICAgY29tcHV0ZVVzZXJQYXNzd29yZFJldmlzaW9uM09yR3JlYXRlcigpIDogVWludDhBcnJheSB7XG4gICAgICAgIGlmICghdGhpcy5maWxlX2lkKVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJObyBmaWxlIGlkXCIpXG5cbiAgICAgICAgbGV0IGlkX3N0cl9hcnJheSA6IFVpbnQ4QXJyYXkgPSB0aGlzLmZpbGVfaWRbMF1cblxuICAgICAgICBsZXQgbmV3X3ZhbCA6IFVpbnQ4QXJyYXkgPSBuZXcgVWludDhBcnJheShDcnlwdG9VdGlsLlBBRERJTkdfU1RSSU5HLmxlbmd0aCArIGlkX3N0cl9hcnJheS5sZW5ndGgpXG4gICAgICAgIG5ld192YWwuc2V0KENyeXB0b1V0aWwuUEFERElOR19TVFJJTkcsIDApXG4gICAgICAgIG5ld192YWwuc2V0KGlkX3N0cl9hcnJheSwgQ3J5cHRvVXRpbC5QQURESU5HX1NUUklORy5sZW5ndGgpXG5cbiAgICAgICAgbGV0IHggPSBDcnlwdG9VdGlsLk1ENShuZXdfdmFsKVxuXG4gICAgICAgIGxldCBlbmNfa2V5ID0gdGhpcy5jb21wdXRlRW5jcnlwdGlvbktleSgpXG5cbiAgICAgICAgZm9yKGxldCBpID0gMDsgaSA8IDIwOyArK2kpIHtcbiAgICAgICAgICAgIHggPSBDcnlwdG9VdGlsLlJDNCh4LCBDcnlwdG9VdGlsLnhvckJ5dGVzKGVuY19rZXksIGkpKVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb21wdXRlZF91c2VyX3Bhc3N3b3JkID0gQ3J5cHRvVXRpbC5jb252ZXJ0V29yZEFycmF5VG9CeXRlQXJyYXkoeClcblxuICAgICAgICByZXR1cm4gdGhpcy5jb21wdXRlZF91c2VyX3Bhc3N3b3JkXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVyaXZlcyB0aGUgb3duZXIgcGFzc3dvcmQgKC9PKSB2YWx1ZVxuICAgICAqKi9cbiAgICBjb21wdXRlT3duZXJQYXNzd29yZCgpIDogVWludDhBcnJheSB7XG4gICAgICAgIGlmICh0aGlzLmNvbXB1dGVkX293bmVyX3Bhc3N3b3JkKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcHV0ZWRfb3duZXJfcGFzc3dvcmRcblxuICAgICAgICBsZXQgcHdkX3N0cmluZyA9IHRoaXMuY3J5cHRvQ29uZmlndXJhdGlvbi5vd25lcl9wd2RcblxuICAgICAgICAvLyBpZiBubyBvd25lciBwYXNzd29yZCBpcyBzZXQsIGJ1dCBhIHVzZXIgcGFzc3dvcmQgdXNlIHRoaXNcbiAgICAgICAgaWYgKCF0aGlzLmNyeXB0b0NvbmZpZ3VyYXRpb24ub3duZXJfcHdkIHx8IHRoaXMuY3J5cHRvQ29uZmlndXJhdGlvbi5vd25lcl9wd2QgPT09IFwiXCIpXG4gICAgICAgICAgICBwd2Rfc3RyaW5nID0gdGhpcy5jcnlwdG9Db25maWd1cmF0aW9uLnVzZXJfcHdkXG5cbiAgICAgICAgbGV0IG93bmVycHdkID0gQ3J5cHRvVXRpbC5wYWRQYXNzd29ydFN0cmluZyhwd2Rfc3RyaW5nKVxuXG4gICAgICAgIGxldCBoID0gQ3J5cHRvVXRpbC5NRDUob3duZXJwd2QpXG5cbiAgICAgICAgbGV0IGNvdW50IDogbnVtYmVyID0gMVxuICAgICAgICBpZiAodGhpcy5jcnlwdG9Db25maWd1cmF0aW9uLnJldmlzaW9uICYmIHRoaXMuY3J5cHRvQ29uZmlndXJhdGlvbi5yZXZpc2lvbiA+PSAzKSB7XG4gICAgICAgICAgICBjb3VudCA9IDIwXG5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNTA7ICsraSkge1xuICAgICAgICAgICAgICAgIGggPSBDcnlwdG9VdGlsLk1ENShoKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGxlbmd0aCA9IDEyOFxuXG4gICAgICAgIGlmICh0aGlzLmNyeXB0b0NvbmZpZ3VyYXRpb24ubGVuZ3RoKVxuICAgICAgICAgICAgbGVuZ3RoID0gdGhpcy5jcnlwdG9Db25maWd1cmF0aW9uLmxlbmd0aFxuXG4gICAgICAgIGxldCBlbmNfa2V5ID0gQ3J5cHRvVXRpbC5jb252ZXJ0V29yZEFycmF5VG9CeXRlQXJyYXkoaCkuc2xpY2UoMCwgbGVuZ3RoIC8gOClcblxuICAgICAgICBsZXQgdXNlcnB3ZCA9IENyeXB0b1V0aWwucGFkUGFzc3dvcnRTdHJpbmcodGhpcy5jcnlwdG9Db25maWd1cmF0aW9uLnVzZXJfcHdkKVxuXG5cbiAgICAgICAgbGV0IHggID0gQ3J5cHRvVXRpbC5jb252ZXJ0VG9Xb3JkQXJyYXkodXNlcnB3ZClcblxuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgY291bnQ7ICsraSkge1xuICAgICAgICAgICAgeCA9IENyeXB0b1V0aWwuUkM0KHgsIENyeXB0b1V0aWwueG9yQnl0ZXMoZW5jX2tleSwgaSkpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbXB1dGVkX293bmVyX3Bhc3N3b3JkID0gQ3J5cHRvVXRpbC5jb252ZXJ0V29yZEFycmF5VG9CeXRlQXJyYXkoeClcblxuICAgICAgICByZXR1cm4gdGhpcy5jb21wdXRlZF9vd25lcl9wYXNzd29yZFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgcHJvdmlkZWQgcGFzc3dvcmQgY29ycmVzcG9uZHMgdG8gdGhlIGRlZmluZWQgL1UgdmFsdWVcbiAgICAgKiAqL1xuICAgIGlzVXNlclBhc3N3b3JkQ29ycmVjdCgpIDogYm9vbGVhbiB7XG4gICAgICAgIGxldCB1c2VyX3B3ZCA9IHRoaXMuY29tcHV0ZVVzZXJQYXNzd29yZCgpXG5cbiAgICAgICAgaWYoIXRoaXMuY3J5cHRvQ29uZmlndXJhdGlvbi51c2VyX3B3ZF9jKVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJJbnZhbGlkIC9VIHZhbHVlICh1c2VyIHBhc3N3b3JkKVwiKVxuXG4gICAgICAgIGlmICh0aGlzLmNyeXB0b0NvbmZpZ3VyYXRpb24ucmV2aXNpb24gJiYgdGhpcy5jcnlwdG9Db25maWd1cmF0aW9uLnJldmlzaW9uID49IDMpIHtcbiAgICAgICAgICAgIHJldHVybiBVdGlsLmFyZUFycmF5c0VxdWFsKHVzZXJfcHdkLCB0aGlzLmNyeXB0b0NvbmZpZ3VyYXRpb24udXNlcl9wd2RfYy5zbGljZSgwLDE2KSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBVdGlsLmFyZUFycmF5c0VxdWFsKHVzZXJfcHdkLCB0aGlzLmNyeXB0b0NvbmZpZ3VyYXRpb24udXNlcl9wd2RfYylcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgcHJvdmlkZWQgcGFzc3dvcmQgY29ycmVzcG9uZHMgdG8gdGhlIGRlZmluZWQgL08gdmFsdWVcbiAgICAgKiAqL1xuICAgIGlzT3duZXJQYXNzd29yZENvcnJlY3QoKSA6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgb3duZXJfcHdkID0gdGhpcy5jb21wdXRlT3duZXJQYXNzd29yZCgpXG5cbiAgICAgICAgaWYoIXRoaXMuY3J5cHRvQ29uZmlndXJhdGlvbi5vd25lcl9wd2RfYylcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiSW52YWxpZCAvTyB2YWx1ZSAob3duZXIgcGFzc3dvcmQpXCIpXG5cbiAgICAgICAgcmV0dXJuIFV0aWwuYXJlQXJyYXlzRXF1YWwob3duZXJfcHdkLCB0aGlzLmNyeXB0b0NvbmZpZ3VyYXRpb24ub3duZXJfcHdkX2MpXG4gICAgfVxufVxuIiwiaW1wb3J0IHsgUmVmZXJlbmNlUG9pbnRlciB9IGZyb20gJy4vcGFyc2VyJztcbmltcG9ydCB7IFV0aWwsIEV4dHJhY3Rpb25SZXN1bHQgfSBmcm9tICcuL3V0aWwnO1xuaW1wb3J0IHsgT2JqZWN0VXRpbCB9IGZyb20gJy4vb2JqZWN0LXV0aWwnXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL3N0cmVhbSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgWFJlZiB7XG4gICAgaWQ6IG51bWJlclxuICAgIHBvaW50ZXI6IG51bWJlclxuICAgIGdlbmVyYXRpb246IG51bWJlclxuICAgIGZyZWU6IGJvb2xlYW5cbiAgICB1cGRhdGU6IGJvb2xlYW5cbiAgICBjb21wcmVzc2VkPzogYm9vbGVhblxufVxuXG5pbnRlcmZhY2UgU3ViU2VjdGlvbkhlYWRlciB7XG4gICAgaWQ6IG51bWJlclxuICAgIGNvdW50OiBudW1iZXJcbiAgICBlbmRfcHRyOiBudW1iZXIgLy8gcG9pbnRzIHRvIHRoZSBlbmQgb2YgdGhlIHN1YiBzZWN0aW9uIGhlYWRlclxufVxuXG5pbnRlcmZhY2UgVHJhaWxlciB7XG4gICAgc2l6ZTogbnVtYmVyXG4gICAgcm9vdDogUmVmZXJlbmNlUG9pbnRlclxuICAgIHByZXY/OiBudW1iZXJcbiAgICBpc19lbmNyeXB0ZWQgOiBib29sZWFuIC8vIHRydWUsIGlmIHRoZSBkb2N1bWVudCBpcyBlbnJ5cHRlZCBvdGhlcndpc2UgZmFsc2VcbiAgICBlbmNyeXB0PzogUmVmZXJlbmNlUG9pbnRlciAvLyByZWZlcmVuY2UgdG8gdGhlIGVuY3J5cHRpb24gZGljdGlvbmFyeSBpZiBkb2N1bWVudCBpcyBlbmNyeXB0ZWRcbiAgICBpZD8gOiBVaW50OEFycmF5W10gLy8gZG9jdW1lbnQgaWRcbn1cblxudmFyIGdlbmVyYXRlRGVmYXVsdFRyYWlsZXIgPSAoKSA9PiB7XG4gICAgcmV0dXJuIHsgc2l6ZTogLTEsIHJvb3Q6IHsgb2JqOiAtMSwgZ2VuZXJhdGlvbjogLTEgfSwgaXNfZW5jcnlwdGVkIDogZmFsc2V9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT2JqZWN0TG9va3VwVGFibGUge1xuICAgIFtpZDogbnVtYmVyXTogWFJlZlxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVwZGF0ZVNlY3Rpb24ge1xuICAgIHN0YXJ0X3BvaW50ZXI6IG51bWJlclxuICAgIHNpemU6IG51bWJlclxuICAgIHJlZnM6IFhSZWZbXVxuICAgIHByZXY/OiBudW1iZXJcbiAgICByb290PzogUmVmZXJlbmNlUG9pbnRlclxuICAgIGlzX2VuY3J5cHRlZCA6IGJvb2xlYW4vLyB0cnVlLCBpZiB0aGUgZG9jdW1lbnQgaXMgZW5yeXB0ZWQgb3RoZXJ3aXNlIGZhbHNlXG4gICAgZW5jcnlwdD86IFJlZmVyZW5jZVBvaW50ZXIvLyByZWZlcmVuY2UgdG8gdGhlIGVuY3J5cHRpb24gZGljdGlvbmFyeSBpZiBkb2N1bWVudCBpcyBlbmNyeXB0ZWRcbiAgICBpZD86IFVpbnQ4QXJyYXlbXS8vIGRvY3VtZW50IGlkXG59XG5cbi8qKlxuICogSG9sZHMgdGhlIGNvbXBsZXRlIGluZm9ybWF0aW9uIG9mIG9uZSB1cGRhdGUgc2VjdGlvbiBpbiB0aGUgQ3Jvc3MtUmVmZXJlbmNlLVN0cmVhbSBPYmplY3QgZm9ybWF0LlxuICpcbiAqICovXG5leHBvcnQgY2xhc3MgQ3Jvc3NSZWZlcmVuY2VTdHJlYW1PYmplY3Qge1xuICAgIHB1YmxpYyByZWZzOiBYUmVmW10gPSBbXVxuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBkYXRhOiBVaW50OEFycmF5KSB7IH1cblxuICAgIHB1YmxpYyB0cmFpbGVyOiBUcmFpbGVyID0gZ2VuZXJhdGVEZWZhdWx0VHJhaWxlcigpXG5cbiAgICBwdWJsaWMgc3RyZWFtTGVuZ3RoOiBudW1iZXIgPSAtMVxuXG4gICAgcHVibGljIHc6IG51bWJlcltdID0gW11cbiAgICBwdWJsaWMgaW5kZXg6IG51bWJlcltdID0gW11cbiAgICBwcml2YXRlIHN0YXJ0X3BvaW50ZXI6IG51bWJlciA9IDBcblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3RzIGEgY3Jvc3MgcmVmZXJlbmNlIHNlY3Rpb24gdGhhdCBpcyBhIGNvbnRpbnVvdXMgZGVmaW5pdGlvbiBvZiBjcm9zcyByZWZlcmVuY2UgZW50cmllc1xuICAgICAqICovXG4gICAgZXh0cmFjdENyb3NzUmVmZXJlbmNlU2VjdGlvbihmaXJzdF9vYmplY3RfaWQ6IG51bWJlciwgb2JqZWN0X2NvdW50OiBudW1iZXIsIHN0cmVhbTogU3RyZWFtKSB7XG4gICAgICAgIGxldCBjdXJyZW50X29iamVjdF9pZCA9IGZpcnN0X29iamVjdF9pZFxuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb2JqZWN0X2NvdW50OyArK2kpIHtcbiAgICAgICAgICAgIGxldCBfdHlwZSA9IHN0cmVhbS5nZXROQnl0ZXNBc051bWJlcih0aGlzLndbMF0pXG5cbiAgICAgICAgICAgIGxldCB4cmVmID0gdW5kZWZpbmVkXG5cbiAgICAgICAgICAgIHN3aXRjaCAoX3R5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgICAgIHhyZWYgPSB7IGlkOiBjdXJyZW50X29iamVjdF9pZCsrLCBwb2ludGVyOiBzdHJlYW0uZ2V0TkJ5dGVzQXNOdW1iZXIodGhpcy53WzFdKSwgZ2VuZXJhdGlvbjogdGhpcy53WzJdID09PSAwID8gMCA6IHN0cmVhbS5nZXROQnl0ZXNBc051bWJlcih0aGlzLndbMl0pLCBmcmVlOiB0cnVlLCB1cGRhdGU6IGZhbHNlIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgICAgIHhyZWYgPSB7IGlkOiBjdXJyZW50X29iamVjdF9pZCsrLCBwb2ludGVyOiBzdHJlYW0uZ2V0TkJ5dGVzQXNOdW1iZXIodGhpcy53WzFdKSwgZ2VuZXJhdGlvbjogdGhpcy53WzJdID09PSAwID8gMCA6IHN0cmVhbS5nZXROQnl0ZXNBc051bWJlcih0aGlzLndbMl0pLCBmcmVlOiBmYWxzZSwgdXBkYXRlOiB0cnVlIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgICAgIC8vIGluIHRoaXMgY2FzZSB0aGUgcG9pbnRlciBiZWNvbWVzIHRoZSBzdHJlYW0gb2JqZWN0IGlkIHRoYXQgY29udGFpbnMgdGhlIGNvbXByZXNzZWQgb2JqZWN0IGFuZCB0aGUgZ2VuZXJhdGlvbiByZXByZXNlbnRzIHRoZSBpbmRleCBvZiB0aGUgb2JqZWN0IGluIHRoZSBzdHJlYW1cbiAgICAgICAgICAgICAgICAgICAgeHJlZiA9IHsgaWQ6IGN1cnJlbnRfb2JqZWN0X2lkKyssIHBvaW50ZXI6IHN0cmVhbS5nZXROQnl0ZXNBc051bWJlcih0aGlzLndbMV0pLCBnZW5lcmF0aW9uOiB0aGlzLndbMl0gPT09IDAgPyAwIDogc3RyZWFtLmdldE5CeXRlc0FzTnVtYmVyKHRoaXMud1syXSksIGZyZWU6IHRydWUsIHVwZGF0ZTogZmFsc2UsIGNvbXByZXNzZWQ6IHRydWUgfVxuICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgIGlmICh4cmVmKVxuICAgICAgICAgICAgICAgIHRoaXMucmVmcy5wdXNoKHhyZWYpXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoYEludmFsaWQgY3Jvc3MtcmVmZXJlbmNlLXN0cmVhbSB0eXBlICR7X3R5cGV9YClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3RzIHRoZSBjcm9zcy1yZWZlcmVuY2UtdGFibGUgZnJvbSB0aGUgc3RyZWFtXG4gICAgICogKi9cbiAgICBleHRyYWN0U3RyZWFtKHN0cmVhbTogU3RyZWFtKSB7XG4gICAgICAgIGxldCBjcm9zc19yZWZlcmVuY2VfbGVuZ3RoID0gdGhpcy53LnJlZHVjZSgoYSwgYikgPT4gYSArIGIsIDApXG5cbiAgICAgICAgLy8gY2hlY2sgaWYgdGhlIGRhdGEgc3RyZWFtIGhhcyBhIHZhbGlkIHNpemVcbiAgICAgICAgaWYgKHN0cmVhbS5nZXRMZW5ndGgoKSAhPT0gY3Jvc3NfcmVmZXJlbmNlX2xlbmd0aCAqIHRoaXMuaW5kZXguZmlsdGVyKCh2LCBpKSA9PiBpICUgMiA9PT0gMSkucmVkdWNlKChhLCBiKSA9PiBhICsgYiwgMCkpXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihgSW52YWxpZCBzdHJlYW0gbGVuZ3RoIC0gaXMgJHtzdHJlYW0uZ2V0TGVuZ3RoKCl9IGJ1dCBzaG91bGQgYmUgJHtjcm9zc19yZWZlcmVuY2VfbGVuZ3RoICogdGhpcy5pbmRleC5maWx0ZXIoKHYsIGkpID0+IGkgJSAyID09PSAxKS5yZWR1Y2UoKGEsIGIpID0+IGEgKyBiLCAwKX1gKVxuXG4gICAgICAgIGlmICh0aGlzLmluZGV4Lmxlbmd0aCAlIDIgPT09IDEpXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihgSW52YWxpZCBpbmRleCBmbGFnICR7dGhpcy5pbmRleH1gKVxuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5pbmRleC5sZW5ndGg7IGkgKz0gMikge1xuICAgICAgICAgICAgdGhpcy5leHRyYWN0Q3Jvc3NSZWZlcmVuY2VTZWN0aW9uKHRoaXMuaW5kZXhbaV0sIHRoaXMuaW5kZXhbaSArIDFdLCBzdHJlYW0pXG4gICAgICAgIH1cblxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgQ3Jvc3MtUmVmZXJlbmNlLVN0cmVhbS1PYmplY3QgYXQgdGhlIGdpdmVuIGluZGV4XG4gICAgICogKi9cbiAgICBleHRyYWN0KHhyZWY6IFhSZWYpIHtcbiAgICAgICAgbGV0IGluZGV4ID0geHJlZi5wb2ludGVyXG4gICAgICAgIHRoaXMuc3RhcnRfcG9pbnRlciA9IGluZGV4XG4gICAgICAgIGxldCBjcnNfb2JqZWN0ID0gT2JqZWN0VXRpbC5leHRyYWN0T2JqZWN0KHRoaXMuZGF0YSwgeHJlZilcblxuICAgICAgICBsZXQgcHRyX29iamVjdF9lbmQgPSBVdGlsLmxvY2F0ZVNlcXVlbmNlKFV0aWwuRU5ET0JKLCB0aGlzLmRhdGEsIGluZGV4KVxuICAgICAgICB0aGlzLmRhdGEgPSB0aGlzLmRhdGEuc2xpY2UoaW5kZXgsIHB0cl9vYmplY3RfZW5kKVxuXG4gICAgICAgIC8vIGNoZWNrIHR5cGVcbiAgICAgICAgaWYgKGNyc19vYmplY3QudmFsdWVbXCIvVHlwZVwiXSAhPT0gXCIvWFJlZlwiKVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoYEludmFsaWQgQ3Jvc3MtUmVmZXJlbmNlLVN0cmVhbS1vYmplY3QgdHlwZTogJHtjcnNfb2JqZWN0LnZhbHVlW1wiL1R5cGVcIl19YClcblxuICAgICAgICAvLyBleHRyYWN0IHNpemVcbiAgICAgICAgaWYgKCFjcnNfb2JqZWN0LnZhbHVlW1wiL1NpemVcIl0pXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihgSW52YWxpZCBzaXplIHZhbHVlICR7Y3JzX29iamVjdC52YWx1ZVtcIi9TaXplXCJdfWApXG4gICAgICAgIHRoaXMudHJhaWxlci5zaXplID0gY3JzX29iamVjdC52YWx1ZVtcIi9TaXplXCJdXG5cbiAgICAgICAgLy8gZXh0cmFjdCBST09UIGlmIGl0IGV4aXN0c1xuICAgICAgICBpZiAoY3JzX29iamVjdC52YWx1ZVtcIi9Sb290XCJdKVxuICAgICAgICAgICAgdGhpcy50cmFpbGVyLnJvb3QgPSBjcnNfb2JqZWN0LnZhbHVlW1wiL1Jvb3RcIl1cblxuICAgICAgICAvLyBleHRyYWN0IFBSRVYgaWYgaXQgZXhpc3RzXG4gICAgICAgIGlmIChjcnNfb2JqZWN0LnZhbHVlW1wiL1ByZXZcIl0pXG4gICAgICAgICAgICB0aGlzLnRyYWlsZXIucHJldiA9IGNyc19vYmplY3QudmFsdWVbXCIvUHJldlwiXVxuXG4gICAgICAgIC8vIGV4dHJhY3QgVyBwYXJhbWV0ZXJcbiAgICAgICAgdGhpcy53ID0gY3JzX29iamVjdC52YWx1ZVtcIi9XXCJdXG5cbiAgICAgICAgaWYgKCF0aGlzLncgfHwgMCA9PT0gdGhpcy53Lmxlbmd0aClcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiSW52YWxpZCAvVyBwYXJhbWV0ZXIgaW4gQ3Jvc3MtUmVmZXJlbmNlLVN0cmVhbS1PYmplY3RcIilcblxuICAgICAgICAvLyBleHRyYWN0IEluZGV4IHBhcmFtZXRlclxuICAgICAgICB0aGlzLmluZGV4ID0gY3JzX29iamVjdC52YWx1ZVtcIi9JbmRleFwiXVxuXG4gICAgICAgIGlmICghdGhpcy5pbmRleCB8fCAwID09PSB0aGlzLmluZGV4Lmxlbmd0aClcbiAgICAgICAgICAgIHRoaXMuaW5kZXggPSBbMCwgY3JzX29iamVjdC52YWx1ZVtcIi9TaXplXCJdXVxuXG4gICAgICAgIGlmICghY3JzX29iamVjdC5zdHJlYW0pXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcIk1pc3Npbmcgc3RyZWFtIGF0IGNyb3NzIHJlZmVyZW5jZSBzdHJlYW0gb2JqZWN0XCIpXG5cbiAgICAgICAgbGV0IHN0cmVhbSA9IGNyc19vYmplY3Quc3RyZWFtXG5cbiAgICAgICAgaWYgKCFzdHJlYW0pXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcIkludmFsaWQgc3RyZWFtIG9iamVjdFwiKVxuXG4gICAgICAgIHRoaXMuc3RyZWFtTGVuZ3RoID0gY3JzX29iamVjdC52YWx1ZVtcIi9MZW5ndGhcIl1cblxuICAgICAgICB0aGlzLmV4dHJhY3RTdHJlYW0oc3RyZWFtKVxuXG4gICAgICAgIC8vIHRoZSBjcm9zcy1yZWZlcmVuY2Utc3RyZWFtIG9iamVjdCBpcyBhbHNvIGEga25vd24gcmVmZXJlbmNlXG4gICAgICAgIHRoaXMucmVmcy5wdXNoKHsgaWQ6IGNyc19vYmplY3QuaWQub2JqLCBwb2ludGVyOiB0aGlzLnN0YXJ0X3BvaW50ZXIsIGdlbmVyYXRpb246IGNyc19vYmplY3QuaWQuZ2VuZXJhdGlvbiwgZnJlZTogZmFsc2UsIHVwZGF0ZTogdHJ1ZSB9KVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVycyB0aGUgdXBkYXRlIHNlY3Rpb24gcmVwcmVzZW50aW5nIHRoaXMgQ3Jvc3NSZWZlcmVuY2VTdHJlYW1PYmplY3RcbiAgICAgKiAqL1xuICAgIGdldFVwZGF0ZVNlY3Rpb24oKTogVXBkYXRlU2VjdGlvbiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGFydF9wb2ludGVyOiB0aGlzLnN0YXJ0X3BvaW50ZXIsXG4gICAgICAgICAgICBzaXplOiB0aGlzLnRyYWlsZXIuc2l6ZSxcbiAgICAgICAgICAgIHByZXY6IHRoaXMudHJhaWxlci5wcmV2LFxuICAgICAgICAgICAgcm9vdDogdGhpcy50cmFpbGVyLnJvb3QsXG4gICAgICAgICAgICByZWZzOiB0aGlzLnJlZnMsXG4gICAgICAgICAgICBpc19lbmNyeXB0ZWQ6IHRoaXMudHJhaWxlci5pc19lbmNyeXB0ZWQsXG4gICAgICAgICAgICBlbmNyeXB0OiB0aGlzLnRyYWlsZXIuZW5jcnlwdCxcbiAgICAgICAgICAgIGlkOiB0aGlzLnRyYWlsZXIuaWRcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiBIb2xkcyB0aGUgY29tcGxldGUgaW5mb3JtYXRpb24gb2Ygb25lIHVwZGF0ZSBzZWN0aW9uIGluIHRoZSBDcm9zcy1SZWZlcmVuY2UtVGFibGUgZm9ybWF0LiBUaGF0IGNvbXByaXNlczpcbiAqIC0gdGhlIGJvZHkgdXBkYXRlXG4gKiAtIHRoZSBjcm9zc2lzdGUgcmVmZXJlbmNlIHRhYmxlXG4gKiAtIHRoZSB0cmFpbGVyXG4gKiAqL1xuZXhwb3J0IGNsYXNzIENyb3NzUmVmZXJlbmNlVGFibGUge1xuICAgIHB1YmxpYyByZWZzOiBYUmVmW10gPSBbXVxuXG4gICAgcHVibGljIHN0YXJ0X3BvaW50ZXI6IG51bWJlciA9IC0xXG5cbiAgICBwdWJsaWMgdHJhaWxlcjogVHJhaWxlciA9IGdlbmVyYXRlRGVmYXVsdFRyYWlsZXIoKVxuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBkYXRhOiBVaW50OEFycmF5KSB7IH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHJlZmVyZW5jZSB3aXRoIHRoZSBnaXZlbiBpZFxuICAgICAqICovXG4gICAgZ2V0UmVmZXJlbmNlKGlkOiBudW1iZXIpOiBYUmVmIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgZm9yIChsZXQgcmVmIG9mIHRoaXMucmVmcykge1xuICAgICAgICAgICAgaWYgKHJlZi5pZCA9PT0gaWQpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlZlxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVycyB0aGUgdXBkYXRlIHNlY3Rpb24gcmVwcmVzZW50aW5nIHRoaXMgQ3Jvc3NSZWZlcmVuY2VUYWJsZVxuICAgICAqICovXG4gICAgZ2V0VXBkYXRlU2VjdGlvbigpOiBVcGRhdGVTZWN0aW9uIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0X3BvaW50ZXI6IHRoaXMuc3RhcnRfcG9pbnRlcixcbiAgICAgICAgICAgIHNpemU6IHRoaXMudHJhaWxlci5zaXplLFxuICAgICAgICAgICAgcmVmczogdGhpcy5yZWZzLFxuICAgICAgICAgICAgcHJldjogdGhpcy50cmFpbGVyLnByZXYsXG4gICAgICAgICAgICByb290OiB0aGlzLnRyYWlsZXIucm9vdCxcbiAgICAgICAgICAgIGlzX2VuY3J5cHRlZDogdGhpcy50cmFpbGVyLmlzX2VuY3J5cHRlZCxcbiAgICAgICAgICAgIGVuY3J5cHQ6IHRoaXMudHJhaWxlci5lbmNyeXB0LFxuICAgICAgICAgICAgaWQ6IHRoaXMudHJhaWxlci5pZFxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdHMgdGhlIGhlYWRlciBvZiBhIHN1YiBzZWN0aW9uLiBGb3IgaW5zdGFuY2VcbiAgICAgKlxuICAgICAqIDAgMSAvLyA8LS1cbiAgICAgKiAuLi5cbiAgICAgKlxuICAgICAqIFNvIHRoZSBvYmVqY3QgaWQgMCBhbmQgdGhlIG51bWJlciBvZiBzdWIgc2VjdGlvbiBlbnRyaWVzIDFcbiAgICAgKiAqL1xuICAgIGV4dHJhY3RTdWJTZWN0aW9uSGVhZGVyKGluZGV4OiBudW1iZXIpOiBTdWJTZWN0aW9uSGVhZGVyIHtcbiAgICAgICAgbGV0IHB0ciA9IFV0aWwubG9jYXRlRGVsaW1pdGVyKHRoaXMuZGF0YSwgaW5kZXgpXG5cbiAgICAgICAgbGV0IG9ial9pZCA9IFV0aWwuZXh0cmFjdE51bWJlcih0aGlzLmRhdGEsIGluZGV4LCBwdHIpLnJlc3VsdFxuXG4gICAgICAgIHB0ciA9IFV0aWwuc2tpcERlbGltaXRlcih0aGlzLmRhdGEsIHB0ciArIDEpXG5cbiAgICAgICAgbGV0IHB0cl9yZWZfY291bnQgPSBwdHJcblxuICAgICAgICBwdHIgPSBVdGlsLmxvY2F0ZURlbGltaXRlcih0aGlzLmRhdGEsIHB0cilcblxuICAgICAgICBsZXQgcmVmZXJlbmNlX2NvdW50ID0gVXRpbC5leHRyYWN0TnVtYmVyKHRoaXMuZGF0YSwgcHRyX3JlZl9jb3VudCwgcHRyKS5yZXN1bHRcblxuICAgICAgICByZXR1cm4geyBpZDogb2JqX2lkLCBjb3VudDogcmVmZXJlbmNlX2NvdW50LCBlbmRfcHRyOiBwdHIgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3RzIHRoZSByZWZlcmVuY2VzIG9mIGEgc3ViIHNlY3Rpb24uIFRoZSBpbmRleCBwb2ludHMgdG8gdGhlIHN0YXJ0IG9mXG4gICAgICogdGhlIGZpcnN0IHJlZmVyZW5jZSBhbmQgY291bnQgcmVwcmVzZW50cyB0aGUgbnVtYmVyIG9mIHJlZmVyZW5jZXMgdGhhdCBhcmVcbiAgICAgKiBjb250YWluZWQgaW4gdGhlIHN1YnNlY3Rpb24uXG4gICAgICpcbiAgICAgKiBUaGUgZmlyc3Rfb2JqZWN0X2lkIGlzIHRoZSBpZCBwcm92aWRlZCBpbiB0aGUgc3ViIHNlY3Rpb24gaGVhZGVyXG4gICAgICpcbiAgICAgKiBCeSBkZWZpbml0aW9uIG9mIHRoZSBQREYgc3RhbmRhcmQgb25lIGVudHJ5IGlzIDIwIGJ5dGVzIGxvbmcsIGJ1dCBzaW5jZSB0aGUgc3RhbmRhcmQgaXMgcmFyZWx5IHJlc3BlY3RlZCB3ZSBiZXR0ZXIgbWFrZSBpdCBmYWlsc2FmZVxuICAgICAqICovXG4gICAgZXh0cmFjdFJlZmVyZW5jZXMoaW5kZXg6IG51bWJlciwgY291bnQ6IG51bWJlciwgZmlyc3Rfb2JqZWN0X2lkOiBudW1iZXIpOiB7cmVmczogWFJlZltdLCBlbmRfaW5kZXg6IG51bWJlcn0ge1xuICAgICAgICBsZXQgX3JlZnM6IFhSZWZbXSA9IFtdXG5cbiAgICAgICAgbGV0IHJlcyA6IEV4dHJhY3Rpb25SZXN1bHQgPSB7IHJlc3VsdDogbnVsbCwgc3RhcnRfaW5kZXg6IC0xLCBlbmRfaW5kZXg6IGluZGV4fVxuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBjb3VudCA9PT0gLTEgfHwgaSA8IGNvdW50OyArK2kpIHtcbiAgICAgICAgICAgIHJlcyA9IFV0aWwucmVhZE5leHRXb3JkKHRoaXMuZGF0YSwgcmVzLmVuZF9pbmRleCArIDEpXG5cbiAgICAgICAgICAgIGxldCBwb2ludGVyID0gVXRpbC5leHRyYWN0TnVtYmVyKHJlcy5yZXN1bHQsIDApLnJlc3VsdFxuXG4gICAgICAgICAgICByZXMgPSBVdGlsLnJlYWROZXh0V29yZCh0aGlzLmRhdGEsIHJlcy5lbmRfaW5kZXggKyAxKVxuXG4gICAgICAgICAgICBsZXQgZ2VuZXJhdGlvbiA9IFV0aWwuZXh0cmFjdE51bWJlcihyZXMucmVzdWx0LCAwKS5yZXN1bHRcblxuICAgICAgICAgICAgcmVzID0gVXRpbC5yZWFkTmV4dFdvcmQodGhpcy5kYXRhLCByZXMuZW5kX2luZGV4ICsgMSlcblxuICAgICAgICAgICAgbGV0IHB0cl9mbGFnID0gcmVzLnJlc3VsdFxuXG4gICAgICAgICAgICBsZXQgaXNGcmVlID0gcHRyX2ZsYWdbMF0gPT09IDEwMiAvLyAxMDIgPSBmXG4gICAgICAgICAgICBfcmVmcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBpZDogZmlyc3Rfb2JqZWN0X2lkICsgaSxcbiAgICAgICAgICAgICAgICBwb2ludGVyOiBwb2ludGVyLFxuICAgICAgICAgICAgICAgIGdlbmVyYXRpb246IGdlbmVyYXRpb24sXG4gICAgICAgICAgICAgICAgZnJlZTogaXNGcmVlLFxuICAgICAgICAgICAgICAgIHVwZGF0ZTogIWlzRnJlZVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgLy8gaWYgdGhlIHdvcmQgdHJhaWxlciBvY2N1cnMgc3RvcCBzaW5jZSB3ZSByZWFjaGVkIHRoZSBlbmRcbiAgICAgICAgICAgIGlmICh0aGlzLmRhdGFbVXRpbC5za2lwU3BhY2VzKHRoaXMuZGF0YSwgcmVzLmVuZF9pbmRleCArIDEpXSA9PT0gMTE2KSB7XG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7cmVmczogX3JlZnMsIGVuZF9pbmRleDogcmVzLmVuZF9pbmRleH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeHRyYWN0cyB0aGUgdHJhaWxlciBvZiB0aGUgc3Vic2VjdGlvbiB0aGF0IG1lYW5zIHRoZSBwYXJ0IHN0YXRpbmcgd2l0aCB0aGUgJ3RyYWlsZXInIGtleXdvcmQgYW5kXG4gICAgICogaW4gcGFydGljdWxhciB0aGUgdHJhaWxlciBkaWN0aW9uYXJ5XG4gICAgICogKi9cbiAgICBleHRyYWN0VHJhaWxlcihpbmRleDogbnVtYmVyKTogVHJhaWxlciB7XG4gICAgICAgIC8vIHJ1biBmb3J3YXJkIHRvIHRoZSBkaWN0aW9uYXJ5IHN0YXJ0XG4gICAgICAgIGluZGV4ID0gVXRpbC5sb2NhdGVTZXF1ZW5jZShVdGlsLkRJQ1RfU1RBUlQsIHRoaXMuZGF0YSwgaW5kZXgpICsgMlxuXG4gICAgICAgIGxldCBvYmo6IGFueSA9IHt9XG4gICAgICAgIE9iamVjdFV0aWwuZXh0cmFjdERpY3RLZXlSZWModGhpcy5kYXRhLCBpbmRleCwgb2JqKVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzaXplOiBvYmpbXCIvU2l6ZVwiXSxcbiAgICAgICAgICAgIHJvb3Q6IG9ialtcIi9Sb290XCJdLFxuICAgICAgICAgICAgcHJldjogb2JqW1wiL1ByZXZcIl0gPyBvYmpbXCIvUHJldlwiXSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGlzX2VuY3J5cHRlZDogb2JqW1wiL0VuY3J5cHRcIl0gPyB0cnVlIDogZmFsc2UsXG4gICAgICAgICAgICBlbmNyeXB0OiBvYmpbXCIvRW5jcnlwdFwiXSA/IG9ialtcIi9FbmNyeXB0XCJdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgaWQ6IG9ialtcIi9JRFwiXSA/IG9ialtcIi9JRFwiXSA6IHVuZGVmaW5lZFxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSBDcm9zcyBSZWZlcmVuY2UgVGFibGUgYXQgdGhlIGdpdmVuIGluZGV4XG4gICAgICogKi9cbiAgICBleHRyYWN0KGluZGV4OiBudW1iZXIsIHNraXBYUkVGU3RyaW5nIDogYm9vbGVhbiA9IGZhbHNlKSB7XG4gICAgICAgIHRoaXMuc3RhcnRfcG9pbnRlciA9IGluZGV4XG5cbiAgICAgICAgbGV0IHN0YXJ0X3B0ciA9IGluZGV4XG5cbiAgICAgICAgaWYgKCFza2lwWFJFRlN0cmluZylcbiAgICAgICAgICAgIHN0YXJ0X3B0ciArPSA1IC8vICsgbGVuZ3RoKHhyZWYpICsgYmxhbmtcblxuICAgICAgICBzdGFydF9wdHIgPSBVdGlsLnNraXBEZWxpbWl0ZXIodGhpcy5kYXRhLCBzdGFydF9wdHIpXG5cbiAgICAgICAgLy8gY2hlY2sgaWYgdGhlcmUgYWN0dWFsbHkgaXMgYSBzdWJzZWN0aW9uIGhlYWRlclxuICAgICAgICAvLyBpZiB0aGUgbGluZSBmaW5pc2hlcyB3aXRoIGFuICdmJyB3ZSBrbm93IHRoYXQgaXQgc3RhcnRzIHdpdGggdGhlIGZpcnN0IGNyb3NzIHJlZmVyZW5jZSBlbnRyeVxuICAgICAgICBsZXQgdG1wX3B0ciA9IHN0YXJ0X3B0clxuICAgICAgICB3aGlsZSh0bXBfcHRyIDwgdGhpcy5kYXRhLmxlbmd0aCAmJiB0aGlzLmRhdGFbdG1wX3B0cl0gIT09IDEwMiAmJiB0aGlzLmRhdGFbdG1wX3B0cl0gIT09IDEzICYmIHRoaXMuZGF0YVt0bXBfcHRyXSAhPT0gMTApIHRtcF9wdHIrK1xuXG4gICAgICAgIGxldCBmaXJzdF9oZWFkZXIgPSB7aWQ6IDAsIGNvdW50OiAtMSwgZW5kX3B0cjogc3RhcnRfcHRyIC0gMX1cblxuICAgICAgICBpZiAodGhpcy5kYXRhW3RtcF9wdHJdID09PSAxMCB8fCB0aGlzLmRhdGFbdG1wX3B0cl0gPT09IDEzKVxuICAgICAgICAgICAgZmlyc3RfaGVhZGVyID0gdGhpcy5leHRyYWN0U3ViU2VjdGlvbkhlYWRlcihzdGFydF9wdHIpXG5cbiAgICAgICAgbGV0IHJlZl9zdGFydCA9IFV0aWwuc2tpcERlbGltaXRlcih0aGlzLmRhdGEsIGZpcnN0X2hlYWRlci5lbmRfcHRyICsgMSlcblxuICAgICAgICAvLyBleHRyYWN0IGZpcnN0IHJlZmVyZW5jZVxuICAgICAgICBsZXQgcmVmZXJlbmNlX3Jlc3VsdCA9IHRoaXMuZXh0cmFjdFJlZmVyZW5jZXMocmVmX3N0YXJ0LCBmaXJzdF9oZWFkZXIuY291bnQsIGZpcnN0X2hlYWRlci5pZClcbiAgICAgICAgdGhpcy5yZWZzID0gdGhpcy5yZWZzLmNvbmNhdChyZWZlcmVuY2VfcmVzdWx0LnJlZnMpXG5cbiAgICAgICAgLy8gZXh0cmFjdCByZW1haW5pbmcgcmVmZXJlbmNlc1xuICAgICAgICBzdGFydF9wdHIgPSBVdGlsLnNraXBTcGFjZXModGhpcy5kYXRhLCByZWZlcmVuY2VfcmVzdWx0LmVuZF9pbmRleCArIDEpXG5cbiAgICAgICAgd2hpbGUgKGZpcnN0X2hlYWRlci5jb3VudCA+IDAgJiYgdGhpcy5kYXRhW3N0YXJ0X3B0cl0gIT09IDExNikgeyAvLyAxMTYgPSAndCcgc3RhcnQgb2YgdGhlIHdvcmQgdHJhaWxlciB0aGF0IGNvbmNsdWRlcyB0aGUgY3Jvc3NzaXRlIHJlZmVyZW5jZSBzZWN0aW9uXG4gICAgICAgICAgICBsZXQgaGVhZGVyID0gdGhpcy5leHRyYWN0U3ViU2VjdGlvbkhlYWRlcihzdGFydF9wdHIpXG5cbiAgICAgICAgICAgIHJlZl9zdGFydCA9IFV0aWwuc2tpcERlbGltaXRlcih0aGlzLmRhdGEsIGhlYWRlci5lbmRfcHRyICsgMSlcblxuICAgICAgICAgICAgbGV0IHJlZmVyZW5jZXMgPSB0aGlzLmV4dHJhY3RSZWZlcmVuY2VzKHJlZl9zdGFydCwgaGVhZGVyLmNvdW50LCBoZWFkZXIuaWQpXG5cbiAgICAgICAgICAgIHRoaXMucmVmcyA9IHRoaXMucmVmcy5jb25jYXQocmVmZXJlbmNlcy5yZWZzKVxuXG4gICAgICAgICAgICBzdGFydF9wdHIgPSBVdGlsLnNraXBTcGFjZXModGhpcy5kYXRhLCByZWZlcmVuY2VzLmVuZF9pbmRleCArIDEpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnRyYWlsZXIgPSB0aGlzLmV4dHJhY3RUcmFpbGVyKHN0YXJ0X3B0cilcbiAgICB9XG59XG5cbi8qKlxuICogUmVwcmVzZW50cyB0aGUgY29tcGxldGUgUERGIGRvY3VtZW50IGhpc3RvcnkgYW5kIHRoZXJlZm9yZSBob2xkcyB0aGVcbiAqIHVwZGF0ZWQgYm9keSBwYXJ0cywgdGhlIGNyb3Nzc2l0ZSByZWZlcmVuY2VzIGFuZCB0aGUgZG9jdW1lbnQgdHJhaWxlcnNcbiAqICovXG5leHBvcnQgY2xhc3MgRG9jdW1lbnRIaXN0b3J5IHtcbiAgICBwdWJsaWMgdXBkYXRlczogVXBkYXRlU2VjdGlvbltdID0gW11cblxuICAgIHB1YmxpYyB0cmFpbGVyU2l6ZTogbnVtYmVyID0gLTFcblxuICAgIC8qKlxuICAgICAqIEhvbGRzIG9iamVjdCBpZHMgdGhhdCB3ZXJlIGZvcm1lcmx5IGZyZWVkIGFuZCBhcmUgbm93ICdhbHJlYWR5JyByZXVzZWQuXG4gICAgICogVGhpcyBpcyB1c2VkIHRvIHByZXZlbnQgYSBmcmVlZCBvYmplY3QgYSBzZWNvbmQgdGltZSAqL1xuICAgIHByaXZhdGUgYWxyZWFkeV9yZXVzZWRfaWRzOiBYUmVmW10gPSBbXVxuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBkYXRhOiBVaW50OEFycmF5KSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KGRhdGEpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdHMgdGhlIGNyb3NzIHJlZmVyZW5jZSB0YWJsZSBzdGFydGluZyBhdCB0aGUgZ2l2ZW4gaW5kZXhcbiAgICAgKiAqL1xuICAgIGV4dHJhY3RDcm9zc1JlZmVyZW5jZVRhYmxlKGluZGV4OiBudW1iZXIsIHNraXBYUkVGU3RyaW5nIDogYm9vbGVhbiA9IGZhbHNlKTogQ3Jvc3NSZWZlcmVuY2VUYWJsZSB7XG4gICAgICAgIGxldCBjcnQgPSBuZXcgQ3Jvc3NSZWZlcmVuY2VUYWJsZSh0aGlzLmRhdGEpXG4gICAgICAgIGNydC5leHRyYWN0KGluZGV4LCBza2lwWFJFRlN0cmluZylcblxuICAgICAgICByZXR1cm4gY3J0XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdHMgdGhlIGNyb3NzIHJlZmVyZW5jZSBzdHJlYW0gb2JqZWN0IHN0YXJ0aW5nIGF0IHRoZSBnaXZlbiBpbmRleFxuICAgICAqICovXG4gICAgZXh0cmFjdENyb3NzUmVmZXJlbmNlU3RyZWFtT2JqZWN0KHhyZWY6IFhSZWYpOiBDcm9zc1JlZmVyZW5jZVN0cmVhbU9iamVjdCB7XG4gICAgICAgIGxldCBjcnMgPSBuZXcgQ3Jvc3NSZWZlcmVuY2VTdHJlYW1PYmplY3QodGhpcy5kYXRhKVxuICAgICAgICBjcnMuZXh0cmFjdCh4cmVmKVxuXG4gICAgICAgIHJldHVybiBjcnNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeHRyYWN0cyB0aGUgbGFzdCB1cGRhdGUgc2VjdGlvbiBvZiBhIGRvY3VtZW50ICh0aGF0IG1lYW5zXG4gICAgICogdGhlIG1vc3QgcmVjZW50IHVwZGF0ZSBsb2NhdGluZyBhdCB0aGUgZW5kIG9mIHRoZSBmaWxlKVxuICAgICAqXG4gICAgICogSGFuZGxlcyBtaXNzaW5nIG9yIHdyb25nIHBvaW50ZXJzXG4gICAgICogYW5kIGFsc28gZGVjaWRlcywgd2hldGhlciB0aGUgY3Jvc3MgcmVmZXJlbmNlIHRhYmxlIGlzIHByb3ZpZGVkIGFzIHN0cmVhbSBvYmplY3Qgb3IgcmVndWxhclxuICAgICAqICovXG4gICAgZXh0cmFjdERvY3VtZW50RW50cnkoKToge3BvaW50ZXI6IG51bWJlciwgc2VjdGlvblR5cGU6IHN0cmluZ30ge1xuICAgICAgICBsZXQgcHRyID0gdGhpcy5kYXRhLmxlbmd0aCAtIDFcblxuXG4gICAgICAgIGxldCBwdHJfc3RhcnR4cmVmID0gVXRpbC5sb2NhdGVTZXF1ZW5jZVJldmVyc2VkKFV0aWwuU1RBUlRYUkVGLCB0aGlzLmRhdGEsIHB0ciwgdHJ1ZSkgKyA5XG5cbiAgICAgICAgLy8gaWRlbnRpZnkgY3Jvc3MgcmVmZXJlbmNlIHNlY3Rpb24gdHlwZVxuICAgICAgICBsZXQgc2VjdGlvbl90eXBlIDogc3RyaW5nID0gXCJVTktOT1dOXCJcbiAgICAgICAgbGV0IHByZWNlZGluZ193b3JkX2luZGV4ID0gVXRpbC5za2lwU3BhY2VzUmV2ZXJzZSh0aGlzLmRhdGEsIHB0cl9zdGFydHhyZWYgLSAxMClcblxuICAgICAgICBpZiAoVXRpbC5hcmVBcnJheXNFcXVhbCh0aGlzLmRhdGEuc2xpY2UocHJlY2VkaW5nX3dvcmRfaW5kZXggLSA1LCBwcmVjZWRpbmdfd29yZF9pbmRleCArIDEpLCBVdGlsLkVORE9CSikpIHtcbiAgICAgICAgICAgIHNlY3Rpb25fdHlwZSA9IFwic3RyZWFtXCJcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNlY3Rpb25fdHlwZSA9IFwidHJhaWxlclwiXG4gICAgICAgIH1cblxuICAgICAgICAvLyB0cnkgdG8gbG9jYXRlIGNyb3NzIHJlZmVyZW5jZSB0YWJsZSBtYW51YWxseVxuICAgICAgICBsZXQgbG9jYXRlWFJFRlN0YXJ0TWFudWFsbHkgPSAoKSA9PiB7XG4gICAgICAgICAgICBsZXQgbmV3X3B0ciA9IFV0aWwubG9jYXRlU2VxdWVuY2VSZXZlcnNlZChVdGlsLlhSRUYsIHRoaXMuZGF0YSwgdGhpcy5kYXRhLmxlbmd0aClcbiAgICAgICAgICAgIHNlY3Rpb25fdHlwZSA9IFwidHJhaWxlclwiXG5cbiAgICAgICAgICAgIHdoaWxlIChuZXdfcHRyID4gMCAmJiB0aGlzLmRhdGFbbmV3X3B0ciAtIDFdID09PSAxMTYpIHsvLyAxMTYgPSAndCcgLT4gd2UgYXJlIGxvb2tpbmcgZm9yICd4cmVmJyBub3QgJ3N0YXJ0eHJlZidcbiAgICAgICAgICAgICAgICBuZXdfcHRyID0gVXRpbC5sb2NhdGVTZXF1ZW5jZVJldmVyc2VkKFV0aWwuWFJFRiwgdGhpcy5kYXRhLCBuZXdfcHRyIC0gMSlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG5ld19wdHIgPT09IC0xKSB7IC8vIHRoYW4gd2UgdHJ5IHRvIGlkZW50aWZ5IHRoZSB3b3JkICd0cmFpbGVyJyBhbmQgcnVuIGJhY2t3YXJkcyBhcyBsb25nIGFzIHdlIGZpbmQgYSBzeW1ib2wgdGhhdCBpcyBub3QgYSBudW1iZXIgb3IgJ2YnIG9yICduJyAtIHdoYXQgY291bGQgcG9zc2libHkgZ28gd3JvbmdcbiAgICAgICAgICAgICAgICBzZWN0aW9uX3R5cGUgPSBcInRyYWlsZXJfd2l0aG91dF94cmVmX3N0YXJ0XCJcbiAgICAgICAgICAgICAgICBuZXdfcHRyID0gVXRpbC5sb2NhdGVTZXF1ZW5jZVJldmVyc2VkKFV0aWwuVFJBSUxFUiwgdGhpcy5kYXRhLCB0aGlzLmRhdGEubGVuZ3RoKVxuXG4gICAgICAgICAgICAgICAgaWYgKG5ld19wdHIgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld19wdHItLVxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAobmV3X3B0ciA+IDAgJiYgKFV0aWwuaXNTcGFjZSh0aGlzLmRhdGFbbmV3X3B0cl0pIHx8IFV0aWwuaXNOdW1iZXIodGhpcy5kYXRhW25ld19wdHJdKSB8fCB0aGlzLmRhdGFbbmV3X3B0cl0gPT09IDExMCB8fCAvLzExMCA9ICduJyAxMDIgPSAnZidcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YVtuZXdfcHRyXSA9PT0gMTAyKSkgLS1uZXdfcHRyXG5cbiAgICAgICAgICAgICAgICAgICAgbmV3X3B0ciA9IFV0aWwuc2tpcFNwYWNlcyh0aGlzLmRhdGEsIG5ld19wdHIgKyAxKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHtwb2ludGVyOiBuZXdfcHRyLCBzZWN0aW9uVHlwZTogc2VjdGlvbl90eXBlfVxuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHB0ciA9IFV0aWwuZXh0cmFjdE51bWJlcih0aGlzLmRhdGEsIHB0cl9zdGFydHhyZWYpLnJlc3VsdFxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHJldHVybiBsb2NhdGVYUkVGU3RhcnRNYW51YWxseSgpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAocHRyID4gdGhpcy5kYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGxvY2F0ZVhSRUZTdGFydE1hbnVhbGx5KClcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHN0YXJ0IHNlY3Rpb24gd2l0aCBYUkVGP1xuICAgICAgICBpZiAoc2VjdGlvbl90eXBlICE9PSBcInN0cmVhbVwiICYmICEodGhpcy5kYXRhW3B0cl0gPT09IFV0aWwuWFJFRlswXSAmJiB0aGlzLmRhdGFbcHRyICsgMV0gPT09IFV0aWwuWFJFRlsxXSAmJiB0aGlzLmRhdGFbcHRyICsgMl0gPT09IFV0aWwuWFJFRlsyXSAmJiB0aGlzLmRhdGFbcHRyICsgM10gPT09IFV0aWwuWFJFRlszXSkpIHtcbiAgICAgICAgICAgIHJldHVybiBsb2NhdGVYUkVGU3RhcnRNYW51YWxseSgpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge3BvaW50ZXI6IHB0ciwgc2VjdGlvblR5cGU6IHNlY3Rpb25fdHlwZX1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeHRyYWN0cyB0aGUgZW50aXJlIHVwZGF0ZSBzZWN0aW9uc1xuICAgICAqXG4gICAgICogTmVlZHMgdG8gYWRhcHQgZGVwZW5kaW5nIHdoZXRoZXIgdGhlIGRvY3VtZW50IHVzZXMgYSBjcm9zcy1yZWZlcmVuY2UgdGFibGUgb3IgYSBjcm9zcy1yZWZlcmVuY2Ugc3RyZWFtIG9iamVjdFxuICAgICAqICovXG4gICAgZXh0cmFjdERvY3VtZW50SGlzdG9yeSgpIHtcblxuICAgICAgICBsZXQgZG9jdW1lbnRfZW50cnkgPSB0aGlzLmV4dHJhY3REb2N1bWVudEVudHJ5KClcbiAgICAgICAgbGV0IHB0ciA9IGRvY3VtZW50X2VudHJ5LnBvaW50ZXJcblxuICAgICAgICBpZiAocHRyID09PSAtMSkge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJDb3VsZCBub3QgbG9jYXRlIGRvY3VtZW50IGVudHJ5XCIpXG4gICAgICAgIH1cblxuICAgICAgICBsZXQgeHJlZiA9IHtcbiAgICAgICAgICAgIGlkOiAtMSxcbiAgICAgICAgICAgIHBvaW50ZXI6IHB0cixcbiAgICAgICAgICAgIGdlbmVyYXRpb246IDAsXG4gICAgICAgICAgICBmcmVlOiBmYWxzZSxcbiAgICAgICAgICAgIHVwZGF0ZTogdHJ1ZVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5leHRyYWN0Q3Jvc3NSZWZlcmVuY2VUYWJsZXMoZG9jdW1lbnRfZW50cnksIHhyZWYpXG5cbiAgICAgICAgLy8gYWRhcHQgcG9pbnRlciBpbiBjYXNlIHRoZXJlIGlzIGp1bmsgYmVmb3JlIHRoZSBoZWFkZXJcbiAgICAgICAgbGV0IHBkZl9oZWFkZXJfc3RhcnQgPSBVdGlsLmxvY2F0ZVNlcXVlbmNlKFV0aWwuVkVSU0lPTiwgdGhpcy5kYXRhLCAwKVxuXG4gICAgICAgIGlmIChwZGZfaGVhZGVyX3N0YXJ0ICE9PSAwICYmIHBkZl9oZWFkZXJfc3RhcnQgIT09IC0xKSB7XG4gICAgICAgICAgICBmb3IgKGxldCB1cGRhdGVTZWN0aW9uIG9mIHRoaXMudXBkYXRlcykge1xuICAgICAgICAgICAgICAgIGZvcihsZXQgcmVmIG9mIHVwZGF0ZVNlY3Rpb24ucmVmcykge1xuICAgICAgICAgICAgICAgICAgICByZWYucG9pbnRlciArPSBwZGZfaGVhZGVyX3N0YXJ0XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBFeHRyYWN0cyB0aGUgY3Jvc3MgcmVmZXJlbmNlIHRhYmxlcyBvZiB0aGUgZW50aXJlIGRvY3VtZW50XG4gICAgICogKi9cbiAgICBleHRyYWN0Q3Jvc3NSZWZlcmVuY2VUYWJsZXMoZG9jdW1lbnRfZW50cnkgOiB7cG9pbnRlcjogbnVtYmVyLCBzZWN0aW9uVHlwZTogc3RyaW5nfSwgeHJlZiA6IFhSZWYpIHtcbiAgICAgICAgbGV0IHB0ciA9IGRvY3VtZW50X2VudHJ5LnBvaW50ZXJcblxuICAgICAgICAvLyBIYW5kbGUgY3Jvc3MgcmVmZXJlbmNlIHRhYmxlXG4gICAgICAgIGlmIChkb2N1bWVudF9lbnRyeS5zZWN0aW9uVHlwZSA9PT0gXCJ0cmFpbGVyXCIpIHtcblxuICAgICAgICAgICAgbGV0IGNydCA9IHRoaXMuZXh0cmFjdENyb3NzUmVmZXJlbmNlVGFibGUocHRyKVxuXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZXMucHVzaChjcnQuZ2V0VXBkYXRlU2VjdGlvbigpKVxuXG4gICAgICAgICAgICBsZXQgdXMgPSB0aGlzLnVwZGF0ZXNbMF1cblxuICAgICAgICAgICAgd2hpbGUgKHVzLnByZXYpIHtcbiAgICAgICAgICAgICAgICBjcnQgPSB0aGlzLmV4dHJhY3RDcm9zc1JlZmVyZW5jZVRhYmxlKHVzLnByZXYpXG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVzLnB1c2goY3J0LmdldFVwZGF0ZVNlY3Rpb24oKSlcbiAgICAgICAgICAgICAgICB1cyA9IHRoaXMudXBkYXRlc1t0aGlzLnVwZGF0ZXMubGVuZ3RoIC0gMV1cbiAgICAgICAgICAgIH1cblxuICAgICAgICB9IGVsc2UgaWYgKGRvY3VtZW50X2VudHJ5LnNlY3Rpb25UeXBlID09PSBcInN0cmVhbVwiKSB7IC8vIGhhbmRsZSBjcm9zcyByZWZlcmVuY2Ugc3RyZWFtIG9iamVjdFxuICAgICAgICAgICAgbGV0IGNycyA9IHRoaXMuZXh0cmFjdENyb3NzUmVmZXJlbmNlU3RyZWFtT2JqZWN0KHhyZWYpXG5cbiAgICAgICAgICAgIHRoaXMudXBkYXRlcy5wdXNoKGNycy5nZXRVcGRhdGVTZWN0aW9uKCkpXG5cbiAgICAgICAgICAgIGxldCB1cyA9IHRoaXMudXBkYXRlc1swXVxuXG4gICAgICAgICAgICB3aGlsZSAodXMucHJldikge1xuICAgICAgICAgICAgICAgIGxldCBfeHJlZiA9IHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IC0xLFxuICAgICAgICAgICAgICAgICAgICBwb2ludGVyOiB1cy5wcmV2LFxuICAgICAgICAgICAgICAgICAgICBnZW5lcmF0aW9uOiAwLFxuICAgICAgICAgICAgICAgICAgICBmcmVlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlOiB0cnVlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNycyA9IHRoaXMuZXh0cmFjdENyb3NzUmVmZXJlbmNlU3RyZWFtT2JqZWN0KF94cmVmKVxuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlcy5wdXNoKGNycy5nZXRVcGRhdGVTZWN0aW9uKCkpXG4gICAgICAgICAgICAgICAgdXMgPSB0aGlzLnVwZGF0ZXNbdGhpcy51cGRhdGVzLmxlbmd0aCAtIDFdXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZG9jdW1lbnRfZW50cnkuc2VjdGlvblR5cGUgPT09IFwidHJhaWxlcl93aXRob3V0X3hyZWZfc3RhcnRcIikge1xuICAgICAgICAgICAgbGV0IGNydCA9IHRoaXMuZXh0cmFjdENyb3NzUmVmZXJlbmNlVGFibGUocHRyLCB0cnVlKVxuXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZXMucHVzaChjcnQuZ2V0VXBkYXRlU2VjdGlvbigpKVxuXG4gICAgICAgICAgICBsZXQgdXMgPSB0aGlzLnVwZGF0ZXNbMF1cblxuICAgICAgICAgICAgd2hpbGUgKHVzLnByZXYpIHtcbiAgICAgICAgICAgICAgICBjcnQgPSB0aGlzLmV4dHJhY3RDcm9zc1JlZmVyZW5jZVRhYmxlKHVzLnByZXYpXG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVzLnB1c2goY3J0LmdldFVwZGF0ZVNlY3Rpb24oKSlcbiAgICAgICAgICAgICAgICB1cyA9IHRoaXMudXBkYXRlc1t0aGlzLnVwZGF0ZXMubGVuZ3RoIC0gMV1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiQ291bGQgbm90IHBhcnQgY3Jvc3MgcmVmZXJlbmNlIHRhYmxlXCIpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnRyYWlsZXJTaXplID0gdGhpcy5leHRyYWN0UmVmZXJlbmNlTnVtYmVyQ291bnQoKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvdW50cyB0aGUgbnVtYmVyIG9mIHNwZWNpZmllZCBvYmplY3RzXG4gICAgICogKi9cbiAgICBleHRyYWN0UmVmZXJlbmNlTnVtYmVyQ291bnQoKSA6IG51bWJlciB7XG4gICAgICAgIGxldCB2aXNpdGVkIDogbnVtYmVyW10gPSBbXVxuICAgICAgICBsZXQgY291bnQgPSAwXG4gICAgICAgIGZvcihsZXQgdXBkYXRlIG9mIHRoaXMudXBkYXRlcykge1xuICAgICAgICAgICAgZm9yKGxldCByZWYgb2YgdXBkYXRlLnJlZnMpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXZpc2l0ZWQuaW5jbHVkZXMocmVmLmlkKSkge1xuICAgICAgICAgICAgICAgICAgICBjb3VudCsrXG4gICAgICAgICAgICAgICAgICAgIHZpc2l0ZWQucHVzaChyZWYuaWQpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvdW50XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJpbWFyaWx5IGZvciBjbGFyaWZpY2F0aW9uLiBUaGUgZmlyc3QgZWxlbWVudCBpcyB0aGUgbW9zdCByZWNlbnQuIFdlIHBhcnNlZCBiYWNrd2FyZHMuXG4gICAgICogKi9cbiAgICBnZXRSZWNlbnRVcGRhdGUoKTogVXBkYXRlU2VjdGlvbiB7XG4gICAgICAgIHJldHVybiB0aGlzLnVwZGF0ZXNbMF1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgUERGIGRvY3VtZW50IGlzIGVuY3J5cHRlZFxuICAgICAqICovXG4gICAgaXNFbmNyeXB0ZWQoKSA6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRSZWNlbnRVcGRhdGUoKS5pc19lbmNyeXB0ZWRcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBCeSBydW5uaW5nIHRocm91Z2ggdGhlIFBEZiBoaXN0b3J5IHdlIGNhbiBmb3IgZXZlcnkgb2JqZWN0IGlkIGRldGVybWluZSB0aGUgcG9pbnRlciBhZGRyZXNzIHRvIHRoZSBtb3N0IHJlY2VudCB2ZXJzaW9uLCBhbmRcbiAgICAgKiB3aGV0aGVyIHRoZSBvYmplY3QgaWQgaXMgc3RpbGwgaW4gdXNlZC5cbiAgICAgKlxuICAgICAqIFNvIHRoZSBvYmplY3QgbG9va3VwIHRhYmxlIGhhcyBhbiBlbnRyeSBmb3IgZXZlcnkgZXhpc3Rpbmcgb2JqZWN0IGlkLCBhIHBvaW50ZXIgdG8gdGhlIHRoZSBtb3N0IHJlY2VudCBvYmplY3QgZGVmaW5pdGlvbiwgYXMgbG9uZ1xuICAgICAqIGFzIHRoZSBvYmplY3QgZXhpc3RzLCBvciBhbiBhY2NvcmRpbmcgaW5kaWNhdGlvbiBvdGhlcndpc2UuXG4gICAgICogKi9cbiAgICBjcmVhdGVPYmplY3RMb29rdXBUYWJsZSgpOiBPYmplY3RMb29rdXBUYWJsZSB7XG4gICAgICAgIGxldCBvYmpUYWJsZTogeyBbaWQ6IG51bWJlcl06IFhSZWYgfSA9IHt9XG5cbiAgICAgICAgbGV0IHVwZGF0ZTogVXBkYXRlU2VjdGlvbiA9IHRoaXMuZ2V0UmVjZW50VXBkYXRlKClcblxuICAgICAgICBsZXQgaSA9IDFcbiAgICAgICAgd2hpbGUgKE9iamVjdC5rZXlzKG9ialRhYmxlKS5sZW5ndGggPCB0aGlzLmV4dHJhY3RSZWZlcmVuY2VOdW1iZXJDb3VudCgpKSB7XG4gICAgICAgICAgICBsZXQgcmVmcyA9IHVwZGF0ZS5yZWZzXG5cbiAgICAgICAgICAgIGZvciAobGV0IHJlZiBvZiByZWZzKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFvYmpUYWJsZS5oYXNPd25Qcm9wZXJ0eShyZWYuaWQpKSB7XG4gICAgICAgICAgICAgICAgICAgIG9ialRhYmxlW3JlZi5pZF0gPSByZWZcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHVwZGF0ZSA9IHRoaXMudXBkYXRlc1tpXVxuICAgICAgICAgICAgKytpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gb2JqVGFibGVcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0IGlkLiBJdCBwcmltYXJpbHkgdHJpZXMgdG8gcmV1c2UgYW4gZXhpc3RpbmcgaWQsIGJ1dCBpZiBubyBzdWNoIGV4aXN0cyBpdCB3aWxsIHJldHVybiBhXG4gICAgICogbmV3IG9uZVxuICAgICAqICovXG4gICAgZ2V0RnJlZU9iamVjdElkKCk6IFJlZmVyZW5jZVBvaW50ZXIge1xuICAgICAgICBsZXQgb2JqZWN0TG9va3VwVGFibGU6IE9iamVjdExvb2t1cFRhYmxlID0gdGhpcy5jcmVhdGVPYmplY3RMb29rdXBUYWJsZSgpXG5cbiAgICAgICAgbGV0IGZyZWVfaGVhZGVyID0gb2JqZWN0TG9va3VwVGFibGVbMF1cblxuICAgICAgICBpZiAoIWZyZWVfaGVhZGVyKVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJDcm9zc3NpdGUgcmVmZXJlbmNlIGhhcyBubyBoZWFkZXIgZm9yIHRoZSBsaW5rZWQgbGlzdCBvZiBmcmVlIG9iamVjdHNcIilcblxuICAgICAgICAvLyBpZiB0aGUgcG9pbnRlciBvZiBvYmplY3QgMCBwb2ludHMgdG8gMCB0aGVyZSBpcyBubyBmcmVlZCBvYmplY3QgdGhhdCBjYW4gYmUgcmV1c2VkXG4gICAgICAgIGlmICgwID09PSBmcmVlX2hlYWRlci5wb2ludGVyKSB7XG4gICAgICAgICAgICBpZiAoLTEgPT09IHRoaXMudHJhaWxlclNpemUpXG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJUcmFpbGVyIHNpemUgbm90IHNldFwiKVxuXG4gICAgICAgICAgICByZXR1cm4geyBvYmo6IHRoaXMudHJhaWxlclNpemUrKywgZ2VuZXJhdGlvbjogMCwgcmV1c2VkOiBmYWxzZSB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBnZXQgbGlzdCBoZWFkXG4gICAgICAgIGxldCBwdHIgPSBmcmVlX2hlYWRlci5wb2ludGVyXG4gICAgICAgIGxldCBmcmVlZEhlYWRlckxpc3Q6IFhSZWZbXSA9IFtdXG4gICAgICAgIHdoaWxlIChwdHIgIT09IDApIHtcbiAgICAgICAgICAgIGZyZWVkSGVhZGVyTGlzdC5wdXNoKGZyZWVfaGVhZGVyKVxuICAgICAgICAgICAgZnJlZV9oZWFkZXIgPSBvYmplY3RMb29rdXBUYWJsZVtwdHJdXG5cbiAgICAgICAgICAgIGlmICghZnJlZV9oZWFkZXIuZnJlZSkge1xuICAgICAgICAgICAgICAgIC8vIGhhbmRsZSB0aGUgY2FzZSBvZiBhbiBpbmNvc2lzdGVudCB4cmVmXG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgb2JqOiB0aGlzLnRyYWlsZXJTaXplKyssIGdlbmVyYXRpb246IDAsIHJldXNlZDogZmFsc2UgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwdHIgPSBmcmVlX2hlYWRlci5wb2ludGVyXG4gICAgICAgIH1cblxuICAgICAgICBsZXQgZ2V0RnJlZUhlYWRlciA9IChmcmVlSGVhZGVyTGlzdDogWFJlZltdKSA9PiB7XG4gICAgICAgICAgICBmb3IgKGxldCBwIG9mIGZyZWVIZWFkZXJMaXN0LnJldmVyc2UoKSkge1xuICAgICAgICAgICAgICAgIGlmIChwLmdlbmVyYXRpb24gPCA2NTUzNSAmJiAvLyBtYXggZ2VuZXJhdGlvbiBudW1iZXJcbiAgICAgICAgICAgICAgICAgICAgLTEgPT09IHRoaXMuYWxyZWFkeV9yZXVzZWRfaWRzLmluZGV4T2YocCkpIHsgLy8gbm90IGFscmVhZHkgcmV1c2VkXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgICAgIH1cbiAgICAgICAgbGV0IHJldXNlZF9mcmVlX2hlYWRlciA9IGdldEZyZWVIZWFkZXIoZnJlZWRIZWFkZXJMaXN0KVxuXG4gICAgICAgIGlmIChyZXVzZWRfZnJlZV9oZWFkZXIpIHtcbiAgICAgICAgICAgIGZyZWVfaGVhZGVyID0gcmV1c2VkX2ZyZWVfaGVhZGVyXG5cbiAgICAgICAgICAgIC8vIHN0b3JlIHVzZWQgaWQgdG8gbWFrZSBzdXJlIGl0IHdpbGwgbm90IGJlIHNlbGVjdGVkIGFnYWluXG4gICAgICAgICAgICB0aGlzLmFscmVhZHlfcmV1c2VkX2lkcy5wdXNoKGZyZWVfaGVhZGVyKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gaGFuZGxlIHRoZSBjYXNlIHRoYXQgYWxsIGZyZWVkIG9iamVjdCBpZHMgYXJlIGFscmVhZHkgcmV1c2VkXG4gICAgICAgICAgICByZXR1cm4geyBvYmo6IHRoaXMudHJhaWxlclNpemUrKywgZ2VuZXJhdGlvbjogMCwgcmV1c2VkOiBmYWxzZSB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4geyBvYmo6IGZyZWVfaGVhZGVyLnBvaW50ZXIsIGdlbmVyYXRpb246IG9iamVjdExvb2t1cFRhYmxlW2ZyZWVfaGVhZGVyLmlkXS5nZW5lcmF0aW9uLCByZXVzZWQ6IHRydWUgfVxuICAgIH1cbn1cbiIsImV4cG9ydCB7IFBERkRvY3VtZW50UGFyc2VyIH0gZnJvbSAnLi9wYXJzZXInO1xuZXhwb3J0IHsgTGluZUVuZGluZ1N0eWxlIH0gZnJvbSAnLi9hbm5vdGF0aW9ucy9hbm5vdGF0aW9uX3R5cGVzJztcbmV4cG9ydCB7IEFubm90YXRpb25JY29uLCBBbm5vdGF0aW9uU3RhdGUsIEFubm90YXRpb25TdGF0ZU1vZGVsIH0gZnJvbSAnLi9hbm5vdGF0aW9ucy90ZXh0X2Fubm90YXRpb24nO1xuZXhwb3J0IHsgVGV4dEp1c3RpZmljYXRpb24sIEZyZWVUZXh0VHlwZSB9IGZyb20gJy4vYW5ub3RhdGlvbnMvZnJlZXRleHRfYW5ub3RhdGlvbic7XG5leHBvcnQgeyBVdGlsIH0gZnJvbSAnLi91dGlsJztcbmV4cG9ydCB7IEFubm90YXRpb25GYWN0b3J5IH0gZnJvbSAnLi9hbm5vdGF0aW9uJztcblxuIiwiaW1wb3J0IHsgVXRpbCB9IGZyb20gJy4vdXRpbCc7XG5pbXBvcnQgeyBBcnJheVV0aWwgfSBmcm9tICcuL2FycmF5LXV0aWwnXG5pbXBvcnQgeyBTdHJlYW0sIEZsYXRlU3RyZWFtLCBEZWNvZGVQYXJhbWV0ZXJzIH0gZnJvbSAnLi9zdHJlYW0nO1xuaW1wb3J0IHsgT2JqZWN0TG9va3VwVGFibGUsIFhSZWYgfSBmcm9tICcuL2RvY3VtZW50LWhpc3RvcnknO1xuXG5pbnRlcmZhY2UgU3RyZWFtT2JqZWN0TG9va3VwVGFibGUge1xuICAgIFtpZDogbnVtYmVyXTogbnVtYmVyXG59XG5cbi8qKlxuICogV2hpbGUgdGhlIGdlbmVyYWwgVXRpbCBjbGFzcyBob2xkcyBsb3cgbGV2ZWwgbWV0aG9kcyB0byBuYXZpZ2F0ZSB0aHJvdWdoIHRoZSBwZGYgZGF0YSwgdGhlIE9iamVjdFV0aWxcbiAqIGlzIHB1cnBvc2VmdWxseSBidWlsZCB0byBleHRyYWN0IGNvbXBsZXRlIG9iamVjdHMuIEl0IHJldHVybnMgdGhvc2UgYXMganNvbiBkaWN0aW9uYXJpZXMuXG4gKiAqL1xuZXhwb3J0IGNsYXNzIE9iamVjdFV0aWwge1xuXG4gICAgcHVibGljIHN0YXRpYyBleHRyYWN0RGljdEtleVJlYyhkYXRhOiBVaW50OEFycmF5LCBwdHI6IG51bWJlciwgZGljdDogYW55KTogbnVtYmVyIHtcbiAgICAgICAgbGV0IG5leHQgPSBVdGlsLnJlYWROZXh0V29yZChkYXRhLCBwdHIpXG4gICAgICAgIGxldCBuZXh0X3N0cmluZzogVWludDhBcnJheSB8IHVuZGVmaW5lZCA9IG5leHQucmVzdWx0XG5cbiAgICAgICAgaWYgKCFuZXh0X3N0cmluZylcbiAgICAgICAgICAgIHJldHVybiBwdHJcblxuICAgICAgICBsZXQgX3B0ciA9IFV0aWwuc2tpcERlbGltaXRlcihuZXh0X3N0cmluZywgMClcblxuICAgICAgICBpZiAobmV4dF9zdHJpbmdbMF0gJiYgVXRpbC5ESUNUX0VORFswXSA9PT0gbmV4dF9zdHJpbmdbMF0pIHtcbiAgICAgICAgICAgIGxldCB3b3JkTG9va3VwID0gVXRpbC5yZWFkTmV4dFdvcmQoZGF0YSwgbmV4dC5lbmRfaW5kZXggKyAxKVxuICAgICAgICAgICAgaWYgKHdvcmRMb29rdXAucmVzdWx0ICYmIFV0aWwuRElDVF9FTkRbMF0gPT09IHdvcmRMb29rdXAucmVzdWx0WzBdKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHdvcmRMb29rdXAuZW5kX2luZGV4XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gT2JqZWN0VXRpbC5leHRyYWN0RGljdFZhbHVlUmVjKGRhdGEsIG5leHQuZW5kX2luZGV4ICsgMSwgZGljdCwgVXRpbC5jb252ZXJ0QXNjaWlUb1N0cmluZyhuZXh0X3N0cmluZykpXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgaTogbnVtYmVyID0gMFxuXG4gICAgcHVibGljIHN0YXRpYyBleHRyYWN0RGljdFZhbHVlUmVjKGRhdGE6IFVpbnQ4QXJyYXksIHB0cjogbnVtYmVyLCBkaWN0OiBhbnksIGN1cnJlbnRfa2V5OiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQpOiBudW1iZXIge1xuICAgICAgICBsZXQgbmV4dCA9IFV0aWwucmVhZE5leHRXb3JkKGRhdGEsIHB0cilcbiAgICAgICAgbGV0IG5leHRfc3RyaW5nOiBVaW50OEFycmF5ID0gbmV4dC5yZXN1bHQgfHwgbmV3IFVpbnQ4QXJyYXkoW10pXG4gICAgICAgIHB0ciA9IG5leHQuZW5kX2luZGV4IC0gbmV4dF9zdHJpbmcubGVuZ3RoICsgMVxuXG4gICAgICAgIGlmIChuZXh0X3N0cmluZ1swXSA9PT0gVXRpbC5BUlJBWV9TVEFSVFswXSkge1xuICAgICAgICAgICAgaWYgKCFjdXJyZW50X2tleSlcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihcIkludmFsaWQgYW5vbnltb3VzIGFycmF5IGRlZmluaXRpb25cIilcbiAgICAgICAgICAgIC8vIGhhbmRsZSBhcnJheVxuICAgICAgICAgICAgbGV0IGV4dHJhY3RlZF9hcnJheSA9IEFycmF5VXRpbC5leHRyYWN0QXJyYXkoZGF0YSwgcHRyKVxuICAgICAgICAgICAgZGljdFtjdXJyZW50X2tleV0gPSBleHRyYWN0ZWRfYXJyYXkucmVzdWx0XG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0VXRpbC5leHRyYWN0RGljdEtleVJlYyhkYXRhLCBleHRyYWN0ZWRfYXJyYXkuZW5kX2luZGV4ICsgMSwgZGljdClcbiAgICAgICAgfSBlbHNlIGlmIChuZXh0X3N0cmluZ1swXSA9PT0gVXRpbC5ESUNUX1NUQVJUWzBdICYmIGRhdGFbbmV4dC5lbmRfaW5kZXggKyAxXSA9PT0gVXRpbC5ESUNUX1NUQVJUWzBdKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudF9rZXkpIHtcbiAgICAgICAgICAgICAgICBsZXQgc3VwX2RpY3QgPSB7fVxuICAgICAgICAgICAgICAgIGxldCBlbmRfc3ViX2RpY3QgPSBPYmplY3RVdGlsLmV4dHJhY3REaWN0S2V5UmVjKGRhdGEsIG5leHQuZW5kX2luZGV4ICsgMiwgc3VwX2RpY3QpXG4gICAgICAgICAgICAgICAgZGljdFtjdXJyZW50X2tleV0gPSBzdXBfZGljdFxuICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3RVdGlsLmV4dHJhY3REaWN0S2V5UmVjKGRhdGEsIGVuZF9zdWJfZGljdCArIDEsIGRpY3QpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3RVdGlsLmV4dHJhY3REaWN0S2V5UmVjKGRhdGEsIG5leHQuZW5kX2luZGV4ICsgMiwgZGljdClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChuZXh0X3N0cmluZ1swXSA9PT0gVXRpbC5IRVhfU1RSSU5HX1NUQVJUWzBdKSB7XG4gICAgICAgICAgICBpZiAoIWN1cnJlbnRfa2V5KVxuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFwiSW52YWxpZCBhbm9ueW1vdXMgc3RyaW5nIGRlZmluaXRpb25cIilcbiAgICAgICAgICAgIGxldCBleHRyYWN0ZWRfc3RyaW5nID0gVXRpbC5leHRyYWN0SGV4U3RyaW5nKGRhdGEsIHB0cilcbiAgICAgICAgICAgIGRpY3RbY3VycmVudF9rZXldID0gZXh0cmFjdGVkX3N0cmluZy5yZXN1bHRcbiAgICAgICAgICAgIHJldHVybiBPYmplY3RVdGlsLmV4dHJhY3REaWN0S2V5UmVjKGRhdGEsIGV4dHJhY3RlZF9zdHJpbmcuZW5kX2luZGV4ICsgMSwgZGljdClcbiAgICAgICAgfSBlbHNlIGlmIChuZXh0X3N0cmluZ1swXSA9PT0gVXRpbC5MSVRFUkFMX1NUUklOR19TVEFSVFswXSkge1xuICAgICAgICAgICAgaWYgKCFjdXJyZW50X2tleSlcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihcIkludmFsaWQgYW5vbnltb3VzIHN0cmluZyBkZWZpbml0aW9uXCIpXG4gICAgICAgICAgICBsZXQgZXh0cmFjdGVkX3N0cmluZyA9IFV0aWwuZXh0cmFjdFN0cmluZyhkYXRhLCBwdHIpXG4gICAgICAgICAgICBkaWN0W2N1cnJlbnRfa2V5XSA9IGV4dHJhY3RlZF9zdHJpbmcucmVzdWx0XG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0VXRpbC5leHRyYWN0RGljdEtleVJlYyhkYXRhLCBleHRyYWN0ZWRfc3RyaW5nLmVuZF9pbmRleCArIDEsIGRpY3QpXG4gICAgICAgIH0gZWxzZSBpZiAobmV4dF9zdHJpbmdbMF0gPT09IDQ3KSB7IC8vIC9cbiAgICAgICAgICAgIGlmICghY3VycmVudF9rZXkpXG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJJbnZhbGlkIGFub255bW91cyBwcm9wZXJ0eSBkZWZpbml0aW9uXCIpXG4gICAgICAgICAgICBsZXQgb3B0X3ZhbHVlID0gVXRpbC5leHRyYWN0T3B0aW9uVmFsdWUoZGF0YSwgcHRyKVxuICAgICAgICAgICAgZGljdFtjdXJyZW50X2tleV0gPSBcIi9cIiArIG9wdF92YWx1ZS5yZXN1bHRcbiAgICAgICAgICAgIHJldHVybiBPYmplY3RVdGlsLmV4dHJhY3REaWN0S2V5UmVjKGRhdGEsIG9wdF92YWx1ZS5lbmRfaW5kZXggKyAxLCBkaWN0KVxuICAgICAgICB9IGVsc2UgeyAvLyBJdCBpcyBhIG51bWJlciwgYnV0IHRoaXMgbnVtYmVyIG1pZ2h0IGJlIHBhcnQgb2YgYSBSZWZlcmVuY2VcbiAgICAgICAgICAgIGxldCBsb29rdXBOZXh0ID0gVXRpbC5yZWFkTmV4dFdvcmQoZGF0YSwgbmV4dC5lbmRfaW5kZXggKyAxKVxuICAgICAgICAgICAgbGV0IGxvb2t1cE5leHRXb3JkID0gbG9va3VwTmV4dC5yZXN1bHQgfHwgbmV3IFVpbnQ4QXJyYXkoW10pXG5cbiAgICAgICAgICAgIGlmICghY3VycmVudF9rZXkpXG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJJbnZhbGlkIGFub255bW91cyByZWZlcmVuY2UvbnVtYmVyIGRlZmluaXRpb25cIilcblxuICAgICAgICAgICAgbGV0IHZhbHVlX2VuZF9wdHIgPSBuZXh0LmVuZF9pbmRleCArIDFcblxuICAgICAgICAgICAgaWYgKGxvb2t1cE5leHRXb3JkWzBdID09PSA0NyB8fCBsb29rdXBOZXh0V29yZFswXSA9PT0gVXRpbC5ESUNUX0VORFswXSkgeyAvLyBpcyBhIG51bWJlclxuICAgICAgICAgICAgICAgIGRpY3RbY3VycmVudF9rZXldID0gVXRpbC5leHRyYWN0TnVtYmVyKGRhdGEsIHB0cikucmVzdWx0XG4gICAgICAgICAgICB9IGVsc2UgeyAvLyBpcyBhIHJlcmVmZXJlbmNlXG4gICAgICAgICAgICAgICAgbGV0IGV4dHJhY3RlZF9yZWZlcmVuY2UgPSBVdGlsLmV4dHJhY3RSZWZlcmVuY2VUeXBlZChkYXRhLCBwdHIpXG4gICAgICAgICAgICAgICAgZGljdFtjdXJyZW50X2tleV0gPSBleHRyYWN0ZWRfcmVmZXJlbmNlLnJlc3VsdFxuICAgICAgICAgICAgICAgIHZhbHVlX2VuZF9wdHIgPSBleHRyYWN0ZWRfcmVmZXJlbmNlLmVuZF9pbmRleCArIDFcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGhhbmRsZSBSZWZlcmVuY2VcbiAgICAgICAgICAgIHJldHVybiBPYmplY3RVdGlsLmV4dHJhY3REaWN0S2V5UmVjKGRhdGEsIHZhbHVlX2VuZF9wdHIsIGRpY3QpXG4gICAgICAgIH1cblxuICAgICAgICB0aHJvdyBFcnJvcihgQ291bGQgbm90IGludGVycHJldDogJHtVdGlsLmNvbnZlcnRBc2NpaVRvU3RyaW5nKG5leHRfc3RyaW5nKX1gKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExvY2F0ZXMgdGhlIG9iamVjdCBzdGFydCBpbiBjYXNlIHRoZSBwdHIgZG9lcyBub3QgcG9pbnQgY29ycmVjdGx5XG4gICAgICogKi9cbiAgICBwdWJsaWMgc3RhdGljIGxvY2F0ZU9iamVjdFN0YXJ0KGRhdGEgOiBVaW50OEFycmF5LCBwdHIgOiBudW1iZXIpIDogbnVtYmVyIHtcbiAgICAgICAgbGV0IG9ial9wdHIgOiBudW1iZXIgPSBVdGlsLmxvY2F0ZVNlcXVlbmNlKFV0aWwuT0JKLCBkYXRhLCBwdHIpXG4gICAgICAgIGxldCBlbmRvYmpfcHRyIDogbnVtYmVyID0gVXRpbC5sb2NhdGVTZXF1ZW5jZShVdGlsLkVORE9CSiwgZGF0YSwgcHRyKVxuXG4gICAgICAgIGxldCBjb25zdW1lR2VuZXJhdGlvbkFuZE51bWJlclJldmVyZSA9IChwdHIgOiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIC8vIDxpZD4gPGdlbmVyYXRpb24+IG9iaiAuLi4gZW5kb2JqXG4gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICBeXG4gICAgICAgICAgICAvLyBiZWluZyBzb21ld2hlcmUgaGVyZVxuICAgICAgICAgICAgbGV0IG5ld19wdHIgPSBVdGlsLnNraXBTcGFjZXNSZXZlcnNlKGRhdGEsIHB0ciAtIDEpXG4gICAgICAgICAgICAvLyA8aWQ+IDxnZW5lcmF0aW9uPiBvYmogLi4uIGVuZG9ialxuICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgIF5cbiAgICAgICAgICAgIC8vIGJlaW5nIHNvbWV3aGVyZSBoZXJlXG4gICAgICAgICAgICB3aGlsZShuZXdfcHRyID4gMCAmJiAhVXRpbC5pc0RlbGltaXRlcihkYXRhW25ld19wdHJdKSktLW5ld19wdHJcbiAgICAgICAgICAgIC8vIDxpZD4gPGdlbmVyYXRpb24+IG9iaiAuLi4gZW5kb2JqXG4gICAgICAgICAgICAvLyAgICAgIF5cbiAgICAgICAgICAgIC8vIGJlaW5nIHNvbWV3aGVyZSBoZXJlXG4gICAgICAgICAgICBuZXdfcHRyID0gVXRpbC5za2lwU3BhY2VzUmV2ZXJzZShkYXRhLCBuZXdfcHRyIC0gMSlcbiAgICAgICAgICAgIC8vIDxpZD4gPGdlbmVyYXRpb24+IG9iaiAuLi4gZW5kb2JqXG4gICAgICAgICAgICAvLyBeXG4gICAgICAgICAgICAvLyBiZWluZyBzb21ld2hlcmUgaGVyZVxuICAgICAgICAgICAgd2hpbGUobmV3X3B0ciA+IDAgJiYgIVV0aWwuaXNEZWxpbWl0ZXIoZGF0YVtuZXdfcHRyXSkpLS1uZXdfcHRyXG5cbiAgICAgICAgICAgIHJldHVybiBuZXdfcHRyXG4gICAgICAgIH1cblxuICAgICAgICBpZiAob2JqX3B0ciAhPT0gLTEgJiYgb2JqX3B0ciA8IGVuZG9ial9wdHIpIHtcbiAgICAgICAgICAgIHJldHVybiBjb25zdW1lR2VuZXJhdGlvbkFuZE51bWJlclJldmVyZShvYmpfcHRyKVxuICAgICAgICB9IGVsc2UgaWYgKG9ial9wdHIgPiBlbmRvYmpfcHRyIHx8IChvYmpfcHRyID09PSAtMSAmJiBlbmRvYmpfcHRyID4gLTEpKSB7XG4gICAgICAgICAgICAvLyA8aWQ+IDxnZW5lcmF0aW9uPiBvYmogLi4uIGVuZG9ialxuICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICBeXG4gICAgICAgICAgICAvLyBiZWluZyBzb21ld2hlcmUgaGVyZVxuICAgICAgICAgICAgbGV0IG5ld19wdHIgPSBVdGlsLmxvY2F0ZVNlcXVlbmNlUmV2ZXJzZWQoVXRpbC5PQkosIGRhdGEsIHB0cilcbiAgICAgICAgICAgIHJldHVybiBjb25zdW1lR2VuZXJhdGlvbkFuZE51bWJlclJldmVyZShuZXdfcHRyKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJDb3VsZCBub3QgY29ycmVjdCBvYmplY3Qgc3RhcnRcIilcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyBhIFBERiBvYmplY3QgYW5kIHJldHVybnMgYSBkaWN0aW9uYXJ5IGNvbnRhaW5pbmcgaXRzIGZpZWxkc1xuICAgICAqICovXG4gICAgcHVibGljIHN0YXRpYyBleHRyYWN0T2JqZWN0KGRhdGE6IFVpbnQ4QXJyYXksIHhyZWY6IFhSZWYgfCBudW1iZXIsIG9iamVjdExvb2t1cFRhYmxlOiBPYmplY3RMb29rdXBUYWJsZSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZCk6IGFueSB7XG4gICAgICAgIGlmICh0eXBlb2YgeHJlZiAhPT0gJ251bWJlcicgJiYgeHJlZi5jb21wcmVzc2VkKSB7XG4gICAgICAgICAgICBpZiAoIW9iamVjdExvb2t1cFRhYmxlKVxuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFwiUHJvdmlkZSBPYmplY3RMb29rdXBUYWJsZSB0byBleHRyYWN0IHN0cmVhbSBvYmplY3RcIilcblxuICAgICAgICAgICAgcmV0dXJuIE9iamVjdFV0aWwuZXh0cmFjdFN0cmVhbU9iamVjdChkYXRhLCB4cmVmLmlkLCB4cmVmLmdlbmVyYXRpb24sIG9iamVjdExvb2t1cFRhYmxlW3hyZWYucG9pbnRlcl0pXG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcmV0X29iajogYW55ID0ge31cbiAgICAgICAgbGV0IHB0ciA9IHR5cGVvZiB4cmVmID09PSAnbnVtYmVyJyA/IHhyZWYgOiB4cmVmLnBvaW50ZXJcblxuICAgICAgICBsZXQgb2JqZWN0X2lkID0gVXRpbC5leHRyYWN0T2JqZWN0SWQoZGF0YSwgcHRyKVxuXG4gICAgICAgIGlmKGlzTmFOKG9iamVjdF9pZC5vYmopIHx8IGlzTmFOKG9iamVjdF9pZC5nZW5lcmF0aW9uKSkge1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdFV0aWwuZXh0cmFjdE9iamVjdChkYXRhLCBPYmplY3RVdGlsLmxvY2F0ZU9iamVjdFN0YXJ0KGRhdGEsIHB0ciksIG9iamVjdExvb2t1cFRhYmxlKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0X29iai5pZCA9IG9iamVjdF9pZFxuXG4gICAgICAgIHB0ciA9IFV0aWwubG9jYXRlU2VxdWVuY2UoVXRpbC5PQkosIGRhdGEsIHB0cilcblxuICAgICAgICBpZiAocHRyID09PSAtMSlcbiAgICAgICAgICAgIHRocm93IHsgbWVzc2FnZTogXCJPYmplY3QgbWlzc2luZyAnb2JqJyBzZXF1ZW5jZVwiLCBuYW1lOiBcIk1pc3NpbmdPYmpTZXF1ZW5jZUVycm9yXCJ9XG5cbiAgICAgICAgcHRyICs9IFV0aWwuT0JKLmxlbmd0aFxuXG4gICAgICAgIGxldCBwdHJfb2JqX2VuZCA9IFV0aWwubG9jYXRlU2VxdWVuY2UoVXRpbC5FTkRPQkosIGRhdGEsIHB0cilcblxuICAgICAgICBkYXRhID0gZGF0YS5zbGljZShwdHIsIHB0cl9vYmpfZW5kKVxuXG4gICAgICAgIC8vIGRldGVybWluZSB0aGUgdHlwZSBvZiB0aGUgb2JqZWN0OlxuICAgICAgICBsZXQgbmV4dCA9IFV0aWwucmVhZE5leHRXb3JkKGRhdGEsIDApXG5cbiAgICAgICAgaWYgKG5leHQucmVzdWx0ICYmIG5leHQucmVzdWx0WzBdID09PSBVdGlsLkRJQ1RfU1RBUlRbMF0pIHsgLy8gb2JqZWN0IGNvbnRhaW5zIGEgZGljdFxuICAgICAgICAgICAgbGV0IHJlc3VsdF9kaWN0ID0ge31cbiAgICAgICAgICAgIE9iamVjdFV0aWwuZXh0cmFjdERpY3RWYWx1ZVJlYyhkYXRhLCAwLCByZXN1bHRfZGljdClcbiAgICAgICAgICAgIHJldF9vYmoudmFsdWUgPSByZXN1bHRfZGljdFxuICAgICAgICB9IGVsc2UgaWYgKG5leHQucmVzdWx0ICYmIG5leHQucmVzdWx0WzBdID09PSBVdGlsLkFSUkFZX1NUQVJUWzBdKSB7IC8vIG9iamVjdCBjb250YWlucyBhbiBhcnJheVxuICAgICAgICAgICAgbGV0IGxzdCA9IEFycmF5VXRpbC5leHRyYWN0QXJyYXkoZGF0YSwgMClcbiAgICAgICAgICAgIHJldF9vYmoudmFsdWUgPSBsc3QucmVzdWx0XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcihgSW52YWxpZCBvYmplY3QgdHlwZSAtIHN0YXJ0aW5nIHdpdGg6ICR7bmV4dC5yZXN1bHR9YClcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNoZWNrIGlmIHRoZSBvYmplY3QgaGFzIGEgc3RyZWFtIHBhcnRcbiAgICAgICAgcHRyID0gVXRpbC5sb2NhdGVTZXF1ZW5jZShVdGlsLlNUUkVBTSwgZGF0YSwgMClcblxuICAgICAgICBpZiAoLTEgIT09IHB0cikge1xuICAgICAgICAgICAgLy8gZXh0cmFjdCBzdHJlYW0gcGFydFxuICAgICAgICAgICAgbGV0IHB0cl9zdHJlYW1fZGF0YV9zdGFydCA9IHB0ciArIFV0aWwuU1RSRUFNLmxlbmd0aFxuICAgICAgICAgICAgcHRyX3N0cmVhbV9kYXRhX3N0YXJ0ID0gVXRpbC5za2lwRGVsaW1pdGVyKGRhdGEsIHB0cl9zdHJlYW1fZGF0YV9zdGFydClcblxuICAgICAgICAgICAgbGV0IHB0cl9zdHJlYW1fZGF0YV9lbmQgPSBwdHJfc3RyZWFtX2RhdGFfc3RhcnQgKyByZXRfb2JqLnZhbHVlW1wiL0xlbmd0aFwiXVxuXG4gICAgICAgICAgICByZXRfb2JqLnN0cmVhbSA9IE9iamVjdFV0aWwuZXh0cmFjdFN0cmVhbURhdGEoZGF0YS5zbGljZShwdHJfc3RyZWFtX2RhdGFfc3RhcnQsIHB0cl9zdHJlYW1fZGF0YV9lbmQpLCByZXRfb2JqLnZhbHVlW1wiL0ZpbHRlclwiXSwgT2JqZWN0VXRpbC50cmFuc2xhdGVEZWNvZGVQYXJhbXMocmV0X29iaikpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmV0X29ialxuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGV4dHJhY3RTdHJlYW1PYmplY3QoZGF0YTogVWludDhBcnJheSwgb2JqZWN0X2lkX3RvX2V4dHJhY3Q6IG51bWJlciwgb2Zmc2V0OiBudW1iZXIsIHN0cmVhbU9ial94cmVmOiBYUmVmKTogYW55IHtcbiAgICAgICAgbGV0IHB0ciA9IHN0cmVhbU9ial94cmVmLnBvaW50ZXJcbiAgICAgICAgbGV0IHJldF9vYmo6IGFueSA9IHt9XG4gICAgICAgIC8vIGV4dHJhY3Qgb2JqZWN0IGlkXG4gICAgICAgIGxldCBvYmplY3RfaWQ6IGFueSA9IFV0aWwuZXh0cmFjdE9iamVjdElkKGRhdGEsIHB0cilcbiAgICAgICAgcmV0X29iai5pZCA9IG9iamVjdF9pZFxuXG4gICAgICAgIHB0ciA9IFV0aWwubG9jYXRlU2VxdWVuY2UoVXRpbC5PQkosIGRhdGEsIHB0cikgKyBVdGlsLk9CSi5sZW5ndGhcbiAgICAgICAgbGV0IHB0cl9vYmpfZW5kID0gVXRpbC5sb2NhdGVTZXF1ZW5jZShVdGlsLkVORE9CSiwgZGF0YSwgcHRyKVxuXG4gICAgICAgIGRhdGEgPSBkYXRhLnNsaWNlKHB0ciwgcHRyX29ial9lbmQpXG5cbiAgICAgICAgLy8gZXh0cmFjdCBkaWN0IHBhcnRcbiAgICAgICAgbGV0IG5leHQgPSBVdGlsLnJlYWROZXh0V29yZChkYXRhLCAwKVxuXG4gICAgICAgIGlmICghbmV4dC5yZXN1bHQgfHwgbmV4dC5yZXN1bHRbMF0gIT09IFV0aWwuRElDVF9TVEFSVFswXSkge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJJbnZhbGlkIHN0cmVhbSBvYmplY3QgLS0gbm8gZGljdFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHJlc3VsdF9kaWN0OiBhbnkgPSB7fVxuICAgICAgICBPYmplY3RVdGlsLmV4dHJhY3REaWN0VmFsdWVSZWMoZGF0YSwgMCwgcmVzdWx0X2RpY3QpXG4gICAgICAgIHJldF9vYmoudmFsdWUgPSByZXN1bHRfZGljdFxuXG4gICAgICAgIGlmIChyZXN1bHRfZGljdFtcIi9GaWx0ZXJcIl0gJiYgQXJyYXkuaXNBcnJheShyZXN1bHRfZGljdFtcIi9GaWx0ZXJcIl0pICYmICByZXN1bHRfZGljdFtcIi9GaWx0ZXJcIl0ubGVuZ3RoID4gMClcbiAgICAgICAgICAgIHJlc3VsdF9kaWN0W1wiL0ZpbHRlclwiXSA9IHJlc3VsdF9kaWN0W1wiL0ZpbHRlclwiXVswXVxuXG4gICAgICAgIC8vIGNoZWNrIGlmIGZpbHRlciBpcyBzdXBwb3J0ZWRcbiAgICAgICAgaWYgKCFyZXN1bHRfZGljdFtcIi9GaWx0ZXJcIl0gfHwgcmVzdWx0X2RpY3RbXCIvRmlsdGVyXCJdICE9PSBcIi9GbGF0ZURlY29kZVwiKVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoYFVuc3VwcG9ydGVkIHN0cmVhbSBmaWx0ZXI6ICR7cmVzdWx0X2RpY3RbXCIvRmlsdGVyXCJdfSAtIE9ubHkgc3VwcG9ydGVkIGZpbHRlciBpcyBGbGF0ZURlY29kZWApXG5cbiAgICAgICAgaWYgKCFyZXN1bHRfZGljdFtcIi9UeXBlXCJdIHx8IHJlc3VsdF9kaWN0W1wiL1R5cGVcIl0gIT09IFwiL09ialN0bVwiKVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoYEludmFsaWQgc3RyZWFtIG9iamVjdCB0eXBlOiAke3Jlc3VsdF9kaWN0W1wiL1R5cGVcIl19YClcblxuICAgICAgICAvLyBleHRyYWN0IHRoZSBzdHJlYW0gbGVuZ3RoXG4gICAgICAgIGxldCBzdHJlYW1MZW5ndGggPSByZXN1bHRfZGljdFtcIi9MZW5ndGhcIl1cblxuICAgICAgICAvLyBleHRyYWN0IHN0cmVhbSBwYXJ0XG4gICAgICAgIGxldCBwdHJfc3RyZWFtX2RhdGFfc3RhcnQgPSBVdGlsLmxvY2F0ZVNlcXVlbmNlKFV0aWwuU1RSRUFNLCBkYXRhKSArIFV0aWwuU1RSRUFNLmxlbmd0aFxuICAgICAgICBwdHJfc3RyZWFtX2RhdGFfc3RhcnQgPSBVdGlsLnNraXBEZWxpbWl0ZXIoZGF0YSwgcHRyX3N0cmVhbV9kYXRhX3N0YXJ0KVxuXG4gICAgICAgIGxldCBwdHJfc3RyZWFtX2RhdGFfZW5kID0gcHRyX3N0cmVhbV9kYXRhX3N0YXJ0ICsgc3RyZWFtTGVuZ3RoXG5cbiAgICAgICAgbGV0IHN0cmVhbSA9IE9iamVjdFV0aWwuZXh0cmFjdFN0cmVhbURhdGEoZGF0YS5zbGljZShwdHJfc3RyZWFtX2RhdGFfc3RhcnQsIHB0cl9zdHJlYW1fZGF0YV9lbmQpLCByZXN1bHRfZGljdFtcIi9GaWx0ZXJcIl0sIE9iamVjdFV0aWwudHJhbnNsYXRlRGVjb2RlUGFyYW1zKHJlc3VsdF9kaWN0KSlcblxuICAgICAgICBpZiAoIXJlc3VsdF9kaWN0W1wiL05cIl0pXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcIkludmFsaWQgc3RyZWFtIG9iamVjdCAtLSBubyBudW1iZXIgb2Ygb2JqZWN0cyBzcGVjaWZpZWRcIilcblxuICAgICAgICBpZiAoIXJlc3VsdF9kaWN0W1wiL0ZpcnN0XCJdKVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJJbnZhbGlkIHN0cmVhbSBvYmplY3QgLS0gbm8gb2Zmc2V0IHRvIHRoZSBmaXJzdCBvYmpjdCBzcGVjaWZpZWRcIilcblxuICAgICAgICBsZXQgc3RyZWFtUmVmZXJlbmNlczogU3RyZWFtT2JqZWN0TG9va3VwVGFibGUgPSBPYmplY3RVdGlsLmV4dHJhY3RTdHJlYW1PYmplY3RUYWJsZShzdHJlYW0sIHJlc3VsdF9kaWN0W1wiL05cIl0sIHJlc3VsdF9kaWN0W1wiL0ZpcnN0XCJdKVxuXG4gICAgICAgIGlmICghc3RyZWFtUmVmZXJlbmNlc1tvYmplY3RfaWRfdG9fZXh0cmFjdF0pXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihgT2JqZWN0ICR7b2JqZWN0X2lkX3RvX2V4dHJhY3R9IG5vdCBpbiBzdHJlYW0gb2JqZWN0YClcblxuICAgICAgICBsZXQgcmVzdWx0X29iajogYW55ID0geyBpZDogeyBvYmo6IG9iamVjdF9pZF90b19leHRyYWN0LCBnZW5lcmF0aW9uOiAwIH0gfVxuXG4gICAgICAgIGxldCBzdHJlYW1fZGF0YSA6IFVpbnQ4QXJyYXkgPSBzdHJlYW0uZ2V0RGF0YSgpXG5cbiAgICAgICAgbmV4dCA9IFV0aWwucmVhZE5leHRXb3JkKHN0cmVhbV9kYXRhLCBzdHJlYW1SZWZlcmVuY2VzW29iamVjdF9pZF90b19leHRyYWN0XSlcblxuICAgICAgICBpZiAobmV4dC5yZXN1bHQgJiYgbmV4dC5yZXN1bHRbMF0gPT09IFV0aWwuRElDVF9TVEFSVFswXSkgeyAvLyBvYmplY3QgY29udGFpbnMgYSBkaWN0XG4gICAgICAgICAgICBsZXQgdmFsdWUgPSB7fVxuICAgICAgICAgICAgcmVzdWx0X29iai5wb2ludGVyX3N0cmVhbV9lbmQgPSBPYmplY3RVdGlsLmV4dHJhY3REaWN0VmFsdWVSZWMoc3RyZWFtX2RhdGEsIHN0cmVhbVJlZmVyZW5jZXNbb2JqZWN0X2lkX3RvX2V4dHJhY3RdLCB2YWx1ZSlcbiAgICAgICAgICAgIHJlc3VsdF9vYmoudmFsdWUgPSB2YWx1ZVxuICAgICAgICAgICAgcmVzdWx0X29iai5zdHJlYW0gPSBzdHJlYW1cbiAgICAgICAgICAgIHJlc3VsdF9vYmoucG9pbnRlcl9zdHJlYW1fc3RhcnQgPSBzdHJlYW1SZWZlcmVuY2VzW29iamVjdF9pZF90b19leHRyYWN0XVxuICAgICAgICB9IGVsc2UgaWYgKG5leHQucmVzdWx0ICYmIG5leHQucmVzdWx0WzBdID09PSBVdGlsLkFSUkFZX1NUQVJUWzBdKSB7IC8vIG9iamVjdCBjb250YWlucyBhbiBhcnJheVxuICAgICAgICAgICAgbGV0IGxzdCA9IEFycmF5VXRpbC5leHRyYWN0QXJyYXkoc3RyZWFtX2RhdGEsIHN0cmVhbVJlZmVyZW5jZXNbb2JqZWN0X2lkX3RvX2V4dHJhY3RdKVxuICAgICAgICAgICAgcmVzdWx0X29iai52YWx1ZSA9IGxzdC5yZXN1bHRcbiAgICAgICAgICAgIHJlc3VsdF9vYmouc3RyZWFtID0gc3RyZWFtXG4gICAgICAgICAgICByZXN1bHRfb2JqLnBvaW50ZXJfc3RyZWFtX3N0YXJ0ID0gc3RyZWFtUmVmZXJlbmNlc1tvYmplY3RfaWRfdG9fZXh0cmFjdF1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKGBJbnZhbGlkIHN0cmVhbSBvYmplY3QgdHlwZSAtIHN0YXJ0aW5nIHdpdGg6ICR7bmV4dC5yZXN1bHR9YClcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXN1bHRfb2JqXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgdHJhbnNsYXRlRGVjb2RlUGFyYW1zKGRpY3Q6IGFueSk6IERlY29kZVBhcmFtZXRlcnMgfCB1bmRlZmluZWQge1xuICAgICAgICBpZiAoIWRpY3QudmFsdWUpXG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG5cbiAgICAgICAgaWYgKCFkaWN0LnZhbHVlW1wiL0RlY29kZVBhcm1zXCJdKVxuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuXG4gICAgICAgIGlmICghZGljdC52YWx1ZVtcIi9EZWNvZGVQYXJtc1wiXVtcIi9Db2x1bW5zXCJdKVxuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuXG4gICAgICAgIGlmICghZGljdC52YWx1ZVtcIi9EZWNvZGVQYXJtc1wiXVtcIi9QcmVkaWN0b3JcIl0pXG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG5cbiAgICAgICAgcmV0dXJuIHsgY29sdW1uczogZGljdC52YWx1ZVtcIi9EZWNvZGVQYXJtc1wiXVtcIi9Db2x1bW5zXCJdLCBwcmVkaWN0b3I6IGRpY3QudmFsdWVbXCIvRGVjb2RlUGFybXNcIl1bXCIvUHJlZGljdG9yXCJdIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBleHRyYWN0U3RyZWFtT2JqZWN0VGFibGUoc3RyZWFtOiBTdHJlYW0sIG51bWJlcl9vZl9vYmo6IG51bWJlciwgb2Zmc2V0X2ZpcnN0X29iajogbnVtYmVyKTogU3RyZWFtT2JqZWN0TG9va3VwVGFibGUge1xuICAgICAgICBsZXQgcmVmZXJlbmNlczogU3RyZWFtT2JqZWN0TG9va3VwVGFibGUgPSB7fVxuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyX29mX29iajsgKytpKSB7XG4gICAgICAgICAgICBsZXQgb2JqX2lkID0gc3RyZWFtLmdldE51bWJlcigpXG4gICAgICAgICAgICBsZXQgcG9pbnRlciA9IHN0cmVhbS5nZXROdW1iZXIoKSArIG9mZnNldF9maXJzdF9vYmpcblxuICAgICAgICAgICAgcmVmZXJlbmNlc1tvYmpfaWRdID0gcG9pbnRlclxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlZmVyZW5jZXNcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBleHRyYWN0U3RyZWFtRGF0YShzdHJlYW1EYXRhOiBVaW50OEFycmF5LCBjb21wcmVzc2lvbjogc3RyaW5nLCBkZWNvZGVQYXJhbWV0ZXJzOiBEZWNvZGVQYXJhbWV0ZXJzIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkKTogU3RyZWFtIHtcbiAgICAgICAgbGV0IHN0cmVhbTogU3RyZWFtIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkXG4gICAgICAgIGlmIChjb21wcmVzc2lvbiA9PT0gJy9GbGF0ZURlY29kZScpIHtcbiAgICAgICAgICAgIHN0cmVhbSA9IG5ldyBGbGF0ZVN0cmVhbShzdHJlYW1EYXRhLCBkZWNvZGVQYXJhbWV0ZXJzKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoYFVuc3VwcG9ydGVkIHN0cmVhbSBmaWx0ZXI6ICR7Y29tcHJlc3Npb259IC0gT25seSBzdXBwb3J0ZWQgZmlsdGVyIGlzIEZsYXRlRGVjb2RlIChyaWdodCBub3cpYClcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghc3RyZWFtKVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJDb3VsZCBub3QgZGVyaXZlIHN0cmVhbVwiKVxuXG4gICAgICAgIHJldHVybiBzdHJlYW1cbiAgICB9XG59XG4iLCJpbXBvcnQgeyBVdGlsLCBQREZWZXJzaW9uIH0gZnJvbSAnLi91dGlsJztcbmltcG9ydCB7IE9iamVjdFV0aWwgfSBmcm9tICcuL29iamVjdC11dGlsJztcbmltcG9ydCB7IERvY3VtZW50SGlzdG9yeSwgT2JqZWN0TG9va3VwVGFibGUsIFhSZWYgfSBmcm9tICcuL2RvY3VtZW50LWhpc3RvcnknO1xuaW1wb3J0IHsgQ3J5cHRvRW5naW5lLCBJZGVudGl0eUVuZ2luZSwgQ3J5cHRvQ29uZmlndXJhdGlvbiwgUkM0Q3J5cHRvRW5naW5lLCBSQzRfNDBfQklUfSBmcm9tICcuL2NyeXB0byc7XG5pbXBvcnQgeyBBbm5vdGF0aW9uRmxhZ3MsIEJvcmRlciwgQ29sb3IgfSBmcm9tICcuL2Fubm90YXRpb25zL2Fubm90YXRpb25fdHlwZXMnO1xuaW1wb3J0IHsgVGV4dEFubm90YXRpb25PYmogfSBmcm9tICcuL2Fubm90YXRpb25zL3RleHRfYW5ub3RhdGlvbic7XG5pbXBvcnQgeyBIaWdobGlnaHRBbm5vdGF0aW9uT2JqIH0gZnJvbSAnLi9hbm5vdGF0aW9ucy90ZXh0X21hcmt1cF9hbm5vdGF0aW9uJztcbmltcG9ydCB7IEZyZWVUZXh0QW5ub3RhdGlvbk9iaiB9IGZyb20gJy4vYW5ub3RhdGlvbnMvZnJlZXRleHRfYW5ub3RhdGlvbic7XG5pbXBvcnQgeyBTcXVhcmVBbm5vdGF0aW9uT2JqLCBDaXJjbGVBbm5vdGF0aW9uT2JqIH0gZnJvbSAnLi9hbm5vdGF0aW9ucy9jaXJjbGVfc3F1YXJlX2Fubm90YXRpb24nO1xuaW1wb3J0IHsgUG9seWdvbkFubm90YXRpb25PYmosIFBvbHlMaW5lQW5ub3RhdGlvbk9iaiB9IGZyb20gJy4vYW5ub3RhdGlvbnMvcG9seWdvbl9wb2x5bGluZV9hbm5vdGF0aW9uJztcbmltcG9ydCB7IElua0Fubm90YXRpb25PYmogfSBmcm9tICcuL2Fubm90YXRpb25zL2lua19hbm5vdGF0aW9uJztcblxuLyoqXG4gKiBOb3RlIHRoYXQgdGhpcyBwYXJzZXIgZG9lcyBub3QgcGFyc2VzIHRoZSBQREYgZmlsZSBjb21wbGV0ZWx5LiBJdCBsb29rdXBzIHRob3NlXG4gKiBwYXJ0cyB0aGF0IGFyZSBpbXBvcnRhbnQgZm9yIHRoZSBjcmVhdGlvbiBvZiBhbm5vdGF0aW9ucy4gRm9yIG1vcmUgaW5mb3JtYXRpb25cbiAqIHBsZWFzZSByZWFkIHRoZSBSRUFETUUuXG4gKiAqL1xuXG5cbi8qKlxuICogUmVmZXJlbmNlcyBpbiBQREYgZG9jdW1lbnMgYXJlICBvZiB0aGUgZm9ybVxuICogPG9ial9pZD4gPGdlbmVyYXRpb24+IFJcbiAqXG4gKiBUaGlzIGhvbGRzIHN1Y2ggYSByZWZlcmVuY2VcbiAqICovXG5leHBvcnQgaW50ZXJmYWNlIFJlZmVyZW5jZVBvaW50ZXIge1xuICAgIG9iajogbnVtYmVyXG4gICAgZ2VuZXJhdGlvbjogbnVtYmVyXG4gICAgcmV1c2VkPzogYm9vbGVhbiB8IHVuZGVmaW5lZFxufVxuXG5leHBvcnQgdHlwZSBBbm5vdGF0aW9uID0gX0Fubm90YXRpb24gfCBUZXh0QW5ub3RhdGlvbk9iaiB8IEhpZ2hsaWdodEFubm90YXRpb25PYmogfCBGcmVlVGV4dEFubm90YXRpb25PYmogfCBTcXVhcmVBbm5vdGF0aW9uT2JqIHwgQ2lyY2xlQW5ub3RhdGlvbk9iaiB8IFBvbHlnb25Bbm5vdGF0aW9uT2JqIHwgUG9seUxpbmVBbm5vdGF0aW9uT2JqIHwgSW5rQW5ub3RhdGlvbk9ialxuXG5leHBvcnQgY2xhc3MgX0Fubm90YXRpb24ge1xuICAgIHBhZ2U6IG51bWJlciA9IC0xLy8gdGhlIHRhcmdldCBwYWdlIG9mIHRoZSBhbm5vdGF0aW9uXG4gICAgdHlwZTogc3RyaW5nID0gXCJcIi8vIHRoZSBzdWIgdHlwZSBvZiB0aGUgYXJyYXkgKFRleHQsIEhpZ2hsaWdodCwgLi4uKVxuICAgIG9iamVjdF9pZDogUmVmZXJlbmNlUG9pbnRlciB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZC8vIGFuIHVudXNlZCBvYmplY3QgaWRcbiAgICBpZDogc3RyaW5nID0gXCJcIi8vIHVuaXF1ZSBhbm5hdGlvbiBpZGVudGlmaWVyXG4gICAgcmVjdDogbnVtYmVyW10gPSBbXS8vIHRoZSBsb2NhdGlvbiBvZiB0aGUgYW5ub3RhdGlvblxuICAgIGF1dGhvcjogc3RyaW5nID0gXCJcIi8vIHRoZSBhdXRob3Igb2YgdGhlIGFubm90YXRpb25cbiAgICBwYWdlUmVmZXJlbmNlOiBQYWdlIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkLy8gVGhlIHJlZmVyZW5jZSB0byB0aGUgcGFnZSBvYmplY3QgdG8gd2hpY2ggdGhlIGFubm90YXRpb24gaXMgYWRkZWRcbiAgICB1cGRhdGVEYXRlOiBzdHJpbmcgPSBcIlwiLy8gVGhlIGRhdGUgd2hlbiB0aGUgYW5ub3RhdGlvbiB3YXMgY3JlYXRlZCBvciB1cGRhdGVkXG4gICAgY29udGVudHM/OiBzdHJpbmcgLy8gVGV4dCB0aGF0IHNoYWxsIGJlIGRpc3BsYXllZCBmb3IgdGhlIGFubm90YXRpb25cbiAgICBhbm5vdGF0aW9uRmxhZ3M/OiBBbm5vdGF0aW9uRmxhZ3MvLyBTZWUgUERGIHNwY2VjaWZpY2F0aW9uICdBbm5vdGF0aW9uIEZsYWcnXG4gICAgYXBwZWFyYW5jZV9kaWN0aW9uYXJ5PzogYW55IC8vIGNvbnRyb2wgdGhlIGFwcGVhcmFuY2Ugb2YgdGhlIGFubm90YXRpb25cbiAgICBhcHBlYXJhbmNlX3N0YXRlPzogYW55IC8vIGNoYW5nZSB0aGUgYXBwZWFyYW5jZSBhY2NvcmRpbmcgdG8gc3RhdGVzXG4gICAgYm9yZGVyPzogQm9yZGVyIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkLy8gZGVmaW5lIHRoZSBib3JkZXJcbiAgICBjb2xvcj86IENvbG9yIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkLy8gdGhlIGNvbG9yIHNldFxuICAgIGZpbGw/OiBDb2xvciB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZC8vIHRoZSBmaWxsIGNvbG9yIHNldFxuICAgIG9wYWNpdHk/OiBudW1iZXIgLy8gdGhlIG9wYWNpdHkgdmFsdWUgKENBIGNhbGxlZCBpbiB0aGUgUERGIHNwZWMpXG4gICAgcmljaHRleHQ/OiBzdHJpbmcgLy8gcmljaCB0ZXh0IHN0cmluZyBkaXNwbGF5ZWQgaW4gdGhlIHBvcHVwIHdpbmRvdyB3aGVuIHRoZSBhbm5vdGF0aW9uIGlzIG9wZW5lZFxuICAgIGluaXRpYWxseU9wZW4/OiBib29sZWFuIC8vIGZsYWcgdG8gZGVzY3JpYmUgd2hldGhlciB0aGUgYW5ub3RhdGlvbiBzaGFsbCBpbml0aWFsbHkgYmUgb3BlblxuICAgIGljb25OYW1lPzogc3RyaW5nIC8vIG5hbWUgb2YgdGhlIHVzZWQgaWNvblxuICAgIGFubm90YXRpb25TdGF0ZT86IHN0cmluZyAvLyB0aGUgc3RhdGUgb2YgdGhlIGFubm90YXRpb25cbiAgICBzdGF0ZU1vZGVsPzogc3RyaW5nXG4gICAgZGVmYXVsdEFwcGVhcmFuY2U/OiBzdHJpbmcgLy8gZGVmYXVsdCBhcHBlYXJhbmNlIHN0cmluZ1xuICAgIHRleHRBbGlnbm1lbnQ/OiBzdHJpbmcgLy8gbGVmdC1qdXN0aWZpZWQsIGNlbnRlcmVkLCByaWdodC1qdXN0aWZpZWRcbiAgICByaWNoVGV4dFN0cmluZz86IHN0cmluZyAvLyBnZW5lcmF0ZXMgdGhlIGFwcGVhcmFuY2Ugb2YgdGhlIGFubm90YXRpb25cbiAgICBjYWxsb3V0TGluZT86IG51bWJlcltdIC8vIGNhbGwgb3V0IGxpbmVcbiAgICBpbnRlbnQ/OiBzdHJpbmcgLy8gYSBzdHJpbmcgZGVzY3JpYmluZyB0aGUgaW50ZW50OiBGcmVlVGV4dCwgRnJlZVRleHRDYWxsb3V0LCBGcmVlVGV4dFR5cGVXcml0ZXJcbiAgICBib3JkZXJFZmZlY3Q/OiBhbnlcbiAgICByZD86IGFueSAvLyA/XG4gICAgYm9yZGVyU3R5bGU/OiBhbnkgLy8gYm9yZGVyIHN0eWxlXG4gICAgbGluZUVuZGluZz86IHN0cmluZyAvLyB0aGUgbGluZSBlbmRpbmcgdHlwZSBvZiB0aGUgY2FsbG91dCBsaW5lXG4gICAgc3RhbXBUeXBlPzogc3RyaW5nIC8vIHRoZSBuYW1lIG9mIHRoZSB1c2VkIHN0YW1wIHR5cGUuIENhbiBiZTogW0FwcHJvdmVkLCBFeHBlcmltZW50YWwsIE5vdEFwcHJvdmVkLCBBc0lzLCBFeHBpcmVkLCBOb3RGb3JQdWJsaWNSZWxlYXNlLCBDb25maWRlbnRpYWwsIEZpbmFsLCBTb2xkLCBEZXBhcnRtZW50YWwsIEZvckNvbW1lbnQsIFRvcFNlY3JldCwgRHJhZnQsIEZvclB1YmxpY1JlbGVhc2VdXG4gICAgY2FyZXRTeW1ib2w/OiBzdHJpbmcgLy8gQ2FuIGJlIFAgdG8gdXNlIGEgcGFyYWdyYXBoIHN5bWJvbCBmb3IgdGhlIGNhcmV0IG9yIE5vbmVcbiAgICBxdWFkUG9pbnRzPzogbnVtYmVyW10gLy8gc3BlY2lmaWVzIGhvdyB0aGUgYW5ub3RhdGlvbiBnb2VzIGFycm91bmQgdGhlIHRleHRcbiAgICBpbmtMaXN0PzogbnVtYmVyW11bXVxuICAgIGJvcmRlcl9zdHlsZT86IGFueVxuICAgIGNvbG9yX3NwYWNlPzogbnVtYmVyW11cbiAgICBib3JkZXJfZWZmZWN0PzogYW55XG4gICAgdmVydGljZXM/OiBudW1iZXJbXVxuICAgIGxpbmVfZW5kaW5nPzogc3RyaW5nW11cbiAgICBpbnRlcmlvcl9jb2xvcj86IG51bWJlcltdXG4gICAgbWVhc3VyZT86IGFueVxuICAgIGlzX2RlbGV0ZWQ/OiBib29sZWFuXG5cbiAgICBwdWJsaWMgd3JpdGVBbm5vdGF0aW9uUHJlYW1ibGUoKSA6IG51bWJlcltdIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoXCJFcnJvclwiKVxuICAgIH1cblxuICAgIHB1YmxpYyB3cml0ZUFubm90YXRpb25Qb3N0YW1ibGUoKSA6IG51bWJlcltdIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoXCJFcnJvclwiKVxuICAgIH1cblxuICAgIHB1YmxpYyB3cml0ZUFubm90YXRpb25PYmplY3QoY3J5cHRvSW50ZXJmYWNlIDogQ3J5cHRvSW50ZXJmYWNlKSA6IG51bWJlcltdIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoXCJFcnJvclwiKVxuICAgIH1cblxuICAgIHB1YmxpYyBlbmNvZGVBbm5vdGF0aW9uRmxhZ3MoKSA6IG51bWJlciB7XG4gICAgICAgIGlmICghdGhpcy5hbm5vdGF0aW9uRmxhZ3MpIHtcbiAgICAgICAgICAgIHJldHVybiAwXG4gICAgICAgIH1cblxuICAgICAgICBsZXQgdmFsID0gMFxuXG4gICAgICAgIGlmICh0aGlzLmFubm90YXRpb25GbGFncy5pbnZpc2libGUpIHtcbiAgICAgICAgICAgIHZhbCB8PSAxXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuYW5ub3RhdGlvbkZsYWdzLmhpZGRlbikge1xuICAgICAgICAgICAgdmFsIHw9IDJcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5hbm5vdGF0aW9uRmxhZ3MucHJpbnQpIHtcbiAgICAgICAgICAgIHZhbCB8PSA0XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuYW5ub3RhdGlvbkZsYWdzLm5vWm9vbSkge1xuICAgICAgICAgICAgdmFsIHw9IDhcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5hbm5vdGF0aW9uRmxhZ3Mubm9Sb3RhdGUpIHtcbiAgICAgICAgICAgIHZhbCB8PSAxNlxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmFubm90YXRpb25GbGFncy5ub1ZpZXcpIHtcbiAgICAgICAgICAgIHZhbCB8PSAzMlxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmFubm90YXRpb25GbGFncy5yZWFkT25seSkge1xuICAgICAgICAgICAgdmFsIHw9IDY0XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuYW5ub3RhdGlvbkZsYWdzLmxvY2tlZCkge1xuICAgICAgICAgICAgdmFsIHw9IDEyOFxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmFubm90YXRpb25GbGFncy50b2dnbGVOb1ZpZXcpIHtcbiAgICAgICAgICAgIHZhbCB8PSAyNTZcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5hbm5vdGF0aW9uRmxhZ3MubG9ja2VkQ29udGVudHMpIHtcbiAgICAgICAgICAgIHZhbCB8PSA1MTJcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB2YWxcbiAgICB9XG5cblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgZGF0YTogVWludDhBcnJheSA9IG5ldyBVaW50OEFycmF5KFtdKSwgcHJpdmF0ZSBjcnlwdG9JbnRlcmZhY2UgOiBDcnlwdG9JbnRlcmZhY2UgPSBuZXcgQ3J5cHRvSW50ZXJmYWNlKCkpIHtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3QgdGhlIGFubm90YXRpb24gb2JqZWN0IChwYXJ0aWFsbHkpXG4gICAgICogKi9cbiAgICBleHRyYWN0KHhyZWY6IFhSZWYsIHBhZ2U6IFBhZ2UsIG9iamVjdExvb2t1cFRhYmxlOiBPYmplY3RMb29rdXBUYWJsZSkge1xuICAgICAgICBsZXQgYW5ub3Rfb2JqID0gT2JqZWN0VXRpbC5leHRyYWN0T2JqZWN0KHRoaXMuZGF0YSwgeHJlZiwgb2JqZWN0TG9va3VwVGFibGUpXG5cbiAgICAgICAgdGhpcy5vYmplY3RfaWQgPSBhbm5vdF9vYmouaWRcblxuICAgICAgICBhbm5vdF9vYmogPSBhbm5vdF9vYmoudmFsdWVcblxuICAgICAgICB0aGlzLnR5cGUgPSBhbm5vdF9vYmpbXCIvU3VidHlwZVwiXVxuICAgICAgICB0aGlzLnJlY3QgPSBhbm5vdF9vYmpbXCIvUmVjdFwiXVxuICAgICAgICB0aGlzLnBhZ2VSZWZlcmVuY2UgPSBwYWdlXG5cbiAgICAgICAgaWYgKGFubm90X29ialtcIi9NXCJdKVxuICAgICAgICAgICAgdGhpcy51cGRhdGVEYXRlID0gVXRpbC5jb252ZXJ0VW5pY29kZVRvU3RyaW5nKHRoaXMuY3J5cHRvSW50ZXJmYWNlLmRlY3J5cHQoYW5ub3Rfb2JqW1wiL01cIl0sIHRoaXMub2JqZWN0X2lkKSlcblxuICAgICAgICBpZiAoYW5ub3Rfb2JqW1wiL0JvcmRlclwiXSlcbiAgICAgICAgICAgIHRoaXMuYm9yZGVyID0gYW5ub3Rfb2JqW1wiL0JvcmRlclwiXVxuXG4gICAgICAgIGlmIChhbm5vdF9vYmpbXCIvQ1wiXSlcbiAgICAgICAgICAgIHRoaXMuY29sb3IgPSBhbm5vdF9vYmpbXCIvQ1wiXVxuXG4gICAgICAgIGlmIChhbm5vdF9vYmpbXCIvVFwiXSlcbiAgICAgICAgICAgIHRoaXMuYXV0aG9yID0gVXRpbC5jb252ZXJ0VW5pY29kZVRvU3RyaW5nKHRoaXMuY3J5cHRvSW50ZXJmYWNlLmRlY3J5cHQoYW5ub3Rfb2JqW1wiL1RcIl0sIHRoaXMub2JqZWN0X2lkKSlcblxuICAgICAgICBpZiAoYW5ub3Rfb2JqW1wiL05NXCJdKVxuICAgICAgICAgICAgdGhpcy5pZCA9IFV0aWwuY29udmVydFVuaWNvZGVUb1N0cmluZyh0aGlzLmNyeXB0b0ludGVyZmFjZS5kZWNyeXB0KGFubm90X29ialtcIi9OTVwiXSwgdGhpcy5vYmplY3RfaWQpKVxuXG4gICAgICAgIGlmIChhbm5vdF9vYmpbXCIvQ29udGVudHNcIl0pXG4gICAgICAgICAgICB0aGlzLmNvbnRlbnRzID0gVXRpbC5jb252ZXJ0VW5pY29kZVRvU3RyaW5nKHRoaXMuY3J5cHRvSW50ZXJmYWNlLmRlY3J5cHQoYW5ub3Rfb2JqW1wiL0NvbnRlbnRzXCJdLCB0aGlzLm9iamVjdF9pZCkpXG5cbiAgICAgICAgaWYgKGFubm90X29ialtcIi9RdWFkUG9pbnRzXCJdKVxuICAgICAgICAgICAgdGhpcy5xdWFkUG9pbnRzID0gYW5ub3Rfb2JqW1wiL1F1YWRQb2ludHNcIl1cblxuICAgICAgICBpZiAoYW5ub3Rfb2JqW1wiL0lua2xpc3RcIl0pXG4gICAgICAgICAgICB0aGlzLmlua0xpc3QgPSBhbm5vdF9vYmpbXCIvSW5rbGlzdFwiXVxuICAgIH1cbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIHRoZSBDYXRhbG9nIG9iamVjdCBvZiB0aGUgUERGIGRvY3VtZW50XG4gKiAqL1xuZXhwb3J0IGNsYXNzIENhdGFsb2dPYmplY3Qge1xuICAgIC8qKlxuICAgICAqIEV4dHJhY3RzIHRoZSBkYXRhIHJlcHJlc2VudGluZyB0aGUgb2JqZWN0LlxuICAgICAqICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBkYXRhOiBVaW50OEFycmF5LCBwcml2YXRlIHhyZWY6IFhSZWYsIHByaXZhdGUgb2JqZWN0TG9va3VwVGFibGU6IE9iamVjdExvb2t1cFRhYmxlKSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGFcblxuICAgICAgICBsZXQgcGFnZV9vYmogPSBPYmplY3RVdGlsLmV4dHJhY3RPYmplY3QodGhpcy5kYXRhLCB4cmVmLCBvYmplY3RMb29rdXBUYWJsZSkudmFsdWVcblxuICAgICAgICBpZiAocGFnZV9vYmpbXCIvVHlwZVwiXSAhPT0gXCIvQ2F0YWxvZ1wiKVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoYEludmFsaWQgY2F0YWxvZyBvYmplY3QgYXQgcG9zaXRpb24gJHt4cmVmLnBvaW50ZXJ9YClcblxuICAgICAgICB0aGlzLnBhZ2VzT2JqZWN0SWQgPSBwYWdlX29ialtcIi9QYWdlc1wiXVxuXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBwYWdlc09iamVjdElkOiBSZWZlcmVuY2VQb2ludGVyID0geyBvYmo6IC0xLCBnZW5lcmF0aW9uOiAtMSB9XG5cbiAgICBnZXRQYWdlc09iamVjdElkKCk6IFJlZmVyZW5jZVBvaW50ZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5wYWdlc09iamVjdElkXG4gICAgfVxufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgdGhlIFBhZ2VUcmVlIG9iamVjdCBvZiB0aGUgUERGIGRvY3VtZW50XG4gKiBUaGlzIGlzIHRoZSBvYmplY3Qgd2l0aCAvVHlwZSAvUGFnZXNcbiAqICovXG5leHBvcnQgY2xhc3MgUGFnZVRyZWUge1xuXG4gICAgcHJpdmF0ZSBwYWdlQ291bnQ6IG51bWJlciA9IC0xXG5cbiAgICBwcml2YXRlIHBhZ2VSZWZlcmVuY2VzOiBSZWZlcmVuY2VQb2ludGVyW10gPSBbXVxuXG4gICAgcHJpdmF0ZSB2aXNpdGVkUGFnZXM6IFJlZmVyZW5jZVBvaW50ZXJbXSA9IFtdXG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGRhdGE6IFVpbnQ4QXJyYXksIHByaXZhdGUgb2JqZWN0TG9va3VwVGFibGU6IE9iamVjdExvb2t1cFRhYmxlKSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGFcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeHRyYWN0cyB0aGUga2lkcyByZWZlcmVuY2VzIHJlY3Vyc2l2ZWx5LlxuICAgICAqIEZvciBldmVyeSBraWQgaXQgY2hlY2tzIGlmIHRoZSByZWZlcmVuY2VkIG9iamVjdCB0eXBlIGlzOlxuICAgICAqIC0gYSAvUGFnZXMgb2JqZWN0IHRoZW4gaXQgcmVjdXJzaXZlbHkgbG9va3VwcyBpdHMgY2hpbGRyZW5cbiAgICAgKiAtIGEgL1BhZ2Ugb2JqZWN0IHRoZW4gaXQgYWRkcyB0aGUgcmVmZXJlbmNlc1xuICAgICAqICovXG4gICAgZXh0cmFjdFBhZ2VSZWZlcmVuY2VzKHJlZmVyZW5jZXM6IFJlZmVyZW5jZVBvaW50ZXJbXSkge1xuICAgICAgICBmb3IgKGxldCByZWZlcmVuY2Ugb2YgcmVmZXJlbmNlcykge1xuXG4gICAgICAgICAgICBpZih0aGlzLnZpc2l0ZWRQYWdlcy5zb21lKGVsID0+IGVsLm9iaiA9PT0gcmVmZXJlbmNlLm9iaiAmJlxuICAgICAgICAgICAgICAgIGVsLmdlbmVyYXRpb24gPT09IHJlZmVyZW5jZS5nZW5lcmF0aW9uKSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCB4cmVmID0gdGhpcy5vYmplY3RMb29rdXBUYWJsZVtyZWZlcmVuY2Uub2JqXVxuXG4gICAgICAgICAgICBsZXQga2lkX3BhZ2Vfb2JqID0gT2JqZWN0VXRpbC5leHRyYWN0T2JqZWN0KHRoaXMuZGF0YSwgeHJlZiwgdGhpcy5vYmplY3RMb29rdXBUYWJsZSkudmFsdWVcblxuICAgICAgICAgICAgaWYgKGtpZF9wYWdlX29ialtcIi9UeXBlXCJdID09PSBcIi9QYWdlXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBhZ2VSZWZlcmVuY2VzLnB1c2gocmVmZXJlbmNlKVxuICAgICAgICAgICAgfSBlbHNlIGlmIChraWRfcGFnZV9vYmpbXCIvVHlwZVwiXSA9PT0gXCIvUGFnZXNcIikge1xuICAgICAgICAgICAgICAgIHRoaXMudmlzaXRlZFBhZ2VzLnB1c2gocmVmZXJlbmNlKVxuICAgICAgICAgICAgICAgIHRoaXMuZXh0cmFjdFBhZ2VSZWZlcmVuY2VzKGtpZF9wYWdlX29ialtcIi9LaWRzXCJdKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihgSW52YWxpZCBvYmplY3QgdHlwZSAke2tpZF9wYWdlX29ialtcIi9UeXBlXCJdfWApXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3QgdGhlIG9iamVjdCBkYXRhIGF0IHRoZSBnaXZlbiBwb2ludGVyXG4gICAgICogKi9cbiAgICBleHRyYWN0KHhyZWY6IFhSZWYsIG9iamVjdExvb2t1cFRhYmxlOiBPYmplY3RMb29rdXBUYWJsZSkge1xuICAgICAgICBsZXQgcGFnZV90cmVlX29iaiA9IE9iamVjdFV0aWwuZXh0cmFjdE9iamVjdCh0aGlzLmRhdGEsIHhyZWYsIG9iamVjdExvb2t1cFRhYmxlKS52YWx1ZVxuXG4gICAgICAgIGlmICghcGFnZV90cmVlX29ialtcIi9LaWRzXCJdKVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoYENvdWxkIG5vdCBmaW5kIGluZGV4IG9mIC9LaWRzIGluIC9QYWdlcyBvYmplY3RgKVxuXG4gICAgICAgIGxldCByZWZzID0gcGFnZV90cmVlX29ialtcIi9LaWRzXCJdXG5cbiAgICAgICAgdGhpcy5wYWdlUmVmZXJlbmNlcyA9IFtdXG5cbiAgICAgICAgdGhpcy5leHRyYWN0UGFnZVJlZmVyZW5jZXMocmVmcylcblxuICAgICAgICB0aGlzLnBhZ2VDb3VudCA9IHRoaXMucGFnZVJlZmVyZW5jZXMubGVuZ3RoXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHBhZ2VzIHRoZSBwYWdlIHRyZWUgY29tcHJpc2VzXG4gICAgICogKi9cbiAgICBnZXRQYWdlQ291bnQoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFnZUNvdW50XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcmVmZXJlbmNlIHRvIHRoZSBwYWdlIG9iamVjdHNcbiAgICAgKiAqL1xuICAgIGdldFBhZ2VSZWZlcmVuY2VzKCk6IFJlZmVyZW5jZVBvaW50ZXJbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhZ2VSZWZlcmVuY2VzXG4gICAgfVxufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBwYWdlIG9iamVjdCBpbiB0aGUgUERGIGRvY3VtZW50XG4gKiAqL1xuZXhwb3J0IGNsYXNzIFBhZ2Uge1xuICAgIHB1YmxpYyBvYmplY3RfaWQ6IFJlZmVyZW5jZVBvaW50ZXIgfCB1bmRlZmluZWQgLy8gVGhlIG9iamVjdCBpZCBhbmQgZ2VuZXJhdGlvbiBvZiB0aGUgb2JqZWN0XG5cbiAgICBwdWJsaWMgYW5ub3RzOiBSZWZlcmVuY2VQb2ludGVyW10gPSBbXVxuXG4gICAgcHVibGljIGhhc0Fubm90c0ZpZWxkOiBib29sZWFuID0gZmFsc2VcblxuICAgIHB1YmxpYyBhbm5vdHNQb2ludGVyOiBSZWZlcmVuY2VQb2ludGVyIHwgdW5kZWZpbmVkXG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGRhdGE6IFVpbnQ4QXJyYXksIHByaXZhdGUgZG9jdW1lbnRIaXN0b3J5OiBEb2N1bWVudEhpc3RvcnkpIHtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3RzIHRoZSByZWZlcmVuY2VzIGluIHRoZSBsaW5rZWQgYW5ub3RhdGlvbnMgYXJyYXlcbiAgICAgKiAqL1xuICAgIGV4dHJhY3RBbm5vdGF0aW9uQXJyYXkoKSB7XG4gICAgICAgIGxldCBvYmpfdGFibGUgPSB0aGlzLmRvY3VtZW50SGlzdG9yeS5jcmVhdGVPYmplY3RMb29rdXBUYWJsZSgpXG5cbiAgICAgICAgaWYgKCF0aGlzLmFubm90c1BvaW50ZXIpXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcIkFubm90YXRpb25zIHBvaW50ZXIgbm90IHNldFwiKVxuXG4gICAgICAgIGxldCByZWZfYW5ub3RfdGFibGUgPSBvYmpfdGFibGVbdGhpcy5hbm5vdHNQb2ludGVyLm9ial1cblxuICAgICAgICBsZXQgYW5ub3RhdGlvbnNfb2JqID0gT2JqZWN0VXRpbC5leHRyYWN0T2JqZWN0KHRoaXMuZGF0YSwgcmVmX2Fubm90X3RhYmxlLCBvYmpfdGFibGUpXG5cbiAgICAgICAgdGhpcy5hbm5vdHMgPSBhbm5vdGF0aW9uc19vYmoudmFsdWVcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeHRyYWN0cyB0aGUgcGFnZSBvYmplY3Qgc3RhcnRpbmcgYXQgcG9zaXRpb24gcHRyXG4gICAgICogKi9cbiAgICBleHRyYWN0KHhyZWY6IFhSZWYsIG9iamVjdExvb2t1cFRhYmxlOiBPYmplY3RMb29rdXBUYWJsZSkge1xuICAgICAgICBsZXQgcGFnZV9vYmogPSBPYmplY3RVdGlsLmV4dHJhY3RPYmplY3QodGhpcy5kYXRhLCB4cmVmLCBvYmplY3RMb29rdXBUYWJsZSlcblxuICAgICAgICB0aGlzLm9iamVjdF9pZCA9IHBhZ2Vfb2JqLmlkXG5cbiAgICAgICAgbGV0IGFubm90cyA9IHBhZ2Vfb2JqLnZhbHVlW1wiL0Fubm90c1wiXVxuXG4gICAgICAgIGlmIChhbm5vdHMpIHtcbiAgICAgICAgICAgIHRoaXMuaGFzQW5ub3RzRmllbGQgPSB0cnVlXG5cbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGFubm90cykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFubm90cyA9IGFubm90cy5maWx0ZXIoKHggOiBhbnkpID0+IHggIT09ICdudWxsJylcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hbm5vdHNQb2ludGVyID0gYW5ub3RzXG5cbiAgICAgICAgICAgICAgICB0aGlzLmV4dHJhY3RBbm5vdGF0aW9uQXJyYXkoKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqIFByb3ZpZGVzIGEgY29uZmlndXJlZCBpbnRlcmZhY2UgdG8gaGFuZGxlIHRoZSBlbmNyeXB0aW9uIGFuZCBkZWNyeXB0aW9uIG9mIFBERnNcbiAqICovXG5leHBvcnQgY2xhc3MgQ3J5cHRvSW50ZXJmYWNlIHtcbiAgICBjcnlwdG9Db25maWd1cmF0aW9uIDogQ3J5cHRvQ29uZmlndXJhdGlvbiA9IHt2ZXJzaW9uOiB1bmRlZmluZWQsIHJldmlzaW9uOiB1bmRlZmluZWQsIGZpbHRlcjogdW5kZWZpbmVkLCB1c2VyX3B3ZCA6IFwiXCIsIG93bmVyX3B3ZCA6IFwiXCIsIGxlbmd0aDogdW5kZWZpbmVkLCBwZXJtaXNzaW9uczogdW5kZWZpbmVkLCBvd25lcl9wd2RfYzogdW5kZWZpbmVkLCB1c2VyX3B3ZF9jOiB1bmRlZmluZWR9XG5cbiAgICBjcnlwdG9FbmdpbmUgOiBDcnlwdG9FbmdpbmUgPSBuZXcgSWRlbnRpdHlFbmdpbmUoKVxuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBkYXRhPzogVWludDhBcnJheSwgcHJpdmF0ZSBkb2N1bWVudEhpc3Rvcnk/OiBEb2N1bWVudEhpc3RvcnksIHByaXZhdGUgcmVmX3B0cj86IFhSZWYsIHVzZXJfcHdkPzogc3RyaW5nLCBvd25lcl9wd2Q/OiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YVxuICAgICAgICB0aGlzLmRvY3VtZW50SGlzdG9yeSA9IGRvY3VtZW50SGlzdG9yeVxuICAgICAgICB0aGlzLmNyeXB0b0NvbmZpZ3VyYXRpb24udXNlcl9wd2QgPSB1c2VyX3B3ZCA/IHVzZXJfcHdkIDogXCJcIlxuICAgICAgICB0aGlzLmNyeXB0b0NvbmZpZ3VyYXRpb24ub3duZXJfcHdkID0gb3duZXJfcHdkID8gb3duZXJfcHdkIDogXCJcIlxuXG4gICAgICAgIGlmICh0aGlzLnJlZl9wdHIgJiYgdGhpcy5kb2N1bWVudEhpc3RvcnkpIHtcbiAgICAgICAgICAgIHRoaXMuZXh0cmFjdEVuY3J5cHRpb25EaWN0aW9uYXJ5KHRoaXMucmVmX3B0cilcblxuICAgICAgICAgICAgLy8gc2V0dXAgY3J5cHRvLWVuZ2luZVxuXG4gICAgICAgICAgICBpZiAodGhpcy5jcnlwdG9Db25maWd1cmF0aW9uLnZlcnNpb24gPT09IDEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNyeXB0b0VuZ2luZSA9IG5ldyBSQzRDcnlwdG9FbmdpbmUodGhpcy5jcnlwdG9Db25maWd1cmF0aW9uLCB0aGlzLmRvY3VtZW50SGlzdG9yeS5nZXRSZWNlbnRVcGRhdGUoKS5pZCwgUkM0XzQwX0JJVClcbiAgICAgICAgICAgIH0gZWxzZSBpZih0aGlzLmNyeXB0b0NvbmZpZ3VyYXRpb24udmVyc2lvbiA9PT0gMikge1xuICAgICAgICAgICAgICAgIHRoaXMuY3J5cHRvRW5naW5lID0gbmV3IFJDNENyeXB0b0VuZ2luZSh0aGlzLmNyeXB0b0NvbmZpZ3VyYXRpb24sIHRoaXMuZG9jdW1lbnRIaXN0b3J5LmdldFJlY2VudFVwZGF0ZSgpLmlkKVxuICAgICAgICAgICAgfSBlbHNlIGlmKHRoaXMuY3J5cHRvQ29uZmlndXJhdGlvbi52ZXJzaW9uID09PSA0KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJTb21lIGZhbmN5IEFFUyBlbmNyeXB0aW9uXCIpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKGBVbnN1cHBvcnRlZCBFbmNyeXB0aW9uICR7dGhpcy5jcnlwdG9Db25maWd1cmF0aW9uLnZlcnNpb259YClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHJlZmVyZW5jZSBwb2ludGVyXG4gICAgICogKi9cbiAgICBnZXRFbmNyeXB0aW9uRGljdFJlZmVyZW5jZSgpIDogUmVmZXJlbmNlUG9pbnRlciB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGlmKCF0aGlzLnJlZl9wdHIpXG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG5cbiAgICAgICAgcmV0dXJuIHtvYmogOiB0aGlzLnJlZl9wdHIuaWQsIGdlbmVyYXRpb24gOiB0aGlzLnJlZl9wdHIuZ2VuZXJhdGlvbn1cbiAgICB9XG5cbiAgICBlbmNyeXB0KGRhdGEgOiBVaW50OEFycmF5LCByZWZlcmVuY2UgOiBSZWZlcmVuY2VQb2ludGVyIHwgdW5kZWZpbmVkKSA6IFVpbnQ4QXJyYXkge1xuICAgICAgICByZXR1cm4gdGhpcy5jcnlwdG9FbmdpbmUuZW5jcnlwdChkYXRhLCByZWZlcmVuY2UpXG4gICAgfVxuXG4gICAgZGVjcnlwdChkYXRhIDogVWludDhBcnJheSwgcmVmZXJlbmNlIDogUmVmZXJlbmNlUG9pbnRlciB8IHVuZGVmaW5lZCkgOiBVaW50OEFycmF5IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY3J5cHRvRW5naW5lLmRlY3J5cHQoZGF0YSwgcmVmZXJlbmNlKVxuICAgIH1cblxuICAgIGlzVXNlclBhc3N3b3JkQ29ycmVjdCgpIDogYm9vbGVhbiB7XG4gICAgICAgIGlmICghdGhpcy5jcnlwdG9FbmdpbmUpIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiQ3J5cHRvIGVuZ2luZSBub3QgY29uZmlndXJlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuY3J5cHRvRW5naW5lLmlzVXNlclBhc3N3b3JkQ29ycmVjdCgpXG4gICAgfVxuXG4gICAgaXNPd25lclBhc3N3b3JkQ29ycmVjdCgpIDogYm9vbGVhbiB7XG4gICAgICAgIGlmICghdGhpcy5jcnlwdG9FbmdpbmUpIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiQ3J5cHRvIGVuZ2luZSBub3QgY29uZmlndXJlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuY3J5cHRvRW5naW5lLmlzT3duZXJQYXNzd29yZENvcnJlY3QoKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3RzIHRoZSBlbnJjeXB0aW9uIGRpY3Rpb25hcnlcbiAgICAgKiAqL1xuICAgIGV4dHJhY3RFbmNyeXB0aW9uRGljdGlvbmFyeShwdHIgOiBYUmVmKSB7XG4gICAgICAgIGlmKCF0aGlzLmRvY3VtZW50SGlzdG9yeSkge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJEb2N1bWVudGhpc3Rvcnkgbm90IGNvbmZpZ3VyZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKCF0aGlzLmRhdGEpIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiRGF0YSBub3QgY29uZmlndXJlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IG9ial90YWJsZSA9IHRoaXMuZG9jdW1lbnRIaXN0b3J5LmNyZWF0ZU9iamVjdExvb2t1cFRhYmxlKClcbiAgICAgICAgbGV0IHBhZ2Vfb2JqID0gT2JqZWN0VXRpbC5leHRyYWN0T2JqZWN0KHRoaXMuZGF0YSwgcHRyLCBvYmpfdGFibGUpXG5cbiAgICAgICAgdGhpcy5jcnlwdG9Db25maWd1cmF0aW9uLnZlcnNpb24gPSBwYWdlX29iai52YWx1ZVtcIi9WXCJdXG4gICAgICAgIHRoaXMuY3J5cHRvQ29uZmlndXJhdGlvbi5yZXZpc2lvbiA9IHBhZ2Vfb2JqLnZhbHVlW1wiL1JcIl1cbiAgICAgICAgdGhpcy5jcnlwdG9Db25maWd1cmF0aW9uLmZpbHRlciA9IHBhZ2Vfb2JqLnZhbHVlW1wiL0ZpbHRlclwiXVxuICAgICAgICB0aGlzLmNyeXB0b0NvbmZpZ3VyYXRpb24udXNlcl9wd2RfYyA9IHBhZ2Vfb2JqLnZhbHVlW1wiL1VcIl1cbiAgICAgICAgdGhpcy5jcnlwdG9Db25maWd1cmF0aW9uLm93bmVyX3B3ZF9jID0gcGFnZV9vYmoudmFsdWVbXCIvT1wiXVxuICAgICAgICB0aGlzLmNyeXB0b0NvbmZpZ3VyYXRpb24ubGVuZ3RoID0gcGFnZV9vYmoudmFsdWVbXCIvTGVuZ3RoXCJdXG4gICAgICAgIHRoaXMuY3J5cHRvQ29uZmlndXJhdGlvbi5wZXJtaXNzaW9ucyA9IHBhZ2Vfb2JqLnZhbHVlW1wiL1BcIl1cbiAgICB9XG59XG5cbi8qKlxuICogUGFyc2VzIHRoZSByZWxldmFudCBwYXJ0cyBvZiB0aGUgUERGIGRvY3VtZW50IGFuZCBwcm92aWRlcyBmdW5jdGlvbmFsaXR5IHRvIGV4dHJhY3QgdGhlIG5lY2Vzc2FyeSBpbmZvcm1hdGlvbiBmb3JcbiAqIGFkZGluZyBhbm5vdGF0aW9uc1xuICogKi9cbmV4cG9ydCBjbGFzcyBQREZEb2N1bWVudFBhcnNlciB7XG5cbiAgICBwcml2YXRlIHZlcnNpb246IFBERlZlcnNpb24gfCB1bmRlZmluZWQgPSB1bmRlZmluZWRcblxuICAgIHB1YmxpYyBkb2N1bWVudEhpc3Rvcnk6IERvY3VtZW50SGlzdG9yeSA9IG5ldyBEb2N1bWVudEhpc3RvcnkobmV3IFVpbnQ4QXJyYXkoW10pKVxuXG4gICAgcHJpdmF0ZSBjYXRhbG9nT2JqZWN0OiBDYXRhbG9nT2JqZWN0IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkXG5cbiAgICBwcml2YXRlIHBhZ2VUcmVlOiBQYWdlVHJlZSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZFxuXG4gICAgcHJpdmF0ZSBjcnlwdG9JbnRlcmZhY2U6IENyeXB0b0ludGVyZmFjZSA9IG5ldyBDcnlwdG9JbnRlcmZhY2UoKVxuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBkYXRhOiBVaW50OEFycmF5LCB1c2VycHdkIDogc3RyaW5nID0gXCJcIiwgb3duZXJwd2QgOiBzdHJpbmcgPSBcIlwiKSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KGRhdGEpXG5cbiAgICAgICAgdGhpcy5kb2N1bWVudEhpc3RvcnkgPSBuZXcgRG9jdW1lbnRIaXN0b3J5KHRoaXMuZGF0YSlcbiAgICAgICAgdGhpcy5kb2N1bWVudEhpc3RvcnkuZXh0cmFjdERvY3VtZW50SGlzdG9yeSgpXG5cbiAgICAgICAgaWYgKHRoaXMuZG9jdW1lbnRIaXN0b3J5LmlzRW5jcnlwdGVkKCkpIHtcbiAgICAgICAgICAgIC8vIGV4dHJhY3QgZW5jcnlwdGlvbiBkaWN0aW9uYXJ5XG4gICAgICAgICAgICBsZXQgb2JqX3RhYmxlID0gdGhpcy5kb2N1bWVudEhpc3RvcnkuY3JlYXRlT2JqZWN0TG9va3VwVGFibGUoKVxuXG4gICAgICAgICAgICBsZXQgZW5jX29iaiA9IHRoaXMuZG9jdW1lbnRIaXN0b3J5LmdldFJlY2VudFVwZGF0ZSgpLmVuY3J5cHRcblxuICAgICAgICAgICAgaWYoIWVuY19vYmopXG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJJbnZhbGlkIGVuY3J5cHRpb24gaW5kaWNhdGlvblwiKVxuXG4gICAgICAgICAgICBsZXQgZW5jX29ial9wdHIgPSBvYmpfdGFibGVbZW5jX29iai5vYmpdXG5cbiAgICAgICAgICAgIHRoaXMuY3J5cHRvSW50ZXJmYWNlID0gbmV3IENyeXB0b0ludGVyZmFjZSh0aGlzLmRhdGEsIHRoaXMuZG9jdW1lbnRIaXN0b3J5LCBlbmNfb2JqX3B0ciwgdXNlcnB3ZCwgb3duZXJwd2QpXG5cbiAgICAgICAgICAgIC8vIHZlcmlmeSBrZXlzXG4gICAgICAgICAgICBpZighdGhpcy5jcnlwdG9JbnRlcmZhY2UuaXNVc2VyUGFzc3dvcmRDb3JyZWN0KCkpIHtcbiAgICAgICAgICAgICAgICBpZighdGhpcy5jcnlwdG9JbnRlcmZhY2UuaXNPd25lclBhc3N3b3JkQ29ycmVjdCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFwiTm8gdmFsaWQgdXNlciBjcmVkZW50aWFsc1wiKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgY3J5cHRvIGludGVyZmFjZVxuICAgICAqICovXG4gICAgZ2V0Q3J5cHRvSW50ZXJmYWNlKCk6IENyeXB0b0ludGVyZmFjZSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNyeXB0b0ludGVyZmFjZVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIG1ham9yIGFuZCBtaW5vciB2ZXJzaW9uIG9mIHRoZSBwZGYgZG9jdW1lbnRcbiAgICAgKiAqL1xuICAgIGdldFBERlZlcnNpb24oKTogUERGVmVyc2lvbiB7XG4gICAgICAgIGlmICh0aGlzLnZlcnNpb24pXG4gICAgICAgICAgICByZXR1cm4gdGhpcy52ZXJzaW9uXG5cbiAgICAgICAgdGhpcy52ZXJzaW9uID0gVXRpbC5leHRyYWN0VmVyc2lvbih0aGlzLmRhdGEsIDApXG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmVyc2lvblxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBmcmVlIG9iamVjdCBpZC4gSXQgZmlyc3QgY2hlY2tzIHdldGhlciB0aGVyZSBjYW4gYmUgYW4gZnJlZWQgb2JqZWN0IGlkIHJldXNlZC4gSWYgdGhhdCBpcyBub3QgdGhlIGNhc2VcbiAgICAgKiBpdCBjcmVhdGVzIGEgbmV3IG9uZVxuICAgICAqICovXG4gICAgZ2V0RnJlZU9iamVjdElkKCk6IFJlZmVyZW5jZVBvaW50ZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5kb2N1bWVudEhpc3RvcnkuZ2V0RnJlZU9iamVjdElkKClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBjYXRhbG9nIG9iamVjdCBvZiB0aGUgUERGIGZpbGVcbiAgICAgKiAqL1xuICAgIGdldENhdGFsb2coKTogQ2F0YWxvZ09iamVjdCB7XG4gICAgICAgIGxldCByZWNlbnRfdXBkYXRlID0gdGhpcy5kb2N1bWVudEhpc3RvcnkuZ2V0UmVjZW50VXBkYXRlKClcbiAgICAgICAgaWYgKHJlY2VudF91cGRhdGUucm9vdCkge1xuICAgICAgICAgICAgbGV0IHJvb3Rfb2JqID0gcmVjZW50X3VwZGF0ZS5yb290XG5cbiAgICAgICAgICAgIGxldCBvYmpfdGFibGUgPSB0aGlzLmRvY3VtZW50SGlzdG9yeS5jcmVhdGVPYmplY3RMb29rdXBUYWJsZSgpXG5cbiAgICAgICAgICAgIHJldHVybiBuZXcgQ2F0YWxvZ09iamVjdCh0aGlzLmRhdGEsIG9ial90YWJsZVtyb290X29iai5vYmpdLCBvYmpfdGFibGUpXG4gICAgICAgIH0gZWxzZSB7IC8vIElmIHdlIGRvIG5vdCBrbm93IHRoZSBjYXRhbG9ndWUgb2JqZWN0IHdlIG5lZWQgdG8gbG9vayBpdCB1cFxuICAgICAgICAgICAgLy8gSW4gY3Jvc3MgcmVmZXJlbmNlIHN0cmVhbSBvYmplY3RzIG5vIC9ST09UIGZpZWxkIGlzIHJlcXVpcmVkLCBob3dldmVyIG9mdGVuIGl0IGlzIHByb3ZpZGVkIGFueXdheVxuICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIHJ1biB0aGlzIHJvdXRpbmUsIGJ1dCBidWZmZXIgdGhlIGNhdGFsb2cgb2JqZWN0XG4gICAgICAgICAgICBpZiAodGhpcy5jYXRhbG9nT2JqZWN0KVxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNhdGFsb2dPYmplY3RcblxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJEb2VzIG5vdCB3b3JrIGZvciBjb21wcmVzc2VkIGRhdGFcIilcblxuICAgICAgICAgICAgLy9sZXQgb2JqX3RhYmxlID0gdGhpcy5kb2N1bWVudEhpc3RvcnkuY3JlYXRlT2JqZWN0TG9va3VwVGFibGUoKVxuXG4gICAgICAgICAgICAvL2ZvciAobGV0IGkgPSAxOyBpIDwgcmVjZW50X3VwZGF0ZS5zaXplOyArK2kpIHtcbiAgICAgICAgICAgIC8vICAgIGxldCBfdHlwZSA9IFV0aWwuZXh0cmFjdEZpZWxkKHRoaXMuZGF0YSwgVXRpbC5fVFlQRSwgb2JqX3RhYmxlW2ldLnBvaW50ZXIpXG5cbiAgICAgICAgICAgIC8vICAgIGlmIChVdGlsLmFyZUFycmF5c0VxdWFsKF90eXBlLCBVdGlsLkNBVEFMT0cpKSB7XG4gICAgICAgICAgICAvLyAgICAgICAgdGhpcy5jYXRhbG9nT2JqZWN0ID0gbmV3IENhdGFsb2dPYmplY3QodGhpcy5kYXRhLCBvYmpfdGFibGVbaV0pXG5cbiAgICAgICAgICAgIC8vICAgICAgICBpZiAodGhpcy5jYXRhbG9nT2JqZWN0KVxuICAgICAgICAgICAgLy8gICAgICAgICAgICByZXR1cm4gdGhpcy5jYXRhbG9nT2JqZWN0XG4gICAgICAgICAgICAvLyAgICB9XG4gICAgICAgICAgICAvL31cbiAgICAgICAgfVxuXG4gICAgICAgIHRocm93IEVycm9yKFwiQ291bGQgbm90IGlkZW50aWZ5IGNhdGFsb2cgb2JqZWN0XCIpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgbGF0ZXN0IHZlcnNpb24gb2YgdGhlIHBhZ2UgdHJlZSBvYmplY3Qgb2YgdGhlIGRvY3VtZW50XG4gICAgICogKi9cbiAgICBnZXRQYWdlVHJlZSgpOiBQYWdlVHJlZSB7XG4gICAgICAgIGlmICh0aGlzLnBhZ2VUcmVlKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFnZVRyZWVcbiAgICAgICAgbGV0IG9ial90YWJsZTogT2JqZWN0TG9va3VwVGFibGUgPSB0aGlzLmRvY3VtZW50SGlzdG9yeS5jcmVhdGVPYmplY3RMb29rdXBUYWJsZSgpXG5cbiAgICAgICAgbGV0IGNhdGFsb2dfb2JqZWN0ID0gdGhpcy5nZXRDYXRhbG9nKClcblxuICAgICAgICBsZXQgcGFnZXNfaWQgPSBjYXRhbG9nX29iamVjdC5nZXRQYWdlc09iamVjdElkKClcbiAgICAgICAgbGV0IHBhZ2VzX3JlZiA9IG9ial90YWJsZVtwYWdlc19pZC5vYmpdXG5cbiAgICAgICAgbGV0IHBhZ2VUcmVlID0gbmV3IFBhZ2VUcmVlKHRoaXMuZGF0YSwgb2JqX3RhYmxlKVxuICAgICAgICBwYWdlVHJlZS5leHRyYWN0KHBhZ2VzX3JlZiwgb2JqX3RhYmxlKVxuXG4gICAgICAgIHRoaXMucGFnZVRyZWUgPSBwYWdlVHJlZVxuXG4gICAgICAgIHJldHVybiBwYWdlVHJlZVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGxhdGVzdCB2ZXJzaW9uIG9mIHRoZSBwYWdlIHdpdGggdGhlIGdpdmVuIHBhZ2VOdW1iZXJcbiAgICAgKiAqL1xuICAgIGdldFBhZ2UocGFnZU51bWJlcjogbnVtYmVyKTogUGFnZSB7XG4gICAgICAgIGxldCBwYWdlVHJlZSA9IHRoaXMuZ2V0UGFnZVRyZWUoKVxuICAgICAgICBsZXQgcGFnZUlkID0gcGFnZVRyZWUuZ2V0UGFnZVJlZmVyZW5jZXMoKVtwYWdlTnVtYmVyXVxuXG4gICAgICAgIGxldCBvYmpfdGFibGUgPSB0aGlzLmRvY3VtZW50SGlzdG9yeS5jcmVhdGVPYmplY3RMb29rdXBUYWJsZSgpXG5cbiAgICAgICAgbGV0IG9ial9wdHIgPSBvYmpfdGFibGVbcGFnZUlkLm9ial1cblxuICAgICAgICBsZXQgcGFnZSA9IG5ldyBQYWdlKHRoaXMuZGF0YSwgdGhpcy5kb2N1bWVudEhpc3RvcnkpXG4gICAgICAgIHBhZ2UuZXh0cmFjdChvYmpfcHRyLCBvYmpfdGFibGUpXG5cbiAgICAgICAgcmV0dXJuIHBhZ2VcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBhbm5vdGF0aW9ucyB0aGF0IGV4aXN0IGluIHRoZSBkb2N1bWVudFxuICAgICAqICovXG4gICAgZXh0cmFjdEFubm90YXRpb25zKCk6IEFubm90YXRpb25bXVtdIHtcbiAgICAgICAgbGV0IGFubm90czogQW5ub3RhdGlvbltdW10gPSBbXVxuICAgICAgICBsZXQgcHQ6IFBhZ2VUcmVlID0gdGhpcy5nZXRQYWdlVHJlZSgpXG4gICAgICAgIGxldCBvYmpfdGFibGUgPSB0aGlzLmRvY3VtZW50SGlzdG9yeS5jcmVhdGVPYmplY3RMb29rdXBUYWJsZSgpXG5cbiAgICAgICAgbGV0IHBhZ2VDb3VudDogbnVtYmVyID0gcHQuZ2V0UGFnZUNvdW50KClcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhZ2VDb3VudDsgKytpKSB7XG4gICAgICAgICAgICBsZXQgcGFnZTogUGFnZSA9IHRoaXMuZ2V0UGFnZShpKVxuXG4gICAgICAgICAgICBsZXQgYW5ub3RhdGlvblJlZmVyZW5jZXM6IFJlZmVyZW5jZVBvaW50ZXJbXSA9IHBhZ2UuYW5ub3RzXG5cbiAgICAgICAgICAgIGxldCBwYWdlQW5ub3RzOiBBbm5vdGF0aW9uW10gPSBbXVxuXG4gICAgICAgICAgICBmb3IgKGxldCByZWZQdHIgb2YgYW5ub3RhdGlvblJlZmVyZW5jZXMpIHtcbiAgICAgICAgICAgICAgICBsZXQgYSA9IG5ldyBfQW5ub3RhdGlvbih0aGlzLmRhdGEsIHRoaXMuY3J5cHRvSW50ZXJmYWNlKVxuICAgICAgICAgICAgICAgIGEuZXh0cmFjdChvYmpfdGFibGVbcmVmUHRyLm9ial0sIHBhZ2UsIG9ial90YWJsZSlcbiAgICAgICAgICAgICAgICBhLnBhZ2UgPSBpXG4gICAgICAgICAgICAgICAgcGFnZUFubm90cy5wdXNoKGEpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhbm5vdHMucHVzaChwYWdlQW5ub3RzKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFubm90c1xuICAgIH1cblxufVxuIiwiaW1wb3J0IHsgVXRpbCB9IGZyb20gJy4vdXRpbCdcbmltcG9ydCB7IE9iamVjdFV0aWwgfSBmcm9tICcuL29iamVjdC11dGlsJztcbmltcG9ydCB7IFhSZWYgfSBmcm9tICcuL2RvY3VtZW50LWhpc3RvcnknO1xuaW1wb3J0ICogYXMgUGFrbyBmcm9tICdwYWtvJ1xuXG5leHBvcnQgaW50ZXJmYWNlIERlY29kZVBhcmFtZXRlcnMge1xuICAgIHByZWRpY3RvcjogbnVtYmVyXG4gICAgY29sdW1uczogbnVtYmVyXG59XG5cbmV4cG9ydCBjbGFzcyBTdHJlYW0ge1xuICAgIHByaXZhdGUgX3B0cjogbnVtYmVyID0gMFxuICAgIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBkYXRhOiBVaW50OEFycmF5KSB7IH1cblxuICAgIGdldERhdGEoKTogVWludDhBcnJheSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGFcbiAgICB9XG5cbiAgICBnZXRMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YS5sZW5ndGhcbiAgICB9XG5cbiAgICBwZWVrTkJ5dGVzKG46IG51bWJlciA9IDEsIHB0cjogbnVtYmVyID0gMCk6IFVpbnQ4QXJyYXkge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRhLnNsaWNlKHB0ciwgcHRyICsgbilcbiAgICB9XG5cbiAgICBwZWVrTkJ5dGVzQXNOdW1iZXIobjogbnVtYmVyID0gMSwgcHRyOiBudW1iZXIgPSAwKTogbnVtYmVyIHtcbiAgICAgICAgbGV0IHJlczogbnVtYmVyID0gMFxuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICAgICAgICByZXMgKz0gKHRoaXMuZGF0YVtpICsgcHRyXSA8PCA4ICogKG4gLSBpIC0gMSkpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogcmVhZHMgdGhlIG5leHQgJ24nIGJ5dGVzIG9mIHBvc2l0aW9uICdwdHInIGFuZCByZXR1cm5zIGl0cyBjb250ZW50IGFzIGEgbnVtYmVyXG4gICAgICogKi9cbiAgICBnZXROQnl0ZXNBc051bWJlcihuOiBudW1iZXIgPSAxKTogbnVtYmVyIHtcbiAgICAgICAgbGV0IHJlczogbnVtYmVyID0gdGhpcy5wZWVrTkJ5dGVzQXNOdW1iZXIobiwgdGhpcy5fcHRyKVxuXG4gICAgICAgIHRoaXMuX3B0ciArPSBuXG5cbiAgICAgICAgcmV0dXJuIHJlc1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlYWRzIHRoZSBuZXh0IGJ5dGUgZnJvbSB0aGUgc3RyZWFtXG4gICAgICogKi9cbiAgICBnZXRCeXRlKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGFbdGhpcy5fcHRyKytdXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2tpcHMgc3BhY2VzIGFuZCB0aGFuIGFkZHMgYXMgbWFueSBieXRlcyB0byB0aGUgbnVtYmVyIHVudGlsIGFub3RoZXIgc3BhY2UgaXMgcmVhY2hlZFxuICAgICAqICovXG4gICAgZ2V0TnVtYmVyKCk6IG51bWJlciB7XG4gICAgICAgIGxldCBuYnIgPSBVdGlsLmV4dHJhY3ROdW1iZXIodGhpcy5kYXRhLCB0aGlzLl9wdHIpXG4gICAgICAgIHRoaXMuX3B0ciA9IG5ici5lbmRfaW5kZXggKyAxXG5cbiAgICAgICAgcmV0dXJuIG5ici5yZXN1bHRcblxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEZsYXRlU3RyZWFtIGV4dGVuZHMgU3RyZWFtIHtcbiAgICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgZGF0YTogVWludDhBcnJheSwgcHJpdmF0ZSBkZWNvZGVQYXJhbWV0ZXJzOiBEZWNvZGVQYXJhbWV0ZXJzIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHN1cGVyKGRhdGEpXG5cbiAgICAgICAgaWYgKHRoaXMuZGF0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEgPSBQYWtvLmluZmxhdGUoZGF0YSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkZWNvZGVQYXJhbWV0ZXJzKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEgPSB0aGlzLmFwcGx5RmlsdGVyKHRoaXMuZGF0YSwgZGVjb2RlUGFyYW1ldGVycylcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXBwbHlGaWx0ZXIoZGF0YTogVWludDhBcnJheSwgZGVjb2RlUGFyYW1ldGVyczogRGVjb2RlUGFyYW1ldGVycyk6IFVpbnQ4QXJyYXkge1xuICAgICAgICBpZiAoZGVjb2RlUGFyYW1ldGVycy5wcmVkaWN0b3IgPj0gMTApIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFwcGx5UE5HRmlsdGVyKGRhdGEsIGRlY29kZVBhcmFtZXRlcnMpXG4gICAgICAgIH0gZWxzZSBpZiAoZGVjb2RlUGFyYW1ldGVycy5wcmVkaWN0b3IgPT09IDIpIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiVW5zdXBwb3J0ZWQgZmlsdGVyIC0tIGZpbGUgZmVhdHVyZSByZXF1ZXN0XCIpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZGF0YVxuICAgIH1cblxuICAgIHB1YmxpYyBhcHBseVBOR0ZpbHRlcihkYXRhOiBVaW50OEFycmF5LCBkZWNvZGVQYXJhbWV0ZXJzOiBEZWNvZGVQYXJhbWV0ZXJzKTogVWludDhBcnJheSB7XG4gICAgICAgIGlmIChkYXRhLmxlbmd0aCAlIChkZWNvZGVQYXJhbWV0ZXJzLmNvbHVtbnMgKyAxKSAhPT0gMClcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiSW52YWxpZCBkZWNvZGUgcGFyYW1ldGVyc1wiKVxuXG4gICAgICAgIGxldCB0b3RhbF9jb2x1bW5zID0gZGVjb2RlUGFyYW1ldGVycy5jb2x1bW5zICsgMVxuXG4gICAgICAgIGxldCB1bmZpbHRlcmVkX2RhdGE6IG51bWJlcltdID0gW11cblxuICAgICAgICBsZXQgZW5jb2Rpbmc6IG51bWJlciA9IDBcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBsZXQgbGVmdF92YWx1ZTogbnVtYmVyID0gMFxuICAgICAgICAgICAgbGV0IHVwcGVyX3ZhbHVlOiBudW1iZXIgPSAwXG4gICAgICAgICAgICBsZXQgaW5kZXhfdXBwZXJfdmFsdWU6IG51bWJlciA9IDBcbiAgICAgICAgICAgIGxldCBsZWZ0X3VwcGVyX3ZhbHVlOiBudW1iZXIgPSAwXG4gICAgICAgICAgICBpZiAoaSAlIHRvdGFsX2NvbHVtbnMgPT09IDApIHtcbiAgICAgICAgICAgICAgICBlbmNvZGluZyA9IGRhdGFbaV1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDA6IC8vIG5vIGVuY29kaW5nXG4gICAgICAgICAgICAgICAgICAgICAgICB1bmZpbHRlcmVkX2RhdGEucHVzaChkYXRhW2ldKVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxOiAvLyBTdWIgZml0bGVyIC0tIHRoZSBkaWZmZXJlbmNlIG9mIHRoZSBjdXJyZW50IHBpeGVsIGFuZCB0aGUgcHhpZWwgYmVmb3JlXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhZGQgdGhlIGxlZnQgYWxyZWFkeSBkZWNvZGVkIHBpeGVsIGFuZCAwIGF0IHRoZSBzdGFydCBvZiBhIHJvd1xuICAgICAgICAgICAgICAgICAgICAgICAgbGVmdF92YWx1ZSA9ICgoaSAlIHRvdGFsX2NvbHVtbnMpIC0gMiA8IDApID8gMCA6IHVuZmlsdGVyZWRfZGF0YVsoKGkgLSAyKSAlIGRlY29kZVBhcmFtZXRlcnMuY29sdW1ucykgKyBNYXRoLmZsb29yKGkgLyB0b3RhbF9jb2x1bW5zKSAqIChkZWNvZGVQYXJhbWV0ZXJzLmNvbHVtbnMgLSAxKV1cbiAgICAgICAgICAgICAgICAgICAgICAgIHVuZmlsdGVyZWRfZGF0YS5wdXNoKChkYXRhW2ldICsgbGVmdF92YWx1ZSkgJSAyNTYpXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDI6IC8vIFVwIGZpbHRlciAtLSB0aGUgZGlmZmVyZW5jZSBvZiB0aGUgY3VycmVudCBwcml4ZWwgYW5kIHRoZSBwaXhlbCBhYm92ZVxuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXhfdXBwZXJfdmFsdWUgPSBpIC0gKHRvdGFsX2NvbHVtbnMgKyBNYXRoLmZsb29yKGkgLyB0b3RhbF9jb2x1bW5zKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHVwcGVyX3ZhbHVlID0gKGluZGV4X3VwcGVyX3ZhbHVlIDwgMCkgPyAwIDogdW5maWx0ZXJlZF9kYXRhW2luZGV4X3VwcGVyX3ZhbHVlXVxuICAgICAgICAgICAgICAgICAgICAgICAgdW5maWx0ZXJlZF9kYXRhLnB1c2goKGRhdGFbaV0gKyB1cHBlcl92YWx1ZSkgJSAyNTYpXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDM6IC8vIEF2ZXJhZ2UgZmlsdGVyIC0tIGNvbnNpZGVycyB0aGUgYXZlcmFnZSBvZiB0aGUgdXBwZXIgYW5kIHRoZSBsZWZ0IHBpeGVsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRleF91cHBlcl92YWx1ZSA9IGkgLSAodG90YWxfY29sdW1ucyArIE1hdGguZmxvb3IoaSAvIHRvdGFsX2NvbHVtbnMpKVxuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXhfdXBwZXJfdmFsdWUgPSBpIC0gKHRvdGFsX2NvbHVtbnMgKyBNYXRoLmZsb29yKGkgLyB0b3RhbF9jb2x1bW5zKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHVwcGVyX3ZhbHVlID0gKGluZGV4X3VwcGVyX3ZhbHVlIDwgMCkgPyAwIDogdW5maWx0ZXJlZF9kYXRhW2luZGV4X3VwcGVyX3ZhbHVlXVxuICAgICAgICAgICAgICAgICAgICAgICAgbGVmdF92YWx1ZSA9ICgoaSAlIHRvdGFsX2NvbHVtbnMpIC0gMiA8IDApID8gMCA6IHVuZmlsdGVyZWRfZGF0YVsoKGkgLSAyKSAlIGRlY29kZVBhcmFtZXRlcnMuY29sdW1ucykgKyBNYXRoLmZsb29yKGkgLyB0b3RhbF9jb2x1bW5zKSAqIChkZWNvZGVQYXJhbWV0ZXJzLmNvbHVtbnMgLSAxKV1cbiAgICAgICAgICAgICAgICAgICAgICAgIHVuZmlsdGVyZWRfZGF0YS5wdXNoKChkYXRhW2ldICsgTWF0aC5mbG9vcigodXBwZXJfdmFsdWUgKyBsZWZ0X3ZhbHVlKSAvIDIpKSAlIDI1NilcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNDogLy8gUGFldGggLS0gdXNlcyB0aHJlZSBuZWlnaGJvdXJpbmcgYnl0ZXMgKGxlZnQsIHVwcGVyIGFuZCB1cHBlciBsZWZ0KSB0byBjb21wdXRlIGEgbGluZWFyIGZ1bmN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRleF91cHBlcl92YWx1ZSA9IGkgLSAodG90YWxfY29sdW1ucyArIE1hdGguZmxvb3IoaSAvIHRvdGFsX2NvbHVtbnMpKVxuICAgICAgICAgICAgICAgICAgICAgICAgdXBwZXJfdmFsdWUgPSAoaW5kZXhfdXBwZXJfdmFsdWUgPCAwKSA/IDAgOiB1bmZpbHRlcmVkX2RhdGFbaW5kZXhfdXBwZXJfdmFsdWVdXG4gICAgICAgICAgICAgICAgICAgICAgICBsZWZ0X3ZhbHVlID0gKChpICUgdG90YWxfY29sdW1ucykgLSAyIDwgMCkgPyAwIDogdW5maWx0ZXJlZF9kYXRhWygoaSAtIDIpICUgZGVjb2RlUGFyYW1ldGVycy5jb2x1bW5zKSArIE1hdGguZmxvb3IoaSAvIHRvdGFsX2NvbHVtbnMpICogKGRlY29kZVBhcmFtZXRlcnMuY29sdW1ucyAtIDEpXVxuICAgICAgICAgICAgICAgICAgICAgICAgbGVmdF91cHBlcl92YWx1ZSA9IChpbmRleF91cHBlcl92YWx1ZSAtIDEgPCAwKSA/IDAgOiB1bmZpbHRlcmVkX2RhdGFbaW5kZXhfdXBwZXJfdmFsdWUgLSAxXVxuICAgICAgICAgICAgICAgICAgICAgICAgdW5maWx0ZXJlZF9kYXRhLnB1c2goKGRhdGFbaV0gKyB0aGlzLnBhZXRoUHJlZGljdG9yKGxlZnRfdmFsdWUsIHVwcGVyX3ZhbHVlLCBsZWZ0X3VwcGVyX3ZhbHVlKSkgJSAyNTYpXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheSh1bmZpbHRlcmVkX2RhdGEpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgdGhlIHBhdGggcHJlZGljdG9yIG9mIHRoZSBnaXZlbiBieWV0c1xuICAgICAqICovXG4gICAgcHJpdmF0ZSBwYWV0aFByZWRpY3RvcihsZWZ0X2J5dGU6IG51bWJlciwgdXBwZXJfYnl0ZTogbnVtYmVyLCB1cHBlcl9sZWZ0X2J5dGU6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGxldCBwID0gbGVmdF9ieXRlICsgdXBwZXJfYnl0ZSAtIHVwcGVyX2xlZnRfYnl0ZVxuICAgICAgICBsZXQgcGEgPSBNYXRoLmFicyhwIC0gbGVmdF9ieXRlKVxuICAgICAgICBsZXQgcGIgPSBNYXRoLmFicyhwIC0gdXBwZXJfYnl0ZSlcbiAgICAgICAgbGV0IHBjID0gTWF0aC5hYnMocCAtIHVwcGVyX2xlZnRfYnl0ZSlcblxuICAgICAgICBpZiAocGEgPD0gcGIgJiYgcGEgPD0gcGMpIHtcbiAgICAgICAgICAgIHJldHVybiBsZWZ0X2J5dGVcbiAgICAgICAgfSBlbHNlIGlmIChwYiA8PSBwYykge1xuICAgICAgICAgICAgcmV0dXJuIHVwcGVyX2J5dGVcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1cHBlcl9sZWZ0X2J5dGVcbiAgICAgICAgfVxuXG4gICAgfVxufVxuIiwiaW1wb3J0IHsgUmVmZXJlbmNlUG9pbnRlciB9IGZyb20gJy4vcGFyc2VyJztcblxuLyoqXG4gKiBUaGUgcmVzdWx0IGNvbnRhaW5zIHRoZSBleHRyYWN0aW9uIHJlc3VsdCBhbmQgdGhlXG4gKiBlbmRfaW5kZXggYWx3YXlzIHBvaW50cyB0byB0aGUgbGFzdCBwb3NpdGlvbiB0aGF0IGRlc2NyaWJlcyB0aGUgZXh0cmFjdGVkIHJlc3VsdC5cbiAqXG4gKiBOT1QgT05FIFBPU0lUSU9OIEFIRUFEIEFORCBOTyBUUkFJTElORyBTUEFDRVMuXG4gKiAqL1xuZXhwb3J0IGludGVyZmFjZSBFeHRyYWN0aW9uUmVzdWx0IHtcbiAgICByZXN1bHQ6IGFueVxuICAgIC8qXG4gICAgICogVGhlIHN0YXJkIGluZGV4IGhvbGRzIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHJlYWQgd29yZC4gVGhpcyBpcyBvZiBwYXJ0aWN1bGFyIGltcG9ydGFuY2UgaW4gY2FzZSBvZiBjb21tZW50cy4gQ29tbWVudHMgYXJlIGlnbm9yZWQgYW5kIHRoYW4gdGhlIG5leHQgd29yZCBtaWdodCBzdGFydCBhdCBhIHN1YnNlcXVlbnQgaW5kZXhcbiAgICAgKiAqL1xuICAgIHN0YXJ0X2luZGV4OiBudW1iZXJcbiAgICBlbmRfaW5kZXg6IG51bWJlclxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBERlZlcnNpb24ge1xuICAgIG1ham9yOiBudW1iZXJcbiAgICBtaW5vcjogbnVtYmVyXG59XG5cblxuLyoqXG4gKiBUaGlzIGNsYXNzIHByb3ZpZGVzIG1ldGhvZHMgdG8gbmF2aWdhdGUgdGhyb3VnaCB0aGUgYnl0ZSBhcnJheSByZXByZXNlbnRpbmcgdGhlIFBERiBkb2N1bWVudFxuICogKi9cbmV4cG9ydCBjbGFzcyBVdGlsIHtcblxuICAgIHB1YmxpYyBzdGF0aWMgVkVSU0lPTjogbnVtYmVyW10gPSBbMzcsIDgwLCA2OCwgNzAsIDQ1XSAvLyAlUERGLVxuICAgIHB1YmxpYyBzdGF0aWMgTlVMTDogbnVtYmVyW10gPSBbMTEwLCAxMTcsIDEwOCwgMTA4XSAvLyBudWxsXG4gICAgcHVibGljIHN0YXRpYyBET1Q6IG51bWJlciA9IDQ2XG4gICAgcHVibGljIHN0YXRpYyBDUjogbnVtYmVyID0gMTNcbiAgICBwdWJsaWMgc3RhdGljIExGOiBudW1iZXIgPSAxMFxuICAgIHB1YmxpYyBzdGF0aWMgVFlQRTogc3RyaW5nID0gXCIvVHlwZSBcIlxuICAgIHB1YmxpYyBzdGF0aWMgU1BBQ0U6IG51bWJlciA9IDMyXG4gICAgcHVibGljIHN0YXRpYyBPQko6IG51bWJlcltdID0gWzExMSwgOTgsIDEwNl0gLy8gJ29iaidcbiAgICBwdWJsaWMgc3RhdGljIEVORE9CSjogbnVtYmVyW10gPSBbMTAxLCAxMTAsIDEwMCwgMTExLCA5OCwgMTA2XSAvLyAnZW5kb2JqJ1xuICAgIHB1YmxpYyBzdGF0aWMgQVJSQVlfU1RBUlQ6IG51bWJlcltdID0gWzkxXSAvLyAnWydcbiAgICBwdWJsaWMgc3RhdGljIEFSUkFZX0VORDogbnVtYmVyW10gPSBbOTNdIC8vICddJ1xuICAgIHB1YmxpYyBzdGF0aWMgTElURVJBTF9TVFJJTkdfU1RBUlQ6IG51bWJlcltdID0gWzQwXSAvLyAnKCdcbiAgICBwdWJsaWMgc3RhdGljIEhFWF9TVFJJTkdfU1RBUlQ6IG51bWJlcltdID0gWzYwXSAvLyAnPCdcbiAgICBwdWJsaWMgc3RhdGljIExJVEVSQUxfU1RSSU5HX0VORDogbnVtYmVyW10gPSBbNDFdIC8vICcpJ1xuICAgIHB1YmxpYyBzdGF0aWMgSEVYX1NUUklOR19FTkQ6IG51bWJlcltdID0gWzYyXSAvLyAnPidcbiAgICBwdWJsaWMgc3RhdGljIFI6IG51bWJlcltdID0gWzgyXSAvLyAnUidcbiAgICBwdWJsaWMgc3RhdGljIEFOTk9UUzogbnVtYmVyW10gPSBbNDcsIDY1LCAxMTAsIDExMCwgMTExLCAxMTYsIDExNV0gLy8gJy9Bbm5vdCdcbiAgICBwdWJsaWMgc3RhdGljIERJQ1RfU1RBUlQ6IG51bWJlcltdID0gWzYwLCA2MF0gLy8gJzw8J1xuICAgIHB1YmxpYyBzdGF0aWMgRElDVF9FTkQ6IG51bWJlcltdID0gWzYyLCA2Ml0gLy8gJz4+J1xuICAgIHB1YmxpYyBzdGF0aWMgUEFHRTogbnVtYmVyW10gPSBbNDcsIDgwLCA5NywgMTAzLCAxMDFdXG4gICAgcHVibGljIHN0YXRpYyBTSVpFOiBudW1iZXJbXSA9IFs0NywgODMsIDEwNSwgMTIyLCAxMDFdIC8vIC9TaXplXG4gICAgcHVibGljIHN0YXRpYyBST09UOiBudW1iZXJbXSA9IFs0NywgODIsIDExMSwgMTExLCAxMTZdIC8vIC9Sb290XG4gICAgcHVibGljIHN0YXRpYyBQUkVWOiBudW1iZXJbXSA9IFs0NywgODAsIDExNCwgMTAxLCAxMThdIC8vIC9QcmV2XG4gICAgcHVibGljIHN0YXRpYyBTVEFSVFhSRUY6IG51bWJlcltdID0gWzExNSwgMTE2LCA5NywgMTE0LCAxMTYsIDEyMCwgMTE0LCAxMDEsIDEwMl0gLy8gPSAnc3RhcnR4cmVmJ1xuICAgIHB1YmxpYyBzdGF0aWMgWFJFRjogbnVtYmVyW10gPSBbMTIwLCAxMTQsIDEwMSwgMTAyXSAvLyA9ICd4cmVmJ1xuICAgIHB1YmxpYyBzdGF0aWMgU1RSRUFNOiBudW1iZXJbXSA9IFsxMTUsIDExNiwgMTE0LCAxMDEsIDk3LCAxMDldIC8vID0gJ3N0cmVhbSdcbiAgICBwdWJsaWMgc3RhdGljIFRSQUlMRVI6IG51bWJlcltdID0gWzExNiwgMTE0LCA5NywgMTA1LCAxMDgsIDEwMSwgMTE0XSAvLyA9ICd0cmFpbGVyJ1xuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdHMgdGhlIHZlcnNpb24gaW5mb3JtYXRpb24gb2YgYSBQREYgZmlsZVxuICAgICAqICovXG4gICAgcHVibGljIHN0YXRpYyBleHRyYWN0VmVyc2lvbihkYXRhOiBVaW50OEFycmF5LCBpbmRleDogbnVtYmVyID0gMCk6IFBERlZlcnNpb24ge1xuXG4gICAgICAgIGxldCBwdHJfdmVyc2lvbl9zdGFydCA9IFV0aWwubG9jYXRlU2VxdWVuY2UoVXRpbC5WRVJTSU9OLCBkYXRhLCBpbmRleCkgKyBVdGlsLlZFUlNJT04ubGVuZ3RoXG4gICAgICAgIGxldCBwdHJfZGVsaW1pdGVyID0gVXRpbC5sb2NhdGVTZXF1ZW5jZShbVXRpbC5ET1RdLCBkYXRhLCBwdHJfdmVyc2lvbl9zdGFydClcbiAgICAgICAgbGV0IG1ham9yX3ZlcnNpb24gPSBVdGlsLmV4dHJhY3ROdW1iZXIoZGF0YSwgcHRyX3ZlcnNpb25fc3RhcnQsIHB0cl9kZWxpbWl0ZXIpLnJlc3VsdFxuICAgICAgICBsZXQgcHRyX2VuZCA9IFV0aWwubG9jYXRlRGVsaW1pdGVyKGRhdGEsIHB0cl9kZWxpbWl0ZXIpXG4gICAgICAgIGxldCBtaW5vcl92ZXJzaW9uID0gVXRpbC5leHRyYWN0TnVtYmVyKGRhdGEsIHB0cl9kZWxpbWl0ZXIgKyAxLCBwdHJfZW5kKS5yZXN1bHRcblxuICAgICAgICByZXR1cm4geyBtYWpvcjogbWFqb3JfdmVyc2lvbiwgbWlub3I6IG1pbm9yX3ZlcnNpb24gfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnN1bWVzIGNvbW1lbnRzIHRoYXQgaXNcbiAgICAgKiAgJyUuLi4uLi4uLi4uLi4uLi4uLi4gRU9MJ1xuICAgICAqXG4gICAgICogIEFsc28gaGFuZGxlcyBtdWxpdHBsZSBsaW5lIGNvbW1lbnRzXG4gICAgICogKi9cbiAgICBwcml2YXRlIHN0YXRpYyBjb25zdW1lQ29tbWVudChkYXRhIDogVWludDhBcnJheSwgaW5kZXg6IG51bWJlcikgOiBudW1iZXIge1xuICAgICAgICB3aGlsZSAoZGF0YVtpbmRleF0gIT09IDEzICYmIGRhdGFbaW5kZXhdICE9IDEwICYmIGluZGV4IDwgZGF0YS5sZW5ndGgpKytpbmRleFxuICAgICAgICBpbmRleCA9IFV0aWwuc2tpcFNwYWNlcyhkYXRhLCBpbmRleClcblxuICAgICAgICBpZiAoZGF0YVtpbmRleF0gPT0gMzcpIC8vJVxuICAgICAgICAgICAgcmV0dXJuIFV0aWwuY29uc3VtZUNvbW1lbnQoZGF0YSwgaW5kZXgpXG5cbiAgICAgICAgcmV0dXJuIGluZGV4XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgbmV4dCB3b3JkLiBUaGVzZSBhcmUgYnl0ZXMgdGhhdCBhcmUgbm90IHNlcGFyYXRlZCBieSBhIGRlbGltaXRlciBhbmQgYSBwdHIgdG8gdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSB3b3JkIGVuZHNcbiAgICAgKiBJdCBpZ25vcmVzL3NraXBzIGNvbW1lbnRzLlxuICAgICAqICovXG4gICAgcHVibGljIHN0YXRpYyByZWFkTmV4dFdvcmQoZGF0YTogVWludDhBcnJheSwgaW5kZXg6IG51bWJlciA9IDApOiBFeHRyYWN0aW9uUmVzdWx0IHtcbiAgICAgICAgaWYgKGluZGV4ID49IGRhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4geyByZXN1bHQ6IHVuZGVmaW5lZCwgc3RhcnRfaW5kZXg6IGluZGV4LCBlbmRfaW5kZXg6IGRhdGEubGVuZ3RoIC0gMSB9XG4gICAgICAgIH1cblxuICAgICAgICBpbmRleCA9IFV0aWwuc2tpcFNwYWNlcyhkYXRhLCBpbmRleClcblxuICAgICAgICBpZiAoZGF0YVtpbmRleF0gPT09IDM3KSB7IC8vJVxuICAgICAgICAgICAgaW5kZXggPSBVdGlsLmNvbnN1bWVDb21tZW50KGRhdGEsIGluZGV4KVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHN0YXJ0X2luZGV4ID0gaW5kZXhcblxuICAgICAgICBpbmRleCsrXG5cbiAgICAgICAgd2hpbGUgKCFVdGlsLmlzRGVsaW1pdGVyKGRhdGFbaW5kZXhdKSAmJiBpbmRleCA8IGRhdGEubGVuZ3RoKSsraW5kZXhcblxuICAgICAgICBpZiAoaW5kZXggPD0gZGF0YS5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm4geyByZXN1bHQ6IGRhdGEuc2xpY2Uoc3RhcnRfaW5kZXgsIGluZGV4KSwgc3RhcnRfaW5kZXg6IHN0YXJ0X2luZGV4LCBlbmRfaW5kZXg6IGluZGV4IC0gMSB9XG5cbiAgICAgICAgcmV0dXJuIHsgcmVzdWx0OiB1bmRlZmluZWQsIHN0YXJ0X2luZGV4OiBzdGFydF9pbmRleCwgZW5kX2luZGV4OiBpbmRleCAtIDEgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFzc3VtZXMgdGhhdCBhdCBwb3NpdGlvbiBpbmRleCBpcyBhIGRlbGltaXRlciBhbmQgdGhhbiBydW5zIGFzIGxvbmcgZm9yd2FyZCB1bnRpbCBpdCBmaW5kc1xuICAgICAqIGFub3RoZXIgZGVsaW1pdGVyIG9yIHJlYWNoZXMgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnRcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgc2tpcERlbGltaXRlcihkYXRhOiBVaW50OEFycmF5LCBpbmRleDogbnVtYmVyID0gMCk6IG51bWJlciB7XG4gICAgICAgIHdoaWxlIChpbmRleCA8IGRhdGEubGVuZ3RoICYmIHRoaXMuaXNEZWxpbWl0ZXIoZGF0YVtpbmRleF0pKSsraW5kZXhcblxuICAgICAgICByZXR1cm4gaW5kZXhcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTa2lwcyBvbmx5IHNwYWNlc1xuICAgICAqICovXG4gICAgcHVibGljIHN0YXRpYyBza2lwU3BhY2VzKGRhdGE6IFVpbnQ4QXJyYXkgfCBudW1iZXJbXSwgaW5kZXg6IG51bWJlciA9IDApOiBudW1iZXIge1xuICAgICAgICB3aGlsZSAoaW5kZXggPCBkYXRhLmxlbmd0aCAmJiAoZGF0YVtpbmRleF0gPT09IDEwIHx8IGRhdGFbaW5kZXhdID09PSA5IHx8IGRhdGFbaW5kZXhdID09PSAxMyB8fCBkYXRhW2luZGV4XSA9PT0gMzIpKSsraW5kZXhcblxuICAgICAgICByZXR1cm4gaW5kZXhcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTa2lwcyBvbmx5IHNwYWNlc1xuICAgICAqICovXG4gICAgcHVibGljIHN0YXRpYyBza2lwU3BhY2VzUmV2ZXJzZShkYXRhOiBVaW50OEFycmF5IHwgbnVtYmVyW10sIGluZGV4OiBudW1iZXIgPSAwKTogbnVtYmVyIHtcbiAgICAgICAgd2hpbGUgKGluZGV4ID4gMCAmJiAoZGF0YVtpbmRleF0gPT09IDEwIHx8IGRhdGFbaW5kZXhdID09PSA5IHx8IGRhdGFbaW5kZXhdID09PSAxMyB8fCBkYXRhW2luZGV4XSA9PT0gMzIpKS0taW5kZXhcblxuICAgICAgICByZXR1cm4gaW5kZXhcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBc3N1bWVzIHRoYXQgYXQgcG9zaXRpb24gaW5kZXggaXMgYSBkZWxpbWl0ZXIgYW5kIHRoYW4gcnVucyBhcyBsb25nIGJhY2t3YXJkcyB1bnRpbCBpdCBmaW5kc1xuICAgICAqIGFub3RoZXIgZGVsaW1pdGVyIG9yIHJlYWNoZXMgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnRcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgc2tpcERlbGltaXRlclJldmVyc2UoZGF0YTogVWludDhBcnJheSwgaW5kZXg6IG51bWJlciA9IDApOiBudW1iZXIge1xuICAgICAgICB3aGlsZSAoaW5kZXggPiAwICYmIHRoaXMuaXNEZWxpbWl0ZXIoZGF0YVtpbmRleF0pKS0taW5kZXhcblxuICAgICAgICByZXR1cm4gaW5kZXhcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmFuc2Zvcm1zIGEgc3RyaW5nIGludG8gYW4gYXJyYXkgb2YgdGhlIGNvcnJlc3BvbmRpbmcgYXNjaWkgdmFsdWVzXG4gICAgICogKi9cbiAgICBwdWJsaWMgc3RhdGljIGNvbnZlcnRTdHJpbmdUb0FzY2lpKHRvQ29udmVydDogc3RyaW5nKTogbnVtYmVyW10ge1xuICAgICAgICBsZXQgYXNjaWlzOiBudW1iZXJbXSA9IFtdXG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0b0NvbnZlcnQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGFzY2lpcy5wdXNoKCt0b0NvbnZlcnQuY2hhckNvZGVBdChpKSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhc2NpaXNcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhdGljIGlzU3BhY2UodmFsdWU6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdmFsdWUgPT09IFV0aWwuTEYgfHxcbiAgICAgICAgICAgIHZhbHVlID09PSBVdGlsLkNSIHx8XG4gICAgICAgICAgICB2YWx1ZSA9PT0gVXRpbC5TUEFDRVxuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgaXNEZWxpbWl0ZXIodmFsdWU6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gVXRpbC5pc1NwYWNlKHZhbHVlKSB8fFxuICAgICAgICAgICAgdmFsdWUgPT09IDQ3IHx8IC8vIC9cbiAgICAgICAgICAgIHZhbHVlID09PSAzNyB8fCAvLyAlXG4gICAgICAgICAgICB2YWx1ZSA9PT0gNjAgfHwgLy8gPFxuICAgICAgICAgICAgdmFsdWUgPT09IDYyIHx8IC8vID5cbiAgICAgICAgICAgIHZhbHVlID09PSA5MSB8fCAvLyBbXG4gICAgICAgICAgICB2YWx1ZSA9PT0gOTMgfHwgLy8gXVxuICAgICAgICAgICAgdmFsdWUgPT09IDQwIHx8IC8vIChcbiAgICAgICAgICAgIHZhbHVlID09PSA0MSAvLyApXG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBpc051bWJlcih2YWx1ZTogbnVtYmVyKSA6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdmFsdWUgPj0gNDggJiYgdmFsdWUgPD0gNTcvLyAwIDw9IHZhbHVlIDw9ICA5XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VhcmNoIHRoZSBzZXF1ZW5jZSBpbiBkYXRhIHN0YXJ0aW5nIGF0IHRoZSBvZmZzZXRcbiAgICAgKlxuICAgICAqIFNldCB0aGUgJ2Nsb3NlZCcgZmxhZyB0byBjaGVjayBpZiB0aGUgc3VjZWVkaW5nIGNoYXIgYWZ0ZXIgdGhlIHNlcXVlbmNlIGlzIGEgbGluZSBmZWVkICgxMCksIGEgY2FycmlhZ2UgcmV0dXJuICgxMyksIHRoZSBlbmRcbiAgICAgKiBvZiB0aGUgd2hvbGUgc2VxdWVuY2Ugb3IgYSBzcGFjZSAoMzIpXG4gICAgICogKi9cbiAgICBwdWJsaWMgc3RhdGljIGxvY2F0ZVNlcXVlbmNlKHNlcXVlbmNlOiBudW1iZXJbXSwgZGF0YTogVWludDhBcnJheSwgb2Zmc2V0OiBudW1iZXIgPSAwLCBjbG9zZWQ6IGJvb2xlYW4gPSBmYWxzZSk6IG51bWJlciB7XG4gICAgICAgIGxldCBpID0gb2Zmc2V0XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBpIDwgZGF0YS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgaWYgKGRhdGFbaV0gPT0gc2VxdWVuY2Vbal0pIHtcbiAgICAgICAgICAgICAgICBpZiAoaiA9PSBzZXF1ZW5jZS5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghY2xvc2VkIHx8IGRhdGEubGVuZ3RoID09IGkgKyAxIHx8IHRoaXMuaXNEZWxpbWl0ZXIoZGF0YVtpICsgMV0pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaSAtIChzZXF1ZW5jZS5sZW5ndGggLSAxKVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgaiA9IC0xXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgKytqXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGogPSAwXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gLTFcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWFyY2ggdGhlIHNlcXVlbmNlIGluIGRhdGEgc3RhcnRpbmcgYXQgdGhlIG9mZnNldCBpbiByZXZlcnNlIGRpcmVjdGlvblxuICAgICAqXG4gICAgICogU2V0IHRoZSAnY2xvc2VkJyBmbGFnIHRvIGNoZWNrIGlmIHRoZSBwcmVjZWRpbmcgY2hhciBiZWZvcmUgdGhlIHNlcXVlbmNlIGlzIGEgbGluZSBmZWVkICgxMCksIGEgY2FycmlhZ2UgcmV0dXJuICgxMyksIHRoZSBzdGFydFxuICAgICAqIG9mIHRoZSB3aG9sZSBkYXRhIHNlcXVlbmNlIG9yIGEgc3BhY2UgKDMyKVxuICAgICAqICovXG4gICAgcHVibGljIHN0YXRpYyBsb2NhdGVTZXF1ZW5jZVJldmVyc2VkKHNlcXVlbmNlOiBudW1iZXJbXSwgZGF0YTogVWludDhBcnJheSwgb2Zmc2V0OiBudW1iZXIgPSBkYXRhLmxlbmd0aCAtIDEsIGNsb3NlZDogYm9vbGVhbiA9IGZhbHNlKTogbnVtYmVyIHtcbiAgICAgICAgbGV0IGkgPSBvZmZzZXRcblxuICAgICAgICBmb3IgKGxldCBqID0gc2VxdWVuY2UubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgIGlmIChkYXRhW2ldID09IHNlcXVlbmNlW2pdKSB7XG4gICAgICAgICAgICAgICAgaWYgKGogPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWNsb3NlZCB8fCBpIC0gMSA8IDAgfHwgdGhpcy5pc0RlbGltaXRlcihkYXRhW2kgLSAxXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBqID0gc2VxdWVuY2UubGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLS1qXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGogPSBzZXF1ZW5jZS5sZW5ndGggLSAxXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gLTFcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMb2NhdGVzIHRoZSBpbmRleCBiZWZvcmUgdGhlIG5leHQgZGVsaW1pdGVyLiBEZWxpbWl0ZXJzIGNhbiBiZSBhIGxpbmUgZmVlZCAoMTApLCBhIGNhcnJpYWdlIHJldHVybiAoMTMpLCB0aGUgZW5kIG9mIHRoZSB3aG9sZSBzZXF1ZW5jZVxuICAgICAqIG9yIGEgc3BhY2UgKDMyKVxuICAgICAqICovXG4gICAgcHVibGljIHN0YXRpYyBsb2NhdGVEZWxpbWl0ZXIoZGF0YTogVWludDhBcnJheSwgb2Zmc2V0OiBudW1iZXIgPSAwKTogbnVtYmVyIHtcbiAgICAgICAgd2hpbGUgKG9mZnNldCA8IGRhdGEubGVuZ3RoICYmICF0aGlzLmlzRGVsaW1pdGVyKGRhdGFbb2Zmc2V0XSkpKytvZmZzZXRcblxuICAgICAgICByZXR1cm4gb2Zmc2V0IC0gMVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExvY2F0ZXMgdGhlIGluZGV4IGFmdGVyIHRoZSBsYXN0IGRlbGltaXRlci4gRGVsaW1pdGVycyBjYW4gYmUgYSBsaW5lIGZlZWQgKDEwKSwgYSBjYXJyaWFnZSByZXR1cm4gKDEzKSwgdGhlIGVuZCBvZiB0aGUgd2hvbGUgc2VxdWVuY2VcbiAgICAgKiBvciBhIHNwYWNlICgzMilcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgbG9jYXRlRGVsaW1pdGVyUmV2ZXJzZWQoZGF0YTogVWludDhBcnJheSwgb2Zmc2V0OiBudW1iZXIgPSBkYXRhLmxlbmd0aCAtIDEpOiBudW1iZXIge1xuICAgICAgICB3aGlsZSAob2Zmc2V0ID4gMCAmJiAhdGhpcy5pc0RlbGltaXRlcihkYXRhW29mZnNldF0pKS0tb2Zmc2V0XG5cbiAgICAgICAgaWYgKG9mZnNldCA8PSAwKVxuICAgICAgICAgICAgcmV0dXJuIG9mZnNldFxuXG4gICAgICAgIHJldHVybiBvZmZzZXQgLSAxXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdCBhbiBvYmplY3QgaWRlbnRpZmllclxuICAgICAqIDxJRD4gPEdFTj4gb2JqXG4gICAgICogKi9cbiAgICBwdWJsaWMgc3RhdGljIGV4dHJhY3RPYmplY3RJZChkYXRhOiBVaW50OEFycmF5LCBpbmRleDogbnVtYmVyKTogUmVmZXJlbmNlUG9pbnRlciB7XG4gICAgICAgIGluZGV4ID0gVXRpbC5za2lwRGVsaW1pdGVyKGRhdGEsIGluZGV4KVxuXG4gICAgICAgIGxldCBlbmRfb2JqX3B0ciA9IFV0aWwubG9jYXRlRGVsaW1pdGVyKGRhdGEsIGluZGV4ICsgMSlcblxuICAgICAgICBsZXQgb2JqID0gVXRpbC5leHRyYWN0TnVtYmVyKGRhdGEsIGluZGV4LCBlbmRfb2JqX3B0cikucmVzdWx0XG5cbiAgICAgICAgbGV0IHN0YXJ0X2dlbl9wdHIgPSBVdGlsLnNraXBEZWxpbWl0ZXIoZGF0YSwgZW5kX29ial9wdHIgKyAxKVxuICAgICAgICBsZXQgZW5kX2dlbl9wdHIgPSBVdGlsLmxvY2F0ZURlbGltaXRlcihkYXRhLCBzdGFydF9nZW5fcHRyICsgMSlcblxuICAgICAgICBsZXQgZ2VuID0gVXRpbC5leHRyYWN0TnVtYmVyKGRhdGEsIHN0YXJ0X2dlbl9wdHIsIGVuZF9nZW5fcHRyKS5yZXN1bHRcblxuICAgICAgICByZXR1cm4geyBvYmo6IG9iaiwgZ2VuZXJhdGlvbjogZ2VuIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeHRyYWN0IHRoZSByZWZlcmVuY2Ugc3RhcnRpbmcgYXQgcG9zaXRpb24gJ2luZGV4J1xuICAgICAqICovXG4gICAgcHVibGljIHN0YXRpYyBleHRyYWN0UmVmZXJlbmNlKGRhdGE6IFVpbnQ4QXJyYXksIGluZGV4OiBudW1iZXIpOiBVaW50OEFycmF5IHtcbiAgICAgICAgaW5kZXggPSBVdGlsLnNraXBEZWxpbWl0ZXIoZGF0YSwgaW5kZXgpXG4gICAgICAgIGxldCByX2luZGV4ID0gdGhpcy5sb2NhdGVTZXF1ZW5jZSh0aGlzLmNvbnZlcnRTdHJpbmdUb0FzY2lpKFwiIFJcIiksIGRhdGEsIGluZGV4LCB0cnVlKVxuXG4gICAgICAgIHJldHVybiBkYXRhLnNsaWNlKGluZGV4LCByX2luZGV4KVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSByZWZlcmVuY2UgYXMgdHlwZWQgb2JqZWN0XG4gICAgICogKi9cbiAgICBwdWJsaWMgc3RhdGljIGV4dHJhY3RSZWZlcmVuY2VUeXBlZChkYXRhOiBVaW50OEFycmF5LCBpbmRleDogbnVtYmVyKTogRXh0cmFjdGlvblJlc3VsdCB7XG5cbiAgICAgICAgbGV0IHJlZl9kYXRhID0gdGhpcy5leHRyYWN0UmVmZXJlbmNlKGRhdGEsIGluZGV4KVxuXG4gICAgICAgIGxldCBkZWxfaW5kZXggPSB0aGlzLmxvY2F0ZURlbGltaXRlcihyZWZfZGF0YSwgMClcblxuICAgICAgICBsZXQgaWQgPSB0aGlzLmV4dHJhY3ROdW1iZXIocmVmX2RhdGEsIDAsIGRlbF9pbmRleCkucmVzdWx0XG4gICAgICAgIGxldCBnZW4gPSB0aGlzLmV4dHJhY3ROdW1iZXIocmVmX2RhdGEsIGRlbF9pbmRleCArIDIpLnJlc3VsdFxuXG4gICAgICAgIHJldHVybiB7IHJlc3VsdDogeyBvYmo6IGlkLCBnZW5lcmF0aW9uOiBnZW4gfSwgc3RhcnRfaW5kZXg6IGluZGV4LCBlbmRfaW5kZXg6IGluZGV4ICsgcmVmX2RhdGEubGVuZ3RoICsgMSB9IC8vICsgX1JcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeHRyYWN0cyBhIHN0cmluZyBpbiBIZXggbm90YXRpb24gPC4uLj5cbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgZXh0cmFjdEhleFN0cmluZyhkYXRhOiBVaW50OEFycmF5LCBpbmRleDogbnVtYmVyKTogRXh0cmFjdGlvblJlc3VsdCB7XG4gICAgICAgIGxldCBzdHJpbmdfc3RhcnQgPSBVdGlsLmxvY2F0ZVNlcXVlbmNlKFV0aWwuSEVYX1NUUklOR19TVEFSVCwgZGF0YSwgaW5kZXgpXG4gICAgICAgIGxldCBzdHJpbmdfZW5kID0gVXRpbC5sb2NhdGVTZXF1ZW5jZShVdGlsLkhFWF9TVFJJTkdfRU5ELCBkYXRhLCBpbmRleClcblxuICAgICAgICBkYXRhID0gZGF0YS5zbGljZShzdHJpbmdfc3RhcnQgKyAxLCBzdHJpbmdfZW5kKVxuXG4gICAgICAgIHJldHVybiB7IHJlc3VsdDogbmV3IFVpbnQ4QXJyYXkoVXRpbC5jb252ZXJ0SGV4U3RyaW5nVG9CeXRlQXJyYXkoZGF0YSkpLCBzdGFydF9pbmRleDogc3RyaW5nX3N0YXJ0LCBlbmRfaW5kZXg6IHN0cmluZ19lbmQgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhdGNzIGEgc3RyaW5nICguLi4pXG4gICAgICogKi9cbiAgICBwdWJsaWMgc3RhdGljIGV4dHJhY3RTdHJpbmcoZGF0YTogVWludDhBcnJheSwgaW5kZXg6IG51bWJlcik6IEV4dHJhY3Rpb25SZXN1bHQge1xuICAgICAgICBsZXQgc3RyaW5nX3N0YXJ0ID0gVXRpbC5sb2NhdGVTZXF1ZW5jZShVdGlsLkxJVEVSQUxfU1RSSU5HX1NUQVJULCBkYXRhLCBpbmRleClcbiAgICAgICAgbGV0IHN0cmluZ19lbmQgPSBVdGlsLmxvY2F0ZVNlcXVlbmNlKFV0aWwuTElURVJBTF9TVFJJTkdfRU5ELCBkYXRhLCBpbmRleClcblxuICAgICAgICB3aGlsZSAoZGF0YVtzdHJpbmdfZW5kIC0gMV0gPT09IDkyKSB7IC8vIFwiXFxcIiBlc2NhcGVcbiAgICAgICAgICAgIHN0cmluZ19lbmQgPSBVdGlsLmxvY2F0ZVNlcXVlbmNlKFV0aWwuTElURVJBTF9TVFJJTkdfRU5ELCBkYXRhLCBzdHJpbmdfZW5kICsgMSlcbiAgICAgICAgfVxuXG4gICAgICAgIGRhdGEgPSBkYXRhLnNsaWNlKHN0cmluZ19zdGFydCArIDEsIHN0cmluZ19lbmQpXG5cbiAgICAgICAgcmV0dXJuIHsgcmVzdWx0OiBVdGlsLnVuZXNjYXBlU3RyaW5nKGRhdGEpLCBzdGFydF9pbmRleDogc3RyaW5nX3N0YXJ0LCBlbmRfaW5kZXg6IHN0cmluZ19lbmQgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGFuIG9wdGlvblxuICAgICAqIC88b3B0aW9uPlxuICAgICAqXG4gICAgICogc28gZm9yIGluc3RhbmNlIGZvciAvSGlnaGxpZ2h0IGl0IHdvdWxkIHJldHVybiAnSGlnaGxpZ2h0J1xuICAgICAqXG4gICAgICogVGhlIGluZGV4IG11c3QgcG9pbnQgdG8gdGhlIFwiL1wiXG4gICAgICogKi9cbiAgICBwdWJsaWMgc3RhdGljIGV4dHJhY3RPcHRpb25WYWx1ZShkYXRhOiBVaW50OEFycmF5LCBpbmRleDogbnVtYmVyID0gMCk6IEV4dHJhY3Rpb25SZXN1bHQge1xuXG4gICAgICAgIGlmIChkYXRhW2luZGV4XSAhPT0gNDcpXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcIm1pc3BsYWNlZCBvcHRpb24gdmFsdWUgcG9pbnRlclwiKVxuXG4gICAgICAgIGxldCBlbmQgPSBVdGlsLmxvY2F0ZURlbGltaXRlcihkYXRhLCBpbmRleCArIDEpXG5cbiAgICAgICAgcmV0dXJuIHsgcmVzdWx0OiBVdGlsLmNvbnZlcnRBc2NpaVRvU3RyaW5nKEFycmF5LmZyb20oZGF0YS5zbGljZShpbmRleCArIDEsIGVuZCArIDEpKSksIHN0YXJ0X2luZGV4OiBpbmRleCwgZW5kX2luZGV4OiBlbmQgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgYXNjaWkgZW5jb2RlZCBudW1iZXIgb2YgdGhlIFBERiBmaWxlXG4gICAgICogKi9cbiAgICBwdWJsaWMgc3RhdGljIGV4dHJhY3ROdW1iZXIoZGF0YTogVWludDhBcnJheSwgc3RhcnQ6IG51bWJlciwgZW5kOiBudW1iZXIgPSAtMSk6IEV4dHJhY3Rpb25SZXN1bHQge1xuICAgICAgICBzdGFydCA9IFV0aWwuc2tpcERlbGltaXRlcihkYXRhLCBzdGFydClcblxuICAgICAgICBpZiAoLTEgPT0gZW5kKSB7XG4gICAgICAgICAgICBlbmQgPSBVdGlsLmxvY2F0ZURlbGltaXRlcihkYXRhLCBzdGFydClcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbmQgPCBzdGFydCkge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoYENvdWxkIG5vdCBpZGVudGlmeSBudW1iZXIgYm91bmRzOiBbJHtzdGFydH0sJHtlbmR9XWApXG4gICAgICAgIH1cblxuICAgICAgICBsZXQgc3RyX2lkID0gXCJcIlxuXG4gICAgICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8PSBlbmQ7ICsraSkge1xuICAgICAgICAgICAgc3RyX2lkICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoZGF0YVtpXSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChcIlwiID09PSBzdHJfaWQpIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKGBDb3VsZCBub3QgcGFyc2UgbnVtYmVyIGF0IHBvc2l0aW9uICR7c3RhcnR9YClcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7IHJlc3VsdDogK3N0cl9pZCwgc3RhcnRfaW5kZXg6IHN0YXJ0LCBlbmRfaW5kZXg6IGVuZCB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhlIGdpdmVuIGRhdGUgaW50byBQREYgZm9ybWF0dGluZ1xuICAgICAqICovXG4gICAgcHVibGljIHN0YXRpYyBjb252ZXJ0RGF0ZVRvUERGRGF0ZShkYXRlOiBEYXRlKTogc3RyaW5nIHtcbiAgICAgICAgbGV0IGRhdGVfc3RyID0gXCJEOlwiXG4gICAgICAgIGRhdGVfc3RyICs9IGRhdGUuZ2V0RnVsbFllYXIoKVxuICAgICAgICBsZXQgbW9udGg6IHN0cmluZyA9IFN0cmluZyhkYXRlLmdldE1vbnRoKCkgKyAxKVxuICAgICAgICBkYXRlX3N0ciArPSAobW9udGgubGVuZ3RoID09IDEgPyBcIjBcIiA6IFwiXCIpICsgbW9udGhcbiAgICAgICAgbGV0IGRheTogc3RyaW5nID0gU3RyaW5nKGRhdGUuZ2V0RGF0ZSgpKVxuICAgICAgICBkYXRlX3N0ciArPSAoZGF5Lmxlbmd0aCA9PSAxID8gXCIwXCIgOiBcIlwiKSArIGRheVxuICAgICAgICBsZXQgaG91cnM6IHN0cmluZyA9IFN0cmluZyhkYXRlLmdldEhvdXJzKCkpXG4gICAgICAgIGRhdGVfc3RyICs9IChob3Vycy5sZW5ndGggPT0gMSA/IFwiMFwiIDogXCJcIikgKyBob3Vyc1xuICAgICAgICBsZXQgbWludXRlczogc3RyaW5nID0gU3RyaW5nKGRhdGUuZ2V0TWludXRlcygpKVxuICAgICAgICBkYXRlX3N0ciArPSAobWludXRlcy5sZW5ndGggPT0gMSA/IFwiMFwiIDogXCJcIikgKyBtaW51dGVzXG4gICAgICAgIGxldCBzZWNvbmRzOiBzdHJpbmcgPSBTdHJpbmcoZGF0ZS5nZXRTZWNvbmRzKCkpXG4gICAgICAgIGRhdGVfc3RyICs9IChzZWNvbmRzLmxlbmd0aCA9PSAxID8gXCIwXCIgOiBcIlwiKSArIHNlY29uZHNcbiAgICAgICAgcmV0dXJuIGRhdGVfc3RyXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYSB1bmljb2RlIHNlcXVlbmNlIGludG8gYSBzdHJpbmdcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY29udmVydFVuaWNvZGVUb1N0cmluZyh2YWw6IFVpbnQ4QXJyYXkpOiBzdHJpbmcge1xuICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgVWludDhBcnJheSlcbiAgICAgICAgICAgIHZhbCA9IG5ldyBVaW50OEFycmF5KHZhbClcblxuICAgICAgICBpZiAodmFsWzBdID09PSAyNTQgJiYgdmFsWzFdID09PSAyNTUpIHtcbiAgICAgICAgICAgIHZhbCA9IHZhbC5zbGljZSgyLCB2YWwubGVuZ3RoKVxuXG4gICAgICAgICAgICBsZXQgdWludFRvU3RyaW5nID0gKHVpbnRBcnJheTogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IHJldCA9IFwiXCJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHVpbnRBcnJheS5sZW5ndGggLSAxOyBpICs9IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKHVpbnRBcnJheVtpXSA8PCA4KSB8IHVpbnRBcnJheVtpICsgMV0gJiAweEZGKVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiByZXRcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IHJldCA9IHVpbnRUb1N0cmluZyh2YWwpXG4gICAgICAgICAgICByZXR1cm4gcmV0XG4gICAgICAgIH1cblxuICAgICAgICAvLyBoYW5kbGUgdXRmLTggY29tcHJlc3Npb25cbiAgICAgICAgbGV0IFV0ZjhBcnJheVRvU3RyID0gKGFycmF5OiBudW1iZXJbXSkgPT4ge1xuICAgICAgICAgICAgbGV0IHJldCA9IFwiXCJcbiAgICAgICAgICAgIGxldCBpID0gMFxuICAgICAgICAgICAgd2hpbGUgKGkgPCBhcnJheS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBsZXQgY2hhcjEgPSBhcnJheVtpKytdXG4gICAgICAgICAgICAgICAgbGV0IGNoYXIyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChjaGFyMSA+PiA0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiBjYXNlIDI6IGNhc2UgMzogY2FzZSA0OiBjYXNlIDU6IGNhc2UgNjogY2FzZSA3OlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gb25lIGJ5dGVcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNoYXIxKVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxMjogY2FzZSAxMzpcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHR3byBieXRlIHNlcXVlbmNlXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFyMiA9IGFycmF5W2krK11cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKCgoY2hhcjEgJiAweDFGKSA8PCA2KSB8IChjaGFyMiAmIDB4M0YpKVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxNDpcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRocmVlIGJ5dGUgc2VxdWVuY2VcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIyID0gYXJyYXlbaSsrXVxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNoYXIzID0gYXJyYXlbaSsrXVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKChjaGFyMSAmIDB4MEYpIDw8IDEyKSB8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKChjaGFyMiAmIDB4M0YpIDw8IDYpIHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGNoYXIzICYgMHgzRikgPDwgMCkpXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHJldFxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHJldCA9IFV0ZjhBcnJheVRvU3RyKEFycmF5LmZyb20odmFsKSlcbiAgICAgICAgcmV0dXJuIHJldFxuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgY29udmVydEFzY2lpVG9TdHJpbmcodmFsOiBudW1iZXJbXSB8IFVpbnQ4QXJyYXkpOiBzdHJpbmcge1xuICAgICAgICBsZXQgcmV0OiBzdHJpbmcgPSBcIlwiXG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWwubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHZhbFtpXSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXRcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB0YWtlcyBhIG51bWJlciBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiBpdHMgY2hhciByZXByZXNlbnRhdGlvbnNcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY29udmVydE51bWJlclRvQ2hhckFycmF5KG5icjogbnVtYmVyIHwgc3RyaW5nKTogbnVtYmVyW10ge1xuICAgICAgICByZXR1cm4gVXRpbC5jb252ZXJ0U3RyaW5nVG9Bc2NpaShTdHJpbmcobmJyKSlcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBhIGhleCBzdHJpbmcgaW50byBhIGJ5dGUgYXJyYXlcbiAgICAgKiBUaGF0IG1lYW5zIHR3byBjb25zZWN1dGl2ZSBoZXggdmFsdWVzIGFyZSBtZXJnZWQgaW50byBvbmUgYnl0ZSB0aGF0IGlzIGFwcGVuZGVkIHRvIHRoZSBhcnJheVxuICAgICAqICovXG4gICAgcHVibGljIHN0YXRpYyBjb252ZXJ0SGV4U3RyaW5nVG9CeXRlQXJyYXkoaGV4X3N0cmluZyA6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudW1iZXJbXSkgOiBudW1iZXJbXSB7XG4gICAgICAgIGxldCByZXRfdmFsIDogbnVtYmVyW10gPSBbXVxuXG4gICAgICAgIGlmICh0eXBlb2YgaGV4X3N0cmluZyAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgaGV4X3N0cmluZyA9IFV0aWwuY29udmVydEFzY2lpVG9TdHJpbmcoaGV4X3N0cmluZylcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGV4X3N0cmluZy5sZW5ndGggLSAxOyBpKz0gMikge1xuICAgICAgICAgICAgcmV0X3ZhbC5wdXNoKChwYXJzZUludChoZXhfc3RyaW5nLmNoYXJBdChpKSwgMTYpIDw8IDQpICsgcGFyc2VJbnQoaGV4X3N0cmluZy5jaGFyQXQoaSArIDEpLCAxNikpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaGV4X3N0cmluZy5sZW5ndGggJSAyICE9PSAwKSB7XG4gICAgICAgICAgICByZXRfdmFsLnB1c2gocGFyc2VJbnQoaGV4X3N0cmluZy5jaGFyQXQoaGV4X3N0cmluZy5sZW5ndGggLSAxKSwgMTYpKVxuXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmV0X3ZhbFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGFuIGFycmF5IG9mIGJ5dGUgdmFsdWVzIGludG8gYSBoZXggc3RyaW5nXG4gICAgICogKi9cbiAgICBwdWJsaWMgc3RhdGljIGNvbnZlcnRCeXRlQXJyYXlUb0hleFN0cmluZyh2YWx1ZXMgOiBVaW50OEFycmF5IHwgbnVtYmVyW10pIDogc3RyaW5nIHtcbiAgICAgICAgbGV0IHJldF92YWwgOiBzdHJpbmcgPSBcIlwiXG5cbiAgICAgICAgbGV0IEhFWF9WQUxVRVMgPSBcIjAxMjM0NTY3ODlBQkNERUZcIlxuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICByZXRfdmFsICs9IEhFWF9WQUxVRVMuY2hhckF0KHZhbHVlc1tpXSA+PiA0KVxuICAgICAgICAgICAgcmV0X3ZhbCArPSBIRVhfVkFMVUVTLmNoYXJBdCh2YWx1ZXNbaV0gJiAxNSlcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJlbW92ZSBsZWFkaW5nIHplcm9zXG4gICAgICAgIGxldCBpIDogbnVtYmVyID0gMFxuICAgICAgICB3aGlsZSgnMCcgPT09IHJldF92YWwuY2hhckF0KGkpICYmIGkgPCByZXRfdmFsLmxlbmd0aCkgKytpXG5cbiAgICAgICAgcmV0dXJuIHJldF92YWwuc2xpY2UoaSwgcmV0X3ZhbC5sZW5ndGgpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogdGFrZXMgdHdvIGFycmF5cyBhbmQgY2hlY2tzIHRoZWlyIGVxdWFsaXR5XG4gICAgICogKi9cbiAgICBwdWJsaWMgc3RhdGljIGFyZUFycmF5c0VxdWFsKGFycmF5X29uZTogVWludDhBcnJheSB8IG51bWJlcltdLCBhcnJheV90d286IFVpbnQ4QXJyYXkgfCBudW1iZXJbXSk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoYXJyYXlfb25lLmxlbmd0aCAhPT0gYXJyYXlfdHdvLmxlbmd0aCkgcmV0dXJuIGZhbHNlXG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheV9vbmUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmIChhcnJheV9vbmVbaV0gIT09IGFycmF5X3R3b1tpXSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJpbnRzIHRoZSBhcnJheSB3aXRoIGxlYWRpbmcgaW5kZXhlcyAxMCBieXRlcyBpbiBhIHJvd1xuICAgICAqIERlbGltaXRlciBhcmUgc3Vic3RpdHV0ZWQgYnkgJy4nXG4gICAgICogKi9cbiAgICBwdWJsaWMgc3RhdGljIGRlYnVnX3ByaW50SW5kZXhlZChhcnJheTogVWludDhBcnJheSB8IG51bWJlcltdKSB7XG4gICAgICAgIGxldCBvdXRwID0gXCJcIlxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBpZiAoaSAlIDEwID09PSAwKSB7XG4gICAgICAgICAgICAgICAgb3V0cCArPSBcIlxcblwiICsgaSArIFwiOlwiXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChVdGlsLmlzU3BhY2UoYXJyYXlbaV0pKVxuICAgICAgICAgICAgICAgIG91dHAgKz0gXCIgLlwiXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgb3V0cCArPSBcIiBcIiArIFN0cmluZy5mcm9tQ2hhckNvZGUoYXJyYXlbaV0pXG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmxvZyhvdXRwKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGEgbGlzdCBvZiA4IGJpdCBpbnRlZ2VycyBpbnRvIGEgbGlzdCBvZiAzMiBiaXQgaW50ZWdlcnNcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY29udmVydFVpbnQ4QXJyYXlUb0ludDMyQXJyYXkoYSA6IFVpbnQ4QXJyYXkgfCBudW1iZXJbXSkgOiBJbnQzMkFycmF5IHtcbiAgICAgICAgbGV0IHJldF92YWwgOiBJbnQzMkFycmF5ID0gbmV3IEludDMyQXJyYXkoTWF0aC5jZWlsKGEubGVuZ3RoIC8gNCkpXG5cbiAgICAgICAgbGV0IGkgPSAwXG4gICAgICAgIGxldCBpbmRleCA9IDBcblxuICAgICAgICB3aGlsZSAoaSA8IGEubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoYVtpXSA+IDI1NSB8fCBhW2kgKyAxXSA+IDI1NSB8fCBhW2kgKyAyXSA+PiAyNTUgfHwgYVtpICsgM10gPiAyNTUpXG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJJbnZhbGlkIGJ5dGUgc2l6ZVwiKVxuXG4gICAgICAgICAgICByZXRfdmFsW2luZGV4KytdID0gKGFbaSsrXSA8PCAyNCkgKyAoYVtpKytdIDw8IDE2KSArIChhW2krK10gPDwgOCkgKyAoYVtpKytdIDw8IDApXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmV0X3ZhbFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGEgbGlzdCBvZiAzMiBiaXQgaW50ZWdlcnMgaW50byBhIGxpc3Qgb2YgOCBiaXQgVU5TSUdORUQgaW50ZWdlcnNcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY29udmVydEludDMyQXJyYXlUb1VpbnQ4QXJyYXkoYSA6IEludDMyQXJyYXkgfCBudW1iZXJbXSkgOiBVaW50OEFycmF5IHtcbiAgICAgICAgbGV0IHJldF92YWwgOiBVaW50OEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYS5sZW5ndGggKiA0KVxuXG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBmb3IobGV0IGogPSAwOyBqIDwgNDsgKytqKSB7XG4gICAgICAgICAgICAgICAgcmV0X3ZhbFtpICogNCArIGpdID0gKGFbaV0gPj4gOCAqICg0IC0gaiAtIDEpKSAmIDB4RkZcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXRfdmFsXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBlc2NhcGUgc3ltYm9scyB0byBzcGVjaWZpYyBlbGVtZW50cyBvZiB0aGUgcHJvdmlkZWQgc3RyaW5nXG4gICAgICpcbiAgICAgKiBTeW1ib2xzIHRoYXQgbmVlZHMgdG8gYmUgZXNjYXBlZCBhcmU6IFxcICkgKFxuICAgICAqICovXG4gICAgcHVibGljIHN0YXRpYyBlc2NhcGVTdHJpbmcoYXJyYXk6IFVpbnQ4QXJyYXkgfCBudW1iZXJbXSkgOiBVaW50OEFycmF5IHtcbiAgICAgICAgbGV0IHJldF92YWwgOiBudW1iZXJbXSA9IFtdXG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgc3dpdGNoIChhcnJheVtpXSkge1xuICAgICAgICAgICAgICAgIGNhc2UgVXRpbC5MSVRFUkFMX1NUUklOR19TVEFSVFswXTpcbiAgICAgICAgICAgICAgICBjYXNlIFV0aWwuTElURVJBTF9TVFJJTkdfRU5EWzBdOlxuICAgICAgICAgICAgICAgIGNhc2UgOTI6IC8vIDkyID0gJ1xcJ1xuICAgICAgICAgICAgICAgICAgICByZXRfdmFsLnB1c2goOTIpXG4gICAgICAgICAgICAgICAgICAgIHJldF92YWwucHVzaChhcnJheVtpXSlcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICBjYXNlIDk6IC8vIDkgPSBUQUJcbiAgICAgICAgICAgICAgICAgICAgcmV0X3ZhbC5wdXNoKDkyKVxuICAgICAgICAgICAgICAgICAgICByZXRfdmFsLnB1c2goMTE2KSAvLyBcXHRcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICBjYXNlIDEwOiAvLyAxMCA9IExJTkUgRkVFRFxuICAgICAgICAgICAgICAgICAgICByZXRfdmFsLnB1c2goOTIpXG4gICAgICAgICAgICAgICAgICAgIHJldF92YWwucHVzaCgxMTApIC8vIFxcblxuICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgIGNhc2UgMTM6IC8vIDEzID0gQ0FSUklBR0UgUkVUVVJOXG4gICAgICAgICAgICAgICAgICAgIHJldF92YWwucHVzaCg5MilcbiAgICAgICAgICAgICAgICAgICAgcmV0X3ZhbC5wdXNoKDExNCkgLy8gXFxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgY2FzZSA4OiAvLyA4ID0gQkFDS1NQQUNFXG4gICAgICAgICAgICAgICAgICAgIHJldF92YWwucHVzaCg5MilcbiAgICAgICAgICAgICAgICAgICAgcmV0X3ZhbC5wdXNoKDk4KSAvLyBcXGJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICBjYXNlIDEyOiAvLyAyNTUgPSBGT1JNIEZFRURcbiAgICAgICAgICAgICAgICAgICAgcmV0X3ZhbC5wdXNoKDkyKVxuICAgICAgICAgICAgICAgICAgICByZXRfdmFsLnB1c2goMTAyKSAvLyBcXGZcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZXRfdmFsLnB1c2goYXJyYXlbaV0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkocmV0X3ZhbClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGVzY2FwZSBzeW1ib2xzIGZyb20gdGhlIGdpdmVuIHN0cmluZ1xuICAgICAqXG4gICAgICogU3ltYm9scyB0aGF0IG5lZWRzIHRvIGJlIGVzY2FwZWQgYXJlOiBcXCApIChcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgdW5lc2NhcGVTdHJpbmcoYXJyYXk6IFVpbnQ4QXJyYXkgfCBudW1iZXJbXSkgOiBVaW50OEFycmF5IHtcbiAgICAgICAgbGV0IHJldF92YWwgOiBudW1iZXJbXSA9IFtdXG5cbiAgICAgICAgbGV0IGluX2VzY2FwZSA9IGZhbHNlXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyArK2kpIHtcblxuICAgICAgICAgICAgaWYgKGluX2VzY2FwZSkge1xuICAgICAgICAgICAgICAgIGluX2VzY2FwZSA9IGZhbHNlXG5cbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGFycmF5W2ldKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgOTI6IC8vIFxcXG4gICAgICAgICAgICAgICAgICAgICAgICByZXRfdmFsLnB1c2goOTIpXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFV0aWwuTElURVJBTF9TVFJJTkdfU1RBUlRbMF06XG4gICAgICAgICAgICAgICAgICAgICAgICByZXRfdmFsLnB1c2goVXRpbC5MSVRFUkFMX1NUUklOR19TVEFSVFswXSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgVXRpbC5MSVRFUkFMX1NUUklOR19FTkRbMF06XG4gICAgICAgICAgICAgICAgICAgICAgICByZXRfdmFsLnB1c2goVXRpbC5MSVRFUkFMX1NUUklOR19FTkRbMF0pXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDExNjogLy8gXFx0XG4gICAgICAgICAgICAgICAgICAgICAgICByZXRfdmFsLnB1c2goOSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTEwOiAvLyBcXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldF92YWwucHVzaCgxMClcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTE0OiAvLyBcXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldF92YWwucHVzaCgxMylcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgOTg6IC8vIFxcYlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0X3ZhbC5wdXNoKDgpXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDEwMjogLy8gXFxmXG4gICAgICAgICAgICAgICAgICAgICAgICByZXRfdmFsLnB1c2goMTIpXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0X3ZhbC5wdXNoKGFycmF5W2ldKVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoYXJyYXlbaV0gPT09IDkyKSB7XG4gICAgICAgICAgICAgICAgICAgIGluX2VzY2FwZSA9IHRydWVcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXRfdmFsLnB1c2goYXJyYXlbaV0pXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KHJldF92YWwpXG4gICAgfVxufVxuIiwiaW1wb3J0IHsgUGFnZSwgUmVmZXJlbmNlUG9pbnRlciB9IGZyb20gJy4vcGFyc2VyJ1xuaW1wb3J0IHsgVXRpbCB9IGZyb20gJy4vdXRpbCdcblxuZXhwb3J0IGNsYXNzIFdyaXRlclV0aWwge1xuICAgIHB1YmxpYyBzdGF0aWMgTjogbnVtYmVyID0gMTEwXG4gICAgcHVibGljIHN0YXRpYyBGOiBudW1iZXIgPSAxMDJcblxuICAgIHB1YmxpYyBzdGF0aWMgU1BBQ0U6IG51bWJlciA9IDMyXG4gICAgcHVibGljIHN0YXRpYyBDUjogbnVtYmVyID0gMTNcbiAgICBwdWJsaWMgc3RhdGljIExGOiBudW1iZXIgPSAxMFxuICAgIHB1YmxpYyBzdGF0aWMgT0JKOiBudW1iZXJbXSA9IFsxMTEsIDk4LCAxMDZdXG4gICAgcHVibGljIHN0YXRpYyBFTkRPQko6IG51bWJlcltdID0gWzEwMSwgMTEwLCAxMDAsIDExMSwgOTgsIDEwNl1cbiAgICBwdWJsaWMgc3RhdGljIEVOQ1JZUFQ6IG51bWJlcltdID0gWzQ3LCA2OSwgMTEwLCA5OSwgMTE0LCAxMjEsIDExMiwgMTE2XVxuICAgIHB1YmxpYyBzdGF0aWMgQVJSQVlfU1RBUlQ6IG51bWJlciA9IDkxXG4gICAgcHVibGljIHN0YXRpYyBPUEVOOiBudW1iZXJbXSA9IFs0NywgNzksIDExMiwgMTAxLCAxMTBdXG4gICAgcHVibGljIHN0YXRpYyBBUlJBWV9FTkQ6IG51bWJlciA9IDkzXG4gICAgcHVibGljIHN0YXRpYyBESUNUX1NUQVJUOiBudW1iZXJbXSA9IFs2MCwgNjBdXG4gICAgcHVibGljIHN0YXRpYyBIRVhfU1RSSU5HX1NUQVJUOiBudW1iZXJbXSA9IFs2MF1cbiAgICBwdWJsaWMgc3RhdGljIEhFWF9TVFJJTkdfRU5EOiBudW1iZXJbXSA9IFs2Ml1cbiAgICBwdWJsaWMgc3RhdGljIERJQ1RfRU5EOiBudW1iZXJbXSA9IFs2MiwgNjJdXG4gICAgcHVibGljIHN0YXRpYyBUWVBFX0FOTk9UOiBudW1iZXJbXSA9IFs0NywgODQsIDEyMSwgMTEyLCAxMDEsIFdyaXRlclV0aWwuU1BBQ0UsIDQ3LCA2NSwgMTEwLCAxMTAsIDExMSwgMTE2XVxuICAgIHB1YmxpYyBzdGF0aWMgUkVDVDogbnVtYmVyW10gPSBbNDcsIDgyLCAxMDEsIDk5LCAxMTZdXG4gICAgcHVibGljIHN0YXRpYyBTVUJUWVBFOiBudW1iZXJbXSA9IFs0NywgODMsIDExNywgOTgsIDExNiwgMTIxLCAxMTIsIDEwMV1cbiAgICBwdWJsaWMgc3RhdGljIFVQREFURV9EQVRFOiBudW1iZXJbXSA9IFs0NywgNzddIC8vID0gJy9NJ1xuICAgIHB1YmxpYyBzdGF0aWMgQVVUSE9SOiBudW1iZXJbXSA9IFs0NywgODRdIC8vID0gJy9UJ1xuICAgIHB1YmxpYyBzdGF0aWMgQ09OVEVOVFM6IG51bWJlcltdID0gWzQ3LCA2NywgMTExLCAxMTAsIDExNiwgMTAxLCAxMTAsIDExNiwgMTE1XSAvLyA9ICcvQ29udGVudHMnXG4gICAgcHVibGljIHN0YXRpYyBCUkFDS0VUX1NUQVJUOiBudW1iZXIgPSA0MFxuICAgIHB1YmxpYyBzdGF0aWMgQlJBQ0tFVF9FTkQ6IG51bWJlciA9IDQxXG4gICAgcHVibGljIHN0YXRpYyBGTEFHOiBudW1iZXJbXSA9IFs0NywgNzBdIC8vID0gJy9GJ1xuICAgIHB1YmxpYyBzdGF0aWMgSUQ6IG51bWJlcltdID0gWzQ3LCA3OCwgNzddIC8vID0gJy9OTSdcbiAgICBwdWJsaWMgc3RhdGljIERPQ1VNRU5UX0lEOiBudW1iZXJbXSA9IFs0NywgNzMsIDY4XSAvLyA9ICcvSUQnXG4gICAgcHVibGljIHN0YXRpYyBDT0xPUjogbnVtYmVyW10gPSBbNDcsIDY3XSAvLyA9ICcvQydcbiAgICBwdWJsaWMgc3RhdGljIEZJTEw6IG51bWJlcltdID0gWzQ3LCA3MywgNjddIC8vID0gJy9JQydcbiAgICBwdWJsaWMgc3RhdGljIFNUQVRFOiBudW1iZXJbXSA9IFs0NywgODMsIDExNiwgOTcsIDExNiwgMTAxXSAvLyA9ICcvU3RhdGUnXG4gICAgcHVibGljIHN0YXRpYyBTVEFURU1PREVMOiBudW1iZXJbXSA9IFs0NywgODMsIDExNiwgOTcsIDExNiwgMTAxLCA3NywgMTExLCAxMDAsIDEwMSwgMTA4XSAvLyA9ICcvU3RhdGVNb2RlbCdcbiAgICBwdWJsaWMgc3RhdGljIE9QQUNJVFk6IG51bWJlcltdID0gWzQ3LCA2NywgNjVdIC8vID0gJy9DQSdcbiAgICBwdWJsaWMgc3RhdGljIEJPUkRFUjogbnVtYmVyW10gPSBbNDcsIDY2LCAxMTEsIDExNCwgMTAwLCAxMDEsIDExNF0gLy8gPSAnL0JvcmRlcidcbiAgICBwdWJsaWMgc3RhdGljIFBBR0VfUkVGRVJFTkNFOiBudW1iZXJbXSA9IFs0NywgODBdIC8vID0gJy9QJ1xuICAgIHB1YmxpYyBzdGF0aWMgREVGQVVMVF9BUFBFQVJBTkNFOiBudW1iZXJbXSA9IFs0NywgNjgsIDY1XSAvLyA9ICcvREEnXG4gICAgcHVibGljIHN0YXRpYyBJTktMSVNUOiBudW1iZXJbXSA9IFs0NywgNzMsIDExMCwgMTA3LCA3NiwgMTA1LCAxMTUsIDExNl0gLy8gPSAnL0lua0xpc3QnXG5cbiAgICBwdWJsaWMgc3RhdGljIFJDOiBudW1iZXJbXSA9IFs0NywgODIsIDY3XSAvLyA9ICcvUkMnXG4gICAgcHVibGljIHN0YXRpYyBDUkVBVElPTl9EQVRFOiBudW1iZXJbXSA9IFs0NywgNjcsIDExNCwgMTAxLCA5NywgMTE2LCAxMDUsIDExMSwgMTEwLCA2OCwgOTcsIDExNiwgMTAxXSAvLyA9ICcvQ3JlYXRpb25EYXRlJ1xuICAgIHB1YmxpYyBzdGF0aWMgU1VCSjogbnVtYmVyW10gPSBbNDcsIDgzLCAxMTcsIDk4LCAxMDZdIC8vID0gJy9TdWJqJ1xuICAgIHB1YmxpYyBzdGF0aWMgVFJBSUxFUjogbnVtYmVyW10gPSBbMTE2LCAxMTQsIDk3LCAxMDUsIDEwOCwgMTAxLCAxMTRdIC8vID0gJ3RyYWlsZXInXG4gICAgcHVibGljIHN0YXRpYyBTSVpFOiBudW1iZXJbXSA9IFs0NywgODMsIDEwNSwgMTIyLCAxMDFdIC8vID0gJy9TaXplJ1xuICAgIHB1YmxpYyBzdGF0aWMgUk9PVDogbnVtYmVyW10gPSBbNDcsIDgyLCAxMTEsIDExMSwgMTE2XSAvLyA9ICcvUm9vdCdcbiAgICBwdWJsaWMgc3RhdGljIFBSRVY6IG51bWJlcltdID0gWzQ3LCA4MCwgMTE0LCAxMDEsIDExOF0gLy8gPScvUHJldidcbiAgICBwdWJsaWMgc3RhdGljIFNUQVJUWFJFRjogbnVtYmVyW10gPSBbMTE1LCAxMTYsIDk3LCAxMTQsIDExNiwgMTIwLCAxMTQsIDEwMSwgMTAyXSAvLyA9ICdzdGFydHhyZWYnXG4gICAgcHVibGljIHN0YXRpYyBFT0Y6IG51bWJlcltdID0gWzM3LCAzNywgNjksIDc5LCA3MF0gLy8gPSAnJSVFT0YnXG5cbiAgICBwdWJsaWMgc3RhdGljIFRSVUU6IG51bWJlcltdID0gWzExNiwgMTE0LCAxMTcsIDEwMV0gLy8gPSAndHJ1ZSdcblxuICAgIHB1YmxpYyBzdGF0aWMgWFJFRjogbnVtYmVyW10gPSBbMTIwLCAxMTQsIDEwMSwgMTAyXSAvLyA9ICd4cmVmJ1xuXG4gICAgcHVibGljIHN0YXRpYyBURVhUX0pVU1RJRklDQVRJT04gOiBudW1iZXJbXSA9IFs0NywgODFdIC8vID0gJy9RJ1xuICAgIHB1YmxpYyBzdGF0aWMgREVGQVVMVF9TVFlMRV9TVFJJTkcgOiBudW1iZXJbXSA9IFs0NywgNjgsIDgzXSAvLyA9ICcvRFMnXG4gICAgcHVibGljIHN0YXRpYyBESUZGRVJFTkNFX1JFQ1RBTkdMRSA6IG51bWJlcltdID0gWzQ3LCA4MiwgNjhdIC8vID0gJy9SRCdcbiAgICBwdWJsaWMgc3RhdGljIElUIDogbnVtYmVyW10gPSBbNDcsIDczLCA4NF0gLy8gPSAnL0lUJ1xuICAgIHB1YmxpYyBzdGF0aWMgTElORV9FTkRJTkcgOiBudW1iZXJbXSA9IFs0NywgNzYsIDY5XSAvLyA9ICcvTEUnXG4gICAgcHVibGljIHN0YXRpYyBDQUxMT1VUX0xJTkUgOiBudW1iZXJbXSA9IFs0NywgNjcsIDc2XSAvLyA9ICcvQ0wnXG4gICAgcHVibGljIHN0YXRpYyBRVUFEUE9JTlRTOiBudW1iZXJbXSA9IFs0NywgODEsIDExNywgOTcsIDEwMCwgODAsIDExMSwgMTA1LCAxMTAsIDExNiwgMTE1XSAvLyA9ICcvUXVhZFBvaW50cydcbiAgICBwdWJsaWMgc3RhdGljIFZFUlRJQ0VTOiBudW1iZXJbXSA9IFs0NywgODYsIDEwMSwgMTE0LCAxMTYsIDEwNSwgOTksIDEwMSwgMTE1XSAvLyA9ICcvVmVydGljZXMnXG4gICAgcHVibGljIHN0YXRpYyBOQU1FOiBudW1iZXJbXSA9IFs0NywgNzgsIDk3LCAxMDksIDEwMV0gLy8gPSAnL05hbWUnXG4gICAgcHVibGljIHN0YXRpYyBEUkFGVDogbnVtYmVyW10gPSBbNDcsIDY4LCAxMTQsIDk3LCAxMDIsIDExNl0gLy8gPSAnL0RyYWZ0J1xuXG4gICAgcHVibGljIHN0YXRpYyBTWTogbnVtYmVyW10gPSBbNDcsIDgzLCAxMjFdIC8vID0gJy9TeSdcbiAgICBwdWJsaWMgc3RhdGljIFA6IG51bWJlciA9IDgwXG5cbiAgICAvKipcbiAgICAgKiBXcml0ZXMgYSByZWZlcmVuY2UgcG9pbnRlclxuICAgICAqXG4gICAgICogPG9ial9pZD4gPGdlbmVyYXRpb24+IFJcbiAgICAgKlxuICAgICAqIFRoZSAnUicgYW5kIHRoZSBwcmVjZWRpbmcgc3BhY2UgaXMgb25seSB3cml0dGVuIGluIGNhc2UgJ3JlZmVyZW5jZWQnIGlzIHRydWVcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgd3JpdGVSZWZlcmVuY2VQb2ludGVyKHJlZjogUmVmZXJlbmNlUG9pbnRlciwgcmVmZXJlbmNlZDogYm9vbGVhbiA9IGZhbHNlKTogbnVtYmVyW10ge1xuICAgICAgICBsZXQgcmV0OiBudW1iZXJbXSA9IFV0aWwuY29udmVydE51bWJlclRvQ2hhckFycmF5KHJlZi5vYmopXG5cbiAgICAgICAgcmV0LnB1c2goVXRpbC5TUEFDRSlcblxuICAgICAgICByZXQgPSByZXQuY29uY2F0KFV0aWwuY29udmVydE51bWJlclRvQ2hhckFycmF5KHJlZi5nZW5lcmF0aW9uKSlcblxuICAgICAgICBpZiAocmVmZXJlbmNlZCkge1xuICAgICAgICAgICAgcmV0LnB1c2goVXRpbC5TUEFDRSlcbiAgICAgICAgICAgIHJldC5wdXNoKC4uLlV0aWwuUilcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXRcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIHByZWNlZGluZyB6ZXJvcyAoMCkgaW4gZnJvbnQgb2YgdGhlICd2YWx1ZScgdG8gbWF0Y2ggdGhlIGxlbmd0aFxuICAgICAqICovXG4gICAgcHVibGljIHN0YXRpYyBwYWQobGVuZ3RoOiBudW1iZXIsIHZhbHVlOiBzdHJpbmcgfCBudW1iZXIpOiBudW1iZXJbXSB7XG4gICAgICAgIHZhbHVlID0gU3RyaW5nKHZhbHVlKVxuXG4gICAgICAgIGxldCByZXQ6IG51bWJlcltdID0gW11cblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aCAtIHZhbHVlLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICByZXQucHVzaCg0OClcbiAgICAgICAgfVxuXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQoVXRpbC5jb252ZXJ0TnVtYmVyVG9DaGFyQXJyYXkodmFsdWUpKVxuXG4gICAgICAgIHJldHVybiByZXRcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXcml0ZXMgYSBuZXN0ZWQgbnVtYmVyIGFycmF5XG4gICAgICogKi9cbiAgICBwdWJsaWMgc3RhdGljIHdyaXRlTmVzdGVkTnVtYmVyQXJyYXkoYXJyYXk6IG51bWJlcltdW10pOiBudW1iZXJbXSB7XG4gICAgICAgIGxldCByZXQ6IG51bWJlcltdID0gVXRpbC5BUlJBWV9TVEFSVFxuXG4gICAgICAgIGZvciAobGV0IHN1YkFycmF5IG9mIGFycmF5KSB7XG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwud3JpdGVOdW1iZXJBcnJheShzdWJBcnJheSkpXG4gICAgICAgICAgICByZXQucHVzaChVdGlsLlNQQUNFKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0LnB1c2goLi4uVXRpbC5BUlJBWV9FTkQpXG4gICAgICAgIHJldHVybiByZXRcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXcml0ZXMgYSBqYXZhc2NyaXB0IG51bWJlciBhcnJheSB0byBhIFBERiBudW1iZXIgYXJyYXlcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgd3JpdGVOdW1iZXJBcnJheShhcnJheTogbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gICAgICAgIGxldCByZXQ6IG51bWJlcltdID0gVXRpbC5BUlJBWV9TVEFSVFxuXG4gICAgICAgIGZvciAobGV0IGkgb2YgYXJyYXkpIHtcbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoVXRpbC5jb252ZXJ0TnVtYmVyVG9DaGFyQXJyYXkoaSkpXG4gICAgICAgICAgICByZXQucHVzaChVdGlsLlNQQUNFKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0LnB1c2goLi4uVXRpbC5BUlJBWV9FTkQpXG5cbiAgICAgICAgcmV0dXJuIHJldFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlcGxhY2VzIHRoZSAvQW5ub3RzIGZpZWxkIGluIGFuIHBhZ2Ugb2JqZWN0XG4gICAgICpcbiAgICAgKiBwdHIgOiBQb2ludGVyIHRvIHRoZSBwYWdlIG9iamVjdFxuICAgICAqIGFubm90X2FycmF5X3JlZmVyZW5jZSA6IFRoZSByZWZlcmVuY2UgdG8gdGhlIGFubm90YXRpb24gYXJyYXlcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzdGF0aWMgcmVwbGFjZUFubm90c0ZpZWxkSW5QYWdlT2JqZWN0KGRhdGE6IFVpbnQ4QXJyYXksIHBhZ2U6IFBhZ2UsIHBhZ2VfcHRyOiBudW1iZXIsIGFubm90X2FycmF5X3JlZmVyZW5jZTogUmVmZXJlbmNlUG9pbnRlcik6IG51bWJlcltdIHtcbiAgICAgICAgbGV0IHB0cl9vYmplbmQgPSBVdGlsLmxvY2F0ZVNlcXVlbmNlKFV0aWwuRU5ET0JKLCBkYXRhLCBwYWdlX3B0ciwgdHJ1ZSlcblxuICAgICAgICBsZXQgY29tcGxldGVfcGFnZV9vYmplY3RfZGF0YSA9IGRhdGEuc2xpY2UocGFnZV9wdHIsIHB0cl9vYmplbmQgKyBVdGlsLkVORE9CSi5sZW5ndGgpXG5cbiAgICAgICAgbGV0IHJldDogbnVtYmVyW10gPSBbXVxuXG4gICAgICAgIGlmIChwYWdlLmhhc0Fubm90c0ZpZWxkKSB7XG4gICAgICAgICAgICAvLyBpbiB0aGlzIGNhc2UgdGhlIHBhZ2Ugb2JqZWN0IGRpcmVjdGx5IGNvbnRhaW5zIGFuIGFycmF5IG9mIHJlZmVyZW5jZXMgYW5kXG4gICAgICAgICAgICAvLyBkb2VzIG5vdCBwb2ludCB0byBhbiBhcnJheSBhcnJheSBvYmplY3QgLS0gd2UgcmVwbGFjZSB0aGUgYXJyYXkgb2YgcmVmZXJlbmNlcyB3aXRoIGEgcG9pbnRlclxuICAgICAgICAgICAgLy8gdG8gdGhlIHJlZmVyZW5jZSBhcnJheVxuICAgICAgICAgICAgbGV0IHB0cl9hbm5vdHMgPSBVdGlsLmxvY2F0ZVNlcXVlbmNlKFV0aWwuQU5OT1RTLCBjb21wbGV0ZV9wYWdlX29iamVjdF9kYXRhLCAwLCB0cnVlKVxuXG4gICAgICAgICAgICByZXQgPSBBcnJheS5mcm9tKGNvbXBsZXRlX3BhZ2Vfb2JqZWN0X2RhdGEuc2xpY2UoMCwgcHRyX2Fubm90cyArIFV0aWwuQU5OT1RTLmxlbmd0aCkpXG4gICAgICAgICAgICByZXQucHVzaChVdGlsLlNQQUNFKVxuICAgICAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLndyaXRlUmVmZXJlbmNlUG9pbnRlcihhbm5vdF9hcnJheV9yZWZlcmVuY2UsIHRydWUpKVxuICAgICAgICAgICAgcmV0LnB1c2goVXRpbC5TUEFDRSlcbiAgICAgICAgICAgIGxldCBwdHJfYW5ub3RzX2FycmF5X2VuZCA9IFV0aWwubG9jYXRlU2VxdWVuY2UoVXRpbC5BUlJBWV9FTkQsIGNvbXBsZXRlX3BhZ2Vfb2JqZWN0X2RhdGEsIHB0cl9hbm5vdHMsIHRydWUpICsgVXRpbC5BUlJBWV9FTkQubGVuZ3RoXG5cbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoQXJyYXkuZnJvbShjb21wbGV0ZV9wYWdlX29iamVjdF9kYXRhLnNsaWNlKHB0cl9hbm5vdHNfYXJyYXlfZW5kLCBjb21wbGV0ZV9wYWdlX29iamVjdF9kYXRhLmxlbmd0aCkpKVxuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgcHRyX2RpY3RfZW5kID0gVXRpbC5sb2NhdGVTZXF1ZW5jZVJldmVyc2VkKFV0aWwuRElDVF9FTkQsIGNvbXBsZXRlX3BhZ2Vfb2JqZWN0X2RhdGEsIGNvbXBsZXRlX3BhZ2Vfb2JqZWN0X2RhdGEubGVuZ3RoIC0gMSlcblxuICAgICAgICAgICAgaWYgKC0xID09PSBwdHJfZGljdF9lbmQpXG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJDb3VsZCBub3QgaWRlbnRpZnkgZGljdGlvbmFyeSBlbmRcIilcblxuICAgICAgICAgICAgcmV0ID0gQXJyYXkuZnJvbShjb21wbGV0ZV9wYWdlX29iamVjdF9kYXRhLnNsaWNlKDAsIHB0cl9kaWN0X2VuZCkpXG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFV0aWwuQU5OT1RTKVxuICAgICAgICAgICAgcmV0LnB1c2goVXRpbC5TUEFDRSlcbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC53cml0ZVJlZmVyZW5jZVBvaW50ZXIoYW5ub3RfYXJyYXlfcmVmZXJlbmNlLCB0cnVlKSlcbiAgICAgICAgICAgIHJldC5wdXNoKFV0aWwuU1BBQ0UpXG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KEFycmF5LmZyb20oY29tcGxldGVfcGFnZV9vYmplY3RfZGF0YS5zbGljZShwdHJfZGljdF9lbmQsIGNvbXBsZXRlX3BhZ2Vfb2JqZWN0X2RhdGEubGVuZ3RoKSkpXG4gICAgICAgIH1cblxuICAgICAgICByZXQucHVzaChVdGlsLkNSKVxuICAgICAgICByZXQucHVzaChVdGlsLkxGKVxuXG4gICAgICAgIHJldHVybiByZXRcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBVdGlsIH0gZnJvbSAnLi91dGlsJ1xuaW1wb3J0IHsgT2JqZWN0VXRpbCB9IGZyb20gJy4vb2JqZWN0LXV0aWwnXG5pbXBvcnQgeyBfQW5ub3RhdGlvbiwgQW5ub3RhdGlvbiwgUmVmZXJlbmNlUG9pbnRlciwgUERGRG9jdW1lbnRQYXJzZXIsIFBhZ2UsIENyeXB0b0ludGVyZmFjZSB9IGZyb20gJy4vcGFyc2VyJ1xuaW1wb3J0IHsgQW5ub3RhdGlvblN0YXRlLCBBbm5vdGF0aW9uU3RhdGVNb2RlbCwgQW5ub3RhdGlvbkljb24sIFRleHRBbm5vdGF0aW9uT2JqIH0gZnJvbSAnLi9hbm5vdGF0aW9ucy90ZXh0X2Fubm90YXRpb24nO1xuaW1wb3J0IHsgQ29sb3IsIE1hcmt1cEFubm90YXRpb25PYmogfSBmcm9tICcuL2Fubm90YXRpb25zL2Fubm90YXRpb25fdHlwZXMnO1xuaW1wb3J0IHsgWFJlZiB9IGZyb20gJy4vZG9jdW1lbnQtaGlzdG9yeSdcbmltcG9ydCB7IFdyaXRlclV0aWwgfSBmcm9tICcuL3dyaXRlci11dGlsJ1xuXG4vKipcbiAqIENyZWF0cyB0aGUgYnl0ZSBhcnJheSB0aGF0IG11c3QgYmUgYXR0YWNoZWQgdG8gdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnRcbiAqICovXG5leHBvcnQgY2xhc3MgV3JpdGVyIHtcblxuXG4gICAgLyoqXG4gICAgICogSG9sZHMgdGhlIGNyb3NzaXRlIHJlZmVyZW5jZSB0YWJsZVxuICAgICAqICovXG4gICAgcHJpdmF0ZSB4cmVmczogWFJlZltdID0gW11cblxuICAgIHByaXZhdGUgY3J5cHRvSW50ZXJmYWNlOiBDcnlwdG9JbnRlcmZhY2VcblxuICAgIC8qKlxuICAgICAqIGRhdGEgOiBUaGUgZGF0YSByZXByZXNlbnRpbmcgdGhlIG9yaWdpbmFsIFBERiBkb2N1bWVudFxuICAgICAqIGFhbm5vdGF0aW9ucyA6IFRoZSBhbm5vdGF0aW9ucyB0byBhZGQgdG8gdGhlIGRvY3VtZW50XG4gICAgICogKi9cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGRhdGE6IFVpbnQ4QXJyYXksIHByaXZhdGUgYW5ub3RhdGlvbnM6IEFubm90YXRpb25bXSwgcHJpdmF0ZSB0b0RlbGV0ZTogQW5ub3RhdGlvbltdLCBwcml2YXRlIHBhcnNlcjogUERGRG9jdW1lbnRQYXJzZXIpIHtcbiAgICAgICAgdGhpcy5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSlcbiAgICAgICAgdGhpcy5jcnlwdG9JbnRlcmZhY2UgPSBwYXJzZXIuZ2V0Q3J5cHRvSW50ZXJmYWNlKClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTb3J0cyB0aGUgYW5ub3RhdGlvbnMgcGFnZXdpc2UuXG4gICAgICpcbiAgICAgKiBUaGlzIGlzIG5lY2Vzc2FyeSBzaW5jZSB0aGUgYW5ub3RhdGlvbiBhcnJheXMgb2YgdGhlIHNpdGVzIG11c3QgYmUgZXh0ZW5kZWRcbiAgICAgKiBhbmQgaXQgbWFrZXMgc2Vuc2UgdG8gZG8gdGhpcyB1cGRhdGUgaW4gb25lIHN0ZXAuXG4gICAgICogKi9cbiAgICBzb3J0UGFnZVdpc2UoYW5ub3RhdGlvbnM6IEFubm90YXRpb25bXSk6IHsgW2l0ZW06IG51bWJlcl06IEFubm90YXRpb25bXSB9IHtcbiAgICAgICAgbGV0IHBhZ2VBbm5vdHM6IHsgW2l0ZW06IG51bWJlcl06IEFubm90YXRpb25bXSB9ID0ge31cblxuICAgICAgICBmb3IgKGxldCBhbm5vdCBvZiBhbm5vdGF0aW9ucykge1xuICAgICAgICAgICAgaWYgKCFwYWdlQW5ub3RzW2Fubm90LnBhZ2VdKVxuICAgICAgICAgICAgICAgIHBhZ2VBbm5vdHNbYW5ub3QucGFnZV0gPSBbXVxuXG4gICAgICAgICAgICBwYWdlQW5ub3RzW2Fubm90LnBhZ2VdLnB1c2goYW5ub3QpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcGFnZUFubm90c1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEl0IHJldHVybnMgdGhlIHBhZ2Ugb2JqZWN0IGVpdGhlciBleHRlbmRlZCBieSBhIC9Bbm5vdHMgZmllbGQsIGlmIHRoaXMgZGlkIG5vdCBleGlzdCB5ZXQgb3Igd2l0aCB0aGUgYW5ub3RzIGZpZWxkIHJlcGxhY2VkIGJ5IGEgcmVyZmVyZW5jZSBwb2ludGVyXG4gICAgICogdG8gYW4gYXJyYXkgaWYgdGhlIHBhZ2Ugb2JqZWN0IGNvbnRhaW5zIHRoZSBsaXN0IG9mIGFubm90YXRpb25zIGRpcmVjdGx5XG4gICAgICpcbiAgICAgKiBwdHIgOiBQb2ludGVyIHRvIHRoZSBwYWdlIG9iamVjdFxuICAgICAqIGFubm90X2FycmF5X3JlZmVyZW5jZSA6IFRoZSByZWZlcmVuY2UgdG8gdGhlIGFubm90YXRpb24gYXJyYXlcbiAgICAgKiAqL1xuICAgIGFkYXB0UGFnZU9iamVjdChwYWdlOiBQYWdlLCBhbm5vdF9hcnJheV9yZWZlcmVuY2U6IFJlZmVyZW5jZVBvaW50ZXIpOiBudW1iZXJbXSB7XG4gICAgICAgIGlmICghcGFnZS5vYmplY3RfaWQpXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcIlBhZ2Ugd2l0aG91dCBvYmplY3QgaWRcIilcblxuICAgICAgICBsZXQgcmV0OiBudW1iZXJbXSA9IFtdXG4gICAgICAgIGxldCBsb29rdXBUYWJsZSA9IHRoaXMucGFyc2VyLmRvY3VtZW50SGlzdG9yeS5jcmVhdGVPYmplY3RMb29rdXBUYWJsZSgpXG5cbiAgICAgICAgbGV0IHBhZ2VfcHRyOiBYUmVmID0gbG9va3VwVGFibGVbcGFnZS5vYmplY3RfaWQub2JqXVxuXG4gICAgICAgIGlmIChwYWdlX3B0ci5jb21wcmVzc2VkKSB7XG4gICAgICAgICAgICBsZXQgb2JqID0gT2JqZWN0VXRpbC5leHRyYWN0T2JqZWN0KHRoaXMuZGF0YSwgcGFnZV9wdHIsIGxvb2t1cFRhYmxlKVxuICAgICAgICAgICAgbGV0IG9ial9kYXRhID0gb2JqLnN0cmVhbS5nZXREYXRhKCkuc2xpY2Uob2JqLnBvaW50ZXJfc3RyZWFtX3N0YXJ0LCBvYmoucG9pbnRlcl9zdHJlYW1fZW5kICsgMSlcblxuICAgICAgICAgICAgbGV0IHJlZl9wdHIgPSBXcml0ZXJVdGlsLndyaXRlUmVmZXJlbmNlUG9pbnRlcihvYmouaWQsIGZhbHNlKS5jb25jYXQoMzIpXG5cbiAgICAgICAgICAgIGxldCBuZXdfZGF0YTogVWludDhBcnJheSA9IG5ldyBVaW50OEFycmF5KHJlZl9wdHIubGVuZ3RoICsgV3JpdGVyVXRpbC5PQkoubGVuZ3RoICsgb2JqX2RhdGEubGVuZ3RoICsgV3JpdGVyVXRpbC5FTkRPQkoubGVuZ3RoKVxuICAgICAgICAgICAgbmV3X2RhdGEuc2V0KHJlZl9wdHIpXG4gICAgICAgICAgICBuZXdfZGF0YS5zZXQoV3JpdGVyVXRpbC5PQkosIHJlZl9wdHIubGVuZ3RoKVxuICAgICAgICAgICAgbmV3X2RhdGEuc2V0KG9ial9kYXRhLCBXcml0ZXJVdGlsLk9CSi5sZW5ndGggKyByZWZfcHRyLmxlbmd0aClcbiAgICAgICAgICAgIG5ld19kYXRhLnNldChXcml0ZXJVdGlsLkVORE9CSiwgV3JpdGVyVXRpbC5PQkoubGVuZ3RoICsgb2JqX2RhdGEubGVuZ3RoICsgcmVmX3B0ci5sZW5ndGgpXG5cbiAgICAgICAgICAgIHJldHVybiBXcml0ZXJVdGlsLnJlcGxhY2VBbm5vdHNGaWVsZEluUGFnZU9iamVjdChuZXdfZGF0YSwgcGFnZSwgMCwgYW5ub3RfYXJyYXlfcmVmZXJlbmNlKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFdyaXRlclV0aWwucmVwbGFjZUFubm90c0ZpZWxkSW5QYWdlT2JqZWN0KHRoaXMuZGF0YSwgcGFnZSwgcGFnZV9wdHIucG9pbnRlciwgYW5ub3RfYXJyYXlfcmVmZXJlbmNlKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRha2VzIHRoZSBhbm5vdGF0aW9ucyBvZiA+Pm9uZTw8IHBhZ2UgYW5kIGRlcml2ZXMgdGhlIGFubm90YXRpb25zIGFycmF5IGZyb20gaXQuXG4gICAgICogVGhlcmVieSBpdCBhbHNvIGNvbnNpZGVycyB0aGUgcG90ZW50aWFsbHkgZXhpc3RpbmcgYW5ub3RhdGlvbiBhcnJheS5cbiAgICAgKlxuICAgICAqIHRvRGVsZXRlIDo9IGNvbnRhaW5zIHRob3NlIGFubm90YXRpb25zIHRoYXQgbXVzdCBiZSBkZWxldGVkLiBJdCByZW1vdmVzIHRoZW0gZnJvbSB0aGUgcmVmZXJlbmNlIGFycmF5XG4gICAgICogYW5kIG1hcmtzIHRoZW0gYXMgcmVtb3ZlZFxuICAgICAqICovXG4gICAgd3JpdGVBbm5vdEFycmF5KGFubm90czogQW5ub3RhdGlvbltdLCB0b0RlbGV0ZTogQW5ub3RhdGlvbltdKTogeyBwdHI6IFJlZmVyZW5jZVBvaW50ZXIsIGRhdGE6IG51bWJlcltdLCBwYWdlUmVmZXJlbmNlOiBSZWZlcmVuY2VQb2ludGVyLCBwYWdlRGF0YTogbnVtYmVyW10gfSB7XG4gICAgICAgIGxldCBwYWdlID0gYW5ub3RzWzBdLnBhZ2VSZWZlcmVuY2VcblxuICAgICAgICBpZiAoIXBhZ2UpXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcIk1pc3NpbmcgcGFnZSByZWZlcmVuY2VcIilcblxuICAgICAgICBpZiAoIXBhZ2Uub2JqZWN0X2lkKVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJQYWdlIHdpdGhvdXQgb2JqZWN0IGlkXCIpXG5cbiAgICAgICAgbGV0IHJlZmVyZW5jZXM6IFJlZmVyZW5jZVBvaW50ZXJbXSA9IHBhZ2UuYW5ub3RzXG5cbiAgICAgICAgcmVmZXJlbmNlcyA9IHJlZmVyZW5jZXMuY29uY2F0KGFubm90cy5tYXAoKHgpID0+IHtcbiAgICAgICAgICAgIGlmICgheC5vYmplY3RfaWQpXG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJBbm5vdGF0aW9uIHdpdGggb2JqZWN0X2lkIG51bGxcIilcblxuICAgICAgICAgICAgcmV0dXJuIHgub2JqZWN0X2lkXG4gICAgICAgIH0pKVxuXG4gICAgICAgIC8vIHJlbW92ZSBhbm5vdGF0aW9uIHJlZmVyZW5jZXMgZnJvbSB0aGUgYXJyYXkgdGhhdCBtdXN0IGJlIGRlbGV0ZWQgYW5kIG1hcmsgdGhlbSBhcyBkZWxldGVkXG4gICAgICAgIHJlZmVyZW5jZXMgPSByZWZlcmVuY2VzLmZpbHRlcigoYTogYW55KSA9PiB7XG4gICAgICAgICAgICBsZXQgdG9EZWwgPSB0b0RlbGV0ZS5maW5kKCh0KSA9PiAoPGFueT50Lm9iamVjdF9pZCkub2JqID09PSBhLm9iaiAmJiAoPGFueT50Lm9iamVjdF9pZCkuZ2VuZXJhdGlvbiA9PT0gYS5nZW5lcmF0aW9uKVxuXG4gICAgICAgICAgICBpZiAodG9EZWwpIHtcbiAgICAgICAgICAgICAgICB0b0RlbC5pc19kZWxldGVkID0gdHJ1ZVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9KVxuXG4gICAgICAgIGxldCByZWZBcnJheV9pZDogYW55ID0gcGFnZS5hbm5vdHNQb2ludGVyXG5cbiAgICAgICAgbGV0IHBhZ2VfZGF0YTogbnVtYmVyW10gPSBbXVxuICAgICAgICBpZiAoIXJlZkFycmF5X2lkKSB7XG4gICAgICAgICAgICByZWZBcnJheV9pZCA9IHRoaXMucGFyc2VyLmdldEZyZWVPYmplY3RJZCgpXG4gICAgICAgICAgICBwYWdlX2RhdGEgPSB0aGlzLmFkYXB0UGFnZU9iamVjdChwYWdlLCByZWZBcnJheV9pZClcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCByZXQ6IG51bWJlcltdID0gV3JpdGVyVXRpbC53cml0ZVJlZmVyZW5jZVBvaW50ZXIocmVmQXJyYXlfaWQpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC5PQkopXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQ1IpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuTEYpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQVJSQVlfU1RBUlQpXG5cblxuICAgICAgICBmb3IgKGxldCBhbiBvZiByZWZlcmVuY2VzKSB7XG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwud3JpdGVSZWZlcmVuY2VQb2ludGVyKGFuLCB0cnVlKSlcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgIH1cblxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLkFSUkFZX0VORClcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5DUilcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5MRilcblxuICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuRU5ET0JKKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLkNSKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLkxGKVxuXG4gICAgICAgIHJldHVybiB7IHB0cjogcmVmQXJyYXlfaWQsIGRhdGE6IHJldCwgcGFnZVJlZmVyZW5jZTogcGFnZS5vYmplY3RfaWQsIHBhZ2VEYXRhOiBwYWdlX2RhdGEgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogV3JpdGVzIGFuIGFubm90YXRpb24gb2JqZWN0XG4gICAgICogKi9cbiAgICB3cml0ZUFubm90YXRpb25PYmplY3QoYW5ub3Q6IEFubm90YXRpb24pOiB7IHB0cjogUmVmZXJlbmNlUG9pbnRlciwgZGF0YTogbnVtYmVyW10gfSB7XG5cbiAgICAgICAgLy9pZiAoKGFubm90IGFzIF9Bbm5vdGF0aW9uKS5zdGFtcFR5cGUpIHtcbiAgICAgICAgLy8gICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXIuTkFNRSlcbiAgICAgICAgLy8gICAgcmV0LnB1c2goV3JpdGVyLlNQQUNFKVxuICAgICAgICAvLyAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlci5EUkFGVClcbiAgICAgICAgLy8gICAgcmV0LnB1c2goV3JpdGVyLlNQQUNFKVxuICAgICAgICAvL31cblxuICAgICAgICAvL2lmICgoYW5ub3QgYXMgX0Fubm90YXRpb24pLmNhcmV0U3ltYm9sKSB7XG4gICAgICAgIC8vICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyLlNZKVxuICAgICAgICAvLyAgICByZXQucHVzaChXcml0ZXIuU1BBQ0UpXG4gICAgICAgIC8vICAgIHJldC5wdXNoKFdyaXRlci5QKVxuICAgICAgICAvLyAgICByZXQucHVzaChXcml0ZXIuU1BBQ0UpXG4gICAgICAgIC8vfVxuXG4gICAgICAgIGxldCByZXQgOiBudW1iZXJbXSA9IGFubm90LndyaXRlQW5ub3RhdGlvblByZWFtYmxlKClcblxuICAgICAgICByZXQgPSByZXQuY29uY2F0KGFubm90LndyaXRlQW5ub3RhdGlvbk9iamVjdCh0aGlzLmNyeXB0b0ludGVyZmFjZSkpXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQoYW5ub3Qud3JpdGVBbm5vdGF0aW9uUG9zdGFtYmxlKCkpXG5cbiAgICAgICAgcmV0dXJuIHsgcHRyOiBhbm5vdC5vYmplY3RfaWQhLCBkYXRhOiByZXQgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRha2VzIGFsbCB0aGUgY3Jvc3Mgc2l0ZSByZWZlcmVuY2UgdGFibGUgZW50cmllcyBhbmQgZXh0cmFjdHMgdGhlIGNvbnNlY3V0aXZlIHNlcXVlbmNlc1xuICAgICAqICovXG4gICAgY29tcHV0ZVhyZWZTZXF1ZW5jZXMoKTogWFJlZltdW10ge1xuICAgICAgICBsZXQgc2VxczogWFJlZltdW10gPSBbXVxuXG4gICAgICAgIGxldCBvcmRlcmVkX3hyZWZzID0gdGhpcy54cmVmcy5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgICAgICBpZiAoYS5pZCA8IGIuaWQpXG4gICAgICAgICAgICAgICAgcmV0dXJuIC0xXG4gICAgICAgICAgICBpZiAoYS5pZCA+IGIuaWQpXG4gICAgICAgICAgICAgICAgcmV0dXJuIDFcbiAgICAgICAgICAgIHJldHVybiAwXG4gICAgICAgIH0pXG5cbiAgICAgICAgbGV0IHNlcTogWFJlZltdID0gW29yZGVyZWRfeHJlZnNbMF1dXG4gICAgICAgIGxldCBsYXN0X2lkID0gb3JkZXJlZF94cmVmc1swXS5pZFxuICAgICAgICBzZXFzLnB1c2goc2VxKVxuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IG9yZGVyZWRfeHJlZnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmIChvcmRlcmVkX3hyZWZzW2ldLmlkID09PSBsYXN0X2lkICsgMSkge1xuICAgICAgICAgICAgICAgIHNlcS5wdXNoKG9yZGVyZWRfeHJlZnNbaV0pXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNlcSA9IFtvcmRlcmVkX3hyZWZzW2ldXVxuICAgICAgICAgICAgICAgIHNlcXMucHVzaChzZXEpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsYXN0X2lkID0gb3JkZXJlZF94cmVmc1tpXS5pZFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNlcXNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIHRoZSBwb2ludGVycyBvZiB0aGUgbGlua2VkIGxpc3QgdGhhdCBjb250YWlucyB0aGUgaWRzIG9mIGZyZWVkIG9iamVjdHNcbiAgICAgKiAqL1xuICAgIGFwcGx5T2JqZWN0RnJlZWluZyhyZWZzOiBYUmVmW10pOiBYUmVmW10ge1xuICAgICAgICAvLyB3cml0ZSBmcmVlIG9iamVjdCBoZWFkXG4gICAgICAgIGxldCBoZWFkID0gdGhpcy5wYXJzZXIuZG9jdW1lbnRIaXN0b3J5LmNyZWF0ZU9iamVjdExvb2t1cFRhYmxlKClbMF1cbiAgICAgICAgbGV0IGxhc3RfZnJlZWRfb2JqZWN0X2lkID0gaGVhZC5pZFxuXG4gICAgICAgIGxldCBmcmVlZF9vYmpzOiBYUmVmW10gPSByZWZzLmZpbHRlcihyID0+IHIuZnJlZSlcbiAgICAgICAgZnJlZWRfb2JqcyA9IGZyZWVkX29ianMuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICAgICAgaWYgKGEuaWQgPCBiLmlkKVxuICAgICAgICAgICAgICAgIHJldHVybiAtMVxuICAgICAgICAgICAgaWYgKGEuaWQgPiBiLmlkKVxuICAgICAgICAgICAgICAgIHJldHVybiAxXG4gICAgICAgICAgICByZXR1cm4gMFxuICAgICAgICB9KVxuXG4gICAgICAgIGxldCBsYXN0b2JqOiBYUmVmIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkXG4gICAgICAgIGZvciAobGV0IG9iaiBvZiBmcmVlZF9vYmpzKSB7XG4gICAgICAgICAgICBpZiAoIWxhc3RvYmopIHtcbiAgICAgICAgICAgICAgICAvLyBzZXQgZmlyc3Qgb2JqZWN0IGFzIGxpc3QgaGVhZGVyXG4gICAgICAgICAgICAgICAgaGVhZC5wb2ludGVyID0gb2JqLmlkXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChsYXN0b2JqKSB7XG4gICAgICAgICAgICAgICAgbGFzdG9iai5wb2ludGVyID0gb2JqLmlkXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxhc3RvYmogPSBvYmpcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmcmVlZF9vYmpzLmxlbmd0aCA+IDApXG4gICAgICAgICAgICBmcmVlZF9vYmpzW2ZyZWVkX29ianMubGVuZ3RoIC0gMV0ucG9pbnRlciA9IGxhc3RfZnJlZWRfb2JqZWN0X2lkXG5cbiAgICAgICAgcmVmcy5wdXNoKGhlYWQpXG5cbiAgICAgICAgcmV0dXJuIHJlZnNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXcml0ZXMgdGhlIGNyb3NzaXRlIHJlZmVyZW5jZSB0YWJsZVxuICAgICAqICovXG4gICAgd3JpdGVDcm9zc1NpdGVSZWZlcmVuY2VUYWJsZSgpOiBudW1iZXJbXSB7XG4gICAgICAgIGxldCByZXQ6IG51bWJlcltdID0gV3JpdGVyVXRpbC5YUkVGXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQ1IpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuTEYpXG5cbiAgICAgICAgdGhpcy54cmVmcyA9IHRoaXMuYXBwbHlPYmplY3RGcmVlaW5nKHRoaXMueHJlZnMpXG5cbiAgICAgICAgbGV0IG9yZGVyZWRfc2VxdWVuY2VzID0gdGhpcy5jb21wdXRlWHJlZlNlcXVlbmNlcygpXG5cbiAgICAgICAgZm9yIChsZXQgc2VxdWVuY2Ugb2Ygb3JkZXJlZF9zZXF1ZW5jZXMpIHtcbiAgICAgICAgICAgIGxldCBoZWFkID0gc2VxdWVuY2VbMF1cbiAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoVXRpbC5jb252ZXJ0TnVtYmVyVG9DaGFyQXJyYXkoaGVhZC5pZCkpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChVdGlsLmNvbnZlcnROdW1iZXJUb0NoYXJBcnJheShzZXF1ZW5jZS5sZW5ndGgpKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5DUilcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuTEYpXG5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VxdWVuY2UubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICBsZXQgX3JldDogbnVtYmVyW10gPSBbXVxuICAgICAgICAgICAgICAgIF9yZXQgPSBfcmV0LmNvbmNhdChXcml0ZXJVdGlsLnBhZCgxMCwgc2VxdWVuY2VbaV0ucG9pbnRlcikpXG4gICAgICAgICAgICAgICAgX3JldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgICAgICAgICAgX3JldCA9IF9yZXQuY29uY2F0KFdyaXRlclV0aWwucGFkKDUsIHNlcXVlbmNlW2ldLmdlbmVyYXRpb24pKVxuICAgICAgICAgICAgICAgIF9yZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuXG4gICAgICAgICAgICAgICAgaWYgKHNlcXVlbmNlW2ldLmZyZWUpXG4gICAgICAgICAgICAgICAgICAgIF9yZXQucHVzaChXcml0ZXJVdGlsLkYpXG5cbiAgICAgICAgICAgICAgICBpZiAoc2VxdWVuY2VbaV0udXBkYXRlKVxuICAgICAgICAgICAgICAgICAgICBfcmV0LnB1c2goV3JpdGVyVXRpbC5OKVxuXG4gICAgICAgICAgICAgICAgX3JldC5wdXNoKFdyaXRlclV0aWwuQ1IpXG4gICAgICAgICAgICAgICAgX3JldC5wdXNoKFdyaXRlclV0aWwuTEYpXG5cbiAgICAgICAgICAgICAgICBpZiAoX3JldC5sZW5ndGggPCAyMClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJYUmVmIGVudHJ5IDwgMjAgYnl0ZXNcIilcblxuICAgICAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoX3JldClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXRcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXcml0ZXMgdGhlIHRyYWlsZXJcbiAgICAgKiAqL1xuICAgIHdyaXRlVHJhaWxlcihwb3NYcmVmOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gICAgICAgIGxldCByZXQ6IG51bWJlcltdID0gV3JpdGVyVXRpbC5UUkFJTEVSXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQ1IpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuTEYpXG5cbiAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLkRJQ1RfU1RBUlQpXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC5TSVpFKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICByZXQgPSByZXQuY29uY2F0KFV0aWwuY29udmVydE51bWJlclRvQ2hhckFycmF5KHRoaXMucGFyc2VyLmRvY3VtZW50SGlzdG9yeS50cmFpbGVyU2l6ZSkpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG5cbiAgICAgICAgaWYgKHRoaXMucGFyc2VyLmRvY3VtZW50SGlzdG9yeS5pc0VuY3J5cHRlZCgpKSB7XG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuRU5DUllQVClcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgICAgICBsZXQgZW5jX3JlZiA9IHRoaXMucGFyc2VyLmdldENyeXB0b0ludGVyZmFjZSgpLmdldEVuY3J5cHRpb25EaWN0UmVmZXJlbmNlKClcbiAgICAgICAgICAgIGlmICghZW5jX3JlZilcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihcIk5vIHJlZmVyZW5jZSBwb2ludGVyIHRvIGVuY3J5cHRpb24gZGljdGlvbmFyeVwiKVxuICAgICAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLndyaXRlUmVmZXJlbmNlUG9pbnRlcihlbmNfcmVmLCB0cnVlKSlcbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgIH1cblxuICAgICAgICBsZXQgdHJhaWxlciA9IHRoaXMucGFyc2VyLmRvY3VtZW50SGlzdG9yeS5nZXRSZWNlbnRVcGRhdGUoKVxuXG4gICAgICAgIGlmICh0cmFpbGVyLmlkKSB7XG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuRE9DVU1FTlRfSUQpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5BUlJBWV9TVEFSVClcblxuICAgICAgICAgICAgZm9yIChsZXQgdmFsIG9mIHRyYWlsZXIuaWQpIHtcbiAgICAgICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC5IRVhfU1RSSU5HX1NUQVJUKVxuICAgICAgICAgICAgICAgIHJldCA9IHJldC5jb25jYXQoVXRpbC5jb252ZXJ0U3RyaW5nVG9Bc2NpaShVdGlsLmNvbnZlcnRCeXRlQXJyYXlUb0hleFN0cmluZyh2YWwpKSlcbiAgICAgICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuSEVYX1NUUklOR19FTkQpXG4gICAgICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQVJSQVlfRU5EKVxuICAgICAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC5ST09UKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuXG4gICAgICAgIGlmICghdHJhaWxlci5yb290KVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJObyByb290IG9iamVjdCBpbiB0cmFpbGVyLCBhbHRob3VnaCB0aGlzIGlzIGFuIGNyb3NzIHJlZmVyZW5jZSB0YWJsZSBkb2N1bWVudFwiKVxuXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC53cml0ZVJlZmVyZW5jZVBvaW50ZXIodHJhaWxlci5yb290LCB0cnVlKSlcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcblxuICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuUFJFVilcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5TUEFDRSlcbiAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChVdGlsLmNvbnZlcnROdW1iZXJUb0NoYXJBcnJheSh0aGlzLnBhcnNlci5kb2N1bWVudEhpc3RvcnkuZ2V0UmVjZW50VXBkYXRlKCkuc3RhcnRfcG9pbnRlcikpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuU1BBQ0UpXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC5ESUNUX0VORClcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5DUilcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5MRilcblxuICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuU1RBUlRYUkVGKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLkNSKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLkxGKVxuXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQoVXRpbC5jb252ZXJ0TnVtYmVyVG9DaGFyQXJyYXkocG9zWHJlZikpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQ1IpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuTEYpXG4gICAgICAgIHJldCA9IHJldC5jb25jYXQoV3JpdGVyVXRpbC5FT0YpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQ1IpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuTEYpXG5cbiAgICAgICAgcmV0dXJuIHJldFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdyaXRlcyB0aGUgYW5uYXRpb25zIGF0IHRoZSBlbmQgb2YgdGhlIFBERiBieXRlIHJlcHJlc2VudGF0aW9uIGFuZCByZXR1cm5zXG4gICAgICogdGhlIGJ5dGUgYXJyYXlcbiAgICAgKiAqL1xuICAgIHdyaXRlKCk6IFVpbnQ4QXJyYXkge1xuICAgICAgICBsZXQgcGFnZVdpc2VTb3J0ZWQgPSB0aGlzLnNvcnRQYWdlV2lzZSh0aGlzLmFubm90YXRpb25zKVxuXG4gICAgICAgIGxldCBwdHI6IG51bWJlciA9IHRoaXMuZGF0YS5sZW5ndGhcblxuICAgICAgICBsZXQgbmV3X2RhdGE6IG51bWJlcltdID0gW11cblxuICAgICAgICAvLyBGaXggY2FzZSB0aGF0IHRoZXJlIGlzIG5vIGxpbmVicmVhayBhZnRlciB0aGUgZW5kIG9mIHRoZSBmaWxlXG4gICAgICAgIGlmICh0aGlzLmRhdGFbcHRyIC0gMV0gPT09IDcwKSB7IC8vIDcwID0gJ0YnIChmcm9tIFslJUVPXUZcbiAgICAgICAgICAgIG5ld19kYXRhLnB1c2goV3JpdGVyVXRpbC5DUilcbiAgICAgICAgICAgIG5ld19kYXRhLnB1c2goV3JpdGVyVXRpbC5MRilcbiAgICAgICAgICAgIHB0ciArPSAyXG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGxldCBrZXkgaW4gcGFnZVdpc2VTb3J0ZWQpIHtcbiAgICAgICAgICAgIGxldCBwYWdlQW5ub3RzID0gcGFnZVdpc2VTb3J0ZWRba2V5XVxuXG4gICAgICAgICAgICAvLyB3cml0ZSB0aGUgYXJyYXkgcmVmZXJlbmNpbmcgdG8gYW5ub3RhdGlvbnMgb2YgYSBjZXJ0YWluIHBhZ2VcbiAgICAgICAgICAgIC8vIGl0IGFsc28gcmVtb3ZlcyByZWZlcmVuY2VzIG9mIGFubm90YXRpb25zIHRoYXQgbXVzdCBiZSBkZWxldGVkXG4gICAgICAgICAgICBsZXQgYW5ub3RfYXJyYXkgPSB0aGlzLndyaXRlQW5ub3RBcnJheShwYWdlQW5ub3RzLCB0aGlzLnRvRGVsZXRlKVxuICAgICAgICAgICAgdGhpcy54cmVmcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBpZDogYW5ub3RfYXJyYXkucHRyLm9iaixcbiAgICAgICAgICAgICAgICBwb2ludGVyOiBwdHIsXG4gICAgICAgICAgICAgICAgZ2VuZXJhdGlvbjogYW5ub3RfYXJyYXkucHRyLmdlbmVyYXRpb24sXG4gICAgICAgICAgICAgICAgZnJlZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgdXBkYXRlOiB0cnVlXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBuZXdfZGF0YSA9IG5ld19kYXRhLmNvbmNhdChhbm5vdF9hcnJheS5kYXRhKVxuICAgICAgICAgICAgcHRyICs9IGFubm90X2FycmF5LmRhdGEubGVuZ3RoXG5cbiAgICAgICAgICAgIC8vIGFkZCBhZGFwdGVkIHBhZ2Ugb2JqZWN0IGlmIGl0IGV4aXN0cyAtLSBJbiB0aGUgY2FzZSB0aGUgcGFnZSBoYWQgbm8gYW5ub3RhdGlvbiB5ZXQgdGhlcmUgZXhpc3RzXG4gICAgICAgICAgICAvLyBubyBzdWNoIGFycmF5IHJlZmVycmluZyB0byBpdHMgYW5ub3RhdGlvbnMuIEEgcG9pbnRlciB0byBzdWNoIGFuIGFycmF5IG11c3QgYmUgYWRkZWQgdG8gdGhlXG4gICAgICAgICAgICAvLyBwYWdlIG9iamVjdC4gSWYgdGhpcyB3YXMgZG9uZSB0aGUgYHBhZ2VEYXRhYCBwYXJhbWF0ZXIgaXMgc2V0IGFuZCBjb250YWlucyB0aGUgYWRhcHRlZCBwYWdlIG9iamVjdFxuICAgICAgICAgICAgaWYgKGFubm90X2FycmF5LnBhZ2VEYXRhLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnhyZWZzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBpZDogYW5ub3RfYXJyYXkucGFnZVJlZmVyZW5jZS5vYmosXG4gICAgICAgICAgICAgICAgICAgIHBvaW50ZXI6IHB0cixcbiAgICAgICAgICAgICAgICAgICAgZ2VuZXJhdGlvbjogYW5ub3RfYXJyYXkucGFnZVJlZmVyZW5jZS5nZW5lcmF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBmcmVlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlOiB0cnVlXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICBuZXdfZGF0YSA9IG5ld19kYXRhLmNvbmNhdChhbm5vdF9hcnJheS5wYWdlRGF0YSlcbiAgICAgICAgICAgICAgICBwdHIgKz0gYW5ub3RfYXJyYXkucGFnZURhdGEubGVuZ3RoXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHdyaXRlcyB0aGUgYWN0dWFsIGFubm90YXRpb24gb2JqZWN0XG4gICAgICAgICAgICBmb3IgKGxldCBhbm5vdCBvZiBwYWdlQW5ub3RzKSB7XG4gICAgICAgICAgICAgICAgbGV0IGFubm90X29iaiA9IHRoaXMud3JpdGVBbm5vdGF0aW9uT2JqZWN0KGFubm90KVxuICAgICAgICAgICAgICAgIHRoaXMueHJlZnMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGlkOiBhbm5vdF9vYmoucHRyLm9iaixcbiAgICAgICAgICAgICAgICAgICAgcG9pbnRlcjogcHRyLFxuICAgICAgICAgICAgICAgICAgICBnZW5lcmF0aW9uOiBhbm5vdF9vYmoucHRyLmdlbmVyYXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGZyZWU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICB1cGRhdGU6IHRydWVcbiAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgICAgbmV3X2RhdGEgPSBuZXdfZGF0YS5jb25jYXQoYW5ub3Rfb2JqLmRhdGEpXG4gICAgICAgICAgICAgICAgcHRyICs9IGFubm90X29iai5kYXRhLmxlbmd0aFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdGFrZSBhbGwgYW5ub3RhdGlvbnMgdGhhdCBhcmUgbm90IGRlbGV0ZWQgeWV0XG4gICAgICAgIGxldCBfdG9EZWxldGU6IEFubm90YXRpb25bXSA9IHRoaXMudG9EZWxldGUuZmlsdGVyKCh0KSA9PiAhdC5pc19kZWxldGVkKVxuICAgICAgICBsZXQgcGFnZVdpc2VTb3J0ZWRUb0RlbGV0ZSA9IHRoaXMuc29ydFBhZ2VXaXNlKF90b0RlbGV0ZSlcblxuICAgICAgICAvLyBhZGFwdCB0aGUgcmVtYWluaW5nIGFubm90YXRpb24gcmVmZXJlbmNlIHRhYmxlc1xuICAgICAgICBmb3IgKGxldCBrZXkgaW4gcGFnZVdpc2VTb3J0ZWRUb0RlbGV0ZSkge1xuICAgICAgICAgICAgbGV0IGRlbF9kYXRhID0gdGhpcy51cGRhdGVQYWdlQW5ub3RhdGlvblJlZmVyZW5jZUFycmF5KHBhZ2VXaXNlU29ydGVkVG9EZWxldGVba2V5XSlcbiAgICAgICAgICAgIHRoaXMueHJlZnMucHVzaCh7XG4gICAgICAgICAgICAgICAgaWQ6IGRlbF9kYXRhLnB0ci5vYmosXG4gICAgICAgICAgICAgICAgcG9pbnRlcjogcHRyLFxuICAgICAgICAgICAgICAgIGdlbmVyYXRpb246IGRlbF9kYXRhLnB0ci5nZW5lcmF0aW9uLFxuICAgICAgICAgICAgICAgIGZyZWU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHVwZGF0ZTogdHJ1ZVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgbmV3X2RhdGEgPSBuZXdfZGF0YS5jb25jYXQoZGVsX2RhdGEuZGF0YSlcbiAgICAgICAgICAgIHB0ciArPSBkZWxfZGF0YS5kYXRhLmxlbmd0aFxuICAgICAgICB9XG5cbiAgICAgICAgLy8gYXQgdGhpcyBwb2ludCBhbGwgcmVmZXJlbmNlcyB0byBhbm5vdGF0aW9uIG9iamVjdHMgaW4gcGFnZXMgc2hvdWxkIGJlIHJlbW92ZWQgYW5kIHdlIGNhbiBmcmVlXG4gICAgICAgIC8vIHRoZSBhbm5vdGF0aW9uIG9iamVjdCBpZHNcbiAgICAgICAgZm9yIChsZXQgdG9EZWwgb2YgdGhpcy50b0RlbGV0ZSkge1xuICAgICAgICAgICAgaWYgKCF0b0RlbC5vYmplY3RfaWQpXG4gICAgICAgICAgICAgICAgY29udGludWVcblxuICAgICAgICAgICAgdGhpcy54cmVmcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBpZDogdG9EZWwub2JqZWN0X2lkLm9iaixcbiAgICAgICAgICAgICAgICBwb2ludGVyOiAtMSxcbiAgICAgICAgICAgICAgICBnZW5lcmF0aW9uOiB0b0RlbC5vYmplY3RfaWQuZ2VuZXJhdGlvbiArIDEsIC8vIGluY3JlYXNlIGdlbmVyYXRpb25cbiAgICAgICAgICAgICAgICBmcmVlOiB0cnVlLFxuICAgICAgICAgICAgICAgIHVwZGF0ZTogZmFsc2VcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICBsZXQgY3J0YWJsZSA9IHRoaXMud3JpdGVDcm9zc1NpdGVSZWZlcmVuY2VUYWJsZSgpXG4gICAgICAgIG5ld19kYXRhID0gbmV3X2RhdGEuY29uY2F0KGNydGFibGUpXG5cbiAgICAgICAgbGV0IHRyYWlsZXIgPSB0aGlzLndyaXRlVHJhaWxlcihwdHIpXG4gICAgICAgIG5ld19kYXRhID0gbmV3X2RhdGEuY29uY2F0KHRyYWlsZXIpXG5cbiAgICAgICAgbGV0IG5ld19kYXRhX2FycmF5ID0gbmV3IFVpbnQ4QXJyYXkobmV3X2RhdGEpXG5cbiAgICAgICAgbGV0IHJldF9hcnJheSA9IG5ldyBVaW50OEFycmF5KHRoaXMuZGF0YS5sZW5ndGggKyBuZXdfZGF0YV9hcnJheS5sZW5ndGgpXG4gICAgICAgIHJldF9hcnJheS5zZXQodGhpcy5kYXRhKVxuICAgICAgICByZXRfYXJyYXkuc2V0KG5ld19kYXRhLCB0aGlzLmRhdGEubGVuZ3RoKVxuXG4gICAgICAgIHJldHVybiByZXRfYXJyYXlcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIHRoZSBnaXZlbiBhbm5vdGF0aW9uXG4gICAgICogKi9cbiAgICB1cGRhdGVQYWdlQW5ub3RhdGlvblJlZmVyZW5jZUFycmF5KHRvRGVsZXRlOiBBbm5vdGF0aW9uW10pOiB7IHB0cjogUmVmZXJlbmNlUG9pbnRlciwgZGF0YTogbnVtYmVyW10gfSB7XG4gICAgICAgIGxldCBwYWdlID0gdG9EZWxldGVbMF0ucGFnZVJlZmVyZW5jZVxuXG4gICAgICAgIGlmICghcGFnZSlcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiTWlzc2luZyBwYWdlIHJlZmVyZW5jZVwiKVxuXG4gICAgICAgIGlmICghcGFnZS5vYmplY3RfaWQpIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiUGFnZSB3aXRob3V0IG9iamVjdCBpZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHJlZmVyZW5jZXM6IFJlZmVyZW5jZVBvaW50ZXJbXSA9IHBhZ2UuYW5ub3RzXG5cbiAgICAgICAgLy8gcmVtb3ZlIGFubm90YXRpb24gcmVmZXJlbmNlcyBmcm9tIHRoZSBhcnJheSB0aGF0IG11c3QgYmUgZGVsZXRlZCBhbmQgbWFyayB0aGVtIGFzIGRlbGV0ZWRcbiAgICAgICAgcmVmZXJlbmNlcyA9IHJlZmVyZW5jZXMuZmlsdGVyKChhOiBhbnkpID0+IHtcbiAgICAgICAgICAgIGxldCB0b0RlbCA9IHRvRGVsZXRlLmZpbmQoKHQpID0+ICg8YW55PnQub2JqZWN0X2lkKS5vYmogPT09IGEub2JqICYmICg8YW55PnQub2JqZWN0X2lkKS5nZW5lcmF0aW9uID09PSBhLmdlbmVyYXRpb24pXG5cbiAgICAgICAgICAgIGlmICh0b0RlbCkge1xuICAgICAgICAgICAgICAgIHRvRGVsLmlzX2RlbGV0ZWQgPSB0cnVlXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0pXG5cbiAgICAgICAgbGV0IHJlZkFycmF5X2lkOiBhbnkgPSBwYWdlLmFubm90c1BvaW50ZXJcblxuICAgICAgICBsZXQgcmV0OiBudW1iZXJbXSA9IFdyaXRlclV0aWwud3JpdGVSZWZlcmVuY2VQb2ludGVyKHJlZkFycmF5X2lkKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICByZXQgPSByZXQuY29uY2F0KFdyaXRlclV0aWwuT0JKKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLkNSKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLkxGKVxuICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLkFSUkFZX1NUQVJUKVxuXG5cbiAgICAgICAgZm9yIChsZXQgYW4gb2YgcmVmZXJlbmNlcykge1xuICAgICAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLndyaXRlUmVmZXJlbmNlUG9pbnRlcihhbiwgdHJ1ZSkpXG4gICAgICAgICAgICByZXQucHVzaChXcml0ZXJVdGlsLlNQQUNFKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5BUlJBWV9FTkQpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuQ1IpXG4gICAgICAgIHJldC5wdXNoKFdyaXRlclV0aWwuTEYpXG5cbiAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChXcml0ZXJVdGlsLkVORE9CSilcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5DUilcbiAgICAgICAgcmV0LnB1c2goV3JpdGVyVXRpbC5MRilcblxuICAgICAgICByZXR1cm4geyBwdHI6IHJlZkFycmF5X2lkLCBkYXRhOiByZXQgfVxuICAgIH1cbn1cbiIsIi8qIChpZ25vcmVkKSAqLyIsIi8qIChpZ25vcmVkKSAqLyIsIi8qIChpZ25vcmVkKSAqLyIsIi8qIChpZ25vcmVkKSAqLyJdLCJzb3VyY2VSb290IjoiIn0= |