(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Syndicate = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o * @license MIT */ /* eslint-disable no-proto */ 'use strict' var base64 = require('base64-js') var ieee754 = require('ieee754') var isArray = require('isarray') exports.Buffer = Buffer exports.SlowBuffer = SlowBuffer exports.INSPECT_MAX_BYTES = 50 Buffer.poolSize = 8192 // not used by this implementation var rootParent = {} /** * 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() function typedArraySupport () { try { var arr = new Uint8Array(1) arr.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 } /** * 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) { if (!(this instanceof Buffer)) { // Avoid going through an ArgumentsAdaptorTrampoline in the common case. if (arguments.length > 1) return new Buffer(arg, arguments[1]) return new Buffer(arg) } if (!Buffer.TYPED_ARRAY_SUPPORT) { this.length = 0 this.parent = undefined } // Common case. if (typeof arg === 'number') { return fromNumber(this, arg) } // Slightly less common case. if (typeof arg === 'string') { return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8') } // Unusual. return fromObject(this, arg) } // TODO: Legacy, not needed anymore. Remove in next major version. Buffer._augment = function (arr) { arr.__proto__ = Buffer.prototype return arr } function fromNumber (that, length) { that = allocate(that, length < 0 ? 0 : checked(length) | 0) if (!Buffer.TYPED_ARRAY_SUPPORT) { for (var i = 0; i < length; i++) { that[i] = 0 } } return that } function fromString (that, string, encoding) { if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8' // Assumption: byteLength() return value is always < kMaxLength. var length = byteLength(string, encoding) | 0 that = allocate(that, length) that.write(string, encoding) return that } function fromObject (that, object) { if (Buffer.isBuffer(object)) return fromBuffer(that, object) if (isArray(object)) return fromArray(that, object) if (object == null) { throw new TypeError('must start with number, buffer, array or string') } if (typeof ArrayBuffer !== 'undefined') { if (object.buffer instanceof ArrayBuffer) { return fromTypedArray(that, object) } if (object instanceof ArrayBuffer) { return fromArrayBuffer(that, object) } } if (object.length) return fromArrayLike(that, object) return fromJsonObject(that, object) } function fromBuffer (that, buffer) { var length = checked(buffer.length) | 0 that = allocate(that, length) buffer.copy(that, 0, 0, length) return that } function fromArray (that, array) { var length = checked(array.length) | 0 that = allocate(that, length) for (var i = 0; i < length; i += 1) { that[i] = array[i] & 255 } return that } // Duplicate of fromArray() to keep fromArray() monomorphic. function fromTypedArray (that, array) { var length = checked(array.length) | 0 that = allocate(that, length) // Truncating the elements is probably not what people expect from typed // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior // of the old Buffer constructor. for (var i = 0; i < length; i += 1) { that[i] = array[i] & 255 } return that } function fromArrayBuffer (that, array) { array.byteLength // this throws if `array` is not a valid ArrayBuffer if (Buffer.TYPED_ARRAY_SUPPORT) { // Return an augmented `Uint8Array` instance, for best performance that = new Uint8Array(array) that.__proto__ = Buffer.prototype } else { // Fallback: Return an object instance of the Buffer class that = fromTypedArray(that, new Uint8Array(array)) } return that } function fromArrayLike (that, array) { var length = checked(array.length) | 0 that = allocate(that, length) for (var i = 0; i < length; i += 1) { that[i] = array[i] & 255 } return that } // Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object. // Returns a zero-length buffer for inputs that don't conform to the spec. function fromJsonObject (that, object) { var array var length = 0 if (object.type === 'Buffer' && isArray(object.data)) { array = object.data length = checked(array.length) | 0 } that = allocate(that, length) for (var i = 0; i < length; i += 1) { that[i] = array[i] & 255 } return that } if (Buffer.TYPED_ARRAY_SUPPORT) { Buffer.prototype.__proto__ = Uint8Array.prototype Buffer.__proto__ = Uint8Array } else { // pre-set for values that may exist in the future Buffer.prototype.length = undefined Buffer.prototype.parent = undefined } function allocate (that, 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 that.length = length } var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1 if (fromPool) that.parent = rootParent return that } 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 (subject, encoding) { if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding) var buf = new Buffer(subject, encoding) delete buf.parent return buf } 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 var i = 0 var len = Math.min(x, y) while (i < len) { if (a[i] !== b[i]) break ++i } if (i !== len) { x = a[i] y = b[i] } 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 'binary': case 'base64': case 'raw': 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 new Buffer(0) } var i if (length === undefined) { length = 0 for (i = 0; i < list.length; i++) { length += list[i].length } } var buf = new Buffer(length) var pos = 0 for (i = 0; i < list.length; i++) { var item = list[i] item.copy(buf, pos) pos += item.length } return buf } function byteLength (string, encoding) { 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 'binary': // Deprecated case 'raw': case 'raws': return len case 'utf8': case 'utf-8': 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 start = start | 0 end = end === undefined || end === Infinity ? this.length : end | 0 if (!encoding) encoding = 'utf8' if (start < 0) start = 0 if (end > this.length) end = this.length if (end <= start) return '' 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 'binary': return binarySlice(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 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.prototype.compare = function compare (b) { if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') if (this === b) return 0 return Buffer.compare(this, b) } Buffer.prototype.indexOf = function indexOf (val, byteOffset) { if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff else if (byteOffset < -0x80000000) byteOffset = -0x80000000 byteOffset >>= 0 if (this.length === 0) return -1 if (byteOffset >= this.length) return -1 // Negative offsets start from the end of the buffer if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) if (typeof val === 'string') { if (val.length === 0) return -1 // special case: looking for empty string always fails return String.prototype.indexOf.call(this, val, byteOffset) } if (Buffer.isBuffer(val)) { return arrayIndexOf(this, val, byteOffset) } if (typeof val === 'number') { if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { return Uint8Array.prototype.indexOf.call(this, val, byteOffset) } return arrayIndexOf(this, [ val ], byteOffset) } function arrayIndexOf (arr, val, byteOffset) { var foundIndex = -1 for (var i = 0; byteOffset + i < arr.length; i++) { if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) { if (foundIndex === -1) foundIndex = i if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex } else { foundIndex = -1 } } return -1 } throw new TypeError('val must be string, number or Buffer') } 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 Error('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)) throw new Error('Invalid hex string') 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 binaryWrite (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 { var swap = encoding encoding = offset offset = length | 0 length = swap } 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 'binary': return binaryWrite(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 binarySlice (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] } } if (newBuf.length) newBuf.parent = this.parent || this 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 must be a Buffer instance') if (value > max || value < min) throw new RangeError('value 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) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 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) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 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 = value < 0 ? 1 : 0 this[offset] = value & 0xFF while (++i < byteLength && (mul *= 0x100)) { 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 = value < 0 ? 1 : 0 this[offset + i] = value & 0xFF while (--i >= 0 && (mul *= 0x100)) { 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 } // fill(value, start=0, end=buffer.length) Buffer.prototype.fill = function fill (value, start, end) { if (!value) value = 0 if (!start) start = 0 if (!end) end = this.length if (end < start) throw new RangeError('end < start') // Fill 0 bytes; we're done if (end === start) return if (this.length === 0) return if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') if (end < 0 || end > this.length) throw new RangeError('end out of bounds') var i if (typeof value === 'number') { for (i = start; i < end; i++) { this[i] = value } } else { var bytes = utf8ToBytes(value.toString()) var len = bytes.length for (i = start; i < end; i++) { this[i] = 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 } }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"base64-js":3,"ieee754":4,"isarray":5}],3:[function(require,module,exports){ ;(function (exports) { 'use strict' var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' var Arr = (typeof Uint8Array !== 'undefined') ? Uint8Array : Array var PLUS = '+'.charCodeAt(0) var SLASH = '/'.charCodeAt(0) var NUMBER = '0'.charCodeAt(0) var LOWER = 'a'.charCodeAt(0) var UPPER = 'A'.charCodeAt(0) var PLUS_URL_SAFE = '-'.charCodeAt(0) var SLASH_URL_SAFE = '_'.charCodeAt(0) function decode (elt) { var code = elt.charCodeAt(0) if (code === PLUS || code === PLUS_URL_SAFE) return 62 // '+' if (code === SLASH || code === SLASH_URL_SAFE) return 63 // '/' if (code < NUMBER) return -1 // no match if (code < NUMBER + 10) return code - NUMBER + 26 + 26 if (code < UPPER + 26) return code - UPPER if (code < LOWER + 26) return code - LOWER + 26 } function b64ToByteArray (b64) { var i, j, l, tmp, placeHolders, arr if (b64.length % 4 > 0) { throw new Error('Invalid string. Length must be a multiple of 4') } // the number of equal signs (place holders) // if there are two placeholders, than the two characters before it // represent one byte // if there is only one, then the three characters before it represent 2 bytes // this is just a cheap hack to not do indexOf twice var len = b64.length placeHolders = b64.charAt(len - 2) === '=' ? 2 : b64.charAt(len - 1) === '=' ? 1 : 0 // base64 is 4/3 + up to two characters of the original data arr = new Arr(b64.length * 3 / 4 - placeHolders) // if there are placeholders, only get up to the last complete 4 chars l = placeHolders > 0 ? b64.length - 4 : b64.length var L = 0 function push (v) { arr[L++] = v } for (i = 0, j = 0; i < l; i += 4, j += 3) { tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) push((tmp & 0xFF0000) >> 16) push((tmp & 0xFF00) >> 8) push(tmp & 0xFF) } if (placeHolders === 2) { tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) push(tmp & 0xFF) } else if (placeHolders === 1) { tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) push((tmp >> 8) & 0xFF) push(tmp & 0xFF) } return arr } function uint8ToBase64 (uint8) { var i var extraBytes = uint8.length % 3 // if we have 1 byte left, pad 2 bytes var output = '' var temp, length function encode (num) { return lookup.charAt(num) } function tripletToBase64 (num) { return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) } // go through the array every three bytes, we'll deal with trailing stuff later for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) output += tripletToBase64(temp) } // pad the end with zeros, but make sure to not forget the extra bytes switch (extraBytes) { case 1: temp = uint8[uint8.length - 1] output += encode(temp >> 2) output += encode((temp << 4) & 0x3F) output += '==' break case 2: temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) output += encode(temp >> 10) output += encode((temp >> 4) & 0x3F) output += encode((temp << 2) & 0x3F) output += '=' break default: break } return output } exports.toByteArray = b64ToByteArray exports.fromByteArray = uint8ToBase64 }(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) },{}],4:[function(require,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 } },{}],5:[function(require,module,exports){ var toString = {}.toString; module.exports = Array.isArray || function (arr) { return toString.call(arr) == '[object Array]'; }; },{}],6:[function(require,module,exports){ 'use strict' exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = require('randombytes') exports.createHash = exports.Hash = require('create-hash') exports.createHmac = exports.Hmac = require('create-hmac') var hashes = ['sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'md5', 'rmd160'].concat(Object.keys(require('browserify-sign/algos'))) exports.getHashes = function () { return hashes } var p = require('pbkdf2') exports.pbkdf2 = p.pbkdf2 exports.pbkdf2Sync = p.pbkdf2Sync var aes = require('browserify-cipher') ;[ 'Cipher', 'createCipher', 'Cipheriv', 'createCipheriv', 'Decipher', 'createDecipher', 'Decipheriv', 'createDecipheriv', 'getCiphers', 'listCiphers' ].forEach(function (key) { exports[key] = aes[key] }) var dh = require('diffie-hellman') ;[ 'DiffieHellmanGroup', 'createDiffieHellmanGroup', 'getDiffieHellman', 'createDiffieHellman', 'DiffieHellman' ].forEach(function (key) { exports[key] = dh[key] }) var sign = require('browserify-sign') ;[ 'createSign', 'Sign', 'createVerify', 'Verify' ].forEach(function (key) { exports[key] = sign[key] }) exports.createECDH = require('create-ecdh') var publicEncrypt = require('public-encrypt') ;[ 'publicEncrypt', 'privateEncrypt', 'publicDecrypt', 'privateDecrypt' ].forEach(function (key) { exports[key] = publicEncrypt[key] }) // 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')) } }) },{"browserify-cipher":7,"browserify-sign":37,"browserify-sign/algos":36,"create-ecdh":104,"create-hash":130,"create-hmac":143,"diffie-hellman":144,"pbkdf2":151,"public-encrypt":152,"randombytes":197}],7:[function(require,module,exports){ var ebtk = require('evp_bytestokey') var aes = require('browserify-aes/browser') var DES = require('browserify-des') var desModes = require('browserify-des/modes') var aesModes = require('browserify-aes/modes') function createCipher (suite, password) { var keyLen, ivLen suite = suite.toLowerCase() 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) { var keyLen, ivLen suite = suite.toLowerCase() 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) } else if (desModes[suite]) { return new DES({ key: key, iv: iv, mode: suite }) } else { throw new TypeError('invalid suite type') } } function createDecipheriv (suite, key, iv) { suite = suite.toLowerCase() if (aesModes[suite]) { return aes.createDecipheriv(suite, key, iv) } else if (desModes[suite]) { return new DES({ key: key, iv: iv, mode: suite, decrypt: true }) } else { throw new TypeError('invalid suite type') } } exports.createCipher = exports.Cipher = createCipher exports.createCipheriv = exports.Cipheriv = createCipheriv exports.createDecipher = exports.Decipher = createDecipher exports.createDecipheriv = exports.Decipheriv = createDecipheriv function getCiphers () { return Object.keys(desModes).concat(aes.getCiphers()) } exports.listCiphers = exports.getCiphers = getCiphers },{"browserify-aes/browser":10,"browserify-aes/modes":14,"browserify-des":25,"browserify-des/modes":26,"evp_bytestokey":35}],8:[function(require,module,exports){ (function (Buffer){ // 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 uint_max = Math.pow(2, 32) function fixup_uint32 (x) { var ret, x_pos ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x return ret } function scrub_vec (v) { for (var i = 0; i < v.length; v++) { v[i] = 0 } return false } function Global () { this.SBOX = [] this.INV_SBOX = [] this.SUB_MIX = [[], [], [], []] this.INV_SUB_MIX = [[], [], [], []] this.init() this.RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36] } Global.prototype.init = function () { var d, i, sx, t, x, x2, x4, x8, xi, _i d = (function () { var _i, _results _results = [] for (i = _i = 0; _i < 256; i = ++_i) { if (i < 128) { _results.push(i << 1) } else { _results.push((i << 1) ^ 0x11b) } } return _results })() x = 0 xi = 0 for (i = _i = 0; _i < 256; i = ++_i) { sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4) sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63 this.SBOX[x] = sx this.INV_SBOX[sx] = x x2 = d[x] x4 = d[x2] x8 = d[x4] t = (d[sx] * 0x101) ^ (sx * 0x1010100) this.SUB_MIX[0][x] = (t << 24) | (t >>> 8) this.SUB_MIX[1][x] = (t << 16) | (t >>> 16) this.SUB_MIX[2][x] = (t << 8) | (t >>> 24) this.SUB_MIX[3][x] = t t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100) this.INV_SUB_MIX[0][sx] = (t << 24) | (t >>> 8) this.INV_SUB_MIX[1][sx] = (t << 16) | (t >>> 16) this.INV_SUB_MIX[2][sx] = (t << 8) | (t >>> 24) this.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 true } var G = new Global() AES.blockSize = 4 * 4 AES.prototype.blockSize = AES.blockSize AES.keySize = 256 / 8 AES.prototype.keySize = AES.keySize function bufferToArray (buf) { var len = buf.length / 4 var out = new Array(len) var i = -1 while (++i < len) { out[i] = buf.readUInt32BE(i * 4) } return out } function AES (key) { this._key = bufferToArray(key) this._doReset() } AES.prototype._doReset = function () { var invKsRow, keySize, keyWords, ksRow, ksRows, t keyWords = this._key keySize = keyWords.length this._nRounds = keySize + 6 ksRows = (this._nRounds + 1) * 4 this._keySchedule = [] for (ksRow = 0; ksRow < ksRows; ksRow++) { this._keySchedule[ksRow] = ksRow < keySize ? keyWords[ksRow] : (t = this._keySchedule[ksRow - 1], (ksRow % 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 ^= G.RCON[(ksRow / keySize) | 0] << 24) : keySize > 6 && ksRow % keySize === 4 ? t = (G.SBOX[t >>> 24] << 24) | (G.SBOX[(t >>> 16) & 0xff] << 16) | (G.SBOX[(t >>> 8) & 0xff] << 8) | G.SBOX[t & 0xff] : void 0, this._keySchedule[ksRow - keySize] ^ t) } this._invKeySchedule = [] for (invKsRow = 0; invKsRow < ksRows; invKsRow++) { ksRow = ksRows - invKsRow t = this._keySchedule[ksRow - (invKsRow % 4 ? 0 : 4)] this._invKeySchedule[invKsRow] = invKsRow < 4 || ksRow <= 4 ? t : G.INV_SUB_MIX[0][G.SBOX[t >>> 24]] ^ G.INV_SUB_MIX[1][G.SBOX[(t >>> 16) & 0xff]] ^ G.INV_SUB_MIX[2][G.SBOX[(t >>> 8) & 0xff]] ^ G.INV_SUB_MIX[3][G.SBOX[t & 0xff]] } return true } AES.prototype.encryptBlock = function (M) { M = bufferToArray(new Buffer(M)) var out = this._doCryptBlock(M, this._keySchedule, G.SUB_MIX, G.SBOX) var buf = new Buffer(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 = bufferToArray(new Buffer(M)) var temp = [M[3], M[1]] M[1] = temp[0] M[3] = temp[1] var out = this._doCryptBlock(M, this._invKeySchedule, G.INV_SUB_MIX, G.INV_SBOX) var buf = new Buffer(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 () { scrub_vec(this._keySchedule) scrub_vec(this._invKeySchedule) scrub_vec(this._key) } AES.prototype._doCryptBlock = function (M, keySchedule, SUB_MIX, SBOX) { var ksRow, s0, s1, s2, s3, t0, t1, t2, t3 s0 = M[0] ^ keySchedule[0] s1 = M[1] ^ keySchedule[1] s2 = M[2] ^ keySchedule[2] s3 = M[3] ^ keySchedule[3] ksRow = 4 for (var round = 1; round < this._nRounds; round++) { 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++] 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++] 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++] 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++] 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++] return [ fixup_uint32(t0), fixup_uint32(t1), fixup_uint32(t2), fixup_uint32(t3) ] } exports.AES = AES }).call(this,require("buffer").Buffer) },{"buffer":2}],9:[function(require,module,exports){ (function (Buffer){ var aes = require('./aes') var Transform = require('cipher-base') var inherits = require('inherits') var GHASH = require('./ghash') var xor = require('buffer-xor') inherits(StreamCipher, Transform) module.exports = StreamCipher function StreamCipher (mode, key, iv, decrypt) { if (!(this instanceof StreamCipher)) { return new StreamCipher(mode, key, iv) } Transform.call(this) this._finID = Buffer.concat([iv, new Buffer([0, 0, 0, 1])]) iv = Buffer.concat([iv, new Buffer([0, 0, 0, 2])]) this._cipher = new aes.AES(key) this._prev = new Buffer(iv.length) this._cache = new Buffer('') this._secCache = new Buffer('') this._decrypt = decrypt this._alen = 0 this._len = 0 iv.copy(this._prev) this._mode = mode var h = new Buffer(4) h.fill(0) this._ghash = new GHASH(this._cipher.encryptBlock(h)) this._authTag = null this._called = false } StreamCipher.prototype._update = function (chunk) { if (!this._called && this._alen) { var rump = 16 - (this._alen % 16) if (rump < 16) { rump = new Buffer(rump) rump.fill(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) { if (xorTest(tag, this._authTag)) { throw new Error('Unsupported state or unable to authenticate data') } } else { this._authTag = tag } this._cipher.scrub() } StreamCipher.prototype.getAuthTag = function getAuthTag () { if (!this._decrypt && Buffer.isBuffer(this._authTag)) { return this._authTag } else { throw new Error('Attempting to get auth tag in unsupported state') } } StreamCipher.prototype.setAuthTag = function setAuthTag (tag) { if (this._decrypt) { this._authTag = tag } else { throw new Error('Attempting to set auth tag in unsupported state') } } StreamCipher.prototype.setAAD = function setAAD (buf) { if (!this._called) { this._ghash.update(buf) this._alen += buf.length } else { throw new Error('Attempting to set AAD in unsupported state') } } function xorTest (a, b) { var out = 0 if (a.length !== b.length) { out++ } var len = Math.min(a.length, b.length) var i = -1 while (++i < len) { out += (a[i] ^ b[i]) } return out } }).call(this,require("buffer").Buffer) },{"./aes":8,"./ghash":13,"buffer":2,"buffer-xor":22,"cipher-base":23,"inherits":199}],10:[function(require,module,exports){ var ciphers = require('./encrypter') exports.createCipher = exports.Cipher = ciphers.createCipher exports.createCipheriv = exports.Cipheriv = ciphers.createCipheriv var deciphers = require('./decrypter') exports.createDecipher = exports.Decipher = deciphers.createDecipher exports.createDecipheriv = exports.Decipheriv = deciphers.createDecipheriv var modes = require('./modes') function getCiphers () { return Object.keys(modes) } exports.listCiphers = exports.getCiphers = getCiphers },{"./decrypter":11,"./encrypter":12,"./modes":14}],11:[function(require,module,exports){ (function (Buffer){ var aes = require('./aes') var Transform = require('cipher-base') var inherits = require('inherits') var modes = require('./modes') var StreamCipher = require('./streamCipher') var AuthCipher = require('./authCipher') var ebtk = require('evp_bytestokey') inherits(Decipher, Transform) function Decipher (mode, key, iv) { if (!(this instanceof Decipher)) { return new Decipher(mode, key, iv) } Transform.call(this) this._cache = new Splitter() this._last = void 0 this._cipher = new aes.AES(key) this._prev = new Buffer(iv.length) iv.copy(this._prev) this._mode = mode this._autopadding = true } 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 () { if (!(this instanceof Splitter)) { return new Splitter() } this.cache = new Buffer('') } 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] 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) } var modelist = { ECB: require('./modes/ecb'), CBC: require('./modes/cbc'), CFB: require('./modes/cfb'), CFB8: require('./modes/cfb8'), CFB1: require('./modes/cfb1'), OFB: require('./modes/ofb'), CTR: require('./modes/ctr'), GCM: require('./modes/ctr') } function createDecipheriv (suite, password, iv) { var config = modes[suite.toLowerCase()] if (!config) { throw new TypeError('invalid suite type') } if (typeof iv === 'string') { iv = new Buffer(iv) } if (typeof password === 'string') { password = new Buffer(password) } if (password.length !== config.key / 8) { throw new TypeError('invalid key length ' + password.length) } if (iv.length !== config.iv) { throw new TypeError('invalid iv length ' + iv.length) } if (config.type === 'stream') { return new StreamCipher(modelist[config.mode], password, iv, true) } else if (config.type === 'auth') { return new AuthCipher(modelist[config.mode], password, iv, true) } return new Decipher(modelist[config.mode], 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 }).call(this,require("buffer").Buffer) },{"./aes":8,"./authCipher":9,"./modes":14,"./modes/cbc":15,"./modes/cfb":16,"./modes/cfb1":17,"./modes/cfb8":18,"./modes/ctr":19,"./modes/ecb":20,"./modes/ofb":21,"./streamCipher":24,"buffer":2,"cipher-base":23,"evp_bytestokey":35,"inherits":199}],12:[function(require,module,exports){ (function (Buffer){ var aes = require('./aes') var Transform = require('cipher-base') var inherits = require('inherits') var modes = require('./modes') var ebtk = require('evp_bytestokey') var StreamCipher = require('./streamCipher') var AuthCipher = require('./authCipher') inherits(Cipher, Transform) function Cipher (mode, key, iv) { if (!(this instanceof Cipher)) { return new Cipher(mode, key, iv) } Transform.call(this) this._cache = new Splitter() this._cipher = new aes.AES(key) this._prev = new Buffer(iv.length) iv.copy(this._prev) this._mode = mode this._autopadding = true } 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) } Cipher.prototype._final = function () { var chunk = this._cache.flush() if (this._autopadding) { chunk = this._mode.encrypt(this, chunk) this._cipher.scrub() return chunk } else if (chunk.toString('hex') !== '10101010101010101010101010101010') { this._cipher.scrub() throw new Error('data not multiple of block length') } } Cipher.prototype.setAutoPadding = function (setTo) { this._autopadding = !!setTo return this } function Splitter () { if (!(this instanceof Splitter)) { return new Splitter() } this.cache = new Buffer('') } 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 = new Buffer(len) var i = -1 while (++i < len) { padBuff.writeUInt8(len, i) } var out = Buffer.concat([this.cache, padBuff]) return out } var modelist = { ECB: require('./modes/ecb'), CBC: require('./modes/cbc'), CFB: require('./modes/cfb'), CFB8: require('./modes/cfb8'), CFB1: require('./modes/cfb1'), OFB: require('./modes/ofb'), CTR: require('./modes/ctr'), GCM: require('./modes/ctr') } function createCipheriv (suite, password, iv) { var config = modes[suite.toLowerCase()] if (!config) { throw new TypeError('invalid suite type') } if (typeof iv === 'string') { iv = new Buffer(iv) } if (typeof password === 'string') { password = new Buffer(password) } if (password.length !== config.key / 8) { throw new TypeError('invalid key length ' + password.length) } if (iv.length !== config.iv) { throw new TypeError('invalid iv length ' + iv.length) } if (config.type === 'stream') { return new StreamCipher(modelist[config.mode], password, iv) } else if (config.type === 'auth') { return new AuthCipher(modelist[config.mode], password, iv) } return new Cipher(modelist[config.mode], 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 }).call(this,require("buffer").Buffer) },{"./aes":8,"./authCipher":9,"./modes":14,"./modes/cbc":15,"./modes/cfb":16,"./modes/cfb1":17,"./modes/cfb8":18,"./modes/ctr":19,"./modes/ecb":20,"./modes/ofb":21,"./streamCipher":24,"buffer":2,"cipher-base":23,"evp_bytestokey":35,"inherits":199}],13:[function(require,module,exports){ (function (Buffer){ var zeros = new Buffer(16) zeros.fill(0) module.exports = GHASH function GHASH (key) { this.h = key this.state = new Buffer(16) this.state.fill(0) this.cache = new Buffer('') } // 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, lsb_Vi 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 = xor(Zi, Vi) } // Store the value of LSB(V_i) lsb_Vi = (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 (lsb_Vi) { 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, zeros], 16)) } this.ghash(fromArray([ 0, abl, 0, bl ])) return this.state } function toArray (buf) { return [ buf.readUInt32BE(0), buf.readUInt32BE(4), buf.readUInt32BE(8), buf.readUInt32BE(12) ] } function fromArray (out) { out = out.map(fixup_uint32) var buf = new Buffer(16) buf.writeUInt32BE(out[0], 0) buf.writeUInt32BE(out[1], 4) buf.writeUInt32BE(out[2], 8) buf.writeUInt32BE(out[3], 12) return buf } var uint_max = Math.pow(2, 32) function fixup_uint32 (x) { var ret, x_pos ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x return ret } function xor (a, b) { return [ a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3] ] } }).call(this,require("buffer").Buffer) },{"buffer":2}],14:[function(require,module,exports){ exports['aes-128-ecb'] = { cipher: 'AES', key: 128, iv: 0, mode: 'ECB', type: 'block' } exports['aes-192-ecb'] = { cipher: 'AES', key: 192, iv: 0, mode: 'ECB', type: 'block' } exports['aes-256-ecb'] = { cipher: 'AES', key: 256, iv: 0, mode: 'ECB', type: 'block' } exports['aes-128-cbc'] = { cipher: 'AES', key: 128, iv: 16, mode: 'CBC', type: 'block' } exports['aes-192-cbc'] = { cipher: 'AES', key: 192, iv: 16, mode: 'CBC', type: 'block' } exports['aes-256-cbc'] = { cipher: 'AES', key: 256, iv: 16, mode: 'CBC', type: 'block' } exports['aes128'] = exports['aes-128-cbc'] exports['aes192'] = exports['aes-192-cbc'] exports['aes256'] = exports['aes-256-cbc'] exports['aes-128-cfb'] = { cipher: 'AES', key: 128, iv: 16, mode: 'CFB', type: 'stream' } exports['aes-192-cfb'] = { cipher: 'AES', key: 192, iv: 16, mode: 'CFB', type: 'stream' } exports['aes-256-cfb'] = { cipher: 'AES', key: 256, iv: 16, mode: 'CFB', type: 'stream' } exports['aes-128-cfb8'] = { cipher: 'AES', key: 128, iv: 16, mode: 'CFB8', type: 'stream' } exports['aes-192-cfb8'] = { cipher: 'AES', key: 192, iv: 16, mode: 'CFB8', type: 'stream' } exports['aes-256-cfb8'] = { cipher: 'AES', key: 256, iv: 16, mode: 'CFB8', type: 'stream' } exports['aes-128-cfb1'] = { cipher: 'AES', key: 128, iv: 16, mode: 'CFB1', type: 'stream' } exports['aes-192-cfb1'] = { cipher: 'AES', key: 192, iv: 16, mode: 'CFB1', type: 'stream' } exports['aes-256-cfb1'] = { cipher: 'AES', key: 256, iv: 16, mode: 'CFB1', type: 'stream' } exports['aes-128-ofb'] = { cipher: 'AES', key: 128, iv: 16, mode: 'OFB', type: 'stream' } exports['aes-192-ofb'] = { cipher: 'AES', key: 192, iv: 16, mode: 'OFB', type: 'stream' } exports['aes-256-ofb'] = { cipher: 'AES', key: 256, iv: 16, mode: 'OFB', type: 'stream' } exports['aes-128-ctr'] = { cipher: 'AES', key: 128, iv: 16, mode: 'CTR', type: 'stream' } exports['aes-192-ctr'] = { cipher: 'AES', key: 192, iv: 16, mode: 'CTR', type: 'stream' } exports['aes-256-ctr'] = { cipher: 'AES', key: 256, iv: 16, mode: 'CTR', type: 'stream' } exports['aes-128-gcm'] = { cipher: 'AES', key: 128, iv: 12, mode: 'GCM', type: 'auth' } exports['aes-192-gcm'] = { cipher: 'AES', key: 192, iv: 12, mode: 'GCM', type: 'auth' } exports['aes-256-gcm'] = { cipher: 'AES', key: 256, iv: 12, mode: 'GCM', type: 'auth' } },{}],15:[function(require,module,exports){ var xor = require('buffer-xor') 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) } },{"buffer-xor":22}],16:[function(require,module,exports){ (function (Buffer){ var xor = require('buffer-xor') exports.encrypt = function (self, data, decrypt) { var out = new Buffer('') var len while (data.length) { if (self._cache.length === 0) { self._cache = self._cipher.encryptBlock(self._prev) self._prev = new Buffer('') } 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 } 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 } }).call(this,require("buffer").Buffer) },{"buffer":2,"buffer-xor":22}],17:[function(require,module,exports){ (function (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 } exports.encrypt = function (self, chunk, decrypt) { var len = chunk.length var out = new Buffer(len) var i = -1 while (++i < len) { out[i] = encryptByte(self, chunk[i], decrypt) } return out } function shiftIn (buffer, value) { var len = buffer.length var i = -1 var out = new Buffer(buffer.length) buffer = Buffer.concat([buffer, new Buffer([value])]) while (++i < len) { out[i] = buffer[i] << 1 | buffer[i + 1] >> (7) } return out } }).call(this,require("buffer").Buffer) },{"buffer":2}],18:[function(require,module,exports){ (function (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), new Buffer([decrypt ? byteParam : out])]) return out } exports.encrypt = function (self, chunk, decrypt) { var len = chunk.length var out = new Buffer(len) var i = -1 while (++i < len) { out[i] = encryptByte(self, chunk[i], decrypt) } return out } }).call(this,require("buffer").Buffer) },{"buffer":2}],19:[function(require,module,exports){ (function (Buffer){ var xor = require('buffer-xor') 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 } } } function getBlock (self) { var out = self._cipher.encryptBlock(self._prev) incr32(self._prev) return out } 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) } }).call(this,require("buffer").Buffer) },{"buffer":2,"buffer-xor":22}],20:[function(require,module,exports){ exports.encrypt = function (self, block) { return self._cipher.encryptBlock(block) } exports.decrypt = function (self, block) { return self._cipher.decryptBlock(block) } },{}],21:[function(require,module,exports){ (function (Buffer){ var xor = require('buffer-xor') 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) } }).call(this,require("buffer").Buffer) },{"buffer":2,"buffer-xor":22}],22:[function(require,module,exports){ (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 } }).call(this,require("buffer").Buffer) },{"buffer":2}],23:[function(require,module,exports){ (function (Buffer){ var Transform = require('stream').Transform var inherits = require('inherits') var StringDecoder = require('string_decoder').StringDecoder module.exports = CipherBase inherits(CipherBase, Transform) function CipherBase (hashMode) { Transform.call(this) this.hashMode = typeof hashMode === 'string' if (this.hashMode) { this[hashMode] = this._finalOrDigest } else { this.final = this._finalOrDigest } this._decoder = null this._encoding = null } CipherBase.prototype.update = function (data, inputEnc, outputEnc) { if (typeof data === 'string') { data = new Buffer(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 } finally { done(err) } } CipherBase.prototype._finalOrDigest = function (outputEnc) { var outData = this._final() || new Buffer('') if (outputEnc) { outData = this._toString(outData, outputEnc, true) } return outData } CipherBase.prototype._toString = function (value, enc, final) { 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 (final) { out += this._decoder.end() } return out } }).call(this,require("buffer").Buffer) },{"buffer":2,"inherits":199,"stream":216,"string_decoder":217}],24:[function(require,module,exports){ (function (Buffer){ var aes = require('./aes') var Transform = require('cipher-base') var inherits = require('inherits') inherits(StreamCipher, Transform) module.exports = StreamCipher function StreamCipher (mode, key, iv, decrypt) { if (!(this instanceof StreamCipher)) { return new StreamCipher(mode, key, iv) } Transform.call(this) this._cipher = new aes.AES(key) this._prev = new Buffer(iv.length) this._cache = new Buffer('') this._secCache = new Buffer('') this._decrypt = decrypt iv.copy(this._prev) this._mode = mode } StreamCipher.prototype._update = function (chunk) { return this._mode.encrypt(this, chunk, this._decrypt) } StreamCipher.prototype._final = function () { this._cipher.scrub() } }).call(this,require("buffer").Buffer) },{"./aes":8,"buffer":2,"cipher-base":23,"inherits":199}],25:[function(require,module,exports){ (function (Buffer){ var CipherBase = require('cipher-base') var des = require('des.js') var inherits = require('inherits') 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 (modeName === 'des-ede' || modeName === 'des-ede-cbc') { key = Buffer.concat([key, key.slice(0, 8)]) } var iv = opts.iv this._des = mode.create({ key: key, iv: iv, type: type }) } DES.prototype._update = function (data) { return new Buffer(this._des.update(data)) } DES.prototype._final = function () { return new Buffer(this._des.final()) } }).call(this,require("buffer").Buffer) },{"buffer":2,"cipher-base":27,"des.js":28,"inherits":199}],26:[function(require,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 } },{}],27:[function(require,module,exports){ (function (Buffer){ var Transform = require('stream').Transform var inherits = require('inherits') var StringDecoder = require('string_decoder').StringDecoder module.exports = CipherBase inherits(CipherBase, Transform) function CipherBase (hashMode) { Transform.call(this) this.hashMode = typeof hashMode === 'string' if (this.hashMode) { this[hashMode] = this._finalOrDigest } else { this.final = this._finalOrDigest } this._decoder = null this._encoding = null } CipherBase.prototype.update = function (data, inputEnc, outputEnc) { if (typeof data === 'string') { data = new Buffer(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 } finally { done(err) } } CipherBase.prototype._finalOrDigest = function (outputEnc) { var outData = this._final() || new Buffer('') if (outputEnc) { outData = this._toString(outData, outputEnc, true) } return outData } CipherBase.prototype._toString = function (value, enc, final) { 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 (final) { out += this._decoder.end() } return out } }).call(this,require("buffer").Buffer) },{"buffer":2,"inherits":199,"stream":216,"string_decoder":217}],28:[function(require,module,exports){ 'use strict'; exports.utils = require('./des/utils'); exports.Cipher = require('./des/cipher'); exports.DES = require('./des/des'); exports.CBC = require('./des/cbc'); exports.EDE = require('./des/ede'); },{"./des/cbc":29,"./des/cipher":30,"./des/des":31,"./des/ede":32,"./des/utils":33}],29:[function(require,module,exports){ 'use strict'; var assert = require('minimalistic-assert'); var inherits = require('inherits'); 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]; } }; },{"inherits":199,"minimalistic-assert":34}],30:[function(require,module,exports){ 'use strict'; var assert = require('minimalistic-assert'); 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); }; },{"minimalistic-assert":34}],31:[function(require,module,exports){ 'use strict'; var assert = require('minimalistic-assert'); var inherits = require('inherits'); var des = require('../des'); 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); }; },{"../des":28,"inherits":199,"minimalistic-assert":34}],32:[function(require,module,exports){ 'use strict'; var assert = require('minimalistic-assert'); var inherits = require('inherits'); var des = require('../des'); 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; },{"../des":28,"inherits":199,"minimalistic-assert":34}],33:[function(require,module,exports){ '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(' '); }; },{}],34:[function(require,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)); }; },{}],35:[function(require,module,exports){ (function (Buffer){ var md5 = require('create-hash/md5') module.exports = EVP_BytesToKey function EVP_BytesToKey (password, salt, keyLen, ivLen) { if (!Buffer.isBuffer(password)) { password = new Buffer(password, 'binary') } if (salt && !Buffer.isBuffer(salt)) { salt = new Buffer(salt, 'binary') } keyLen = keyLen / 8 ivLen = ivLen || 0 var ki = 0 var ii = 0 var key = new Buffer(keyLen) var iv = new Buffer(ivLen) var addmd = 0 var md_buf var i var bufs = [] while (true) { if (addmd++ > 0) { bufs.push(md_buf) } bufs.push(password) if (salt) { bufs.push(salt) } md_buf = md5(Buffer.concat(bufs)) bufs = [] i = 0 if (keyLen > 0) { while (true) { if (keyLen === 0) { break } if (i === md_buf.length) { break } key[ki++] = md_buf[i] keyLen-- i++ } } if (ivLen > 0 && i !== md_buf.length) { while (true) { if (ivLen === 0) { break } if (i === md_buf.length) { break } iv[ii++] = md_buf[i] ivLen-- i++ } } if (keyLen === 0 && ivLen === 0) { break } } for (i = 0; i < md_buf.length; i++) { md_buf[i] = 0 } return { key: key, iv: iv } } }).call(this,require("buffer").Buffer) },{"buffer":2,"create-hash/md5":132}],36:[function(require,module,exports){ (function (Buffer){ 'use strict' exports['RSA-SHA224'] = exports.sha224WithRSAEncryption = { sign: 'rsa', hash: 'sha224', id: new Buffer('302d300d06096086480165030402040500041c', 'hex') } exports['RSA-SHA256'] = exports.sha256WithRSAEncryption = { sign: 'rsa', hash: 'sha256', id: new Buffer('3031300d060960864801650304020105000420', 'hex') } exports['RSA-SHA384'] = exports.sha384WithRSAEncryption = { sign: 'rsa', hash: 'sha384', id: new Buffer('3041300d060960864801650304020205000430', 'hex') } exports['RSA-SHA512'] = exports.sha512WithRSAEncryption = { sign: 'rsa', hash: 'sha512', id: new Buffer('3051300d060960864801650304020305000440', 'hex') } exports['RSA-SHA1'] = { sign: 'rsa', hash: 'sha1', id: new Buffer('3021300906052b0e03021a05000414', 'hex') } exports['ecdsa-with-SHA1'] = { sign: 'ecdsa', hash: 'sha1', id: new Buffer('', 'hex') } exports.DSA = exports['DSA-SHA1'] = exports['DSA-SHA'] = { sign: 'dsa', hash: 'sha1', id: new Buffer('', 'hex') } exports['DSA-SHA224'] = exports['DSA-WITH-SHA224'] = { sign: 'dsa', hash: 'sha224', id: new Buffer('', 'hex') } exports['DSA-SHA256'] = exports['DSA-WITH-SHA256'] = { sign: 'dsa', hash: 'sha256', id: new Buffer('', 'hex') } exports['DSA-SHA384'] = exports['DSA-WITH-SHA384'] = { sign: 'dsa', hash: 'sha384', id: new Buffer('', 'hex') } exports['DSA-SHA512'] = exports['DSA-WITH-SHA512'] = { sign: 'dsa', hash: 'sha512', id: new Buffer('', 'hex') } exports['DSA-RIPEMD160'] = { sign: 'dsa', hash: 'rmd160', id: new Buffer('', 'hex') } exports['RSA-RIPEMD160'] = exports.ripemd160WithRSA = { sign: 'rsa', hash: 'rmd160', id: new Buffer('3021300906052b2403020105000414', 'hex') } exports['RSA-MD5'] = exports.md5WithRSAEncryption = { sign: 'rsa', hash: 'md5', id: new Buffer('3020300c06082a864886f70d020505000410', 'hex') } }).call(this,require("buffer").Buffer) },{"buffer":2}],37:[function(require,module,exports){ (function (Buffer){ var _algos = require('./algos') var createHash = require('create-hash') var inherits = require('inherits') var sign = require('./sign') var stream = require('stream') var verify = require('./verify') var algos = {} Object.keys(_algos).forEach(function (key) { algos[key] = algos[key.toLowerCase()] = _algos[key] }) function Sign (algorithm) { stream.Writable.call(this) var data = algos[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(Buffer.concat([this._tag, hash]), key, this._hashType, this._signType) return enc ? sig.toString(enc) : sig } function Verify (algorithm) { stream.Writable.call(this) var data = algos[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, Buffer.concat([this._tag, hash]), key, this._signType) } function createSign (algorithm) { return new Sign(algorithm) } function createVerify (algorithm) { return new Verify(algorithm) } module.exports = { Sign: createSign, Verify: createVerify, createSign: createSign, createVerify: createVerify } }).call(this,require("buffer").Buffer) },{"./algos":36,"./sign":102,"./verify":103,"buffer":2,"create-hash":130,"inherits":199,"stream":216}],38:[function(require,module,exports){ 'use strict' exports['1.3.132.0.10'] = 'secp256k1' exports['1.3.132.0.33'] = 'p224' exports['1.2.840.10045.3.1.1'] = 'p192' exports['1.2.840.10045.3.1.7'] = 'p256' exports['1.3.132.0.34'] = 'p384' exports['1.3.132.0.35'] = 'p521' },{}],39:[function(require,module,exports){ (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) { // May be `new BN(bn)` ? if (number !== null && typeof number === 'object' && Array.isArray(number.words)) { 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 = require('buffer').Buffer; } catch (e) { } 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; 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; }; // 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 ? ''; }; /* 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 length = this.bitLength(); var ret; if (length <= 26) { ret = this.words[0]; } else if (length <= 52) { ret = (this.words[1] * 0x4000000) + this.words[0]; } else if (length === 53) { // NOTE: at this stage it is known that the top bit is set ret = 0x10000000000000 + (this.words[1] * 0x4000000) + this.words[0]; } else { 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 new Buffer(this.toArray(endian, length)); }; BN.prototype.toArray = function toArray (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 Array(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 while (this.length < bytesNeeded) { this.words[this.length++] = 0; } 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; while (this.length <= off) { this.words[this.length++] = 0; } 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 += Math.imul(ah0, bl0); hi = Math.imul(ah0, bh0); var w0 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w0 >>> 26); w0 &= 0x3ffffff; /* k = 1 */ lo = Math.imul(al1, bl0); mid = Math.imul(al1, bh0); mid += Math.imul(ah1, bl0); hi = Math.imul(ah1, bh0); lo += Math.imul(al0, bl1); mid += Math.imul(al0, bh1); mid += Math.imul(ah0, bl1); hi += Math.imul(ah0, bh1); var w1 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w1 >>> 26); w1 &= 0x3ffffff; /* k = 2 */ lo = Math.imul(al2, bl0); mid = Math.imul(al2, bh0); mid += Math.imul(ah2, bl0); hi = Math.imul(ah2, bh0); lo += Math.imul(al1, bl1); mid += Math.imul(al1, bh1); mid += Math.imul(ah1, bl1); hi += Math.imul(ah1, bh1); lo += Math.imul(al0, bl2); mid += Math.imul(al0, bh2); mid += Math.imul(ah0, bl2); hi += Math.imul(ah0, bh2); var w2 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w2 >>> 26); w2 &= 0x3ffffff; /* k = 3 */ lo = Math.imul(al3, bl0); mid = Math.imul(al3, bh0); mid += Math.imul(ah3, bl0); hi = Math.imul(ah3, bh0); lo += Math.imul(al2, bl1); mid += Math.imul(al2, bh1); mid += Math.imul(ah2, bl1); hi += Math.imul(ah2, bh1); lo += Math.imul(al1, bl2); mid += Math.imul(al1, bh2); mid += Math.imul(ah1, bl2); hi += Math.imul(ah1, bh2); lo += Math.imul(al0, bl3); mid += Math.imul(al0, bh3); mid += Math.imul(ah0, bl3); hi += Math.imul(ah0, bh3); var w3 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w3 >>> 26); w3 &= 0x3ffffff; /* k = 4 */ lo = Math.imul(al4, bl0); mid = Math.imul(al4, bh0); mid += Math.imul(ah4, bl0); hi = Math.imul(ah4, bh0); lo += Math.imul(al3, bl1); mid += Math.imul(al3, bh1); mid += Math.imul(ah3, bl1); hi += Math.imul(ah3, bh1); lo += Math.imul(al2, bl2); mid += Math.imul(al2, bh2); mid += Math.imul(ah2, bl2); hi += Math.imul(ah2, bh2); lo += Math.imul(al1, bl3); mid += Math.imul(al1, bh3); mid += Math.imul(ah1, bl3); hi += Math.imul(ah1, bh3); lo += Math.imul(al0, bl4); mid += Math.imul(al0, bh4); mid += Math.imul(ah0, bl4); hi += Math.imul(ah0, bh4); var w4 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w4 >>> 26); w4 &= 0x3ffffff; /* k = 5 */ lo = Math.imul(al5, bl0); mid = Math.imul(al5, bh0); mid += Math.imul(ah5, bl0); hi = Math.imul(ah5, bh0); lo += Math.imul(al4, bl1); mid += Math.imul(al4, bh1); mid += Math.imul(ah4, bl1); hi += Math.imul(ah4, bh1); lo += Math.imul(al3, bl2); mid += Math.imul(al3, bh2); mid += Math.imul(ah3, bl2); hi += Math.imul(ah3, bh2); lo += Math.imul(al2, bl3); mid += Math.imul(al2, bh3); mid += Math.imul(ah2, bl3); hi += Math.imul(ah2, bh3); lo += Math.imul(al1, bl4); mid += Math.imul(al1, bh4); mid += Math.imul(ah1, bl4); hi += Math.imul(ah1, bh4); lo += Math.imul(al0, bl5); mid += Math.imul(al0, bh5); mid += Math.imul(ah0, bl5); hi += Math.imul(ah0, bh5); var w5 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w5 >>> 26); w5 &= 0x3ffffff; /* k = 6 */ lo = Math.imul(al6, bl0); mid = Math.imul(al6, bh0); mid += Math.imul(ah6, bl0); hi = Math.imul(ah6, bh0); lo += Math.imul(al5, bl1); mid += Math.imul(al5, bh1); mid += Math.imul(ah5, bl1); hi += Math.imul(ah5, bh1); lo += Math.imul(al4, bl2); mid += Math.imul(al4, bh2); mid += Math.imul(ah4, bl2); hi += Math.imul(ah4, bh2); lo += Math.imul(al3, bl3); mid += Math.imul(al3, bh3); mid += Math.imul(ah3, bl3); hi += Math.imul(ah3, bh3); lo += Math.imul(al2, bl4); mid += Math.imul(al2, bh4); mid += Math.imul(ah2, bl4); hi += Math.imul(ah2, bh4); lo += Math.imul(al1, bl5); mid += Math.imul(al1, bh5); mid += Math.imul(ah1, bl5); hi += Math.imul(ah1, bh5); lo += Math.imul(al0, bl6); mid += Math.imul(al0, bh6); mid += Math.imul(ah0, bl6); hi += Math.imul(ah0, bh6); var w6 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w6 >>> 26); w6 &= 0x3ffffff; /* k = 7 */ lo = Math.imul(al7, bl0); mid = Math.imul(al7, bh0); mid += Math.imul(ah7, bl0); hi = Math.imul(ah7, bh0); lo += Math.imul(al6, bl1); mid += Math.imul(al6, bh1); mid += Math.imul(ah6, bl1); hi += Math.imul(ah6, bh1); lo += Math.imul(al5, bl2); mid += Math.imul(al5, bh2); mid += Math.imul(ah5, bl2); hi += Math.imul(ah5, bh2); lo += Math.imul(al4, bl3); mid += Math.imul(al4, bh3); mid += Math.imul(ah4, bl3); hi += Math.imul(ah4, bh3); lo += Math.imul(al3, bl4); mid += Math.imul(al3, bh4); mid += Math.imul(ah3, bl4); hi += Math.imul(ah3, bh4); lo += Math.imul(al2, bl5); mid += Math.imul(al2, bh5); mid += Math.imul(ah2, bl5); hi += Math.imul(ah2, bh5); lo += Math.imul(al1, bl6); mid += Math.imul(al1, bh6); mid += Math.imul(ah1, bl6); hi += Math.imul(ah1, bh6); lo += Math.imul(al0, bl7); mid += Math.imul(al0, bh7); mid += Math.imul(ah0, bl7); hi += Math.imul(ah0, bh7); var w7 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w7 >>> 26); w7 &= 0x3ffffff; /* k = 8 */ lo = Math.imul(al8, bl0); mid = Math.imul(al8, bh0); mid += Math.imul(ah8, bl0); hi = Math.imul(ah8, bh0); lo += Math.imul(al7, bl1); mid += Math.imul(al7, bh1); mid += Math.imul(ah7, bl1); hi += Math.imul(ah7, bh1); lo += Math.imul(al6, bl2); mid += Math.imul(al6, bh2); mid += Math.imul(ah6, bl2); hi += Math.imul(ah6, bh2); lo += Math.imul(al5, bl3); mid += Math.imul(al5, bh3); mid += Math.imul(ah5, bl3); hi += Math.imul(ah5, bh3); lo += Math.imul(al4, bl4); mid += Math.imul(al4, bh4); mid += Math.imul(ah4, bl4); hi += Math.imul(ah4, bh4); lo += Math.imul(al3, bl5); mid += Math.imul(al3, bh5); mid += Math.imul(ah3, bl5); hi += Math.imul(ah3, bh5); lo += Math.imul(al2, bl6); mid += Math.imul(al2, bh6); mid += Math.imul(ah2, bl6); hi += Math.imul(ah2, bh6); lo += Math.imul(al1, bl7); mid += Math.imul(al1, bh7); mid += Math.imul(ah1, bl7); hi += Math.imul(ah1, bh7); lo += Math.imul(al0, bl8); mid += Math.imul(al0, bh8); mid += Math.imul(ah0, bl8); hi += Math.imul(ah0, bh8); var w8 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w8 >>> 26); w8 &= 0x3ffffff; /* k = 9 */ lo = Math.imul(al9, bl0); mid = Math.imul(al9, bh0); mid += Math.imul(ah9, bl0); hi = Math.imul(ah9, bh0); lo += Math.imul(al8, bl1); mid += Math.imul(al8, bh1); mid += Math.imul(ah8, bl1); hi += Math.imul(ah8, bh1); lo += Math.imul(al7, bl2); mid += Math.imul(al7, bh2); mid += Math.imul(ah7, bl2); hi += Math.imul(ah7, bh2); lo += Math.imul(al6, bl3); mid += Math.imul(al6, bh3); mid += Math.imul(ah6, bl3); hi += Math.imul(ah6, bh3); lo += Math.imul(al5, bl4); mid += Math.imul(al5, bh4); mid += Math.imul(ah5, bl4); hi += Math.imul(ah5, bh4); lo += Math.imul(al4, bl5); mid += Math.imul(al4, bh5); mid += Math.imul(ah4, bl5); hi += Math.imul(ah4, bh5); lo += Math.imul(al3, bl6); mid += Math.imul(al3, bh6); mid += Math.imul(ah3, bl6); hi += Math.imul(ah3, bh6); lo += Math.imul(al2, bl7); mid += Math.imul(al2, bh7); mid += Math.imul(ah2, bl7); hi += Math.imul(ah2, bh7); lo += Math.imul(al1, bl8); mid += Math.imul(al1, bh8); mid += Math.imul(ah1, bl8); hi += Math.imul(ah1, bh8); lo += Math.imul(al0, bl9); mid += Math.imul(al0, bh9); mid += Math.imul(ah0, bl9); hi += Math.imul(ah0, bh9); var w9 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w9 >>> 26); w9 &= 0x3ffffff; /* k = 10 */ lo = Math.imul(al9, bl1); mid = Math.imul(al9, bh1); mid += Math.imul(ah9, bl1); hi = Math.imul(ah9, bh1); lo += Math.imul(al8, bl2); mid += Math.imul(al8, bh2); mid += Math.imul(ah8, bl2); hi += Math.imul(ah8, bh2); lo += Math.imul(al7, bl3); mid += Math.imul(al7, bh3); mid += Math.imul(ah7, bl3); hi += Math.imul(ah7, bh3); lo += Math.imul(al6, bl4); mid += Math.imul(al6, bh4); mid += Math.imul(ah6, bl4); hi += Math.imul(ah6, bh4); lo += Math.imul(al5, bl5); mid += Math.imul(al5, bh5); mid += Math.imul(ah5, bl5); hi += Math.imul(ah5, bh5); lo += Math.imul(al4, bl6); mid += Math.imul(al4, bh6); mid += Math.imul(ah4, bl6); hi += Math.imul(ah4, bh6); lo += Math.imul(al3, bl7); mid += Math.imul(al3, bh7); mid += Math.imul(ah3, bl7); hi += Math.imul(ah3, bh7); lo += Math.imul(al2, bl8); mid += Math.imul(al2, bh8); mid += Math.imul(ah2, bl8); hi += Math.imul(ah2, bh8); lo += Math.imul(al1, bl9); mid += Math.imul(al1, bh9); mid += Math.imul(ah1, bl9); hi += Math.imul(ah1, bh9); var w10 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w10 >>> 26); w10 &= 0x3ffffff; /* k = 11 */ lo = Math.imul(al9, bl2); mid = Math.imul(al9, bh2); mid += Math.imul(ah9, bl2); hi = Math.imul(ah9, bh2); lo += Math.imul(al8, bl3); mid += Math.imul(al8, bh3); mid += Math.imul(ah8, bl3); hi += Math.imul(ah8, bh3); lo += Math.imul(al7, bl4); mid += Math.imul(al7, bh4); mid += Math.imul(ah7, bl4); hi += Math.imul(ah7, bh4); lo += Math.imul(al6, bl5); mid += Math.imul(al6, bh5); mid += Math.imul(ah6, bl5); hi += Math.imul(ah6, bh5); lo += Math.imul(al5, bl6); mid += Math.imul(al5, bh6); mid += Math.imul(ah5, bl6); hi += Math.imul(ah5, bh6); lo += Math.imul(al4, bl7); mid += Math.imul(al4, bh7); mid += Math.imul(ah4, bl7); hi += Math.imul(ah4, bh7); lo += Math.imul(al3, bl8); mid += Math.imul(al3, bh8); mid += Math.imul(ah3, bl8); hi += Math.imul(ah3, bh8); lo += Math.imul(al2, bl9); mid += Math.imul(al2, bh9); mid += Math.imul(ah2, bl9); hi += Math.imul(ah2, bh9); var w11 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w11 >>> 26); w11 &= 0x3ffffff; /* k = 12 */ lo = Math.imul(al9, bl3); mid = Math.imul(al9, bh3); mid += Math.imul(ah9, bl3); hi = Math.imul(ah9, bh3); lo += Math.imul(al8, bl4); mid += Math.imul(al8, bh4); mid += Math.imul(ah8, bl4); hi += Math.imul(ah8, bh4); lo += Math.imul(al7, bl5); mid += Math.imul(al7, bh5); mid += Math.imul(ah7, bl5); hi += Math.imul(ah7, bh5); lo += Math.imul(al6, bl6); mid += Math.imul(al6, bh6); mid += Math.imul(ah6, bl6); hi += Math.imul(ah6, bh6); lo += Math.imul(al5, bl7); mid += Math.imul(al5, bh7); mid += Math.imul(ah5, bl7); hi += Math.imul(ah5, bh7); lo += Math.imul(al4, bl8); mid += Math.imul(al4, bh8); mid += Math.imul(ah4, bl8); hi += Math.imul(ah4, bh8); lo += Math.imul(al3, bl9); mid += Math.imul(al3, bh9); mid += Math.imul(ah3, bl9); hi += Math.imul(ah3, bh9); var w12 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w12 >>> 26); w12 &= 0x3ffffff; /* k = 13 */ lo = Math.imul(al9, bl4); mid = Math.imul(al9, bh4); mid += Math.imul(ah9, bl4); hi = Math.imul(ah9, bh4); lo += Math.imul(al8, bl5); mid += Math.imul(al8, bh5); mid += Math.imul(ah8, bl5); hi += Math.imul(ah8, bh5); lo += Math.imul(al7, bl6); mid += Math.imul(al7, bh6); mid += Math.imul(ah7, bl6); hi += Math.imul(ah7, bh6); lo += Math.imul(al6, bl7); mid += Math.imul(al6, bh7); mid += Math.imul(ah6, bl7); hi += Math.imul(ah6, bh7); lo += Math.imul(al5, bl8); mid += Math.imul(al5, bh8); mid += Math.imul(ah5, bl8); hi += Math.imul(ah5, bh8); lo += Math.imul(al4, bl9); mid += Math.imul(al4, bh9); mid += Math.imul(ah4, bl9); hi += Math.imul(ah4, bh9); var w13 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w13 >>> 26); w13 &= 0x3ffffff; /* k = 14 */ lo = Math.imul(al9, bl5); mid = Math.imul(al9, bh5); mid += Math.imul(ah9, bl5); hi = Math.imul(ah9, bh5); lo += Math.imul(al8, bl6); mid += Math.imul(al8, bh6); mid += Math.imul(ah8, bl6); hi += Math.imul(ah8, bh6); lo += Math.imul(al7, bl7); mid += Math.imul(al7, bh7); mid += Math.imul(ah7, bl7); hi += Math.imul(ah7, bh7); lo += Math.imul(al6, bl8); mid += Math.imul(al6, bh8); mid += Math.imul(ah6, bl8); hi += Math.imul(ah6, bh8); lo += Math.imul(al5, bl9); mid += Math.imul(al5, bh9); mid += Math.imul(ah5, bl9); hi += Math.imul(ah5, bh9); var w14 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w14 >>> 26); w14 &= 0x3ffffff; /* k = 15 */ lo = Math.imul(al9, bl6); mid = Math.imul(al9, bh6); mid += Math.imul(ah9, bl6); hi = Math.imul(ah9, bh6); lo += Math.imul(al8, bl7); mid += Math.imul(al8, bh7); mid += Math.imul(ah8, bl7); hi += Math.imul(ah8, bh7); lo += Math.imul(al7, bl8); mid += Math.imul(al7, bh8); mid += Math.imul(ah7, bl8); hi += Math.imul(ah7, bh8); lo += Math.imul(al6, bl9); mid += Math.imul(al6, bh9); mid += Math.imul(ah6, bl9); hi += Math.imul(ah6, bh9); var w15 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w15 >>> 26); w15 &= 0x3ffffff; /* k = 16 */ lo = Math.imul(al9, bl7); mid = Math.imul(al9, bh7); mid += Math.imul(ah9, bl7); hi = Math.imul(ah9, bh7); lo += Math.imul(al8, bl8); mid += Math.imul(al8, bh8); mid += Math.imul(ah8, bl8); hi += Math.imul(ah8, bh8); lo += Math.imul(al7, bl9); mid += Math.imul(al7, bh9); mid += Math.imul(ah7, bl9); hi += Math.imul(ah7, bh9); var w16 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w16 >>> 26); w16 &= 0x3ffffff; /* k = 17 */ lo = Math.imul(al9, bl8); mid = Math.imul(al9, bh8); mid += Math.imul(ah9, bl8); hi = Math.imul(ah9, bh8); lo += Math.imul(al8, bl9); mid += Math.imul(al8, bh9); mid += Math.imul(ah8, bl9); hi += Math.imul(ah8, bh9); var w17 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w17 >>> 26); w17 &= 0x3ffffff; /* k = 18 */ lo = Math.imul(al9, bl9); mid = Math.imul(al9, bh9); mid += Math.imul(ah9, bl9); hi = Math.imul(ah9, bh9); var w18 = c + lo + ((mid & 0x1fff) << 13); c = hi + (mid >>> 13) + (w18 >>> 26); 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'); // 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 (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'); 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'); 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) { // Bigger storage is needed var len = num.length + shift; var i; if (this.words.length < len) { var t = new Array(len); for (i = 0; i < this.length; i++) { t[i] = this.words[i]; } this.words = t; } else { i = this.length; } // Zeroify rest this.length = Math.max(this.length, len); for (; i < this.length; i++) { this.words[i] = 0; } 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 }; }; BN.prototype.divmod = function divmod (num, mode, positive) { assert(!num.isZero()); 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.clone(); if (num.isZero()) return this.clone(); 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) { for (var i = this.length; i < s + 1; i++) { this.words[i] = 0; } this.words[s] |= q; this.length = s + 1; return this; } // Add bit and propagate, if needed var carry = q; for (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) { res = -res; } 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; 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.ushl(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; } input.words[i - 10] = prev >>> 22; 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 { 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); 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); }; })(typeof module === 'undefined' || module, this); },{"buffer":1}],40:[function(require,module,exports){ (function (Buffer){ var bn = require('bn.js'); var randomBytes = require('randombytes'); 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; } }).call(this,require("buffer").Buffer) },{"bn.js":39,"buffer":2,"randombytes":197}],41:[function(require,module,exports){ 'use strict'; var elliptic = exports; elliptic.version = require('../package.json').version; elliptic.utils = require('./elliptic/utils'); elliptic.rand = require('brorand'); elliptic.hmacDRBG = require('./elliptic/hmac-drbg'); elliptic.curve = require('./elliptic/curve'); elliptic.curves = require('./elliptic/curves'); // Protocols elliptic.ec = require('./elliptic/ec'); elliptic.eddsa = require('./elliptic/eddsa'); },{"../package.json":64,"./elliptic/curve":44,"./elliptic/curves":47,"./elliptic/ec":48,"./elliptic/eddsa":51,"./elliptic/hmac-drbg":54,"./elliptic/utils":56,"brorand":57}],42:[function(require,module,exports){ 'use strict'; var BN = require('bn.js'); var elliptic = require('../../elliptic'); var utils = elliptic.utils; 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); } 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); 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); // 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) { 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]); naf[b] = getNAF(coeffs[b], wndWidth[b]); 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; 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(); if (bytes[0] === 0x04 && bytes.length - 1 === 2 * len) { return this.point(bytes.slice(1, 1 + len), bytes.slice(1 + len, 1 + 2 * len)); } 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; }; },{"../../elliptic":41,"bn.js":39}],43:[function(require,module,exports){ 'use strict'; var curve = require('../curve'); var elliptic = require('../../elliptic'); var BN = require('bn.js'); var inherits = require('inherits'); var Base = curve.base; var assert = elliptic.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 - 1) / (d y^2 + 1) var y2 = y.redSqr(); var lhs = y2.redSub(this.one); var rhs = y2.redMul(this.d).redAdd(this.one); 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.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 ''; return ''; }; 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; }; 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.c.redMul(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); }; 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; }; // Compatibility with BaseCurve Point.prototype.toP = Point.prototype.normalize; Point.prototype.mixedAdd = Point.prototype.add; },{"../../elliptic":41,"../curve":44,"bn.js":39,"inherits":199}],44:[function(require,module,exports){ 'use strict'; var curve = exports; curve.base = require('./base'); curve.short = require('./short'); curve.mont = require('./mont'); curve.edwards = require('./edwards'); },{"./base":42,"./edwards":43,"./mont":45,"./short":46}],45:[function(require,module,exports){ 'use strict'; var curve = require('../curve'); var BN = require('bn.js'); var inherits = require('inherits'); var Base = curve.base; var elliptic = require('../../elliptic'); var utils = elliptic.utils; 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 ''; return ''; }; 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.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(); }; },{"../../elliptic":41,"../curve":44,"bn.js":39,"inherits":199}],46:[function(require,module,exports){ 'use strict'; var curve = require('../curve'); var elliptic = require('../../elliptic'); var BN = require('bn.js'); var inherits = require('inherits'); var Base = curve.base; var assert = elliptic.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) { 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); // 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 ''; return ''; }; 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._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.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.inspect = function inspect() { if (this.isInfinity()) return ''; return ''; }; JPoint.prototype.isInfinity = function isInfinity() { // XXX This code assumes that zero is always zero in red return this.z.cmpn(0) === 0; }; },{"../../elliptic":41,"../curve":44,"bn.js":39,"inherits":199}],47:[function(require,module,exports){ 'use strict'; var curves = exports; var hash = require('hash.js'); var elliptic = require('../elliptic'); var assert = elliptic.utils.assert; function PresetCurve(options) { if (options.type === 'short') this.curve = new elliptic.curve.short(options); else if (options.type === 'edwards') this.curve = new elliptic.curve.edwards(options); else this.curve = new elliptic.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: '0', 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 = require('./precomputed/secp256k1'); } 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 ] }); },{"../elliptic":41,"./precomputed/secp256k1":55,"hash.js":58}],48:[function(require,module,exports){ 'use strict'; var BN = require('bn.js'); var elliptic = require('../../elliptic'); var utils = elliptic.utils; var assert = utils.assert; var KeyPair = require('./key'); var Signature = require('./signature'); function EC(options) { if (!(this instanceof EC)) return new EC(options); // Shortcut `elliptic.ec(curve-name)` if (typeof options === 'string') { assert(elliptic.curves.hasOwnProperty(options), 'Unknown curve ' + options); options = elliptic.curves[options]; } // Shortcut for `elliptic.ec(elliptic.curves.curveName)` if (options instanceof elliptic.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 elliptic.hmacDRBG({ hash: this.hash, pers: options.pers, entropy: options.entropy || elliptic.rand(this.hash.hmacStrength), 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 elliptic.hmacDRBG({ hash: this.hash, entropy: bkey, nonce: nonce, pers: options.pers, persEnc: options.persEnc }); // 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); var p = this.g.mulAdd(u1, key.getPublic(), u2); if (p.isInfinity()) return false; return p.getX().umod(this.n).cmp(r) === 0; }; 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 eNeg = n.sub(e); // 1.6.1 Compute Q = r^-1 (sR - eG) // Q = r^-1 (sR + -eG) var rInv = signature.r.invm(n); return this.g.mulAdd(eNeg, r, s).mul(rInv); }; 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'); }; },{"../../elliptic":41,"./key":49,"./signature":50,"bn.js":39}],49:[function(require,module,exports){ 'use strict'; var BN = require('bn.js'); 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) { 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 ''; }; },{"bn.js":39}],50:[function(require,module,exports){ 'use strict'; var BN = require('bn.js'); var elliptic = require('../../elliptic'); var utils = elliptic.utils; 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; var val = 0; for (var i = 0, off = p.place; i < octetLen; i++, off++) { val <<= 8; val |= buf[off]; } 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 + p.place) !== data.length) { return false; } if (data[p.place++] !== 0x02) { return false; } var rlen = getLength(data, p); 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 (data.length !== slen + p.place) { return false; } var s = data.slice(p.place, slen + p.place); if (r[0] === 0 && (r[1] & 0x80)) { r = r.slice(1); } if (s[0] === 0 && (s[1] & 0x80)) { s = s.slice(1); } 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); }; },{"../../elliptic":41,"bn.js":39}],51:[function(require,module,exports){ 'use strict'; var hash = require('hash.js'); var elliptic = require('../../elliptic'); var utils = elliptic.utils; var assert = utils.assert; var parseBytes = utils.parseBytes; var KeyPair = require('./key'); var Signature = require('./signature'); function EDDSA(curve) { assert(curve === 'ed25519', 'only tested with ed25519 so far'); if (!(this instanceof EDDSA)) return new EDDSA(curve); var curve = elliptic.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; }; },{"../../elliptic":41,"./key":52,"./signature":53,"hash.js":58}],52:[function(require,module,exports){ 'use strict'; var elliptic = require('../../elliptic'); var utils = elliptic.utils; 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} [params.secret] - secret seed bytes * @param {Point} [params.pub] - public key point (aka `A` in eddsa terms) * @param {Array} [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, function pubBytes() { return this.eddsa.encodePoint(this.pub()); }); cachedProperty(KeyPair, function pub() { if (this._pubBytes) return this.eddsa.decodePoint(this._pubBytes); return this.eddsa.g.mul(this.priv()); }); cachedProperty(KeyPair, 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, function priv() { return this.eddsa.decodeInt(this.privBytes()); }); cachedProperty(KeyPair, function hash() { return this.eddsa.hash().update(this.secret()).digest(); }); cachedProperty(KeyPair, 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; },{"../../elliptic":41}],53:[function(require,module,exports){ 'use strict'; var BN = require('bn.js'); var elliptic = require('../../elliptic'); var utils = elliptic.utils; var assert = utils.assert; var cachedProperty = utils.cachedProperty; var parseBytes = utils.parseBytes; /** * @param {EDDSA} eddsa - eddsa instance * @param {Array|Object} sig - * @param {Array|Point} [sig.R] - R point as Point or bytes * @param {Array|bn} [sig.S] - S scalar as bn or bytes * @param {Array} [sig.Rencoded] - R point encoded * @param {Array} [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, function S() { return this.eddsa.decodeInt(this.Sencoded()); }); cachedProperty(Signature, function R() { return this.eddsa.decodePoint(this.Rencoded()); }); cachedProperty(Signature, function Rencoded() { return this.eddsa.encodePoint(this.R()); }); cachedProperty(Signature, 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; },{"../../elliptic":41,"bn.js":39}],54:[function(require,module,exports){ 'use strict'; var hash = require('hash.js'); var elliptic = require('../elliptic'); var utils = elliptic.utils; var assert = utils.assert; 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); var nonce = utils.toArray(options.nonce, options.nonceEnc); var pers = utils.toArray(options.pers, options.persEnc); 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.toBuffer(entropy, entropyEnc); add = utils.toBuffer(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); 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); }; },{"../elliptic":41,"hash.js":58}],55:[function(require,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' ] ] } }; },{}],56:[function(require,module,exports){ 'use strict'; var utils = exports; var BN = require('bn.js'); utils.assert = function assert(val, msg) { if (!val) throw new Error(msg || 'Assertion failed'); }; 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) { 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); } } else 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)); } 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; }; // Represent num in a w-NAF form function getNAF(num, w) { var naf = []; var ws = 1 << (w + 1); var k = num.clone(); while (k.cmpn(1) >= 0) { var z; if (k.isOdd()) { var mod = k.andln(ws - 1); if (mod > (ws >> 1) - 1) z = (ws >> 1) - mod; else z = mod; k.isubn(z); } else { z = 0; } naf.push(z); // Optimization, shift by word if possible var shift = (k.cmpn(0) !== 0 && k.andln(ws - 1) === 0) ? (w + 1) : 1; for (var i = 1; i < shift; i++) naf.push(0); k.iushrn(shift); } 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, computer) { var name = computer.name; 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; },{"bn.js":39}],57:[function(require,module,exports){ 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); }; if (typeof window === 'object') { if (window.crypto && window.crypto.getRandomValues) { // Modern browsers Rand.prototype._rand = function _rand(n) { var arr = new Uint8Array(n); window.crypto.getRandomValues(arr); return arr; }; } else if (window.msCrypto && window.msCrypto.getRandomValues) { // IE Rand.prototype._rand = function _rand(n) { var arr = new Uint8Array(n); window.msCrypto.getRandomValues(arr); return arr; }; } else { // Old junk Rand.prototype._rand = function() { throw new Error('Not implemented yet'); }; } } else { // Node.js or Web worker try { var crypto = require('cry' + 'pto'); Rand.prototype._rand = function _rand(n) { return crypto.randomBytes(n); }; } catch (e) { // Emulate crypto API using randy Rand.prototype._rand = function _rand(n) { var res = new Uint8Array(n); for (var i = 0; i < res.length; i++) res[i] = this.rand.getByte(); return res; }; } } },{}],58:[function(require,module,exports){ var hash = exports; hash.utils = require('./hash/utils'); hash.common = require('./hash/common'); hash.sha = require('./hash/sha'); hash.ripemd = require('./hash/ripemd'); hash.hmac = require('./hash/hmac'); // 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; },{"./hash/common":59,"./hash/hmac":60,"./hash/ripemd":61,"./hash/sha":62,"./hash/utils":63}],59:[function(require,module,exports){ var hash = require('../hash'); var utils = hash.utils; var assert = utils.assert; 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 (var t = 8; t < this.padLength; t++) res[i++] = 0; } return res; }; },{"../hash":58}],60:[function(require,module,exports){ var hmac = exports; var hash = require('../hash'); var utils = hash.utils; var assert = utils.assert; 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 (var i = 0; i < key.length; i++) key[i] ^= 0x36; this.inner = new this.Hash().update(key); // 0x36 ^ 0x5c = 0x6a for (var 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); }; },{"../hash":58}],61:[function(require,module,exports){ var hash = require('../hash'); var utils = hash.utils; var rotl32 = utils.rotl32; var sum32 = utils.sum32; var sum32_3 = utils.sum32_3; var sum32_4 = utils.sum32_4; var BlockHash = hash.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 ]; },{"../hash":58}],62:[function(require,module,exports){ var hash = require('../hash'); var utils = hash.utils; var assert = utils.assert; var rotr32 = utils.rotr32; var rotl32 = utils.rotl32; var sum32 = utils.sum32; var sum32_4 = utils.sum32_4; var sum32_5 = utils.sum32_5; 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 = hash.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 ]; 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 ]; var sha1_K = [ 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 ]; 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); exports.sha256 = 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 (var 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'); }; 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); exports.sha224 = 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'); }; 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); exports.sha512 = 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); var c0_hi = s0_512_hi(ah, al); var c0_lo = s0_512_lo(ah, al); var c1_hi = maj64_hi(ah, al, bh, bl, ch, cl); var 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 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); exports.sha384 = 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'); }; 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); exports.sha1 = 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 (var 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'); }; function ch32(x, y, z) { return (x & y) ^ ((~x) & z); } function maj32(x, y, z) { return (x & y) ^ (x & z) ^ (y & z); } function p32(x, y, z) { return x ^ y ^ z; } function s0_256(x) { return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22); } function s1_256(x) { return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25); } function g0_256(x) { return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3); } function g1_256(x) { return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10); } 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); } function ch64_hi(xh, xl, yh, yl, zh, zl) { 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, zl) { 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; } },{"../hash":58}],63:[function(require,module,exports){ var utils = exports; var inherits = require('inherits'); function toArray(msg, enc) { if (Array.isArray(msg)) return msg.slice(); if (!msg) return []; var res = []; if (typeof msg === 'string') { if (!enc) { 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); } } else 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++) res[i] = msg[i] | 0; } return res; } utils.toArray = toArray; function toHex(msg) { var res = ''; for (var i = 0; i < msg.length; i++) res += zero2(msg[i].toString(16)); return res; } utils.toHex = toHex; function htonl(w) { var res = (w >>> 24) | ((w >>> 8) & 0xff00) | ((w << 8) & 0xff0000) | ((w & 0xff) << 24); return res >>> 0; } utils.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; } utils.toHex32 = toHex32; function zero2(word) { if (word.length === 1) return '0' + word; else return word; } utils.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; } utils.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; } utils.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; } utils.split32 = split32; function rotr32(w, b) { return (w >>> b) | (w << (32 - b)); } utils.rotr32 = rotr32; function rotl32(w, b) { return (w << b) | (w >>> (32 - b)); } utils.rotl32 = rotl32; function sum32(a, b) { return (a + b) >>> 0; } utils.sum32 = sum32; function sum32_3(a, b, c) { return (a + b + c) >>> 0; } utils.sum32_3 = sum32_3; function sum32_4(a, b, c, d) { return (a + b + c + d) >>> 0; } utils.sum32_4 = sum32_4; function sum32_5(a, b, c, d, e) { return (a + b + c + d + e) >>> 0; } utils.sum32_5 = sum32_5; function assert(cond, msg) { if (!cond) throw new Error(msg || 'Assertion failed'); } utils.assert = assert; utils.inherits = inherits; 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; },{"inherits":199}],64:[function(require,module,exports){ module.exports={ "name": "elliptic", "version": "6.2.3", "description": "EC cryptography", "main": "lib/elliptic.js", "files": [ "lib" ], "scripts": { "coverage": "npm run unit --coverage", "coveralls": "npm run coverage && cat ./coverage/lcov.info | coveralls", "jscs": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/*.js", "jshint": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/*.js", "lint": "npm run jscs && npm run jshint", "test": "npm run lint && npm run unit", "unit": "istanbul test _mocha --reporter=spec test/*-test.js" }, "repository": { "type": "git", "url": "git+ssh://git@github.com/indutny/elliptic.git" }, "keywords": [ "EC", "Elliptic", "curve", "Cryptography" ], "author": { "name": "Fedor Indutny", "email": "fedor@indutny.com" }, "license": "MIT", "bugs": { "url": "https://github.com/indutny/elliptic/issues" }, "homepage": "https://github.com/indutny/elliptic", "devDependencies": { "coveralls": "^2.11.3", "istanbul": "^0.4.2", "jscs": "^2.9.0", "jshint": "^2.6.0", "mocha": "^2.1.0" }, "dependencies": { "bn.js": "^4.0.0", "brorand": "^1.0.1", "hash.js": "^1.0.0", "inherits": "^2.0.1" }, "gitHead": "c32f20b22b420eb6af3c6dda28963deb7facf823", "_id": "elliptic@6.2.3", "_shasum": "18e46d7306b0951275a2d42063270a14b74ebe99", "_from": "elliptic@^6.0.0", "_npmVersion": "3.3.12", "_nodeVersion": "5.4.1", "_npmUser": { "name": "indutny", "email": "fedor@indutny.com" }, "dist": { "shasum": "18e46d7306b0951275a2d42063270a14b74ebe99", "tarball": "http://registry.npmjs.org/elliptic/-/elliptic-6.2.3.tgz" }, "maintainers": [ { "name": "indutny", "email": "fedor@indutny.com" } ], "directories": {}, "_resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.2.3.tgz" } },{}],65:[function(require,module,exports){ module.exports={"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" } },{}],66:[function(require,module,exports){ // from https://github.com/indutny/self-signed/blob/gh-pages/lib/asn1.js // Fedor, you are amazing. var asn1 = require('asn1.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() ) }) },{"asn1.js":69}],67:[function(require,module,exports){ (function (Buffer){ // adapted from https://github.com/apatil/pemstrip var findProc = /Proc-Type: 4,ENCRYPTED\r?\nDEK-Info: AES-((?:128)|(?:192)|(?:256))-CBC,([0-9A-H]+)\r?\n\r?\n([0-9A-z\n\r\+\/\=]+)\r?\n/m var startRegex = /^-----BEGIN (.*) KEY-----\r?\n/m var fullRegex = /^-----BEGIN (.*) KEY-----\r?\n([0-9A-z\n\r\+\/\=]+)\r?\n-----END \1 KEY-----$/m var evp = require('evp_bytestokey') var ciphers = require('browserify-aes') 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 = new Buffer(match[2], 'hex') var cipherText = new Buffer(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] + ' KEY' return { tag: tag, data: decrypted } } }).call(this,require("buffer").Buffer) },{"browserify-aes":86,"buffer":2,"evp_bytestokey":101}],68:[function(require,module,exports){ (function (Buffer){ var asn1 = require('./asn1') var aesid = require('./aesid.json') var fixProc = require('./fixProc') var ciphers = require('browserify-aes') var compat = require('pbkdf2') 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 = new Buffer(buffer) } var stripped = fixProc(buffer, password) var type = stripped.tag var data = stripped.data var subtype, ndata switch (type) { case 'PUBLIC KEY': 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) var cipher = ciphers.createDecipheriv(algo, key, iv) var out = [] out.push(cipher.update(cipherText)) out.push(cipher.final()) return Buffer.concat(out) } }).call(this,require("buffer").Buffer) },{"./aesid.json":65,"./asn1":66,"./fixProc":67,"browserify-aes":86,"buffer":2,"pbkdf2":151}],69:[function(require,module,exports){ var asn1 = exports; asn1.bignum = require('bn.js'); asn1.define = require('./asn1/api').define; asn1.base = require('./asn1/base'); asn1.constants = require('./asn1/constants'); asn1.decoders = require('./asn1/decoders'); asn1.encoders = require('./asn1/encoders'); },{"./asn1/api":70,"./asn1/base":72,"./asn1/constants":76,"./asn1/decoders":78,"./asn1/encoders":81,"bn.js":39}],70:[function(require,module,exports){ var asn1 = require('../asn1'); var inherits = require('inherits'); 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 = require('vm').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) { // 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) { // 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); }; },{"../asn1":69,"inherits":199,"vm":218}],71:[function(require,module,exports){ var inherits = require('inherits'); var Reporter = require('../base').Reporter; var Buffer = require('buffer').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; }; },{"../base":72,"buffer":2,"inherits":199}],72:[function(require,module,exports){ var base = exports; base.Reporter = require('./reporter').Reporter; base.DecoderBuffer = require('./buffer').DecoderBuffer; base.EncoderBuffer = require('./buffer').EncoderBuffer; base.Node = require('./node'); },{"./buffer":71,"./node":73,"./reporter":74}],73:[function(require,module,exports){ var Reporter = require('../base').Reporter; var EncoderBuffer = require('../base').EncoderBuffer; var assert = require('minimalistic-assert'); // Supported tags var tags = [ 'seq', 'seqof', 'set', 'setof', 'octstr', 'bitstr', 'objid', 'bool', 'gentime', 'utctime', 'null_', 'enum', 'int', 'ia5str', 'utf8str', 'bmpstr', 'numstr', 'printstr' ]; // Public methods list var methods = [ 'key', 'obj', 'use', 'optional', 'explicit', 'implicit', 'def', 'choice', 'any' ].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; // 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' ]; 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) { 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; }; // // Decoding // Node.prototype._decode = function decode(input) { var state = this._baseState; // Decode root node if (state.parent === null) return input.wrapResult(state.children[0]._decode(input)); var result = state['default']; var present = true; var prevKey; 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); else this._decodeChoice(input); 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; } // 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; } // Select proper method for tag if (state.any) result = result; else if (state.choice === null) result = this._decodeGeneric(state.tag, input); else result = this._decodeChoice(input); if (input.isError(result)) return result; // Decode children if (!state.any && state.choice === null && state.children !== null) { var fail = state.children.some(function decodeChildren(child) { // NOTE: We are ignoring errors here, to let parser continue with other // parts of encoded data child._decode(input); }); if (fail) return err; } } // 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); return result; }; Node.prototype._decodeGeneric = function decodeGeneric(tag, input) { var state = this._baseState; if (tag === 'seq' || tag === 'set') return null; if (tag === 'seqof' || tag === 'setof') return this._decodeList(input, tag, state.args[0]); else if (tag === 'octstr' || tag === 'bitstr') return this._decodeStr(input, tag); else if (tag === 'ia5str' || tag === 'utf8str' || tag === 'bmpstr') return this._decodeStr(input, tag); else if (tag === 'numstr' || tag === 'printstr') return this._decodeStr(input, tag); else if (tag === 'objid' && state.args) return this._decodeObjid(input, state.args[0], state.args[1]); else if (tag === 'objid') return this._decodeObjid(input, null, null); else if (tag === 'gentime' || tag === 'utctime') return this._decodeTime(input, tag); else if (tag === 'null_') return this._decodeNull(input); else if (tag === 'bool') return this._decodeBool(input); else if (tag === 'int' || tag === 'enum') return this._decodeInt(input, state.args && state.args[0]); else if (state.use !== null) return this._getUse(state.use, input._reporterState.obj)._decode(input); else return input.error('unknown tag: ' + tag); return null; }; 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) { 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); 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; var present = true; // 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; } // For error reporting var prevKey; // 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.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 ommited 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 (tag === 'octstr' || tag === 'bitstr' || tag === 'ia5str') return this._encodeStr(data, tag); else if (tag === 'utf8str' || tag === 'bmpstr') return this._encodeStr(data, tag); else if (tag === 'numstr' || tag === 'printstr') 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 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); }; },{"../base":72,"minimalistic-assert":83}],74:[function(require,module,exports){ var inherits = require('inherits'); 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.leaveKey = function leaveKey(index, key, value) { var state = this._reporterState; state.path = state.path.slice(0, index - 1); if (state.obj !== null) state.obj[key] = value; }; 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)'); Error.captureStackTrace(this, ReporterError); return this; }; },{"inherits":199}],75:[function(require,module,exports){ var constants = require('../constants'); 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); },{"../constants":76}],76:[function(require,module,exports){ 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 = require('./der'); },{"./der":75}],77:[function(require,module,exports){ var inherits = require('inherits'); var asn1 = require('../../asn1'); 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 || 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) { var result = []; while (!buffer.isEmpty()) { var possibleEnd = this._peekTag(buffer, 'end'); if (buffer.isError(possibleEnd)) return possibleEnd; var res = decoder.decode(buffer, 'der'); if (buffer.isError(res) && possibleEnd) break; result.push(res); } return result; }; DERNode.prototype._decodeStr = function decodeStr(buffer, tag) { if (tag === 'octstr') { return buffer.raw(); } else if (tag === 'bitstr') { var unused = buffer.readUInt8(); if (buffer.isError(unused)) return unused; return { unused: unused, data: buffer.raw() }; } else if (tag === 'ia5str' || tag === 'utf8str') { return buffer.raw().toString(); } 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 === '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(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 { return buffer.error('Decoding of string type: ' + tag + ' unsupported'); } }; DERNode.prototype._decodeObjid = function decodeObjid(buffer, values, relative) { 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; } },{"../../asn1":69,"inherits":199}],78:[function(require,module,exports){ var decoders = exports; decoders.der = require('./der'); decoders.pem = require('./pem'); },{"./der":77,"./pem":79}],79:[function(require,module,exports){ var inherits = require('inherits'); var Buffer = require('buffer').Buffer; var asn1 = require('../../asn1'); var DERDecoder = require('./der'); 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); }; },{"../../asn1":69,"./der":77,"buffer":2,"inherits":199}],80:[function(require,module,exports){ var inherits = require('inherits'); var Buffer = require('buffer').Buffer; var asn1 = require('../../asn1'); var base = asn1.base; var bignum = asn1.bignum; // 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 === 'octstr') { return this._createEncoderBuffer(str); } else if (tag === 'bitstr') { return this._createEncoderBuffer([ str.unused | 0, str.data ]); } else if (tag === 'ia5str' || tag === 'utf8str') { return this._createEncoderBuffer(str); } 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 { 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; } },{"../../asn1":69,"buffer":2,"inherits":199}],81:[function(require,module,exports){ var encoders = exports; encoders.der = require('./der'); encoders.pem = require('./pem'); },{"./der":80,"./pem":82}],82:[function(require,module,exports){ var inherits = require('inherits'); var Buffer = require('buffer').Buffer; var asn1 = require('../../asn1'); var DEREncoder = require('./der'); 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'); }; },{"../../asn1":69,"./der":80,"buffer":2,"inherits":199}],83:[function(require,module,exports){ arguments[4][34][0].apply(exports,arguments) },{"dup":34}],84:[function(require,module,exports){ (function (Buffer){ // 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 uint_max = Math.pow(2, 32) function fixup_uint32 (x) { var ret, x_pos ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x return ret } function scrub_vec (v) { for (var i = 0; i < v.length; v++) { v[i] = 0 } return false } function Global () { this.SBOX = [] this.INV_SBOX = [] this.SUB_MIX = [[], [], [], []] this.INV_SUB_MIX = [[], [], [], []] this.init() this.RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36] } Global.prototype.init = function () { var d, i, sx, t, x, x2, x4, x8, xi, _i d = (function () { var _i, _results _results = [] for (i = _i = 0; _i < 256; i = ++_i) { if (i < 128) { _results.push(i << 1) } else { _results.push((i << 1) ^ 0x11b) } } return _results })() x = 0 xi = 0 for (i = _i = 0; _i < 256; i = ++_i) { sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4) sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63 this.SBOX[x] = sx this.INV_SBOX[sx] = x x2 = d[x] x4 = d[x2] x8 = d[x4] t = (d[sx] * 0x101) ^ (sx * 0x1010100) this.SUB_MIX[0][x] = (t << 24) | (t >>> 8) this.SUB_MIX[1][x] = (t << 16) | (t >>> 16) this.SUB_MIX[2][x] = (t << 8) | (t >>> 24) this.SUB_MIX[3][x] = t t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100) this.INV_SUB_MIX[0][sx] = (t << 24) | (t >>> 8) this.INV_SUB_MIX[1][sx] = (t << 16) | (t >>> 16) this.INV_SUB_MIX[2][sx] = (t << 8) | (t >>> 24) this.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 true } var G = new Global() AES.blockSize = 4 * 4 AES.prototype.blockSize = AES.blockSize AES.keySize = 256 / 8 AES.prototype.keySize = AES.keySize function bufferToArray (buf) { var len = buf.length / 4 var out = new Array(len) var i = -1 while (++i < len) { out[i] = buf.readUInt32BE(i * 4) } return out } function AES (key) { this._key = bufferToArray(key) this._doReset() } AES.prototype._doReset = function () { var invKsRow, keySize, keyWords, ksRow, ksRows, t keyWords = this._key keySize = keyWords.length this._nRounds = keySize + 6 ksRows = (this._nRounds + 1) * 4 this._keySchedule = [] for (ksRow = 0; ksRow < ksRows; ksRow++) { this._keySchedule[ksRow] = ksRow < keySize ? keyWords[ksRow] : (t = this._keySchedule[ksRow - 1], (ksRow % 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 ^= G.RCON[(ksRow / keySize) | 0] << 24) : keySize > 6 && ksRow % keySize === 4 ? t = (G.SBOX[t >>> 24] << 24) | (G.SBOX[(t >>> 16) & 0xff] << 16) | (G.SBOX[(t >>> 8) & 0xff] << 8) | G.SBOX[t & 0xff] : void 0, this._keySchedule[ksRow - keySize] ^ t) } this._invKeySchedule = [] for (invKsRow = 0; invKsRow < ksRows; invKsRow++) { ksRow = ksRows - invKsRow t = this._keySchedule[ksRow - (invKsRow % 4 ? 0 : 4)] this._invKeySchedule[invKsRow] = invKsRow < 4 || ksRow <= 4 ? t : G.INV_SUB_MIX[0][G.SBOX[t >>> 24]] ^ G.INV_SUB_MIX[1][G.SBOX[(t >>> 16) & 0xff]] ^ G.INV_SUB_MIX[2][G.SBOX[(t >>> 8) & 0xff]] ^ G.INV_SUB_MIX[3][G.SBOX[t & 0xff]] } return true } AES.prototype.encryptBlock = function (M) { M = bufferToArray(new Buffer(M)) var out = this._doCryptBlock(M, this._keySchedule, G.SUB_MIX, G.SBOX) var buf = new Buffer(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 = bufferToArray(new Buffer(M)) var temp = [M[3], M[1]] M[1] = temp[0] M[3] = temp[1] var out = this._doCryptBlock(M, this._invKeySchedule, G.INV_SUB_MIX, G.INV_SBOX) var buf = new Buffer(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 () { scrub_vec(this._keySchedule) scrub_vec(this._invKeySchedule) scrub_vec(this._key) } AES.prototype._doCryptBlock = function (M, keySchedule, SUB_MIX, SBOX) { var ksRow, s0, s1, s2, s3, t0, t1, t2, t3 s0 = M[0] ^ keySchedule[0] s1 = M[1] ^ keySchedule[1] s2 = M[2] ^ keySchedule[2] s3 = M[3] ^ keySchedule[3] ksRow = 4 for (var round = 1; round < this._nRounds; round++) { 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++] 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++] 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++] 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++] 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++] return [ fixup_uint32(t0), fixup_uint32(t1), fixup_uint32(t2), fixup_uint32(t3) ] } exports.AES = AES }).call(this,require("buffer").Buffer) },{"buffer":2}],85:[function(require,module,exports){ (function (Buffer){ var aes = require('./aes') var Transform = require('cipher-base') var inherits = require('inherits') var GHASH = require('./ghash') var xor = require('buffer-xor') inherits(StreamCipher, Transform) module.exports = StreamCipher function StreamCipher (mode, key, iv, decrypt) { if (!(this instanceof StreamCipher)) { return new StreamCipher(mode, key, iv) } Transform.call(this) this._finID = Buffer.concat([iv, new Buffer([0, 0, 0, 1])]) iv = Buffer.concat([iv, new Buffer([0, 0, 0, 2])]) this._cipher = new aes.AES(key) this._prev = new Buffer(iv.length) this._cache = new Buffer('') this._secCache = new Buffer('') this._decrypt = decrypt this._alen = 0 this._len = 0 iv.copy(this._prev) this._mode = mode var h = new Buffer(4) h.fill(0) this._ghash = new GHASH(this._cipher.encryptBlock(h)) this._authTag = null this._called = false } StreamCipher.prototype._update = function (chunk) { if (!this._called && this._alen) { var rump = 16 - (this._alen % 16) if (rump < 16) { rump = new Buffer(rump) rump.fill(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) { if (xorTest(tag, this._authTag)) { throw new Error('Unsupported state or unable to authenticate data') } } else { this._authTag = tag } this._cipher.scrub() } StreamCipher.prototype.getAuthTag = function getAuthTag () { if (!this._decrypt && Buffer.isBuffer(this._authTag)) { return this._authTag } else { throw new Error('Attempting to get auth tag in unsupported state') } } StreamCipher.prototype.setAuthTag = function setAuthTag (tag) { if (this._decrypt) { this._authTag = tag } else { throw new Error('Attempting to set auth tag in unsupported state') } } StreamCipher.prototype.setAAD = function setAAD (buf) { if (!this._called) { this._ghash.update(buf) this._alen += buf.length } else { throw new Error('Attempting to set AAD in unsupported state') } } function xorTest (a, b) { var out = 0 if (a.length !== b.length) { out++ } var len = Math.min(a.length, b.length) var i = -1 while (++i < len) { out += (a[i] ^ b[i]) } return out } }).call(this,require("buffer").Buffer) },{"./aes":84,"./ghash":89,"buffer":2,"buffer-xor":98,"cipher-base":99,"inherits":199}],86:[function(require,module,exports){ arguments[4][10][0].apply(exports,arguments) },{"./decrypter":87,"./encrypter":88,"./modes":90,"dup":10}],87:[function(require,module,exports){ (function (Buffer){ var aes = require('./aes') var Transform = require('cipher-base') var inherits = require('inherits') var modes = require('./modes') var StreamCipher = require('./streamCipher') var AuthCipher = require('./authCipher') var ebtk = require('evp_bytestokey') inherits(Decipher, Transform) function Decipher (mode, key, iv) { if (!(this instanceof Decipher)) { return new Decipher(mode, key, iv) } Transform.call(this) this._cache = new Splitter() this._last = void 0 this._cipher = new aes.AES(key) this._prev = new Buffer(iv.length) iv.copy(this._prev) this._mode = mode this._autopadding = true } 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 () { if (!(this instanceof Splitter)) { return new Splitter() } this.cache = new Buffer('') } 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] 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) } var modelist = { ECB: require('./modes/ecb'), CBC: require('./modes/cbc'), CFB: require('./modes/cfb'), CFB8: require('./modes/cfb8'), CFB1: require('./modes/cfb1'), OFB: require('./modes/ofb'), CTR: require('./modes/ctr'), GCM: require('./modes/ctr') } function createDecipheriv (suite, password, iv) { var config = modes[suite.toLowerCase()] if (!config) { throw new TypeError('invalid suite type') } if (typeof iv === 'string') { iv = new Buffer(iv) } if (typeof password === 'string') { password = new Buffer(password) } if (password.length !== config.key / 8) { throw new TypeError('invalid key length ' + password.length) } if (iv.length !== config.iv) { throw new TypeError('invalid iv length ' + iv.length) } if (config.type === 'stream') { return new StreamCipher(modelist[config.mode], password, iv, true) } else if (config.type === 'auth') { return new AuthCipher(modelist[config.mode], password, iv, true) } return new Decipher(modelist[config.mode], 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 }).call(this,require("buffer").Buffer) },{"./aes":84,"./authCipher":85,"./modes":90,"./modes/cbc":91,"./modes/cfb":92,"./modes/cfb1":93,"./modes/cfb8":94,"./modes/ctr":95,"./modes/ecb":96,"./modes/ofb":97,"./streamCipher":100,"buffer":2,"cipher-base":99,"evp_bytestokey":101,"inherits":199}],88:[function(require,module,exports){ (function (Buffer){ var aes = require('./aes') var Transform = require('cipher-base') var inherits = require('inherits') var modes = require('./modes') var ebtk = require('evp_bytestokey') var StreamCipher = require('./streamCipher') var AuthCipher = require('./authCipher') inherits(Cipher, Transform) function Cipher (mode, key, iv) { if (!(this instanceof Cipher)) { return new Cipher(mode, key, iv) } Transform.call(this) this._cache = new Splitter() this._cipher = new aes.AES(key) this._prev = new Buffer(iv.length) iv.copy(this._prev) this._mode = mode this._autopadding = true } 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) } Cipher.prototype._final = function () { var chunk = this._cache.flush() if (this._autopadding) { chunk = this._mode.encrypt(this, chunk) this._cipher.scrub() return chunk } else if (chunk.toString('hex') !== '10101010101010101010101010101010') { this._cipher.scrub() throw new Error('data not multiple of block length') } } Cipher.prototype.setAutoPadding = function (setTo) { this._autopadding = !!setTo return this } function Splitter () { if (!(this instanceof Splitter)) { return new Splitter() } this.cache = new Buffer('') } 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 = new Buffer(len) var i = -1 while (++i < len) { padBuff.writeUInt8(len, i) } var out = Buffer.concat([this.cache, padBuff]) return out } var modelist = { ECB: require('./modes/ecb'), CBC: require('./modes/cbc'), CFB: require('./modes/cfb'), CFB8: require('./modes/cfb8'), CFB1: require('./modes/cfb1'), OFB: require('./modes/ofb'), CTR: require('./modes/ctr'), GCM: require('./modes/ctr') } function createCipheriv (suite, password, iv) { var config = modes[suite.toLowerCase()] if (!config) { throw new TypeError('invalid suite type') } if (typeof iv === 'string') { iv = new Buffer(iv) } if (typeof password === 'string') { password = new Buffer(password) } if (password.length !== config.key / 8) { throw new TypeError('invalid key length ' + password.length) } if (iv.length !== config.iv) { throw new TypeError('invalid iv length ' + iv.length) } if (config.type === 'stream') { return new StreamCipher(modelist[config.mode], password, iv) } else if (config.type === 'auth') { return new AuthCipher(modelist[config.mode], password, iv) } return new Cipher(modelist[config.mode], 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 }).call(this,require("buffer").Buffer) },{"./aes":84,"./authCipher":85,"./modes":90,"./modes/cbc":91,"./modes/cfb":92,"./modes/cfb1":93,"./modes/cfb8":94,"./modes/ctr":95,"./modes/ecb":96,"./modes/ofb":97,"./streamCipher":100,"buffer":2,"cipher-base":99,"evp_bytestokey":101,"inherits":199}],89:[function(require,module,exports){ (function (Buffer){ var zeros = new Buffer(16) zeros.fill(0) module.exports = GHASH function GHASH (key) { this.h = key this.state = new Buffer(16) this.state.fill(0) this.cache = new Buffer('') } // 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, lsb_Vi 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 = xor(Zi, Vi) } // Store the value of LSB(V_i) lsb_Vi = (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 (lsb_Vi) { 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, zeros], 16)) } this.ghash(fromArray([ 0, abl, 0, bl ])) return this.state } function toArray (buf) { return [ buf.readUInt32BE(0), buf.readUInt32BE(4), buf.readUInt32BE(8), buf.readUInt32BE(12) ] } function fromArray (out) { out = out.map(fixup_uint32) var buf = new Buffer(16) buf.writeUInt32BE(out[0], 0) buf.writeUInt32BE(out[1], 4) buf.writeUInt32BE(out[2], 8) buf.writeUInt32BE(out[3], 12) return buf } var uint_max = Math.pow(2, 32) function fixup_uint32 (x) { var ret, x_pos ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x return ret } function xor (a, b) { return [ a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3] ] } }).call(this,require("buffer").Buffer) },{"buffer":2}],90:[function(require,module,exports){ arguments[4][14][0].apply(exports,arguments) },{"dup":14}],91:[function(require,module,exports){ arguments[4][15][0].apply(exports,arguments) },{"buffer-xor":98,"dup":15}],92:[function(require,module,exports){ (function (Buffer){ var xor = require('buffer-xor') exports.encrypt = function (self, data, decrypt) { var out = new Buffer('') var len while (data.length) { if (self._cache.length === 0) { self._cache = self._cipher.encryptBlock(self._prev) self._prev = new Buffer('') } 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 } 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 } }).call(this,require("buffer").Buffer) },{"buffer":2,"buffer-xor":98}],93:[function(require,module,exports){ (function (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 } exports.encrypt = function (self, chunk, decrypt) { var len = chunk.length var out = new Buffer(len) var i = -1 while (++i < len) { out[i] = encryptByte(self, chunk[i], decrypt) } return out } function shiftIn (buffer, value) { var len = buffer.length var i = -1 var out = new Buffer(buffer.length) buffer = Buffer.concat([buffer, new Buffer([value])]) while (++i < len) { out[i] = buffer[i] << 1 | buffer[i + 1] >> (7) } return out } }).call(this,require("buffer").Buffer) },{"buffer":2}],94:[function(require,module,exports){ (function (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), new Buffer([decrypt ? byteParam : out])]) return out } exports.encrypt = function (self, chunk, decrypt) { var len = chunk.length var out = new Buffer(len) var i = -1 while (++i < len) { out[i] = encryptByte(self, chunk[i], decrypt) } return out } }).call(this,require("buffer").Buffer) },{"buffer":2}],95:[function(require,module,exports){ (function (Buffer){ var xor = require('buffer-xor') 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 } } } function getBlock (self) { var out = self._cipher.encryptBlock(self._prev) incr32(self._prev) return out } 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) } }).call(this,require("buffer").Buffer) },{"buffer":2,"buffer-xor":98}],96:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"dup":20}],97:[function(require,module,exports){ (function (Buffer){ var xor = require('buffer-xor') 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) } }).call(this,require("buffer").Buffer) },{"buffer":2,"buffer-xor":98}],98:[function(require,module,exports){ (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 } }).call(this,require("buffer").Buffer) },{"buffer":2}],99:[function(require,module,exports){ (function (Buffer){ var Transform = require('stream').Transform var inherits = require('inherits') var StringDecoder = require('string_decoder').StringDecoder module.exports = CipherBase inherits(CipherBase, Transform) function CipherBase (hashMode) { Transform.call(this) this.hashMode = typeof hashMode === 'string' if (this.hashMode) { this[hashMode] = this._finalOrDigest } else { this.final = this._finalOrDigest } this._decoder = null this._encoding = null } CipherBase.prototype.update = function (data, inputEnc, outputEnc) { if (typeof data === 'string') { data = new Buffer(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 } finally { done(err) } } CipherBase.prototype._finalOrDigest = function (outputEnc) { var outData = this._final() || new Buffer('') if (outputEnc) { outData = this._toString(outData, outputEnc, true) } return outData } CipherBase.prototype._toString = function (value, enc, final) { 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 (final) { out += this._decoder.end() } return out } }).call(this,require("buffer").Buffer) },{"buffer":2,"inherits":199,"stream":216,"string_decoder":217}],100:[function(require,module,exports){ (function (Buffer){ var aes = require('./aes') var Transform = require('cipher-base') var inherits = require('inherits') inherits(StreamCipher, Transform) module.exports = StreamCipher function StreamCipher (mode, key, iv, decrypt) { if (!(this instanceof StreamCipher)) { return new StreamCipher(mode, key, iv) } Transform.call(this) this._cipher = new aes.AES(key) this._prev = new Buffer(iv.length) this._cache = new Buffer('') this._secCache = new Buffer('') this._decrypt = decrypt iv.copy(this._prev) this._mode = mode } StreamCipher.prototype._update = function (chunk) { return this._mode.encrypt(this, chunk, this._decrypt) } StreamCipher.prototype._final = function () { this._cipher.scrub() } }).call(this,require("buffer").Buffer) },{"./aes":84,"buffer":2,"cipher-base":99,"inherits":199}],101:[function(require,module,exports){ (function (Buffer){ var md5 = require('create-hash/md5') module.exports = EVP_BytesToKey function EVP_BytesToKey (password, salt, keyLen, ivLen) { if (!Buffer.isBuffer(password)) { password = new Buffer(password, 'binary') } if (salt && !Buffer.isBuffer(salt)) { salt = new Buffer(salt, 'binary') } keyLen = keyLen / 8 ivLen = ivLen || 0 var ki = 0 var ii = 0 var key = new Buffer(keyLen) var iv = new Buffer(ivLen) var addmd = 0 var md_buf var i var bufs = [] while (true) { if (addmd++ > 0) { bufs.push(md_buf) } bufs.push(password) if (salt) { bufs.push(salt) } md_buf = md5(Buffer.concat(bufs)) bufs = [] i = 0 if (keyLen > 0) { while (true) { if (keyLen === 0) { break } if (i === md_buf.length) { break } key[ki++] = md_buf[i] keyLen-- i++ } } if (ivLen > 0 && i !== md_buf.length) { while (true) { if (ivLen === 0) { break } if (i === md_buf.length) { break } iv[ii++] = md_buf[i] ivLen-- i++ } } if (keyLen === 0 && ivLen === 0) { break } } for (i = 0; i < md_buf.length; i++) { md_buf[i] = 0 } return { key: key, iv: iv } } }).call(this,require("buffer").Buffer) },{"buffer":2,"create-hash/md5":132}],102:[function(require,module,exports){ (function (Buffer){ // much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js var createHmac = require('create-hmac') var crt = require('browserify-rsa') var curves = require('./curves') var elliptic = require('elliptic') var parseKeys = require('parse-asn1') var BN = require('bn.js') var EC = elliptic.ec function sign (hash, key, hashType, signType) { var priv = parseKeys(key) if (priv.curve) { if (signType !== 'ecdsa') 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') throw new Error('wrong private key type') } 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.genKeyPair() key._importPrivate(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)) { 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) } // Pad values 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, k do { t = new Buffer('') 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 }).call(this,require("buffer").Buffer) },{"./curves":38,"bn.js":39,"browserify-rsa":40,"buffer":2,"create-hmac":143,"elliptic":41,"parse-asn1":68}],103:[function(require,module,exports){ (function (Buffer){ // much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js var curves = require('./curves') var elliptic = require('elliptic') var parseKeys = require('parse-asn1') var BN = require('bn.js') var EC = elliptic.ec function verify (sig, hash, key, signType) { var pub = parseKeys(key) if (pub.type === 'ec') { if (signType !== 'ecdsa') { 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') { throw new Error('wrong public key type') } } 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 = 0 if (padNum < 8) { out = 1 } 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) } 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 }).call(this,require("buffer").Buffer) },{"./curves":38,"bn.js":39,"buffer":2,"elliptic":41,"parse-asn1":68}],104:[function(require,module,exports){ (function (Buffer){ var elliptic = require('elliptic'); var BN = require('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); 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._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); } } }).call(this,require("buffer").Buffer) },{"bn.js":105,"buffer":2,"elliptic":106}],105:[function(require,module,exports){ arguments[4][39][0].apply(exports,arguments) },{"buffer":1,"dup":39}],106:[function(require,module,exports){ arguments[4][41][0].apply(exports,arguments) },{"../package.json":129,"./elliptic/curve":109,"./elliptic/curves":112,"./elliptic/ec":113,"./elliptic/eddsa":116,"./elliptic/hmac-drbg":119,"./elliptic/utils":121,"brorand":122,"dup":41}],107:[function(require,module,exports){ arguments[4][42][0].apply(exports,arguments) },{"../../elliptic":106,"bn.js":105,"dup":42}],108:[function(require,module,exports){ arguments[4][43][0].apply(exports,arguments) },{"../../elliptic":106,"../curve":109,"bn.js":105,"dup":43,"inherits":199}],109:[function(require,module,exports){ arguments[4][44][0].apply(exports,arguments) },{"./base":107,"./edwards":108,"./mont":110,"./short":111,"dup":44}],110:[function(require,module,exports){ arguments[4][45][0].apply(exports,arguments) },{"../../elliptic":106,"../curve":109,"bn.js":105,"dup":45,"inherits":199}],111:[function(require,module,exports){ arguments[4][46][0].apply(exports,arguments) },{"../../elliptic":106,"../curve":109,"bn.js":105,"dup":46,"inherits":199}],112:[function(require,module,exports){ arguments[4][47][0].apply(exports,arguments) },{"../elliptic":106,"./precomputed/secp256k1":120,"dup":47,"hash.js":123}],113:[function(require,module,exports){ arguments[4][48][0].apply(exports,arguments) },{"../../elliptic":106,"./key":114,"./signature":115,"bn.js":105,"dup":48}],114:[function(require,module,exports){ arguments[4][49][0].apply(exports,arguments) },{"bn.js":105,"dup":49}],115:[function(require,module,exports){ arguments[4][50][0].apply(exports,arguments) },{"../../elliptic":106,"bn.js":105,"dup":50}],116:[function(require,module,exports){ arguments[4][51][0].apply(exports,arguments) },{"../../elliptic":106,"./key":117,"./signature":118,"dup":51,"hash.js":123}],117:[function(require,module,exports){ arguments[4][52][0].apply(exports,arguments) },{"../../elliptic":106,"dup":52}],118:[function(require,module,exports){ arguments[4][53][0].apply(exports,arguments) },{"../../elliptic":106,"bn.js":105,"dup":53}],119:[function(require,module,exports){ arguments[4][54][0].apply(exports,arguments) },{"../elliptic":106,"dup":54,"hash.js":123}],120:[function(require,module,exports){ arguments[4][55][0].apply(exports,arguments) },{"dup":55}],121:[function(require,module,exports){ arguments[4][56][0].apply(exports,arguments) },{"bn.js":105,"dup":56}],122:[function(require,module,exports){ arguments[4][57][0].apply(exports,arguments) },{"dup":57}],123:[function(require,module,exports){ arguments[4][58][0].apply(exports,arguments) },{"./hash/common":124,"./hash/hmac":125,"./hash/ripemd":126,"./hash/sha":127,"./hash/utils":128,"dup":58}],124:[function(require,module,exports){ arguments[4][59][0].apply(exports,arguments) },{"../hash":123,"dup":59}],125:[function(require,module,exports){ arguments[4][60][0].apply(exports,arguments) },{"../hash":123,"dup":60}],126:[function(require,module,exports){ arguments[4][61][0].apply(exports,arguments) },{"../hash":123,"dup":61}],127:[function(require,module,exports){ arguments[4][62][0].apply(exports,arguments) },{"../hash":123,"dup":62}],128:[function(require,module,exports){ arguments[4][63][0].apply(exports,arguments) },{"dup":63,"inherits":199}],129:[function(require,module,exports){ arguments[4][64][0].apply(exports,arguments) },{"dup":64}],130:[function(require,module,exports){ (function (Buffer){ 'use strict'; var inherits = require('inherits') var md5 = require('./md5') var rmd160 = require('ripemd160') var sha = require('sha.js') var Base = require('cipher-base') function HashNoConstructor(hash) { Base.call(this, 'digest') this._hash = hash this.buffers = [] } inherits(HashNoConstructor, Base) HashNoConstructor.prototype._update = function (data) { this.buffers.push(data) } HashNoConstructor.prototype._final = function () { var buf = Buffer.concat(this.buffers) var r = this._hash(buf) this.buffers = null return r } 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 ('md5' === alg) return new HashNoConstructor(md5) if ('rmd160' === alg || 'ripemd160' === alg) return new HashNoConstructor(rmd160) return new Hash(sha(alg)) } }).call(this,require("buffer").Buffer) },{"./md5":132,"buffer":2,"cipher-base":133,"inherits":199,"ripemd160":134,"sha.js":136}],131:[function(require,module,exports){ (function (Buffer){ 'use strict'; var intSize = 4; var zeroBuffer = new Buffer(intSize); zeroBuffer.fill(0); var chrsz = 8; function toArray(buf, bigEndian) { if ((buf.length % intSize) !== 0) { var len = buf.length + (intSize - (buf.length % intSize)); buf = Buffer.concat([buf, zeroBuffer], len); } var arr = []; var fn = bigEndian ? buf.readInt32BE : buf.readInt32LE; for (var i = 0; i < buf.length; i += intSize) { arr.push(fn.call(buf, i)); } return arr; } function toBuffer(arr, size, bigEndian) { var buf = new Buffer(size); var fn = bigEndian ? buf.writeInt32BE : buf.writeInt32LE; for (var i = 0; i < arr.length; i++) { fn.call(buf, arr[i], i * 4, true); } return buf; } function hash(buf, fn, hashSize, bigEndian) { if (!Buffer.isBuffer(buf)) buf = new Buffer(buf); var arr = fn(toArray(buf, bigEndian), buf.length * chrsz); return toBuffer(arr, hashSize, bigEndian); } exports.hash = hash; }).call(this,require("buffer").Buffer) },{"buffer":2}],132:[function(require,module,exports){ 'use strict'; /* * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message * Digest Algorithm, as defined in RFC 1321. * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for more info. */ var helpers = require('./helpers'); /* * Calculate the MD5 of an array of little-endian words, and a bit length */ function core_md5(x, len) { /* append padding */ x[len >> 5] |= 0x80 << ((len) % 32); x[(((len + 64) >>> 9) << 4) + 14] = len; var a = 1732584193; var b = -271733879; var c = -1732584194; var d = 271733878; for(var i = 0; i < x.length; i += 16) { var olda = a; var oldb = b; var oldc = c; var oldd = d; a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); c = md5_ff(c, d, a, b, x[i+10], 17, -42063); b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); a = safe_add(a, olda); b = safe_add(b, oldb); c = safe_add(c, oldc); d = safe_add(d, oldd); } return Array(a, b, c, d); } /* * These functions implement the four basic operations the algorithm uses. */ function md5_cmn(q, a, b, x, s, t) { return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); } function md5_ff(a, b, c, d, x, s, t) { return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); } function md5_gg(a, b, c, d, x, s, t) { return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); } function md5_hh(a, b, c, d, x, s, t) { return md5_cmn(b ^ c ^ d, a, b, x, s, t); } function md5_ii(a, b, c, d, x, s, t) { return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); } /* * Add integers, wrapping at 2^32. This uses 16-bit operations internally * to work around bugs in some JS interpreters. */ function safe_add(x, y) { var lsw = (x & 0xFFFF) + (y & 0xFFFF); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xFFFF); } /* * Bitwise rotate a 32-bit number to the left. */ function bit_rol(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)); } module.exports = function md5(buf) { return helpers.hash(buf, core_md5, 16); }; },{"./helpers":131}],133:[function(require,module,exports){ (function (Buffer){ var Transform = require('stream').Transform var inherits = require('inherits') var StringDecoder = require('string_decoder').StringDecoder module.exports = CipherBase inherits(CipherBase, Transform) function CipherBase (hashMode) { Transform.call(this) this.hashMode = typeof hashMode === 'string' if (this.hashMode) { this[hashMode] = this._finalOrDigest } else { this.final = this._finalOrDigest } this._decoder = null this._encoding = null } CipherBase.prototype.update = function (data, inputEnc, outputEnc) { if (typeof data === 'string') { data = new Buffer(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 } finally { done(err) } } CipherBase.prototype._finalOrDigest = function (outputEnc) { var outData = this._final() || new Buffer('') if (outputEnc) { outData = this._toString(outData, outputEnc, true) } return outData } CipherBase.prototype._toString = function (value, enc, final) { 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 (final) { out += this._decoder.end() } return out } }).call(this,require("buffer").Buffer) },{"buffer":2,"inherits":199,"stream":216,"string_decoder":217}],134:[function(require,module,exports){ (function (Buffer){ /* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ /** @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. */ // constants table 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 bytesToWords (bytes) { var words = [] for (var i = 0, b = 0; i < bytes.length; i++, b += 8) { words[b >>> 5] |= bytes[i] << (24 - b % 32) } return words } function wordsToBytes (words) { var bytes = [] for (var b = 0; b < words.length * 32; b += 8) { bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF) } return bytes } function processBlock (H, M, offset) { // swap endian for (var i = 0; i < 16; i++) { 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) ) } // 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 (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 } 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)) } function ripemd160 (message) { var H = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0] if (typeof message === 'string') { message = new Buffer(message, 'utf8') } var m = bytesToWords(message) var nBitsLeft = message.length * 8 var nBitsTotal = message.length * 8 // Add padding m[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32) m[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ( (((nBitsTotal << 8) | (nBitsTotal >>> 24)) & 0x00ff00ff) | (((nBitsTotal << 24) | (nBitsTotal >>> 8)) & 0xff00ff00) ) for (var i = 0; i < m.length; i += 16) { processBlock(H, m, i) } // swap endian for (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) } var digestbytes = wordsToBytes(H) return new Buffer(digestbytes) } module.exports = ripemd160 }).call(this,require("buffer").Buffer) },{"buffer":2}],135:[function(require,module,exports){ (function (Buffer){ // prototype class for hash functions function Hash (blockSize, finalSize) { this._block = new Buffer(blockSize) this._finalSize = finalSize this._blockSize = blockSize this._len = 0 this._s = 0 } Hash.prototype.update = function (data, enc) { if (typeof data === 'string') { enc = enc || 'utf8' data = new Buffer(data, enc) } var l = this._len += data.length var s = this._s || 0 var f = 0 var buffer = this._block while (s < l) { var t = Math.min(data.length, f + this._blockSize - (s % this._blockSize)) var ch = (t - f) for (var i = 0; i < ch; i++) { buffer[(s % this._blockSize) + i] = data[i + f] } s += ch f += ch if ((s % this._blockSize) === 0) { this._update(buffer) } } this._s = s return this } Hash.prototype.digest = function (enc) { // Suppose the length of the message M, in bits, is l var l = this._len * 8 // Append the bit 1 to the end of the message this._block[this._len % this._blockSize] = 0x80 // and then k zero bits, where k is the smallest non-negative solution to the equation (l + 1 + k) === finalSize mod blockSize this._block.fill(0, this._len % this._blockSize + 1) if (l % (this._blockSize * 8) >= this._finalSize * 8) { this._update(this._block) this._block.fill(0) } // to this append the block which is equal to the number l written in binary // TODO: handle case where l is > Math.pow(2, 29) this._block.writeInt32BE(l, this._blockSize - 4) var hash = this._update(this._block) || this._hash() return enc ? hash.toString(enc) : hash } Hash.prototype._update = function () { throw new Error('_update must be implemented by subclass') } module.exports = Hash }).call(this,require("buffer").Buffer) },{"buffer":2}],136:[function(require,module,exports){ 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 = require('./sha') exports.sha1 = require('./sha1') exports.sha224 = require('./sha224') exports.sha256 = require('./sha256') exports.sha384 = require('./sha384') exports.sha512 = require('./sha512') },{"./sha":137,"./sha1":138,"./sha224":139,"./sha256":140,"./sha384":141,"./sha512":142}],137:[function(require,module,exports){ (function (Buffer){ /* * 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 = require('inherits') var Hash = require('./hash') 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 | 0 this._b = 0xefcdab89 | 0 this._c = 0x98badcfe | 0 this._d = 0x10325476 | 0 this._e = 0xc3d2e1f0 | 0 return this } /* * Bitwise rotate a 32-bit number to the left. */ function rol (num, cnt) { return (num << cnt) | (num >>> (32 - cnt)) } Sha.prototype._update = function (M) { var W = this._w var a = this._a var b = this._b var c = this._c var d = this._d var e = this._e var j = 0 var k /* * SHA-1 has a bitwise rotate left operation. But, SHA is not * function calcW() { return rol(W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16], 1) } */ function calcW () { return W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16] } function loop (w, f) { W[j] = w var t = rol(a, 5) + f + e + w + k e = d d = c c = rol(b, 30) b = a a = t j++ } k = 1518500249 while (j < 16) loop(M.readInt32BE(j * 4), (b & c) | ((~b) & d)) while (j < 20) loop(calcW(), (b & c) | ((~b) & d)) k = 1859775393 while (j < 40) loop(calcW(), b ^ c ^ d) k = -1894007588 while (j < 60) loop(calcW(), (b & c) | (b & d) | (c & d)) k = -899497514 while (j < 80) loop(calcW(), b ^ c ^ d) 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 = new Buffer(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 }).call(this,require("buffer").Buffer) },{"./hash":135,"buffer":2,"inherits":199}],138:[function(require,module,exports){ (function (Buffer){ /* * 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 = require('inherits') var Hash = require('./hash') 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 | 0 this._b = 0xefcdab89 | 0 this._c = 0x98badcfe | 0 this._d = 0x10325476 | 0 this._e = 0xc3d2e1f0 | 0 return this } /* * Bitwise rotate a 32-bit number to the left. */ function rol (num, cnt) { return (num << cnt) | (num >>> (32 - cnt)) } Sha1.prototype._update = function (M) { var W = this._w var a = this._a var b = this._b var c = this._c var d = this._d var e = this._e var j = 0 var k function calcW () { return rol(W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16], 1) } function loop (w, f) { W[j] = w var t = rol(a, 5) + f + e + w + k e = d d = c c = rol(b, 30) b = a a = t j++ } k = 1518500249 while (j < 16) loop(M.readInt32BE(j * 4), (b & c) | ((~b) & d)) while (j < 20) loop(calcW(), (b & c) | ((~b) & d)) k = 1859775393 while (j < 40) loop(calcW(), b ^ c ^ d) k = -1894007588 while (j < 60) loop(calcW(), (b & c) | (b & d) | (c & d)) k = -899497514 while (j < 80) loop(calcW(), b ^ c ^ d) 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 = new Buffer(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 }).call(this,require("buffer").Buffer) },{"./hash":135,"buffer":2,"inherits":199}],139:[function(require,module,exports){ (function (Buffer){ /** * 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 = require('inherits') var Sha256 = require('./sha256') var Hash = require('./hash') 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 | 0 this._b = 0x367cd507 | 0 this._c = 0x3070dd17 | 0 this._d = 0xf70e5939 | 0 this._e = 0xffc00b31 | 0 this._f = 0x68581511 | 0 this._g = 0x64f98fa7 | 0 this._h = 0xbefa4fa4 | 0 return this } Sha224.prototype._hash = function () { var H = new Buffer(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 }).call(this,require("buffer").Buffer) },{"./hash":135,"./sha256":140,"buffer":2,"inherits":199}],140:[function(require,module,exports){ (function (Buffer){ /** * 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 = require('inherits') var Hash = require('./hash') 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 | 0 this._b = 0xbb67ae85 | 0 this._c = 0x3c6ef372 | 0 this._d = 0xa54ff53a | 0 this._e = 0x510e527f | 0 this._f = 0x9b05688c | 0 this._g = 0x1f83d9ab | 0 this._h = 0x5be0cd19 | 0 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 var j = 0 function calcW () { return Gamma1(W[j - 2]) + W[j - 7] + Gamma0(W[j - 15]) + W[j - 16] } function loop (w) { W[j] = w var T1 = h + Sigma1(e) + Ch(e, f, g) + K[j] + w var T2 = Sigma0(a) + Maj(a, b, c) h = g g = f f = e e = d + T1 d = c c = b b = a a = T1 + T2 j++ } while (j < 16) loop(M.readInt32BE(j * 4)) while (j < 64) loop(calcW()) 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 = new Buffer(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 }).call(this,require("buffer").Buffer) },{"./hash":135,"buffer":2,"inherits":199}],141:[function(require,module,exports){ (function (Buffer){ var inherits = require('inherits') var SHA512 = require('./sha512') var Hash = require('./hash') 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._a = 0xcbbb9d5d | 0 this._b = 0x629a292a | 0 this._c = 0x9159015a | 0 this._d = 0x152fecd8 | 0 this._e = 0x67332667 | 0 this._f = 0x8eb44a87 | 0 this._g = 0xdb0c2e0d | 0 this._h = 0x47b5481d | 0 this._al = 0xc1059ed8 | 0 this._bl = 0x367cd507 | 0 this._cl = 0x3070dd17 | 0 this._dl = 0xf70e5939 | 0 this._el = 0xffc00b31 | 0 this._fl = 0x68581511 | 0 this._gl = 0x64f98fa7 | 0 this._hl = 0xbefa4fa4 | 0 return this } Sha384.prototype._hash = function () { var H = new Buffer(48) function writeInt64BE (h, l, offset) { H.writeInt32BE(h, offset) H.writeInt32BE(l, offset + 4) } writeInt64BE(this._a, this._al, 0) writeInt64BE(this._b, this._bl, 8) writeInt64BE(this._c, this._cl, 16) writeInt64BE(this._d, this._dl, 24) writeInt64BE(this._e, this._el, 32) writeInt64BE(this._f, this._fl, 40) return H } module.exports = Sha384 }).call(this,require("buffer").Buffer) },{"./hash":135,"./sha512":142,"buffer":2,"inherits":199}],142:[function(require,module,exports){ (function (Buffer){ var inherits = require('inherits') var Hash = require('./hash') 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._a = 0x6a09e667 | 0 this._b = 0xbb67ae85 | 0 this._c = 0x3c6ef372 | 0 this._d = 0xa54ff53a | 0 this._e = 0x510e527f | 0 this._f = 0x9b05688c | 0 this._g = 0x1f83d9ab | 0 this._h = 0x5be0cd19 | 0 this._al = 0xf3bcc908 | 0 this._bl = 0x84caa73b | 0 this._cl = 0xfe94f82b | 0 this._dl = 0x5f1d36f1 | 0 this._el = 0xade682d1 | 0 this._fl = 0x2b3e6c1f | 0 this._gl = 0xfb41bd6b | 0 this._hl = 0x137e2179 | 0 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) } Sha512.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 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 var i = 0 var j = 0 var Wi, Wil function calcW () { var x = W[j - 15 * 2] var xl = W[j - 15 * 2 + 1] var gamma0 = Gamma0(x, xl) var gamma0l = Gamma0l(xl, x) x = W[j - 2 * 2] xl = W[j - 2 * 2 + 1] var gamma1 = Gamma1(x, xl) var gamma1l = Gamma1l(xl, x) // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16] var Wi7 = W[j - 7 * 2] var Wi7l = W[j - 7 * 2 + 1] var Wi16 = W[j - 16 * 2] var Wi16l = W[j - 16 * 2 + 1] Wil = gamma0l + Wi7l Wi = gamma0 + Wi7 + ((Wil >>> 0) < (gamma0l >>> 0) ? 1 : 0) Wil = Wil + gamma1l Wi = Wi + gamma1 + ((Wil >>> 0) < (gamma1l >>> 0) ? 1 : 0) Wil = Wil + Wi16l Wi = Wi + Wi16 + ((Wil >>> 0) < (Wi16l >>> 0) ? 1 : 0) } function loop () { W[j] = Wi W[j + 1] = Wil var maj = Maj(a, b, c) var majl = Maj(al, bl, cl) var sigma0h = Sigma0(a, al) var sigma0l = Sigma0(al, a) var sigma1h = Sigma1(e, el) var sigma1l = Sigma1(el, e) // t1 = h + sigma1 + ch + K[i] + W[i] var Ki = K[j] var Kil = K[j + 1] var ch = Ch(e, f, g) var chl = Ch(el, fl, gl) var t1l = hl + sigma1l var t1 = h + sigma1h + ((t1l >>> 0) < (hl >>> 0) ? 1 : 0) t1l = t1l + chl t1 = t1 + ch + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0) t1l = t1l + Kil t1 = t1 + Ki + ((t1l >>> 0) < (Kil >>> 0) ? 1 : 0) t1l = t1l + Wil t1 = t1 + Wi + ((t1l >>> 0) < (Wil >>> 0) ? 1 : 0) // t2 = sigma0 + maj var t2l = sigma0l + majl var t2 = sigma0h + maj + ((t2l >>> 0) < (sigma0l >>> 0) ? 1 : 0) h = g hl = gl g = f gl = fl f = e fl = el el = (dl + t1l) | 0 e = (d + t1 + ((el >>> 0) < (dl >>> 0) ? 1 : 0)) | 0 d = c dl = cl c = b cl = bl b = a bl = al al = (t1l + t2l) | 0 a = (t1 + t2 + ((al >>> 0) < (t1l >>> 0) ? 1 : 0)) | 0 i++ j += 2 } while (i < 16) { Wi = M.readInt32BE(j * 4) Wil = M.readInt32BE(j * 4 + 4) loop() } while (i < 80) { calcW() loop() } 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._a = (this._a + a + ((this._al >>> 0) < (al >>> 0) ? 1 : 0)) | 0 this._b = (this._b + b + ((this._bl >>> 0) < (bl >>> 0) ? 1 : 0)) | 0 this._c = (this._c + c + ((this._cl >>> 0) < (cl >>> 0) ? 1 : 0)) | 0 this._d = (this._d + d + ((this._dl >>> 0) < (dl >>> 0) ? 1 : 0)) | 0 this._e = (this._e + e + ((this._el >>> 0) < (el >>> 0) ? 1 : 0)) | 0 this._f = (this._f + f + ((this._fl >>> 0) < (fl >>> 0) ? 1 : 0)) | 0 this._g = (this._g + g + ((this._gl >>> 0) < (gl >>> 0) ? 1 : 0)) | 0 this._h = (this._h + h + ((this._hl >>> 0) < (hl >>> 0) ? 1 : 0)) | 0 } Sha512.prototype._hash = function () { var H = new Buffer(64) function writeInt64BE (h, l, offset) { H.writeInt32BE(h, offset) H.writeInt32BE(l, offset + 4) } writeInt64BE(this._a, this._al, 0) writeInt64BE(this._b, this._bl, 8) writeInt64BE(this._c, this._cl, 16) writeInt64BE(this._d, this._dl, 24) writeInt64BE(this._e, this._el, 32) writeInt64BE(this._f, this._fl, 40) writeInt64BE(this._g, this._gl, 48) writeInt64BE(this._h, this._hl, 56) return H } module.exports = Sha512 }).call(this,require("buffer").Buffer) },{"./hash":135,"buffer":2,"inherits":199}],143:[function(require,module,exports){ (function (Buffer){ 'use strict'; var createHash = require('create-hash/browser'); var inherits = require('inherits') var Transform = require('stream').Transform var ZEROS = new Buffer(128) ZEROS.fill(0) function Hmac(alg, key) { Transform.call(this) alg = alg.toLowerCase() if (typeof key === 'string') { key = new Buffer(key) } var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64 this._alg = alg this._key = key if (key.length > blocksize) { key = createHash(alg).update(key).digest() } else if (key.length < blocksize) { key = Buffer.concat([key, ZEROS], blocksize) } var ipad = this._ipad = new Buffer(blocksize) var opad = this._opad = new Buffer(blocksize) for (var i = 0; i < blocksize; i++) { ipad[i] = key[i] ^ 0x36 opad[i] = key[i] ^ 0x5C } this._hash = createHash(alg).update(ipad) } inherits(Hmac, Transform) Hmac.prototype.update = function (data, enc) { this._hash.update(data, enc) return this } Hmac.prototype._transform = function (data, _, next) { this._hash.update(data) next() } Hmac.prototype._flush = function (next) { this.push(this.digest()) next() } Hmac.prototype.digest = function (enc) { var h = this._hash.digest() return createHash(this._alg).update(this._opad).update(h).digest(enc) } module.exports = function createHmac(alg, key) { return new Hmac(alg, key) } }).call(this,require("buffer").Buffer) },{"buffer":2,"create-hash/browser":130,"inherits":199,"stream":216}],144:[function(require,module,exports){ (function (Buffer){ var generatePrime = require('./lib/generatePrime') var primes = require('./lib/primes.json') var DH = require('./lib/dh') 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 }).call(this,require("buffer").Buffer) },{"./lib/dh":145,"./lib/generatePrime":146,"./lib/primes.json":147,"buffer":2}],145:[function(require,module,exports){ (function (Buffer){ var BN = require('bn.js'); var MillerRabin = require('miller-rabin'); 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 = require('./generatePrime'); var randomBytes = require('randombytes'); 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); } } }).call(this,require("buffer").Buffer) },{"./generatePrime":146,"bn.js":148,"buffer":2,"miller-rabin":149,"randombytes":197}],146:[function(require,module,exports){ var randomBytes = require('randombytes'); module.exports = findPrime; findPrime.simpleSieve = simpleSieve; findPrime.fermatTest = fermatTest; var BN = require('bn.js'); var TWENTYFOUR = new BN(24); var MillerRabin = require('miller-rabin'); 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; } } } },{"bn.js":148,"miller-rabin":149,"randombytes":197}],147:[function(require,module,exports){ module.exports={ "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" } } },{}],148:[function(require,module,exports){ arguments[4][39][0].apply(exports,arguments) },{"buffer":1,"dup":39}],149:[function(require,module,exports){ var bn = require('bn.js'); var brorand = require('brorand'); function MillerRabin(rand) { this.rand = rand || new brorand.Rand(); } module.exports = MillerRabin; MillerRabin.create = function create(rand) { return new MillerRabin(rand); }; MillerRabin.prototype._rand = function _rand(n) { var len = n.bitLength(); var buf = this.rand.generate(Math.ceil(len / 8)); // Set low bits buf[0] |= 3; // Mask high bits var mask = len & 0x7; if (mask !== 0) buf[buf.length - 1] >>= 7 - mask; return new bn(buf); } 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); var n2 = n1.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._rand(n2); 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); var n2 = n1.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._rand(n2); 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; }; },{"bn.js":148,"brorand":150}],150:[function(require,module,exports){ arguments[4][57][0].apply(exports,arguments) },{"dup":57}],151:[function(require,module,exports){ (function (Buffer){ var createHmac = require('create-hmac') var MAX_ALLOC = Math.pow(2, 30) - 1 // default in iojs exports.pbkdf2 = pbkdf2 function pbkdf2 (password, salt, iterations, keylen, digest, callback) { if (typeof digest === 'function') { callback = digest digest = undefined } if (typeof callback !== 'function') { throw new Error('No callback provided to pbkdf2') } var result = pbkdf2Sync(password, salt, iterations, keylen, digest) setTimeout(function () { callback(undefined, result) }) } exports.pbkdf2Sync = pbkdf2Sync function pbkdf2Sync (password, salt, iterations, keylen, digest) { 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) { throw new TypeError('Bad key length') } digest = digest || 'sha1' if (!Buffer.isBuffer(password)) password = new Buffer(password, 'binary') if (!Buffer.isBuffer(salt)) salt = new Buffer(salt, 'binary') var hLen var l = 1 var DK = new Buffer(keylen) var block1 = new Buffer(salt.length + 4) salt.copy(block1, 0, 0, salt.length) var r var T for (var i = 1; i <= l; i++) { block1.writeUInt32BE(i, salt.length) var U = createHmac(digest, password).update(block1).digest() if (!hLen) { hLen = U.length T = new Buffer(hLen) l = Math.ceil(keylen / hLen) r = keylen - (l - 1) * hLen } U.copy(T, 0, 0, hLen) for (var j = 1; j < iterations; j++) { U = createHmac(digest, password).update(U).digest() for (var k = 0; k < hLen; k++) { T[k] ^= U[k] } } var destPos = (i - 1) * hLen var len = (i === l ? r : hLen) T.copy(DK, destPos, 0, len) } return DK } }).call(this,require("buffer").Buffer) },{"buffer":2,"create-hmac":143}],152:[function(require,module,exports){ exports.publicEncrypt = require('./publicEncrypt'); exports.privateDecrypt = require('./privateDecrypt'); exports.privateEncrypt = function privateEncrypt(key, buf) { return exports.publicEncrypt(key, buf, true); }; exports.publicDecrypt = function publicDecrypt(key, buf) { return exports.privateDecrypt(key, buf, true); }; },{"./privateDecrypt":193,"./publicEncrypt":194}],153:[function(require,module,exports){ (function (Buffer){ var createHash = require('create-hash'); module.exports = function (seed, len) { var t = new Buffer(''); var i = 0, 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 = new Buffer(4); out.writeUInt32BE(c,0); return out; } }).call(this,require("buffer").Buffer) },{"buffer":2,"create-hash":130}],154:[function(require,module,exports){ arguments[4][39][0].apply(exports,arguments) },{"buffer":1,"dup":39}],155:[function(require,module,exports){ (function (Buffer){ var bn = require('bn.js'); var randomBytes = require('randombytes'); 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; } }).call(this,require("buffer").Buffer) },{"bn.js":154,"buffer":2,"randombytes":197}],156:[function(require,module,exports){ arguments[4][65][0].apply(exports,arguments) },{"dup":65}],157:[function(require,module,exports){ arguments[4][66][0].apply(exports,arguments) },{"asn1.js":160,"dup":66}],158:[function(require,module,exports){ (function (Buffer){ // adapted from https://github.com/apatil/pemstrip var findProc = /Proc-Type: 4,ENCRYPTED\r?\nDEK-Info: AES-((?:128)|(?:192)|(?:256))-CBC,([0-9A-H]+)\r?\n\r?\n([0-9A-z\n\r\+\/\=]+)\r?\n/m var startRegex = /^-----BEGIN (.*) KEY-----\r?\n/m var fullRegex = /^-----BEGIN (.*) KEY-----\r?\n([0-9A-z\n\r\+\/\=]+)\r?\n-----END \1 KEY-----$/m var evp = require('evp_bytestokey') var ciphers = require('browserify-aes') 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 = new Buffer(match[2], 'hex') var cipherText = new Buffer(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] + ' KEY' return { tag: tag, data: decrypted } } }).call(this,require("buffer").Buffer) },{"browserify-aes":177,"buffer":2,"evp_bytestokey":192}],159:[function(require,module,exports){ (function (Buffer){ var asn1 = require('./asn1') var aesid = require('./aesid.json') var fixProc = require('./fixProc') var ciphers = require('browserify-aes') var compat = require('pbkdf2') 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 = new Buffer(buffer) } var stripped = fixProc(buffer, password) var type = stripped.tag var data = stripped.data var subtype, ndata switch (type) { case 'PUBLIC KEY': 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) var cipher = ciphers.createDecipheriv(algo, key, iv) var out = [] out.push(cipher.update(cipherText)) out.push(cipher.final()) return Buffer.concat(out) } }).call(this,require("buffer").Buffer) },{"./aesid.json":156,"./asn1":157,"./fixProc":158,"browserify-aes":177,"buffer":2,"pbkdf2":151}],160:[function(require,module,exports){ arguments[4][69][0].apply(exports,arguments) },{"./asn1/api":161,"./asn1/base":163,"./asn1/constants":167,"./asn1/decoders":169,"./asn1/encoders":172,"bn.js":154,"dup":69}],161:[function(require,module,exports){ arguments[4][70][0].apply(exports,arguments) },{"../asn1":160,"dup":70,"inherits":199,"vm":218}],162:[function(require,module,exports){ arguments[4][71][0].apply(exports,arguments) },{"../base":163,"buffer":2,"dup":71,"inherits":199}],163:[function(require,module,exports){ arguments[4][72][0].apply(exports,arguments) },{"./buffer":162,"./node":164,"./reporter":165,"dup":72}],164:[function(require,module,exports){ arguments[4][73][0].apply(exports,arguments) },{"../base":163,"dup":73,"minimalistic-assert":174}],165:[function(require,module,exports){ arguments[4][74][0].apply(exports,arguments) },{"dup":74,"inherits":199}],166:[function(require,module,exports){ arguments[4][75][0].apply(exports,arguments) },{"../constants":167,"dup":75}],167:[function(require,module,exports){ arguments[4][76][0].apply(exports,arguments) },{"./der":166,"dup":76}],168:[function(require,module,exports){ arguments[4][77][0].apply(exports,arguments) },{"../../asn1":160,"dup":77,"inherits":199}],169:[function(require,module,exports){ arguments[4][78][0].apply(exports,arguments) },{"./der":168,"./pem":170,"dup":78}],170:[function(require,module,exports){ arguments[4][79][0].apply(exports,arguments) },{"../../asn1":160,"./der":168,"buffer":2,"dup":79,"inherits":199}],171:[function(require,module,exports){ arguments[4][80][0].apply(exports,arguments) },{"../../asn1":160,"buffer":2,"dup":80,"inherits":199}],172:[function(require,module,exports){ arguments[4][81][0].apply(exports,arguments) },{"./der":171,"./pem":173,"dup":81}],173:[function(require,module,exports){ arguments[4][82][0].apply(exports,arguments) },{"../../asn1":160,"./der":171,"buffer":2,"dup":82,"inherits":199}],174:[function(require,module,exports){ arguments[4][34][0].apply(exports,arguments) },{"dup":34}],175:[function(require,module,exports){ (function (Buffer){ // 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 uint_max = Math.pow(2, 32) function fixup_uint32 (x) { var ret, x_pos ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x return ret } function scrub_vec (v) { for (var i = 0; i < v.length; v++) { v[i] = 0 } return false } function Global () { this.SBOX = [] this.INV_SBOX = [] this.SUB_MIX = [[], [], [], []] this.INV_SUB_MIX = [[], [], [], []] this.init() this.RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36] } Global.prototype.init = function () { var d, i, sx, t, x, x2, x4, x8, xi, _i d = (function () { var _i, _results _results = [] for (i = _i = 0; _i < 256; i = ++_i) { if (i < 128) { _results.push(i << 1) } else { _results.push((i << 1) ^ 0x11b) } } return _results })() x = 0 xi = 0 for (i = _i = 0; _i < 256; i = ++_i) { sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4) sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63 this.SBOX[x] = sx this.INV_SBOX[sx] = x x2 = d[x] x4 = d[x2] x8 = d[x4] t = (d[sx] * 0x101) ^ (sx * 0x1010100) this.SUB_MIX[0][x] = (t << 24) | (t >>> 8) this.SUB_MIX[1][x] = (t << 16) | (t >>> 16) this.SUB_MIX[2][x] = (t << 8) | (t >>> 24) this.SUB_MIX[3][x] = t t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100) this.INV_SUB_MIX[0][sx] = (t << 24) | (t >>> 8) this.INV_SUB_MIX[1][sx] = (t << 16) | (t >>> 16) this.INV_SUB_MIX[2][sx] = (t << 8) | (t >>> 24) this.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 true } var G = new Global() AES.blockSize = 4 * 4 AES.prototype.blockSize = AES.blockSize AES.keySize = 256 / 8 AES.prototype.keySize = AES.keySize function bufferToArray (buf) { var len = buf.length / 4 var out = new Array(len) var i = -1 while (++i < len) { out[i] = buf.readUInt32BE(i * 4) } return out } function AES (key) { this._key = bufferToArray(key) this._doReset() } AES.prototype._doReset = function () { var invKsRow, keySize, keyWords, ksRow, ksRows, t keyWords = this._key keySize = keyWords.length this._nRounds = keySize + 6 ksRows = (this._nRounds + 1) * 4 this._keySchedule = [] for (ksRow = 0; ksRow < ksRows; ksRow++) { this._keySchedule[ksRow] = ksRow < keySize ? keyWords[ksRow] : (t = this._keySchedule[ksRow - 1], (ksRow % 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 ^= G.RCON[(ksRow / keySize) | 0] << 24) : keySize > 6 && ksRow % keySize === 4 ? t = (G.SBOX[t >>> 24] << 24) | (G.SBOX[(t >>> 16) & 0xff] << 16) | (G.SBOX[(t >>> 8) & 0xff] << 8) | G.SBOX[t & 0xff] : void 0, this._keySchedule[ksRow - keySize] ^ t) } this._invKeySchedule = [] for (invKsRow = 0; invKsRow < ksRows; invKsRow++) { ksRow = ksRows - invKsRow t = this._keySchedule[ksRow - (invKsRow % 4 ? 0 : 4)] this._invKeySchedule[invKsRow] = invKsRow < 4 || ksRow <= 4 ? t : G.INV_SUB_MIX[0][G.SBOX[t >>> 24]] ^ G.INV_SUB_MIX[1][G.SBOX[(t >>> 16) & 0xff]] ^ G.INV_SUB_MIX[2][G.SBOX[(t >>> 8) & 0xff]] ^ G.INV_SUB_MIX[3][G.SBOX[t & 0xff]] } return true } AES.prototype.encryptBlock = function (M) { M = bufferToArray(new Buffer(M)) var out = this._doCryptBlock(M, this._keySchedule, G.SUB_MIX, G.SBOX) var buf = new Buffer(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 = bufferToArray(new Buffer(M)) var temp = [M[3], M[1]] M[1] = temp[0] M[3] = temp[1] var out = this._doCryptBlock(M, this._invKeySchedule, G.INV_SUB_MIX, G.INV_SBOX) var buf = new Buffer(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 () { scrub_vec(this._keySchedule) scrub_vec(this._invKeySchedule) scrub_vec(this._key) } AES.prototype._doCryptBlock = function (M, keySchedule, SUB_MIX, SBOX) { var ksRow, s0, s1, s2, s3, t0, t1, t2, t3 s0 = M[0] ^ keySchedule[0] s1 = M[1] ^ keySchedule[1] s2 = M[2] ^ keySchedule[2] s3 = M[3] ^ keySchedule[3] ksRow = 4 for (var round = 1; round < this._nRounds; round++) { 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++] 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++] 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++] 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++] 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++] return [ fixup_uint32(t0), fixup_uint32(t1), fixup_uint32(t2), fixup_uint32(t3) ] } exports.AES = AES }).call(this,require("buffer").Buffer) },{"buffer":2}],176:[function(require,module,exports){ (function (Buffer){ var aes = require('./aes') var Transform = require('cipher-base') var inherits = require('inherits') var GHASH = require('./ghash') var xor = require('buffer-xor') inherits(StreamCipher, Transform) module.exports = StreamCipher function StreamCipher (mode, key, iv, decrypt) { if (!(this instanceof StreamCipher)) { return new StreamCipher(mode, key, iv) } Transform.call(this) this._finID = Buffer.concat([iv, new Buffer([0, 0, 0, 1])]) iv = Buffer.concat([iv, new Buffer([0, 0, 0, 2])]) this._cipher = new aes.AES(key) this._prev = new Buffer(iv.length) this._cache = new Buffer('') this._secCache = new Buffer('') this._decrypt = decrypt this._alen = 0 this._len = 0 iv.copy(this._prev) this._mode = mode var h = new Buffer(4) h.fill(0) this._ghash = new GHASH(this._cipher.encryptBlock(h)) this._authTag = null this._called = false } StreamCipher.prototype._update = function (chunk) { if (!this._called && this._alen) { var rump = 16 - (this._alen % 16) if (rump < 16) { rump = new Buffer(rump) rump.fill(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) { if (xorTest(tag, this._authTag)) { throw new Error('Unsupported state or unable to authenticate data') } } else { this._authTag = tag } this._cipher.scrub() } StreamCipher.prototype.getAuthTag = function getAuthTag () { if (!this._decrypt && Buffer.isBuffer(this._authTag)) { return this._authTag } else { throw new Error('Attempting to get auth tag in unsupported state') } } StreamCipher.prototype.setAuthTag = function setAuthTag (tag) { if (this._decrypt) { this._authTag = tag } else { throw new Error('Attempting to set auth tag in unsupported state') } } StreamCipher.prototype.setAAD = function setAAD (buf) { if (!this._called) { this._ghash.update(buf) this._alen += buf.length } else { throw new Error('Attempting to set AAD in unsupported state') } } function xorTest (a, b) { var out = 0 if (a.length !== b.length) { out++ } var len = Math.min(a.length, b.length) var i = -1 while (++i < len) { out += (a[i] ^ b[i]) } return out } }).call(this,require("buffer").Buffer) },{"./aes":175,"./ghash":180,"buffer":2,"buffer-xor":189,"cipher-base":190,"inherits":199}],177:[function(require,module,exports){ arguments[4][10][0].apply(exports,arguments) },{"./decrypter":178,"./encrypter":179,"./modes":181,"dup":10}],178:[function(require,module,exports){ (function (Buffer){ var aes = require('./aes') var Transform = require('cipher-base') var inherits = require('inherits') var modes = require('./modes') var StreamCipher = require('./streamCipher') var AuthCipher = require('./authCipher') var ebtk = require('evp_bytestokey') inherits(Decipher, Transform) function Decipher (mode, key, iv) { if (!(this instanceof Decipher)) { return new Decipher(mode, key, iv) } Transform.call(this) this._cache = new Splitter() this._last = void 0 this._cipher = new aes.AES(key) this._prev = new Buffer(iv.length) iv.copy(this._prev) this._mode = mode this._autopadding = true } 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 () { if (!(this instanceof Splitter)) { return new Splitter() } this.cache = new Buffer('') } 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] 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) } var modelist = { ECB: require('./modes/ecb'), CBC: require('./modes/cbc'), CFB: require('./modes/cfb'), CFB8: require('./modes/cfb8'), CFB1: require('./modes/cfb1'), OFB: require('./modes/ofb'), CTR: require('./modes/ctr'), GCM: require('./modes/ctr') } function createDecipheriv (suite, password, iv) { var config = modes[suite.toLowerCase()] if (!config) { throw new TypeError('invalid suite type') } if (typeof iv === 'string') { iv = new Buffer(iv) } if (typeof password === 'string') { password = new Buffer(password) } if (password.length !== config.key / 8) { throw new TypeError('invalid key length ' + password.length) } if (iv.length !== config.iv) { throw new TypeError('invalid iv length ' + iv.length) } if (config.type === 'stream') { return new StreamCipher(modelist[config.mode], password, iv, true) } else if (config.type === 'auth') { return new AuthCipher(modelist[config.mode], password, iv, true) } return new Decipher(modelist[config.mode], 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 }).call(this,require("buffer").Buffer) },{"./aes":175,"./authCipher":176,"./modes":181,"./modes/cbc":182,"./modes/cfb":183,"./modes/cfb1":184,"./modes/cfb8":185,"./modes/ctr":186,"./modes/ecb":187,"./modes/ofb":188,"./streamCipher":191,"buffer":2,"cipher-base":190,"evp_bytestokey":192,"inherits":199}],179:[function(require,module,exports){ (function (Buffer){ var aes = require('./aes') var Transform = require('cipher-base') var inherits = require('inherits') var modes = require('./modes') var ebtk = require('evp_bytestokey') var StreamCipher = require('./streamCipher') var AuthCipher = require('./authCipher') inherits(Cipher, Transform) function Cipher (mode, key, iv) { if (!(this instanceof Cipher)) { return new Cipher(mode, key, iv) } Transform.call(this) this._cache = new Splitter() this._cipher = new aes.AES(key) this._prev = new Buffer(iv.length) iv.copy(this._prev) this._mode = mode this._autopadding = true } 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) } Cipher.prototype._final = function () { var chunk = this._cache.flush() if (this._autopadding) { chunk = this._mode.encrypt(this, chunk) this._cipher.scrub() return chunk } else if (chunk.toString('hex') !== '10101010101010101010101010101010') { this._cipher.scrub() throw new Error('data not multiple of block length') } } Cipher.prototype.setAutoPadding = function (setTo) { this._autopadding = !!setTo return this } function Splitter () { if (!(this instanceof Splitter)) { return new Splitter() } this.cache = new Buffer('') } 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 = new Buffer(len) var i = -1 while (++i < len) { padBuff.writeUInt8(len, i) } var out = Buffer.concat([this.cache, padBuff]) return out } var modelist = { ECB: require('./modes/ecb'), CBC: require('./modes/cbc'), CFB: require('./modes/cfb'), CFB8: require('./modes/cfb8'), CFB1: require('./modes/cfb1'), OFB: require('./modes/ofb'), CTR: require('./modes/ctr'), GCM: require('./modes/ctr') } function createCipheriv (suite, password, iv) { var config = modes[suite.toLowerCase()] if (!config) { throw new TypeError('invalid suite type') } if (typeof iv === 'string') { iv = new Buffer(iv) } if (typeof password === 'string') { password = new Buffer(password) } if (password.length !== config.key / 8) { throw new TypeError('invalid key length ' + password.length) } if (iv.length !== config.iv) { throw new TypeError('invalid iv length ' + iv.length) } if (config.type === 'stream') { return new StreamCipher(modelist[config.mode], password, iv) } else if (config.type === 'auth') { return new AuthCipher(modelist[config.mode], password, iv) } return new Cipher(modelist[config.mode], 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 }).call(this,require("buffer").Buffer) },{"./aes":175,"./authCipher":176,"./modes":181,"./modes/cbc":182,"./modes/cfb":183,"./modes/cfb1":184,"./modes/cfb8":185,"./modes/ctr":186,"./modes/ecb":187,"./modes/ofb":188,"./streamCipher":191,"buffer":2,"cipher-base":190,"evp_bytestokey":192,"inherits":199}],180:[function(require,module,exports){ (function (Buffer){ var zeros = new Buffer(16) zeros.fill(0) module.exports = GHASH function GHASH (key) { this.h = key this.state = new Buffer(16) this.state.fill(0) this.cache = new Buffer('') } // 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, lsb_Vi 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 = xor(Zi, Vi) } // Store the value of LSB(V_i) lsb_Vi = (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 (lsb_Vi) { 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, zeros], 16)) } this.ghash(fromArray([ 0, abl, 0, bl ])) return this.state } function toArray (buf) { return [ buf.readUInt32BE(0), buf.readUInt32BE(4), buf.readUInt32BE(8), buf.readUInt32BE(12) ] } function fromArray (out) { out = out.map(fixup_uint32) var buf = new Buffer(16) buf.writeUInt32BE(out[0], 0) buf.writeUInt32BE(out[1], 4) buf.writeUInt32BE(out[2], 8) buf.writeUInt32BE(out[3], 12) return buf } var uint_max = Math.pow(2, 32) function fixup_uint32 (x) { var ret, x_pos ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x return ret } function xor (a, b) { return [ a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3] ] } }).call(this,require("buffer").Buffer) },{"buffer":2}],181:[function(require,module,exports){ arguments[4][14][0].apply(exports,arguments) },{"dup":14}],182:[function(require,module,exports){ arguments[4][15][0].apply(exports,arguments) },{"buffer-xor":189,"dup":15}],183:[function(require,module,exports){ (function (Buffer){ var xor = require('buffer-xor') exports.encrypt = function (self, data, decrypt) { var out = new Buffer('') var len while (data.length) { if (self._cache.length === 0) { self._cache = self._cipher.encryptBlock(self._prev) self._prev = new Buffer('') } 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 } 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 } }).call(this,require("buffer").Buffer) },{"buffer":2,"buffer-xor":189}],184:[function(require,module,exports){ (function (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 } exports.encrypt = function (self, chunk, decrypt) { var len = chunk.length var out = new Buffer(len) var i = -1 while (++i < len) { out[i] = encryptByte(self, chunk[i], decrypt) } return out } function shiftIn (buffer, value) { var len = buffer.length var i = -1 var out = new Buffer(buffer.length) buffer = Buffer.concat([buffer, new Buffer([value])]) while (++i < len) { out[i] = buffer[i] << 1 | buffer[i + 1] >> (7) } return out } }).call(this,require("buffer").Buffer) },{"buffer":2}],185:[function(require,module,exports){ (function (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), new Buffer([decrypt ? byteParam : out])]) return out } exports.encrypt = function (self, chunk, decrypt) { var len = chunk.length var out = new Buffer(len) var i = -1 while (++i < len) { out[i] = encryptByte(self, chunk[i], decrypt) } return out } }).call(this,require("buffer").Buffer) },{"buffer":2}],186:[function(require,module,exports){ (function (Buffer){ var xor = require('buffer-xor') 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 } } } function getBlock (self) { var out = self._cipher.encryptBlock(self._prev) incr32(self._prev) return out } 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) } }).call(this,require("buffer").Buffer) },{"buffer":2,"buffer-xor":189}],187:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"dup":20}],188:[function(require,module,exports){ (function (Buffer){ var xor = require('buffer-xor') 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) } }).call(this,require("buffer").Buffer) },{"buffer":2,"buffer-xor":189}],189:[function(require,module,exports){ (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 } }).call(this,require("buffer").Buffer) },{"buffer":2}],190:[function(require,module,exports){ (function (Buffer){ var Transform = require('stream').Transform var inherits = require('inherits') var StringDecoder = require('string_decoder').StringDecoder module.exports = CipherBase inherits(CipherBase, Transform) function CipherBase (hashMode) { Transform.call(this) this.hashMode = typeof hashMode === 'string' if (this.hashMode) { this[hashMode] = this._finalOrDigest } else { this.final = this._finalOrDigest } this._decoder = null this._encoding = null } CipherBase.prototype.update = function (data, inputEnc, outputEnc) { if (typeof data === 'string') { data = new Buffer(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 } finally { done(err) } } CipherBase.prototype._finalOrDigest = function (outputEnc) { var outData = this._final() || new Buffer('') if (outputEnc) { outData = this._toString(outData, outputEnc, true) } return outData } CipherBase.prototype._toString = function (value, enc, final) { 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 (final) { out += this._decoder.end() } return out } }).call(this,require("buffer").Buffer) },{"buffer":2,"inherits":199,"stream":216,"string_decoder":217}],191:[function(require,module,exports){ (function (Buffer){ var aes = require('./aes') var Transform = require('cipher-base') var inherits = require('inherits') inherits(StreamCipher, Transform) module.exports = StreamCipher function StreamCipher (mode, key, iv, decrypt) { if (!(this instanceof StreamCipher)) { return new StreamCipher(mode, key, iv) } Transform.call(this) this._cipher = new aes.AES(key) this._prev = new Buffer(iv.length) this._cache = new Buffer('') this._secCache = new Buffer('') this._decrypt = decrypt iv.copy(this._prev) this._mode = mode } StreamCipher.prototype._update = function (chunk) { return this._mode.encrypt(this, chunk, this._decrypt) } StreamCipher.prototype._final = function () { this._cipher.scrub() } }).call(this,require("buffer").Buffer) },{"./aes":175,"buffer":2,"cipher-base":190,"inherits":199}],192:[function(require,module,exports){ (function (Buffer){ var md5 = require('create-hash/md5') module.exports = EVP_BytesToKey function EVP_BytesToKey (password, salt, keyLen, ivLen) { if (!Buffer.isBuffer(password)) { password = new Buffer(password, 'binary') } if (salt && !Buffer.isBuffer(salt)) { salt = new Buffer(salt, 'binary') } keyLen = keyLen / 8 ivLen = ivLen || 0 var ki = 0 var ii = 0 var key = new Buffer(keyLen) var iv = new Buffer(ivLen) var addmd = 0 var md_buf var i var bufs = [] while (true) { if (addmd++ > 0) { bufs.push(md_buf) } bufs.push(password) if (salt) { bufs.push(salt) } md_buf = md5(Buffer.concat(bufs)) bufs = [] i = 0 if (keyLen > 0) { while (true) { if (keyLen === 0) { break } if (i === md_buf.length) { break } key[ki++] = md_buf[i] keyLen-- i++ } } if (ivLen > 0 && i !== md_buf.length) { while (true) { if (ivLen === 0) { break } if (i === md_buf.length) { break } iv[ii++] = md_buf[i] ivLen-- i++ } } if (keyLen === 0 && ivLen === 0) { break } } for (i = 0; i < md_buf.length; i++) { md_buf[i] = 0 } return { key: key, iv: iv } } }).call(this,require("buffer").Buffer) },{"buffer":2,"create-hash/md5":132}],193:[function(require,module,exports){ (function (Buffer){ var parseKeys = require('parse-asn1'); var mgf = require('./mgf'); var xor = require('./xor'); var bn = require('bn.js'); var crt = require('browserify-rsa'); var createHash = require('create-hash'); var withPublic = require('./withPublic'); module.exports = function privateDecrypt(private_key, enc, reverse) { var padding; if (private_key.padding) { padding = private_key.padding; } else if (reverse) { padding = 1; } else { padding = 4; } var key = parseKeys(private_key); 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 = new Buffer(k - msg.length); zBuffer.fill(0); 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 n = key.modulus; var k = key.modulus.byteLength(); var mLen = msg.length; var iHash = createHash('sha1').update(new Buffer('')).digest(); var hLen = iHash.length; var hLen2 = 2 * hLen; 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); var p2 = msg.slice(i - 1, i); 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 = new Buffer(a); b = new Buffer(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; } }).call(this,require("buffer").Buffer) },{"./mgf":153,"./withPublic":195,"./xor":196,"bn.js":154,"browserify-rsa":155,"buffer":2,"create-hash":130,"parse-asn1":159}],194:[function(require,module,exports){ (function (Buffer){ var parseKeys = require('parse-asn1'); var randomBytes = require('randombytes'); var createHash = require('create-hash'); var mgf = require('./mgf'); var xor = require('./xor'); var bn = require('bn.js'); var withPublic = require('./withPublic'); var crt = require('browserify-rsa'); var constants = { RSA_PKCS1_OAEP_PADDING: 4, RSA_PKCS1_PADDIN: 1, RSA_NO_PADDING: 3 }; module.exports = function publicEncrypt(public_key, msg, reverse) { var padding; if (public_key.padding) { padding = public_key.padding; } else if (reverse) { padding = 1; } else { padding = 4; } var key = parseKeys(public_key); 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(new Buffer('')).digest(); var hLen = iHash.length; var hLen2 = 2 * hLen; if (mLen > k - hLen2 - 2) { throw new Error('message too long'); } var ps = new Buffer(k - mLen - hLen2 - 2); ps.fill(0); var dblen = k - hLen - 1; var seed = randomBytes(hLen); var maskedDb = xor(Buffer.concat([iHash, ps, new Buffer([1]), msg], dblen), mgf(seed, dblen)); var maskedSeed = xor(seed, mgf(maskedDb, hLen)); return new bn(Buffer.concat([new Buffer([0]), 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 = new Buffer(k - mLen - 3); ps.fill(0xff); } else { ps = nonZero(k - mLen - 3); } return new bn(Buffer.concat([new Buffer([0, reverse?1:2]), ps, new Buffer([0]), msg], k)); } function nonZero(len, crypto) { var out = new Buffer(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; } }).call(this,require("buffer").Buffer) },{"./mgf":153,"./withPublic":195,"./xor":196,"bn.js":154,"browserify-rsa":155,"buffer":2,"create-hash":130,"parse-asn1":159,"randombytes":197}],195:[function(require,module,exports){ (function (Buffer){ var bn = require('bn.js'); function withPublic(paddedMsg, key) { return new Buffer(paddedMsg .toRed(bn.mont(key.modulus)) .redPow(new bn(key.publicExponent)) .fromRed() .toArray()); } module.exports = withPublic; }).call(this,require("buffer").Buffer) },{"bn.js":154,"buffer":2}],196:[function(require,module,exports){ module.exports = function xor(a, b) { var len = a.length; var i = -1; while (++i < len) { a[i] ^= b[i]; } return a }; },{}],197:[function(require,module,exports){ (function (process,global,Buffer){ 'use strict' function oldBrowser () { throw new Error('secure random number generation not supported by this browser\nuse chrome, FireFox or Internet Explorer 11') } 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 > 65536) throw new Error('requested too many random bytes') // in case browserify isn't using the Uint8Array version var rawBytes = new global.Uint8Array(size) // This will not work in older browsers. // See https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues crypto.getRandomValues(rawBytes) // phantomjs doesn't like a buffer being passed here var bytes = new Buffer(rawBytes.buffer) if (typeof cb === 'function') { return process.nextTick(function () { cb(null, bytes) }) } return bytes } }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) },{"_process":202,"buffer":2}],198:[function(require,module,exports){ // 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. function EventEmitter() { this._events = this._events || {}; this._maxListeners = this._maxListeners || undefined; } module.exports = EventEmitter; // Backwards-compat with node 0.10.x EventEmitter.EventEmitter = EventEmitter; EventEmitter.prototype._events = undefined; 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. EventEmitter.defaultMaxListeners = 10; // 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(n) { if (!isNumber(n) || n < 0 || isNaN(n)) throw TypeError('n must be a positive number'); this._maxListeners = n; return this; }; EventEmitter.prototype.emit = function(type) { var er, handler, len, args, i, listeners; if (!this._events) this._events = {}; // If there is no 'error' event listener then throw. if (type === 'error') { if (!this._events.error || (isObject(this._events.error) && !this._events.error.length)) { er = arguments[1]; if (er instanceof Error) { throw er; // Unhandled 'error' event } throw TypeError('Uncaught, unspecified "error" event.'); } } handler = this._events[type]; if (isUndefined(handler)) return false; if (isFunction(handler)) { switch (arguments.length) { // fast cases case 1: handler.call(this); break; case 2: handler.call(this, arguments[1]); break; case 3: handler.call(this, arguments[1], arguments[2]); break; // slower default: args = Array.prototype.slice.call(arguments, 1); handler.apply(this, args); } } else if (isObject(handler)) { args = Array.prototype.slice.call(arguments, 1); listeners = handler.slice(); len = listeners.length; for (i = 0; i < len; i++) listeners[i].apply(this, args); } return true; }; EventEmitter.prototype.addListener = function(type, listener) { var m; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events) this._events = {}; // To avoid recursion in the case that type === "newListener"! Before // adding it to the listeners, first emit "newListener". if (this._events.newListener) this.emit('newListener', type, isFunction(listener.listener) ? listener.listener : listener); if (!this._events[type]) // Optimize the case of one listener. Don't need the extra array object. this._events[type] = listener; else if (isObject(this._events[type])) // If we've already got an array, just append. this._events[type].push(listener); else // Adding the second element, need to change to array. this._events[type] = [this._events[type], listener]; // Check for listener leak if (isObject(this._events[type]) && !this._events[type].warned) { if (!isUndefined(this._maxListeners)) { m = this._maxListeners; } else { m = EventEmitter.defaultMaxListeners; } if (m && m > 0 && this._events[type].length > m) { this._events[type].warned = true; console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length); if (typeof console.trace === 'function') { // not supported in IE 10 console.trace(); } } } return this; }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.once = function(type, listener) { if (!isFunction(listener)) throw TypeError('listener must be a function'); var fired = false; function g() { this.removeListener(type, g); if (!fired) { fired = true; listener.apply(this, arguments); } } g.listener = listener; this.on(type, g); return this; }; // emits a 'removeListener' event iff the listener was removed EventEmitter.prototype.removeListener = function(type, listener) { var list, position, length, i; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events || !this._events[type]) return this; list = this._events[type]; length = list.length; position = -1; if (list === listener || (isFunction(list.listener) && list.listener === listener)) { delete this._events[type]; if (this._events.removeListener) this.emit('removeListener', type, listener); } else if (isObject(list)) { for (i = length; i-- > 0;) { if (list[i] === listener || (list[i].listener && list[i].listener === listener)) { position = i; break; } } if (position < 0) return this; if (list.length === 1) { list.length = 0; delete this._events[type]; } else { list.splice(position, 1); } if (this._events.removeListener) this.emit('removeListener', type, listener); } return this; }; EventEmitter.prototype.removeAllListeners = function(type) { var key, listeners; if (!this._events) return this; // not listening for removeListener, no need to emit if (!this._events.removeListener) { if (arguments.length === 0) this._events = {}; else if (this._events[type]) delete this._events[type]; return this; } // emit removeListener for all listeners on all events if (arguments.length === 0) { for (key in this._events) { if (key === 'removeListener') continue; this.removeAllListeners(key); } this.removeAllListeners('removeListener'); this._events = {}; return this; } listeners = this._events[type]; if (isFunction(listeners)) { this.removeListener(type, listeners); } else if (listeners) { // LIFO order while (listeners.length) this.removeListener(type, listeners[listeners.length - 1]); } delete this._events[type]; return this; }; EventEmitter.prototype.listeners = function(type) { var ret; if (!this._events || !this._events[type]) ret = []; else if (isFunction(this._events[type])) ret = [this._events[type]]; else ret = this._events[type].slice(); return ret; }; EventEmitter.prototype.listenerCount = function(type) { if (this._events) { var evlistener = this._events[type]; if (isFunction(evlistener)) return 1; else if (evlistener) return evlistener.length; } return 0; }; EventEmitter.listenerCount = function(emitter, type) { return emitter.listenerCount(type); }; function isFunction(arg) { return typeof arg === 'function'; } function isNumber(arg) { return typeof arg === 'number'; } function isObject(arg) { return typeof arg === 'object' && arg !== null; } function isUndefined(arg) { return arg === void 0; } },{}],199:[function(require,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 } } },{}],200:[function(require,module,exports){ /** * Determine if an object is Buffer * * Author: Feross Aboukhadijeh * License: MIT * * `npm install is-buffer` */ module.exports = function (obj) { return !!(obj != null && (obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor) (obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)) )) } },{}],201:[function(require,module,exports){ module.exports = Array.isArray || function (arr) { return Object.prototype.toString.call(arr) == '[object Array]'; }; },{}],202:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = setTimeout(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; clearTimeout(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) { setTimeout(drainQueue, 0); } }; // 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.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; }; },{}],203:[function(require,module,exports){ module.exports = require("./lib/_stream_duplex.js") },{"./lib/_stream_duplex.js":204}],204:[function(require,module,exports){ // 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. 'use strict'; /**/ var objectKeys = Object.keys || function (obj) { var keys = []; for (var key in obj) keys.push(key); return keys; } /**/ module.exports = Duplex; /**/ var processNextTick = require('process-nextick-args'); /**/ /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ var Readable = require('./_stream_readable'); var Writable = require('./_stream_writable'); util.inherits(Duplex, Readable); 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); } // 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. processNextTick(onEndNT, this); } function onEndNT(self) { self.end(); } function forEach (xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); } } },{"./_stream_readable":206,"./_stream_writable":208,"core-util-is":209,"inherits":199,"process-nextick-args":210}],205:[function(require,module,exports){ // a passthrough stream. // basically just the most minimal sort of Transform stream. // Every written chunk gets output as-is. 'use strict'; module.exports = PassThrough; var Transform = require('./_stream_transform'); /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ 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); }; },{"./_stream_transform":207,"core-util-is":209,"inherits":199}],206:[function(require,module,exports){ (function (process){ 'use strict'; module.exports = Readable; /**/ var processNextTick = require('process-nextick-args'); /**/ /**/ var isArray = require('isarray'); /**/ /**/ var Buffer = require('buffer').Buffer; /**/ Readable.ReadableState = ReadableState; var EE = require('events'); /**/ var EElistenerCount = function(emitter, type) { return emitter.listeners(type).length; }; /**/ /**/ var Stream; (function (){try{ Stream = require('st' + 'ream'); }catch(_){}finally{ if (!Stream) Stream = require('events').EventEmitter; }}()) /**/ var Buffer = require('buffer').Buffer; /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ /**/ var debugUtil = require('util'); var debug; if (debugUtil && debugUtil.debuglog) { debug = debugUtil.debuglog('stream'); } else { debug = function () {}; } /**/ var StringDecoder; util.inherits(Readable, Stream); var Duplex; function ReadableState(options, stream) { Duplex = Duplex || require('./_stream_duplex'); options = options || {}; // 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 (stream instanceof Duplex) 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 defaultHwm = this.objectMode ? 16 : 16 * 1024; this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; // cast to ints. this.highWaterMark = ~~this.highWaterMark; this.buffer = []; 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 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; // 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; // 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'; // when piping, we only care about 'readable' events that happen // after read()ing all the bytes and not getting any pushback. this.ranOut = false; // 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 = require('string_decoder/').StringDecoder; this.decoder = new StringDecoder(options.encoding); this.encoding = options.encoding; } } var Duplex; function Readable(options) { Duplex = Duplex || require('./_stream_duplex'); if (!(this instanceof Readable)) return new Readable(options); this._readableState = new ReadableState(options, this); // legacy this.readable = true; if (options && typeof options.read === 'function') this._read = options.read; Stream.call(this); } // 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; if (!state.objectMode && typeof chunk === 'string') { encoding = encoding || state.defaultEncoding; if (encoding !== state.encoding) { chunk = new Buffer(chunk, encoding); encoding = ''; } } return readableAddChunk(this, state, chunk, encoding, false); }; // Unshift should *always* be something directly out of read() Readable.prototype.unshift = function(chunk) { var state = this._readableState; return readableAddChunk(this, state, chunk, '', true); }; Readable.prototype.isPaused = function() { return this._readableState.flowing === false; }; function readableAddChunk(stream, state, chunk, encoding, addToFront) { var er = chunkInvalid(state, chunk); if (er) { stream.emit('error', er); } else if (chunk === null) { state.reading = false; onEofChunk(stream, state); } else if (state.objectMode || chunk && chunk.length > 0) { if (state.ended && !addToFront) { var e = new Error('stream.push() after EOF'); stream.emit('error', e); } else if (state.endEmitted && addToFront) { var e = new Error('stream.unshift() after end event'); stream.emit('error', e); } else { if (state.decoder && !addToFront && !encoding) chunk = state.decoder.write(chunk); if (!addToFront) state.reading = false; // if we want the data now, just emit it. 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); } } else if (!addToFront) { state.reading = false; } return needMoreData(state); } // 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); } // backwards compatibility. Readable.prototype.setEncoding = function(enc) { if (!StringDecoder) StringDecoder = require('string_decoder/').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 n--; n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; n++; } return n; } function howMuchToRead(n, state) { if (state.length === 0 && state.ended) return 0; if (state.objectMode) return n === 0 ? 0 : 1; if (n === null || isNaN(n)) { // only flow one buffer at a time if (state.flowing && state.buffer.length) return state.buffer[0].length; else return state.length; } if (n <= 0) return 0; // If we're asking for more than the target buffer level, // then raise the water mark. Bump up to the next highest // power of 2, to prevent increasing it excessively in tiny // amounts. if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); // don't have that much. return null, unless we've ended. if (n > state.length) { if (!state.ended) { state.needReadable = true; return 0; } else { return state.length; } } return n; } // you can override either this method, or the async _read(n) below. Readable.prototype.read = function(n) { debug('read', n); var state = this._readableState; var nOrig = n; if (typeof n !== 'number' || 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); } 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 (doRead && !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; } state.length -= n; // If we have nothing in the buffer, then we want to know // as soon as we *do* get something into the buffer. if (state.length === 0 && !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 && state.length === 0) endReadable(this); if (ret !== null) this.emit('data', ret); return ret; }; function chunkInvalid(state, chunk) { var er = null; if (!(Buffer.isBuffer(chunk)) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) { er = new TypeError('Invalid non-string/buffer chunk'); } return er; } 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) processNextTick(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; processNextTick(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('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 : cleanup; if (state.endEmitted) processNextTick(endFn); else src.once('end', endFn); dest.on('unpipe', onunpipe); function onunpipe(readable) { debug('onunpipe'); if (readable === src) { 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', cleanup); 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(); } src.on('data', ondata); function ondata(chunk) { debug('ondata'); var ret = dest.write(chunk); if (false === ret) { // If the user unpiped during `dest.write()`, it is possible // to get stuck in a permanently paused state if that write // also returned false. if (state.pipesCount === 1 && state.pipes[0] === dest && src.listenerCount('data') === 1 && !cleanedUp) { debug('false write response, pause', src._readableState.awaitDrain); src._readableState.awaitDrain++; } 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); } // This is a brutally ugly hack to make sure that our error handler // is attached before any userland ones. NEVER DO THIS. if (!dest._events || !dest._events.error) dest.on('error', onerror); else if (isArray(dest._events.error)) dest._events.error.unshift(onerror); else dest._events.error = [onerror, dest._events.error]; // 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; // 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); 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); return this; } // try to find the right one. var i = indexOf(state.pipes, dest); if (i === -1) return this; state.pipes.splice(i, 1); state.pipesCount -= 1; if (state.pipesCount === 1) state.pipes = state.pipes[0]; dest.emit('unpipe', this); 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 listening to data, and it has not explicitly been paused, // then call resume to start the flow of data on the next tick. if (ev === 'data' && false !== this._readableState.flowing) { this.resume(); } if (ev === 'readable' && this.readable) { var state = this._readableState; if (!state.readableListening) { state.readableListening = true; state.emittedReadable = false; state.needReadable = true; if (!state.reading) { processNextTick(nReadingNextTick, this); } else if (state.length) { emitReadable(this, state); } } } 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; processNextTick(resume_, stream, state); } } function resume_(stream, state) { if (!state.reading) { debug('resume read 0'); stream.read(0); } state.resumeScheduled = false; 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); if (state.flowing) { do { var chunk = stream.read(); } while (null !== chunk && state.flowing); } } // 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 state = this._readableState; var paused = false; var self = this; stream.on('end', function() { debug('wrapped end'); if (state.decoder && !state.ended) { var chunk = state.decoder.end(); if (chunk && chunk.length) self.push(chunk); } self.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 = self.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. var events = ['error', 'close', 'destroy', 'pause', 'resume']; forEach(events, function(ev) { stream.on(ev, self.emit.bind(self, ev)); }); // when we try to consume some more bytes, simply unpause the // underlying stream. self._read = function(n) { debug('wrapped _read', n); if (paused) { paused = false; stream.resume(); } }; return self; }; // 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. function fromList(n, state) { var list = state.buffer; var length = state.length; var stringMode = !!state.decoder; var objectMode = !!state.objectMode; var ret; // nothing in the list, definitely empty. if (list.length === 0) return null; if (length === 0) ret = null; else if (objectMode) ret = list.shift(); else if (!n || n >= length) { // read it all, truncate the array. if (stringMode) ret = list.join(''); else if (list.length === 1) ret = list[0]; else ret = Buffer.concat(list, length); list.length = 0; } else { // read just some of it. if (n < list[0].length) { // just take a part of the first list item. // slice is the same for buffers and strings. var buf = list[0]; ret = buf.slice(0, n); list[0] = buf.slice(n); } else if (n === list[0].length) { // first list is a perfect match ret = list.shift(); } else { // complex case. // we have enough to cover it, but it spans past the first buffer. if (stringMode) ret = ''; else ret = new Buffer(n); var c = 0; for (var i = 0, l = list.length; i < l && c < n; i++) { var buf = list[0]; var cpy = Math.min(n - c, buf.length); if (stringMode) ret += buf.slice(0, cpy); else buf.copy(ret, c, 0, cpy); if (cpy < buf.length) list[0] = buf.slice(cpy); else list.shift(); c += cpy; } } } 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; processNextTick(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 forEach (xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); } } function indexOf (xs, x) { for (var i = 0, l = xs.length; i < l; i++) { if (xs[i] === x) return i; } return -1; } }).call(this,require('_process')) },{"./_stream_duplex":204,"_process":202,"buffer":2,"core-util-is":209,"events":198,"inherits":199,"isarray":201,"process-nextick-args":210,"string_decoder/":217,"util":1}],207:[function(require,module,exports){ // 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. 'use strict'; module.exports = Transform; var Duplex = require('./_stream_duplex'); /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ util.inherits(Transform, Duplex); function TransformState(stream) { this.afterTransform = function(er, data) { return afterTransform(stream, er, data); }; this.needTransform = false; this.transforming = false; this.writecb = null; this.writechunk = null; } function afterTransform(stream, er, data) { var ts = stream._transformState; ts.transforming = false; var cb = ts.writecb; if (!cb) return stream.emit('error', new Error('no writecb in Transform class')); ts.writechunk = null; ts.writecb = null; if (data !== null && data !== undefined) stream.push(data); if (cb) cb(er); var rs = stream._readableState; rs.reading = false; if (rs.needReadable || rs.length < rs.highWaterMark) { stream._read(rs.highWaterMark); } } function Transform(options) { if (!(this instanceof Transform)) return new Transform(options); Duplex.call(this, options); this._transformState = new TransformState(this); // when the writable side finishes, then flush out anything remaining. var stream = this; // 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; } this.once('prefinish', function() { if (typeof this._flush === 'function') this._flush(function(er) { done(stream, er); }); else done(stream); }); } 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('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; } }; function done(stream, er) { if (er) return stream.emit('error', er); // if there's nothing in the write buffer, then that means // that nothing more will ever be provided var ws = stream._writableState; var ts = stream._transformState; if (ws.length) throw new Error('calling transform done when ws.length != 0'); if (ts.transforming) throw new Error('calling transform done when still transforming'); return stream.push(null); } },{"./_stream_duplex":204,"core-util-is":209,"inherits":199}],208:[function(require,module,exports){ // A bit simpler than readable streams. // Implement an async ._write(chunk, encoding, cb), and it'll handle all // the drain event emission and buffering. 'use strict'; module.exports = Writable; /**/ var processNextTick = require('process-nextick-args'); /**/ /**/ var Buffer = require('buffer').Buffer; /**/ Writable.WritableState = WritableState; /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ /**/ var internalUtil = { deprecate: require('util-deprecate') }; /**/ /**/ var Stream; (function (){try{ Stream = require('st' + 'ream'); }catch(_){}finally{ if (!Stream) Stream = require('events').EventEmitter; }}()) /**/ var Buffer = require('buffer').Buffer; util.inherits(Writable, Stream); function nop() {} function WriteReq(chunk, encoding, cb) { this.chunk = chunk; this.encoding = encoding; this.callback = cb; this.next = null; } var Duplex; function WritableState(options, stream) { Duplex = Duplex || require('./_stream_duplex'); options = options || {}; // object stream flag to indicate whether or not this stream // contains buffers or objects. this.objectMode = !!options.objectMode; if (stream instanceof Duplex) 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 defaultHwm = this.objectMode ? 16 : 16 * 1024; this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; // cast to ints. this.highWaterMark = ~~this.highWaterMark; 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; // 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; } WritableState.prototype.getBuffer = function writableStateGetBuffer() { 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.') }); }catch(_){}}()); var Duplex; function Writable(options) { Duplex = Duplex || require('./_stream_duplex'); // Writable ctor is applied to Duplexes, though they're not // instanceof Writable, they're instanceof Readable. if (!(this instanceof Writable) && !(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; } 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); processNextTick(cb, er); } // If we get something that is not a buffer, string, null, or undefined, // and we're not in objectMode, then that's an error. // Otherwise stream chunks are all considered to be of length=1, and the // watermarks determine how many objects to keep in the buffer, rather than // how many bytes or characters. function validChunk(stream, state, chunk, cb) { var valid = true; if (!(Buffer.isBuffer(chunk)) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) { var er = new TypeError('Invalid non-string/buffer chunk'); stream.emit('error', er); processNextTick(cb, er); valid = false; } return valid; } Writable.prototype.write = function(chunk, encoding, cb) { var state = this._writableState; var ret = false; if (typeof encoding === 'function') { cb = encoding; encoding = null; } if (Buffer.isBuffer(chunk)) encoding = 'buffer'; else if (!encoding) encoding = state.defaultEncoding; if (typeof cb !== 'function') cb = nop; if (state.ended) writeAfterEnd(this, cb); else if (validChunk(this, state, chunk, cb)) { state.pendingcb++; ret = writeOrBuffer(this, state, 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; }; function decodeChunk(state, chunk, encoding) { if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { chunk = new Buffer(chunk, encoding); } return chunk; } // 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, chunk, encoding, cb) { chunk = decodeChunk(state, chunk, encoding); if (Buffer.isBuffer(chunk)) encoding = 'buffer'; 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 = new WriteReq(chunk, encoding, cb); if (last) { last.next = state.lastBufferedRequest; } else { state.bufferedRequest = state.lastBufferedRequest; } } 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) processNextTick(cb, er); else cb(er); stream._writableState.errorEmitted = true; stream.emit('error', er); } 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) { processNextTick(afterWrite, stream, state, finished, cb); } 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 buffer = []; var cbs = []; while (entry) { cbs.push(entry.callback); buffer.push(entry); entry = entry.next; } // count the one we are adding, as well. // TODO(isaacs) clean this up state.pendingcb++; state.lastBufferedRequest = null; doWrite(stream, state, true, state.length, buffer, '', function(err) { for (var i = 0; i < cbs.length; i++) { state.pendingcb--; cbs[i](err); } }); // Clear buffer } 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; // 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('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 prefinish(stream, state) { if (!state.prefinished) { state.prefinished = true; stream.emit('prefinish'); } } function finishMaybe(stream, state) { var need = needFinish(state); if (need) { if (state.pendingcb === 0) { prefinish(stream, state); state.finished = true; stream.emit('finish'); } else { prefinish(stream, state); } } return need; } function endWritable(stream, state, cb) { state.ending = true; finishMaybe(stream, state); if (cb) { if (state.finished) processNextTick(cb); else stream.once('finish', cb); } state.ended = true; } },{"./_stream_duplex":204,"buffer":2,"core-util-is":209,"events":198,"inherits":199,"process-nextick-args":210,"util-deprecate":211}],209:[function(require,module,exports){ (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); } }).call(this,{"isBuffer":require("../../../../insert-module-globals/node_modules/is-buffer/index.js")}) },{"../../../../insert-module-globals/node_modules/is-buffer/index.js":200}],210:[function(require,module,exports){ (function (process){ 'use strict'; if (!process.version || process.version.indexOf('v0.') === 0 || process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { module.exports = nextTick; } else { module.exports = process.nextTick; } function nextTick(fn) { var args = new Array(arguments.length - 1); var i = 0; while (i < args.length) { args[i++] = arguments[i]; } process.nextTick(function afterTick() { fn.apply(null, args); }); } }).call(this,require('_process')) },{"_process":202}],211:[function(require,module,exports){ (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'; } }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],212:[function(require,module,exports){ module.exports = require("./lib/_stream_passthrough.js") },{"./lib/_stream_passthrough.js":205}],213:[function(require,module,exports){ var Stream = (function (){ try { return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify } catch(_){} }()); exports = module.exports = require('./lib/_stream_readable.js'); exports.Stream = Stream || exports; exports.Readable = exports; exports.Writable = require('./lib/_stream_writable.js'); exports.Duplex = require('./lib/_stream_duplex.js'); exports.Transform = require('./lib/_stream_transform.js'); exports.PassThrough = require('./lib/_stream_passthrough.js'); },{"./lib/_stream_duplex.js":204,"./lib/_stream_passthrough.js":205,"./lib/_stream_readable.js":206,"./lib/_stream_transform.js":207,"./lib/_stream_writable.js":208}],214:[function(require,module,exports){ module.exports = require("./lib/_stream_transform.js") },{"./lib/_stream_transform.js":207}],215:[function(require,module,exports){ module.exports = require("./lib/_stream_writable.js") },{"./lib/_stream_writable.js":208}],216:[function(require,module,exports){ // 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 = require('events').EventEmitter; var inherits = require('inherits'); inherits(Stream, EE); Stream.Readable = require('readable-stream/readable.js'); Stream.Writable = require('readable-stream/writable.js'); Stream.Duplex = require('readable-stream/duplex.js'); Stream.Transform = require('readable-stream/transform.js'); Stream.PassThrough = require('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; }; },{"events":198,"inherits":199,"readable-stream/duplex.js":203,"readable-stream/passthrough.js":212,"readable-stream/readable.js":213,"readable-stream/transform.js":214,"readable-stream/writable.js":215}],217:[function(require,module,exports){ // 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 Buffer = require('buffer').Buffer; var isBufferEncoding = Buffer.isEncoding || function(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 assertEncoding(encoding) { if (encoding && !isBufferEncoding(encoding)) { throw new Error('Unknown encoding: ' + encoding); } } // StringDecoder provides an interface for efficiently splitting a series of // buffers into a series of JS strings without breaking apart multi-byte // characters. CESU-8 is handled as part of the UTF-8 encoding. // // @TODO Handling all encodings inside a single object makes it very difficult // to reason about this code, so it should be split up in the future. // @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code // points as used by CESU-8. var StringDecoder = exports.StringDecoder = function(encoding) { this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); assertEncoding(encoding); switch (this.encoding) { case 'utf8': // CESU-8 represents each of Surrogate Pair by 3-bytes this.surrogateSize = 3; break; case 'ucs2': case 'utf16le': // UTF-16 represents each of Surrogate Pair by 2-bytes this.surrogateSize = 2; this.detectIncompleteChar = utf16DetectIncompleteChar; break; case 'base64': // Base-64 stores 3 bytes in 4 chars, and pads the remainder. this.surrogateSize = 3; this.detectIncompleteChar = base64DetectIncompleteChar; break; default: this.write = passThroughWrite; return; } // Enough space to store all bytes of a single character. UTF-8 needs 4 // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). this.charBuffer = new Buffer(6); // Number of bytes received for the current incomplete multi-byte character. this.charReceived = 0; // Number of bytes expected for the current incomplete multi-byte character. this.charLength = 0; }; // write decodes the given buffer and returns it as JS string that is // guaranteed to not contain any partial multi-byte characters. Any partial // character found at the end of the buffer is buffered up, and will be // returned when calling write again with the remaining bytes. // // Note: Converting a Buffer containing an orphan surrogate to a String // currently works, but converting a String to a Buffer (via `new Buffer`, or // Buffer#write) will replace incomplete surrogates with the unicode // replacement character. See https://codereview.chromium.org/121173009/ . StringDecoder.prototype.write = function(buffer) { var charStr = ''; // if our last write ended with an incomplete multibyte character while (this.charLength) { // determine how many remaining bytes this buffer has to offer for this char var available = (buffer.length >= this.charLength - this.charReceived) ? this.charLength - this.charReceived : buffer.length; // add the new bytes to the char buffer buffer.copy(this.charBuffer, this.charReceived, 0, available); this.charReceived += available; if (this.charReceived < this.charLength) { // still not enough chars in this buffer? wait for more ... return ''; } // remove bytes belonging to the current character from the buffer buffer = buffer.slice(available, buffer.length); // get the character that was split charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character var charCode = charStr.charCodeAt(charStr.length - 1); if (charCode >= 0xD800 && charCode <= 0xDBFF) { this.charLength += this.surrogateSize; charStr = ''; continue; } this.charReceived = this.charLength = 0; // if there are no more bytes in this buffer, just emit our char if (buffer.length === 0) { return charStr; } break; } // determine and set charLength / charReceived this.detectIncompleteChar(buffer); var end = buffer.length; if (this.charLength) { // buffer the incomplete character bytes we got buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); end -= this.charReceived; } charStr += buffer.toString(this.encoding, 0, end); var end = charStr.length - 1; var charCode = charStr.charCodeAt(end); // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character if (charCode >= 0xD800 && charCode <= 0xDBFF) { var size = this.surrogateSize; this.charLength += size; this.charReceived += size; this.charBuffer.copy(this.charBuffer, size, 0, size); buffer.copy(this.charBuffer, 0, 0, size); return charStr.substring(0, end); } // or just emit the charStr return charStr; }; // detectIncompleteChar determines if there is an incomplete UTF-8 character at // the end of the given buffer. If so, it sets this.charLength to the byte // length that character, and sets this.charReceived to the number of bytes // that are available for this character. StringDecoder.prototype.detectIncompleteChar = function(buffer) { // determine how many bytes we have to check at the end of this buffer var i = (buffer.length >= 3) ? 3 : buffer.length; // Figure out if one of the last i bytes of our buffer announces an // incomplete char. for (; i > 0; i--) { var c = buffer[buffer.length - i]; // See http://en.wikipedia.org/wiki/UTF-8#Description // 110XXXXX if (i == 1 && c >> 5 == 0x06) { this.charLength = 2; break; } // 1110XXXX if (i <= 2 && c >> 4 == 0x0E) { this.charLength = 3; break; } // 11110XXX if (i <= 3 && c >> 3 == 0x1E) { this.charLength = 4; break; } } this.charReceived = i; }; StringDecoder.prototype.end = function(buffer) { var res = ''; if (buffer && buffer.length) res = this.write(buffer); if (this.charReceived) { var cr = this.charReceived; var buf = this.charBuffer; var enc = this.encoding; res += buf.slice(0, cr).toString(enc); } return res; }; function passThroughWrite(buffer) { return buffer.toString(this.encoding); } function utf16DetectIncompleteChar(buffer) { this.charReceived = buffer.length % 2; this.charLength = this.charReceived ? 2 : 0; } function base64DetectIncompleteChar(buffer) { this.charReceived = buffer.length % 3; this.charLength = this.charReceived ? 3 : 0; } },{"buffer":2}],218:[function(require,module,exports){ var indexOf = require('indexof'); 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); 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.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; }; },{"indexof":219}],219:[function(require,module,exports){ var indexOf = [].indexOf; module.exports = function(arr, obj){ if (indexOf) return arr.indexOf(obj); for (var i = 0; i < arr.length; ++i) { if (arr[i] === obj) return i; } return -1; }; },{}],220:[function(require,module,exports){ /** * Copyright (c) 2014-2015, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : global.Immutable = factory(); }(this, function () { 'use strict';var SLICE$0 = Array.prototype.slice; function createClass(ctor, superClass) { if (superClass) { ctor.prototype = Object.create(superClass.prototype); } ctor.prototype.constructor = ctor; } function Iterable(value) { return isIterable(value) ? value : Seq(value); } createClass(KeyedIterable, Iterable); function KeyedIterable(value) { return isKeyed(value) ? value : KeyedSeq(value); } createClass(IndexedIterable, Iterable); function IndexedIterable(value) { return isIndexed(value) ? value : IndexedSeq(value); } createClass(SetIterable, Iterable); function SetIterable(value) { return isIterable(value) && !isAssociative(value) ? value : SetSeq(value); } function isIterable(maybeIterable) { return !!(maybeIterable && maybeIterable[IS_ITERABLE_SENTINEL]); } function isKeyed(maybeKeyed) { return !!(maybeKeyed && maybeKeyed[IS_KEYED_SENTINEL]); } function isIndexed(maybeIndexed) { return !!(maybeIndexed && maybeIndexed[IS_INDEXED_SENTINEL]); } function isAssociative(maybeAssociative) { return isKeyed(maybeAssociative) || isIndexed(maybeAssociative); } function isOrdered(maybeOrdered) { return !!(maybeOrdered && maybeOrdered[IS_ORDERED_SENTINEL]); } Iterable.isIterable = isIterable; Iterable.isKeyed = isKeyed; Iterable.isIndexed = isIndexed; Iterable.isAssociative = isAssociative; Iterable.isOrdered = isOrdered; Iterable.Keyed = KeyedIterable; Iterable.Indexed = IndexedIterable; Iterable.Set = SetIterable; var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@'; var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@'; var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@'; var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@'; // Used for setting prototype methods that IE8 chokes on. var DELETE = 'delete'; // Constants describing the size of trie nodes. var SHIFT = 5; // Resulted in best performance after ______? var SIZE = 1 << SHIFT; var MASK = SIZE - 1; // A consistent shared value representing "not set" which equals nothing other // than itself, and nothing that could be provided externally. var NOT_SET = {}; // Boolean references, Rough equivalent of `bool &`. var CHANGE_LENGTH = { value: false }; var DID_ALTER = { value: false }; function MakeRef(ref) { ref.value = false; return ref; } function SetRef(ref) { ref && (ref.value = true); } // A function which returns a value representing an "owner" for transient writes // to tries. The return value will only ever equal itself, and will not equal // the return of any subsequent call of this function. function OwnerID() {} // http://jsperf.com/copy-array-inline function arrCopy(arr, offset) { offset = offset || 0; var len = Math.max(0, arr.length - offset); var newArr = new Array(len); for (var ii = 0; ii < len; ii++) { newArr[ii] = arr[ii + offset]; } return newArr; } function ensureSize(iter) { if (iter.size === undefined) { iter.size = iter.__iterate(returnTrue); } return iter.size; } function wrapIndex(iter, index) { // This implements "is array index" which the ECMAString spec defines as: // // A String property name P is an array index if and only if // ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal // to 2^32−1. // // http://www.ecma-international.org/ecma-262/6.0/#sec-array-exotic-objects if (typeof index !== 'number') { var uint32Index = index >>> 0; // N >>> 0 is shorthand for ToUint32 if ('' + uint32Index !== index || uint32Index === 4294967295) { return NaN; } index = uint32Index; } return index < 0 ? ensureSize(iter) + index : index; } function returnTrue() { return true; } function wholeSlice(begin, end, size) { return (begin === 0 || (size !== undefined && begin <= -size)) && (end === undefined || (size !== undefined && end >= size)); } function resolveBegin(begin, size) { return resolveIndex(begin, size, 0); } function resolveEnd(end, size) { return resolveIndex(end, size, size); } function resolveIndex(index, size, defaultIndex) { return index === undefined ? defaultIndex : index < 0 ? Math.max(0, size + index) : size === undefined ? index : Math.min(size, index); } /* global Symbol */ var ITERATE_KEYS = 0; var ITERATE_VALUES = 1; var ITERATE_ENTRIES = 2; var REAL_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; var FAUX_ITERATOR_SYMBOL = '@@iterator'; var ITERATOR_SYMBOL = REAL_ITERATOR_SYMBOL || FAUX_ITERATOR_SYMBOL; function Iterator(next) { this.next = next; } Iterator.prototype.toString = function() { return '[Iterator]'; }; Iterator.KEYS = ITERATE_KEYS; Iterator.VALUES = ITERATE_VALUES; Iterator.ENTRIES = ITERATE_ENTRIES; Iterator.prototype.inspect = Iterator.prototype.toSource = function () { return this.toString(); } Iterator.prototype[ITERATOR_SYMBOL] = function () { return this; }; function iteratorValue(type, k, v, iteratorResult) { var value = type === 0 ? k : type === 1 ? v : [k, v]; iteratorResult ? (iteratorResult.value = value) : (iteratorResult = { value: value, done: false }); return iteratorResult; } function iteratorDone() { return { value: undefined, done: true }; } function hasIterator(maybeIterable) { return !!getIteratorFn(maybeIterable); } function isIterator(maybeIterator) { return maybeIterator && typeof maybeIterator.next === 'function'; } function getIterator(iterable) { var iteratorFn = getIteratorFn(iterable); return iteratorFn && iteratorFn.call(iterable); } function getIteratorFn(iterable) { var iteratorFn = iterable && ( (REAL_ITERATOR_SYMBOL && iterable[REAL_ITERATOR_SYMBOL]) || iterable[FAUX_ITERATOR_SYMBOL] ); if (typeof iteratorFn === 'function') { return iteratorFn; } } function isArrayLike(value) { return value && typeof value.length === 'number'; } createClass(Seq, Iterable); function Seq(value) { return value === null || value === undefined ? emptySequence() : isIterable(value) ? value.toSeq() : seqFromValue(value); } Seq.of = function(/*...values*/) { return Seq(arguments); }; Seq.prototype.toSeq = function() { return this; }; Seq.prototype.toString = function() { return this.__toString('Seq {', '}'); }; Seq.prototype.cacheResult = function() { if (!this._cache && this.__iterateUncached) { this._cache = this.entrySeq().toArray(); this.size = this._cache.length; } return this; }; // abstract __iterateUncached(fn, reverse) Seq.prototype.__iterate = function(fn, reverse) { return seqIterate(this, fn, reverse, true); }; // abstract __iteratorUncached(type, reverse) Seq.prototype.__iterator = function(type, reverse) { return seqIterator(this, type, reverse, true); }; createClass(KeyedSeq, Seq); function KeyedSeq(value) { return value === null || value === undefined ? emptySequence().toKeyedSeq() : isIterable(value) ? (isKeyed(value) ? value.toSeq() : value.fromEntrySeq()) : keyedSeqFromValue(value); } KeyedSeq.prototype.toKeyedSeq = function() { return this; }; createClass(IndexedSeq, Seq); function IndexedSeq(value) { return value === null || value === undefined ? emptySequence() : !isIterable(value) ? indexedSeqFromValue(value) : isKeyed(value) ? value.entrySeq() : value.toIndexedSeq(); } IndexedSeq.of = function(/*...values*/) { return IndexedSeq(arguments); }; IndexedSeq.prototype.toIndexedSeq = function() { return this; }; IndexedSeq.prototype.toString = function() { return this.__toString('Seq [', ']'); }; IndexedSeq.prototype.__iterate = function(fn, reverse) { return seqIterate(this, fn, reverse, false); }; IndexedSeq.prototype.__iterator = function(type, reverse) { return seqIterator(this, type, reverse, false); }; createClass(SetSeq, Seq); function SetSeq(value) { return ( value === null || value === undefined ? emptySequence() : !isIterable(value) ? indexedSeqFromValue(value) : isKeyed(value) ? value.entrySeq() : value ).toSetSeq(); } SetSeq.of = function(/*...values*/) { return SetSeq(arguments); }; SetSeq.prototype.toSetSeq = function() { return this; }; Seq.isSeq = isSeq; Seq.Keyed = KeyedSeq; Seq.Set = SetSeq; Seq.Indexed = IndexedSeq; var IS_SEQ_SENTINEL = '@@__IMMUTABLE_SEQ__@@'; Seq.prototype[IS_SEQ_SENTINEL] = true; createClass(ArraySeq, IndexedSeq); function ArraySeq(array) { this._array = array; this.size = array.length; } ArraySeq.prototype.get = function(index, notSetValue) { return this.has(index) ? this._array[wrapIndex(this, index)] : notSetValue; }; ArraySeq.prototype.__iterate = function(fn, reverse) { var array = this._array; var maxIndex = array.length - 1; for (var ii = 0; ii <= maxIndex; ii++) { if (fn(array[reverse ? maxIndex - ii : ii], ii, this) === false) { return ii + 1; } } return ii; }; ArraySeq.prototype.__iterator = function(type, reverse) { var array = this._array; var maxIndex = array.length - 1; var ii = 0; return new Iterator(function() {return ii > maxIndex ? iteratorDone() : iteratorValue(type, ii, array[reverse ? maxIndex - ii++ : ii++])} ); }; createClass(ObjectSeq, KeyedSeq); function ObjectSeq(object) { var keys = Object.keys(object); this._object = object; this._keys = keys; this.size = keys.length; } ObjectSeq.prototype.get = function(key, notSetValue) { if (notSetValue !== undefined && !this.has(key)) { return notSetValue; } return this._object[key]; }; ObjectSeq.prototype.has = function(key) { return this._object.hasOwnProperty(key); }; ObjectSeq.prototype.__iterate = function(fn, reverse) { var object = this._object; var keys = this._keys; var maxIndex = keys.length - 1; for (var ii = 0; ii <= maxIndex; ii++) { var key = keys[reverse ? maxIndex - ii : ii]; if (fn(object[key], key, this) === false) { return ii + 1; } } return ii; }; ObjectSeq.prototype.__iterator = function(type, reverse) { var object = this._object; var keys = this._keys; var maxIndex = keys.length - 1; var ii = 0; return new Iterator(function() { var key = keys[reverse ? maxIndex - ii : ii]; return ii++ > maxIndex ? iteratorDone() : iteratorValue(type, key, object[key]); }); }; ObjectSeq.prototype[IS_ORDERED_SENTINEL] = true; createClass(IterableSeq, IndexedSeq); function IterableSeq(iterable) { this._iterable = iterable; this.size = iterable.length || iterable.size; } IterableSeq.prototype.__iterateUncached = function(fn, reverse) { if (reverse) { return this.cacheResult().__iterate(fn, reverse); } var iterable = this._iterable; var iterator = getIterator(iterable); var iterations = 0; if (isIterator(iterator)) { var step; while (!(step = iterator.next()).done) { if (fn(step.value, iterations++, this) === false) { break; } } } return iterations; }; IterableSeq.prototype.__iteratorUncached = function(type, reverse) { if (reverse) { return this.cacheResult().__iterator(type, reverse); } var iterable = this._iterable; var iterator = getIterator(iterable); if (!isIterator(iterator)) { return new Iterator(iteratorDone); } var iterations = 0; return new Iterator(function() { var step = iterator.next(); return step.done ? step : iteratorValue(type, iterations++, step.value); }); }; createClass(IteratorSeq, IndexedSeq); function IteratorSeq(iterator) { this._iterator = iterator; this._iteratorCache = []; } IteratorSeq.prototype.__iterateUncached = function(fn, reverse) { if (reverse) { return this.cacheResult().__iterate(fn, reverse); } var iterator = this._iterator; var cache = this._iteratorCache; var iterations = 0; while (iterations < cache.length) { if (fn(cache[iterations], iterations++, this) === false) { return iterations; } } var step; while (!(step = iterator.next()).done) { var val = step.value; cache[iterations] = val; if (fn(val, iterations++, this) === false) { break; } } return iterations; }; IteratorSeq.prototype.__iteratorUncached = function(type, reverse) { if (reverse) { return this.cacheResult().__iterator(type, reverse); } var iterator = this._iterator; var cache = this._iteratorCache; var iterations = 0; return new Iterator(function() { if (iterations >= cache.length) { var step = iterator.next(); if (step.done) { return step; } cache[iterations] = step.value; } return iteratorValue(type, iterations, cache[iterations++]); }); }; // # pragma Helper functions function isSeq(maybeSeq) { return !!(maybeSeq && maybeSeq[IS_SEQ_SENTINEL]); } var EMPTY_SEQ; function emptySequence() { return EMPTY_SEQ || (EMPTY_SEQ = new ArraySeq([])); } function keyedSeqFromValue(value) { var seq = Array.isArray(value) ? new ArraySeq(value).fromEntrySeq() : isIterator(value) ? new IteratorSeq(value).fromEntrySeq() : hasIterator(value) ? new IterableSeq(value).fromEntrySeq() : typeof value === 'object' ? new ObjectSeq(value) : undefined; if (!seq) { throw new TypeError( 'Expected Array or iterable object of [k, v] entries, '+ 'or keyed object: ' + value ); } return seq; } function indexedSeqFromValue(value) { var seq = maybeIndexedSeqFromValue(value); if (!seq) { throw new TypeError( 'Expected Array or iterable object of values: ' + value ); } return seq; } function seqFromValue(value) { var seq = maybeIndexedSeqFromValue(value) || (typeof value === 'object' && new ObjectSeq(value)); if (!seq) { throw new TypeError( 'Expected Array or iterable object of values, or keyed object: ' + value ); } return seq; } function maybeIndexedSeqFromValue(value) { return ( isArrayLike(value) ? new ArraySeq(value) : isIterator(value) ? new IteratorSeq(value) : hasIterator(value) ? new IterableSeq(value) : undefined ); } function seqIterate(seq, fn, reverse, useKeys) { var cache = seq._cache; if (cache) { var maxIndex = cache.length - 1; for (var ii = 0; ii <= maxIndex; ii++) { var entry = cache[reverse ? maxIndex - ii : ii]; if (fn(entry[1], useKeys ? entry[0] : ii, seq) === false) { return ii + 1; } } return ii; } return seq.__iterateUncached(fn, reverse); } function seqIterator(seq, type, reverse, useKeys) { var cache = seq._cache; if (cache) { var maxIndex = cache.length - 1; var ii = 0; return new Iterator(function() { var entry = cache[reverse ? maxIndex - ii : ii]; return ii++ > maxIndex ? iteratorDone() : iteratorValue(type, useKeys ? entry[0] : ii - 1, entry[1]); }); } return seq.__iteratorUncached(type, reverse); } function fromJS(json, converter) { return converter ? fromJSWith(converter, json, '', {'': json}) : fromJSDefault(json); } function fromJSWith(converter, json, key, parentJSON) { if (Array.isArray(json)) { return converter.call(parentJSON, key, IndexedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)})); } if (isPlainObj(json)) { return converter.call(parentJSON, key, KeyedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)})); } return json; } function fromJSDefault(json) { if (Array.isArray(json)) { return IndexedSeq(json).map(fromJSDefault).toList(); } if (isPlainObj(json)) { return KeyedSeq(json).map(fromJSDefault).toMap(); } return json; } function isPlainObj(value) { return value && (value.constructor === Object || value.constructor === undefined); } /** * An extension of the "same-value" algorithm as [described for use by ES6 Map * and Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Key_equality) * * NaN is considered the same as NaN, however -0 and 0 are considered the same * value, which is different from the algorithm described by * [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is). * * This is extended further to allow Objects to describe the values they * represent, by way of `valueOf` or `equals` (and `hashCode`). * * Note: because of this extension, the key equality of Immutable.Map and the * value equality of Immutable.Set will differ from ES6 Map and Set. * * ### Defining custom values * * The easiest way to describe the value an object represents is by implementing * `valueOf`. For example, `Date` represents a value by returning a unix * timestamp for `valueOf`: * * var date1 = new Date(1234567890000); // Fri Feb 13 2009 ... * var date2 = new Date(1234567890000); * date1.valueOf(); // 1234567890000 * assert( date1 !== date2 ); * assert( Immutable.is( date1, date2 ) ); * * Note: overriding `valueOf` may have other implications if you use this object * where JavaScript expects a primitive, such as implicit string coercion. * * For more complex types, especially collections, implementing `valueOf` may * not be performant. An alternative is to implement `equals` and `hashCode`. * * `equals` takes another object, presumably of similar type, and returns true * if the it is equal. Equality is symmetrical, so the same result should be * returned if this and the argument are flipped. * * assert( a.equals(b) === b.equals(a) ); * * `hashCode` returns a 32bit integer number representing the object which will * be used to determine how to store the value object in a Map or Set. You must * provide both or neither methods, one must not exist without the other. * * Also, an important relationship between these methods must be upheld: if two * values are equal, they *must* return the same hashCode. If the values are not * equal, they might have the same hashCode; this is called a hash collision, * and while undesirable for performance reasons, it is acceptable. * * if (a.equals(b)) { * assert( a.hashCode() === b.hashCode() ); * } * * All Immutable collections implement `equals` and `hashCode`. * */ function is(valueA, valueB) { if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) { return true; } if (!valueA || !valueB) { return false; } if (typeof valueA.valueOf === 'function' && typeof valueB.valueOf === 'function') { valueA = valueA.valueOf(); valueB = valueB.valueOf(); if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) { return true; } if (!valueA || !valueB) { return false; } } if (typeof valueA.equals === 'function' && typeof valueB.equals === 'function' && valueA.equals(valueB)) { return true; } return false; } function deepEqual(a, b) { if (a === b) { return true; } if ( !isIterable(b) || a.size !== undefined && b.size !== undefined && a.size !== b.size || a.__hash !== undefined && b.__hash !== undefined && a.__hash !== b.__hash || isKeyed(a) !== isKeyed(b) || isIndexed(a) !== isIndexed(b) || isOrdered(a) !== isOrdered(b) ) { return false; } if (a.size === 0 && b.size === 0) { return true; } var notAssociative = !isAssociative(a); if (isOrdered(a)) { var entries = a.entries(); return b.every(function(v, k) { var entry = entries.next().value; return entry && is(entry[1], v) && (notAssociative || is(entry[0], k)); }) && entries.next().done; } var flipped = false; if (a.size === undefined) { if (b.size === undefined) { if (typeof a.cacheResult === 'function') { a.cacheResult(); } } else { flipped = true; var _ = a; a = b; b = _; } } var allEqual = true; var bSize = b.__iterate(function(v, k) { if (notAssociative ? !a.has(v) : flipped ? !is(v, a.get(k, NOT_SET)) : !is(a.get(k, NOT_SET), v)) { allEqual = false; return false; } }); return allEqual && a.size === bSize; } createClass(Repeat, IndexedSeq); function Repeat(value, times) { if (!(this instanceof Repeat)) { return new Repeat(value, times); } this._value = value; this.size = times === undefined ? Infinity : Math.max(0, times); if (this.size === 0) { if (EMPTY_REPEAT) { return EMPTY_REPEAT; } EMPTY_REPEAT = this; } } Repeat.prototype.toString = function() { if (this.size === 0) { return 'Repeat []'; } return 'Repeat [ ' + this._value + ' ' + this.size + ' times ]'; }; Repeat.prototype.get = function(index, notSetValue) { return this.has(index) ? this._value : notSetValue; }; Repeat.prototype.includes = function(searchValue) { return is(this._value, searchValue); }; Repeat.prototype.slice = function(begin, end) { var size = this.size; return wholeSlice(begin, end, size) ? this : new Repeat(this._value, resolveEnd(end, size) - resolveBegin(begin, size)); }; Repeat.prototype.reverse = function() { return this; }; Repeat.prototype.indexOf = function(searchValue) { if (is(this._value, searchValue)) { return 0; } return -1; }; Repeat.prototype.lastIndexOf = function(searchValue) { if (is(this._value, searchValue)) { return this.size; } return -1; }; Repeat.prototype.__iterate = function(fn, reverse) { for (var ii = 0; ii < this.size; ii++) { if (fn(this._value, ii, this) === false) { return ii + 1; } } return ii; }; Repeat.prototype.__iterator = function(type, reverse) {var this$0 = this; var ii = 0; return new Iterator(function() {return ii < this$0.size ? iteratorValue(type, ii++, this$0._value) : iteratorDone()} ); }; Repeat.prototype.equals = function(other) { return other instanceof Repeat ? is(this._value, other._value) : deepEqual(other); }; var EMPTY_REPEAT; function invariant(condition, error) { if (!condition) throw new Error(error); } createClass(Range, IndexedSeq); function Range(start, end, step) { if (!(this instanceof Range)) { return new Range(start, end, step); } invariant(step !== 0, 'Cannot step a Range by 0'); start = start || 0; if (end === undefined) { end = Infinity; } step = step === undefined ? 1 : Math.abs(step); if (end < start) { step = -step; } this._start = start; this._end = end; this._step = step; this.size = Math.max(0, Math.ceil((end - start) / step - 1) + 1); if (this.size === 0) { if (EMPTY_RANGE) { return EMPTY_RANGE; } EMPTY_RANGE = this; } } Range.prototype.toString = function() { if (this.size === 0) { return 'Range []'; } return 'Range [ ' + this._start + '...' + this._end + (this._step > 1 ? ' by ' + this._step : '') + ' ]'; }; Range.prototype.get = function(index, notSetValue) { return this.has(index) ? this._start + wrapIndex(this, index) * this._step : notSetValue; }; Range.prototype.includes = function(searchValue) { var possibleIndex = (searchValue - this._start) / this._step; return possibleIndex >= 0 && possibleIndex < this.size && possibleIndex === Math.floor(possibleIndex); }; Range.prototype.slice = function(begin, end) { if (wholeSlice(begin, end, this.size)) { return this; } begin = resolveBegin(begin, this.size); end = resolveEnd(end, this.size); if (end <= begin) { return new Range(0, 0); } return new Range(this.get(begin, this._end), this.get(end, this._end), this._step); }; Range.prototype.indexOf = function(searchValue) { var offsetValue = searchValue - this._start; if (offsetValue % this._step === 0) { var index = offsetValue / this._step; if (index >= 0 && index < this.size) { return index } } return -1; }; Range.prototype.lastIndexOf = function(searchValue) { return this.indexOf(searchValue); }; Range.prototype.__iterate = function(fn, reverse) { var maxIndex = this.size - 1; var step = this._step; var value = reverse ? this._start + maxIndex * step : this._start; for (var ii = 0; ii <= maxIndex; ii++) { if (fn(value, ii, this) === false) { return ii + 1; } value += reverse ? -step : step; } return ii; }; Range.prototype.__iterator = function(type, reverse) { var maxIndex = this.size - 1; var step = this._step; var value = reverse ? this._start + maxIndex * step : this._start; var ii = 0; return new Iterator(function() { var v = value; value += reverse ? -step : step; return ii > maxIndex ? iteratorDone() : iteratorValue(type, ii++, v); }); }; Range.prototype.equals = function(other) { return other instanceof Range ? this._start === other._start && this._end === other._end && this._step === other._step : deepEqual(this, other); }; var EMPTY_RANGE; createClass(Collection, Iterable); function Collection() { throw TypeError('Abstract'); } createClass(KeyedCollection, Collection);function KeyedCollection() {} createClass(IndexedCollection, Collection);function IndexedCollection() {} createClass(SetCollection, Collection);function SetCollection() {} Collection.Keyed = KeyedCollection; Collection.Indexed = IndexedCollection; Collection.Set = SetCollection; var imul = typeof Math.imul === 'function' && Math.imul(0xffffffff, 2) === -2 ? Math.imul : function imul(a, b) { a = a | 0; // int b = b | 0; // int var c = a & 0xffff; var d = b & 0xffff; // Shift by 0 fixes the sign on the high part. return (c * d) + ((((a >>> 16) * d + c * (b >>> 16)) << 16) >>> 0) | 0; // int }; // v8 has an optimization for storing 31-bit signed numbers. // Values which have either 00 or 11 as the high order bits qualify. // This function drops the highest order bit in a signed number, maintaining // the sign bit. function smi(i32) { return ((i32 >>> 1) & 0x40000000) | (i32 & 0xBFFFFFFF); } function hash(o) { if (o === false || o === null || o === undefined) { return 0; } if (typeof o.valueOf === 'function') { o = o.valueOf(); if (o === false || o === null || o === undefined) { return 0; } } if (o === true) { return 1; } var type = typeof o; if (type === 'number') { var h = o | 0; if (h !== o) { h ^= o * 0xFFFFFFFF; } while (o > 0xFFFFFFFF) { o /= 0xFFFFFFFF; h ^= o; } return smi(h); } if (type === 'string') { return o.length > STRING_HASH_CACHE_MIN_STRLEN ? cachedHashString(o) : hashString(o); } if (typeof o.hashCode === 'function') { return o.hashCode(); } if (type === 'object') { return hashJSObj(o); } if (typeof o.toString === 'function') { return hashString(o.toString()); } throw new Error('Value type ' + type + ' cannot be hashed.'); } function cachedHashString(string) { var hash = stringHashCache[string]; if (hash === undefined) { hash = hashString(string); if (STRING_HASH_CACHE_SIZE === STRING_HASH_CACHE_MAX_SIZE) { STRING_HASH_CACHE_SIZE = 0; stringHashCache = {}; } STRING_HASH_CACHE_SIZE++; stringHashCache[string] = hash; } return hash; } // http://jsperf.com/hashing-strings function hashString(string) { // This is the hash from JVM // The hash code for a string is computed as // s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1], // where s[i] is the ith character of the string and n is the length of // the string. We "mod" the result to make it between 0 (inclusive) and 2^31 // (exclusive) by dropping high bits. var hash = 0; for (var ii = 0; ii < string.length; ii++) { hash = 31 * hash + string.charCodeAt(ii) | 0; } return smi(hash); } function hashJSObj(obj) { var hash; if (usingWeakMap) { hash = weakMap.get(obj); if (hash !== undefined) { return hash; } } hash = obj[UID_HASH_KEY]; if (hash !== undefined) { return hash; } if (!canDefineProperty) { hash = obj.propertyIsEnumerable && obj.propertyIsEnumerable[UID_HASH_KEY]; if (hash !== undefined) { return hash; } hash = getIENodeHash(obj); if (hash !== undefined) { return hash; } } hash = ++objHashUID; if (objHashUID & 0x40000000) { objHashUID = 0; } if (usingWeakMap) { weakMap.set(obj, hash); } else if (isExtensible !== undefined && isExtensible(obj) === false) { throw new Error('Non-extensible objects are not allowed as keys.'); } else if (canDefineProperty) { Object.defineProperty(obj, UID_HASH_KEY, { 'enumerable': false, 'configurable': false, 'writable': false, 'value': hash }); } else if (obj.propertyIsEnumerable !== undefined && obj.propertyIsEnumerable === obj.constructor.prototype.propertyIsEnumerable) { // Since we can't define a non-enumerable property on the object // we'll hijack one of the less-used non-enumerable properties to // save our hash on it. Since this is a function it will not show up in // `JSON.stringify` which is what we want. obj.propertyIsEnumerable = function() { return this.constructor.prototype.propertyIsEnumerable.apply(this, arguments); }; obj.propertyIsEnumerable[UID_HASH_KEY] = hash; } else if (obj.nodeType !== undefined) { // At this point we couldn't get the IE `uniqueID` to use as a hash // and we couldn't use a non-enumerable property to exploit the // dontEnum bug so we simply add the `UID_HASH_KEY` on the node // itself. obj[UID_HASH_KEY] = hash; } else { throw new Error('Unable to set a non-enumerable property on object.'); } return hash; } // Get references to ES5 object methods. var isExtensible = Object.isExtensible; // True if Object.defineProperty works as expected. IE8 fails this test. var canDefineProperty = (function() { try { Object.defineProperty({}, '@', {}); return true; } catch (e) { return false; } }()); // IE has a `uniqueID` property on DOM nodes. We can construct the hash from it // and avoid memory leaks from the IE cloneNode bug. function getIENodeHash(node) { if (node && node.nodeType > 0) { switch (node.nodeType) { case 1: // Element return node.uniqueID; case 9: // Document return node.documentElement && node.documentElement.uniqueID; } } } // If possible, use a WeakMap. var usingWeakMap = typeof WeakMap === 'function'; var weakMap; if (usingWeakMap) { weakMap = new WeakMap(); } var objHashUID = 0; var UID_HASH_KEY = '__immutablehash__'; if (typeof Symbol === 'function') { UID_HASH_KEY = Symbol(UID_HASH_KEY); } var STRING_HASH_CACHE_MIN_STRLEN = 16; var STRING_HASH_CACHE_MAX_SIZE = 255; var STRING_HASH_CACHE_SIZE = 0; var stringHashCache = {}; function assertNotInfinite(size) { invariant( size !== Infinity, 'Cannot perform this action with an infinite size.' ); } createClass(Map, KeyedCollection); // @pragma Construction function Map(value) { return value === null || value === undefined ? emptyMap() : isMap(value) && !isOrdered(value) ? value : emptyMap().withMutations(function(map ) { var iter = KeyedIterable(value); assertNotInfinite(iter.size); iter.forEach(function(v, k) {return map.set(k, v)}); }); } Map.prototype.toString = function() { return this.__toString('Map {', '}'); }; // @pragma Access Map.prototype.get = function(k, notSetValue) { return this._root ? this._root.get(0, undefined, k, notSetValue) : notSetValue; }; // @pragma Modification Map.prototype.set = function(k, v) { return updateMap(this, k, v); }; Map.prototype.setIn = function(keyPath, v) { return this.updateIn(keyPath, NOT_SET, function() {return v}); }; Map.prototype.remove = function(k) { return updateMap(this, k, NOT_SET); }; Map.prototype.deleteIn = function(keyPath) { return this.updateIn(keyPath, function() {return NOT_SET}); }; Map.prototype.update = function(k, notSetValue, updater) { return arguments.length === 1 ? k(this) : this.updateIn([k], notSetValue, updater); }; Map.prototype.updateIn = function(keyPath, notSetValue, updater) { if (!updater) { updater = notSetValue; notSetValue = undefined; } var updatedValue = updateInDeepMap( this, forceIterator(keyPath), notSetValue, updater ); return updatedValue === NOT_SET ? undefined : updatedValue; }; Map.prototype.clear = function() { if (this.size === 0) { return this; } if (this.__ownerID) { this.size = 0; this._root = null; this.__hash = undefined; this.__altered = true; return this; } return emptyMap(); }; // @pragma Composition Map.prototype.merge = function(/*...iters*/) { return mergeIntoMapWith(this, undefined, arguments); }; Map.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1); return mergeIntoMapWith(this, merger, iters); }; Map.prototype.mergeIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1); return this.updateIn( keyPath, emptyMap(), function(m ) {return typeof m.merge === 'function' ? m.merge.apply(m, iters) : iters[iters.length - 1]} ); }; Map.prototype.mergeDeep = function(/*...iters*/) { return mergeIntoMapWith(this, deepMerger, arguments); }; Map.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1); return mergeIntoMapWith(this, deepMergerWith(merger), iters); }; Map.prototype.mergeDeepIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1); return this.updateIn( keyPath, emptyMap(), function(m ) {return typeof m.mergeDeep === 'function' ? m.mergeDeep.apply(m, iters) : iters[iters.length - 1]} ); }; Map.prototype.sort = function(comparator) { // Late binding return OrderedMap(sortFactory(this, comparator)); }; Map.prototype.sortBy = function(mapper, comparator) { // Late binding return OrderedMap(sortFactory(this, comparator, mapper)); }; // @pragma Mutability Map.prototype.withMutations = function(fn) { var mutable = this.asMutable(); fn(mutable); return mutable.wasAltered() ? mutable.__ensureOwner(this.__ownerID) : this; }; Map.prototype.asMutable = function() { return this.__ownerID ? this : this.__ensureOwner(new OwnerID()); }; Map.prototype.asImmutable = function() { return this.__ensureOwner(); }; Map.prototype.wasAltered = function() { return this.__altered; }; Map.prototype.__iterator = function(type, reverse) { return new MapIterator(this, type, reverse); }; Map.prototype.__iterate = function(fn, reverse) {var this$0 = this; var iterations = 0; this._root && this._root.iterate(function(entry ) { iterations++; return fn(entry[1], entry[0], this$0); }, reverse); return iterations; }; Map.prototype.__ensureOwner = function(ownerID) { if (ownerID === this.__ownerID) { return this; } if (!ownerID) { this.__ownerID = ownerID; this.__altered = false; return this; } return makeMap(this.size, this._root, ownerID, this.__hash); }; function isMap(maybeMap) { return !!(maybeMap && maybeMap[IS_MAP_SENTINEL]); } Map.isMap = isMap; var IS_MAP_SENTINEL = '@@__IMMUTABLE_MAP__@@'; var MapPrototype = Map.prototype; MapPrototype[IS_MAP_SENTINEL] = true; MapPrototype[DELETE] = MapPrototype.remove; MapPrototype.removeIn = MapPrototype.deleteIn; // #pragma Trie Nodes function ArrayMapNode(ownerID, entries) { this.ownerID = ownerID; this.entries = entries; } ArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) { var entries = this.entries; for (var ii = 0, len = entries.length; ii < len; ii++) { if (is(key, entries[ii][0])) { return entries[ii][1]; } } return notSetValue; }; ArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { var removed = value === NOT_SET; var entries = this.entries; var idx = 0; for (var len = entries.length; idx < len; idx++) { if (is(key, entries[idx][0])) { break; } } var exists = idx < len; if (exists ? entries[idx][1] === value : removed) { return this; } SetRef(didAlter); (removed || !exists) && SetRef(didChangeSize); if (removed && entries.length === 1) { return; // undefined } if (!exists && !removed && entries.length >= MAX_ARRAY_MAP_SIZE) { return createNodes(ownerID, entries, key, value); } var isEditable = ownerID && ownerID === this.ownerID; var newEntries = isEditable ? entries : arrCopy(entries); if (exists) { if (removed) { idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop()); } else { newEntries[idx] = [key, value]; } } else { newEntries.push([key, value]); } if (isEditable) { this.entries = newEntries; return this; } return new ArrayMapNode(ownerID, newEntries); }; function BitmapIndexedNode(ownerID, bitmap, nodes) { this.ownerID = ownerID; this.bitmap = bitmap; this.nodes = nodes; } BitmapIndexedNode.prototype.get = function(shift, keyHash, key, notSetValue) { if (keyHash === undefined) { keyHash = hash(key); } var bit = (1 << ((shift === 0 ? keyHash : keyHash >>> shift) & MASK)); var bitmap = this.bitmap; return (bitmap & bit) === 0 ? notSetValue : this.nodes[popCount(bitmap & (bit - 1))].get(shift + SHIFT, keyHash, key, notSetValue); }; BitmapIndexedNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { if (keyHash === undefined) { keyHash = hash(key); } var keyHashFrag = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; var bit = 1 << keyHashFrag; var bitmap = this.bitmap; var exists = (bitmap & bit) !== 0; if (!exists && value === NOT_SET) { return this; } var idx = popCount(bitmap & (bit - 1)); var nodes = this.nodes; var node = exists ? nodes[idx] : undefined; var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter); if (newNode === node) { return this; } if (!exists && newNode && nodes.length >= MAX_BITMAP_INDEXED_SIZE) { return expandNodes(ownerID, nodes, bitmap, keyHashFrag, newNode); } if (exists && !newNode && nodes.length === 2 && isLeafNode(nodes[idx ^ 1])) { return nodes[idx ^ 1]; } if (exists && newNode && nodes.length === 1 && isLeafNode(newNode)) { return newNode; } var isEditable = ownerID && ownerID === this.ownerID; var newBitmap = exists ? newNode ? bitmap : bitmap ^ bit : bitmap | bit; var newNodes = exists ? newNode ? setIn(nodes, idx, newNode, isEditable) : spliceOut(nodes, idx, isEditable) : spliceIn(nodes, idx, newNode, isEditable); if (isEditable) { this.bitmap = newBitmap; this.nodes = newNodes; return this; } return new BitmapIndexedNode(ownerID, newBitmap, newNodes); }; function HashArrayMapNode(ownerID, count, nodes) { this.ownerID = ownerID; this.count = count; this.nodes = nodes; } HashArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) { if (keyHash === undefined) { keyHash = hash(key); } var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; var node = this.nodes[idx]; return node ? node.get(shift + SHIFT, keyHash, key, notSetValue) : notSetValue; }; HashArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { if (keyHash === undefined) { keyHash = hash(key); } var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; var removed = value === NOT_SET; var nodes = this.nodes; var node = nodes[idx]; if (removed && !node) { return this; } var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter); if (newNode === node) { return this; } var newCount = this.count; if (!node) { newCount++; } else if (!newNode) { newCount--; if (newCount < MIN_HASH_ARRAY_MAP_SIZE) { return packNodes(ownerID, nodes, newCount, idx); } } var isEditable = ownerID && ownerID === this.ownerID; var newNodes = setIn(nodes, idx, newNode, isEditable); if (isEditable) { this.count = newCount; this.nodes = newNodes; return this; } return new HashArrayMapNode(ownerID, newCount, newNodes); }; function HashCollisionNode(ownerID, keyHash, entries) { this.ownerID = ownerID; this.keyHash = keyHash; this.entries = entries; } HashCollisionNode.prototype.get = function(shift, keyHash, key, notSetValue) { var entries = this.entries; for (var ii = 0, len = entries.length; ii < len; ii++) { if (is(key, entries[ii][0])) { return entries[ii][1]; } } return notSetValue; }; HashCollisionNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { if (keyHash === undefined) { keyHash = hash(key); } var removed = value === NOT_SET; if (keyHash !== this.keyHash) { if (removed) { return this; } SetRef(didAlter); SetRef(didChangeSize); return mergeIntoNode(this, ownerID, shift, keyHash, [key, value]); } var entries = this.entries; var idx = 0; for (var len = entries.length; idx < len; idx++) { if (is(key, entries[idx][0])) { break; } } var exists = idx < len; if (exists ? entries[idx][1] === value : removed) { return this; } SetRef(didAlter); (removed || !exists) && SetRef(didChangeSize); if (removed && len === 2) { return new ValueNode(ownerID, this.keyHash, entries[idx ^ 1]); } var isEditable = ownerID && ownerID === this.ownerID; var newEntries = isEditable ? entries : arrCopy(entries); if (exists) { if (removed) { idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop()); } else { newEntries[idx] = [key, value]; } } else { newEntries.push([key, value]); } if (isEditable) { this.entries = newEntries; return this; } return new HashCollisionNode(ownerID, this.keyHash, newEntries); }; function ValueNode(ownerID, keyHash, entry) { this.ownerID = ownerID; this.keyHash = keyHash; this.entry = entry; } ValueNode.prototype.get = function(shift, keyHash, key, notSetValue) { return is(key, this.entry[0]) ? this.entry[1] : notSetValue; }; ValueNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { var removed = value === NOT_SET; var keyMatch = is(key, this.entry[0]); if (keyMatch ? value === this.entry[1] : removed) { return this; } SetRef(didAlter); if (removed) { SetRef(didChangeSize); return; // undefined } if (keyMatch) { if (ownerID && ownerID === this.ownerID) { this.entry[1] = value; return this; } return new ValueNode(ownerID, this.keyHash, [key, value]); } SetRef(didChangeSize); return mergeIntoNode(this, ownerID, shift, hash(key), [key, value]); }; // #pragma Iterators ArrayMapNode.prototype.iterate = HashCollisionNode.prototype.iterate = function (fn, reverse) { var entries = this.entries; for (var ii = 0, maxIndex = entries.length - 1; ii <= maxIndex; ii++) { if (fn(entries[reverse ? maxIndex - ii : ii]) === false) { return false; } } } BitmapIndexedNode.prototype.iterate = HashArrayMapNode.prototype.iterate = function (fn, reverse) { var nodes = this.nodes; for (var ii = 0, maxIndex = nodes.length - 1; ii <= maxIndex; ii++) { var node = nodes[reverse ? maxIndex - ii : ii]; if (node && node.iterate(fn, reverse) === false) { return false; } } } ValueNode.prototype.iterate = function (fn, reverse) { return fn(this.entry); } createClass(MapIterator, Iterator); function MapIterator(map, type, reverse) { this._type = type; this._reverse = reverse; this._stack = map._root && mapIteratorFrame(map._root); } MapIterator.prototype.next = function() { var type = this._type; var stack = this._stack; while (stack) { var node = stack.node; var index = stack.index++; var maxIndex; if (node.entry) { if (index === 0) { return mapIteratorValue(type, node.entry); } } else if (node.entries) { maxIndex = node.entries.length - 1; if (index <= maxIndex) { return mapIteratorValue(type, node.entries[this._reverse ? maxIndex - index : index]); } } else { maxIndex = node.nodes.length - 1; if (index <= maxIndex) { var subNode = node.nodes[this._reverse ? maxIndex - index : index]; if (subNode) { if (subNode.entry) { return mapIteratorValue(type, subNode.entry); } stack = this._stack = mapIteratorFrame(subNode, stack); } continue; } } stack = this._stack = this._stack.__prev; } return iteratorDone(); }; function mapIteratorValue(type, entry) { return iteratorValue(type, entry[0], entry[1]); } function mapIteratorFrame(node, prev) { return { node: node, index: 0, __prev: prev }; } function makeMap(size, root, ownerID, hash) { var map = Object.create(MapPrototype); map.size = size; map._root = root; map.__ownerID = ownerID; map.__hash = hash; map.__altered = false; return map; } var EMPTY_MAP; function emptyMap() { return EMPTY_MAP || (EMPTY_MAP = makeMap(0)); } function updateMap(map, k, v) { var newRoot; var newSize; if (!map._root) { if (v === NOT_SET) { return map; } newSize = 1; newRoot = new ArrayMapNode(map.__ownerID, [[k, v]]); } else { var didChangeSize = MakeRef(CHANGE_LENGTH); var didAlter = MakeRef(DID_ALTER); newRoot = updateNode(map._root, map.__ownerID, 0, undefined, k, v, didChangeSize, didAlter); if (!didAlter.value) { return map; } newSize = map.size + (didChangeSize.value ? v === NOT_SET ? -1 : 1 : 0); } if (map.__ownerID) { map.size = newSize; map._root = newRoot; map.__hash = undefined; map.__altered = true; return map; } return newRoot ? makeMap(newSize, newRoot) : emptyMap(); } function updateNode(node, ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { if (!node) { if (value === NOT_SET) { return node; } SetRef(didAlter); SetRef(didChangeSize); return new ValueNode(ownerID, keyHash, [key, value]); } return node.update(ownerID, shift, keyHash, key, value, didChangeSize, didAlter); } function isLeafNode(node) { return node.constructor === ValueNode || node.constructor === HashCollisionNode; } function mergeIntoNode(node, ownerID, shift, keyHash, entry) { if (node.keyHash === keyHash) { return new HashCollisionNode(ownerID, keyHash, [node.entry, entry]); } var idx1 = (shift === 0 ? node.keyHash : node.keyHash >>> shift) & MASK; var idx2 = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; var newNode; var nodes = idx1 === idx2 ? [mergeIntoNode(node, ownerID, shift + SHIFT, keyHash, entry)] : ((newNode = new ValueNode(ownerID, keyHash, entry)), idx1 < idx2 ? [node, newNode] : [newNode, node]); return new BitmapIndexedNode(ownerID, (1 << idx1) | (1 << idx2), nodes); } function createNodes(ownerID, entries, key, value) { if (!ownerID) { ownerID = new OwnerID(); } var node = new ValueNode(ownerID, hash(key), [key, value]); for (var ii = 0; ii < entries.length; ii++) { var entry = entries[ii]; node = node.update(ownerID, 0, undefined, entry[0], entry[1]); } return node; } function packNodes(ownerID, nodes, count, excluding) { var bitmap = 0; var packedII = 0; var packedNodes = new Array(count); for (var ii = 0, bit = 1, len = nodes.length; ii < len; ii++, bit <<= 1) { var node = nodes[ii]; if (node !== undefined && ii !== excluding) { bitmap |= bit; packedNodes[packedII++] = node; } } return new BitmapIndexedNode(ownerID, bitmap, packedNodes); } function expandNodes(ownerID, nodes, bitmap, including, node) { var count = 0; var expandedNodes = new Array(SIZE); for (var ii = 0; bitmap !== 0; ii++, bitmap >>>= 1) { expandedNodes[ii] = bitmap & 1 ? nodes[count++] : undefined; } expandedNodes[including] = node; return new HashArrayMapNode(ownerID, count + 1, expandedNodes); } function mergeIntoMapWith(map, merger, iterables) { var iters = []; for (var ii = 0; ii < iterables.length; ii++) { var value = iterables[ii]; var iter = KeyedIterable(value); if (!isIterable(value)) { iter = iter.map(function(v ) {return fromJS(v)}); } iters.push(iter); } return mergeIntoCollectionWith(map, merger, iters); } function deepMerger(existing, value, key) { return existing && existing.mergeDeep && isIterable(value) ? existing.mergeDeep(value) : is(existing, value) ? existing : value; } function deepMergerWith(merger) { return function(existing, value, key) { if (existing && existing.mergeDeepWith && isIterable(value)) { return existing.mergeDeepWith(merger, value); } var nextValue = merger(existing, value, key); return is(existing, nextValue) ? existing : nextValue; }; } function mergeIntoCollectionWith(collection, merger, iters) { iters = iters.filter(function(x ) {return x.size !== 0}); if (iters.length === 0) { return collection; } if (collection.size === 0 && !collection.__ownerID && iters.length === 1) { return collection.constructor(iters[0]); } return collection.withMutations(function(collection ) { var mergeIntoMap = merger ? function(value, key) { collection.update(key, NOT_SET, function(existing ) {return existing === NOT_SET ? value : merger(existing, value, key)} ); } : function(value, key) { collection.set(key, value); } for (var ii = 0; ii < iters.length; ii++) { iters[ii].forEach(mergeIntoMap); } }); } function updateInDeepMap(existing, keyPathIter, notSetValue, updater) { var isNotSet = existing === NOT_SET; var step = keyPathIter.next(); if (step.done) { var existingValue = isNotSet ? notSetValue : existing; var newValue = updater(existingValue); return newValue === existingValue ? existing : newValue; } invariant( isNotSet || (existing && existing.set), 'invalid keyPath' ); var key = step.value; var nextExisting = isNotSet ? NOT_SET : existing.get(key, NOT_SET); var nextUpdated = updateInDeepMap( nextExisting, keyPathIter, notSetValue, updater ); return nextUpdated === nextExisting ? existing : nextUpdated === NOT_SET ? existing.remove(key) : (isNotSet ? emptyMap() : existing).set(key, nextUpdated); } function popCount(x) { x = x - ((x >> 1) & 0x55555555); x = (x & 0x33333333) + ((x >> 2) & 0x33333333); x = (x + (x >> 4)) & 0x0f0f0f0f; x = x + (x >> 8); x = x + (x >> 16); return x & 0x7f; } function setIn(array, idx, val, canEdit) { var newArray = canEdit ? array : arrCopy(array); newArray[idx] = val; return newArray; } function spliceIn(array, idx, val, canEdit) { var newLen = array.length + 1; if (canEdit && idx + 1 === newLen) { array[idx] = val; return array; } var newArray = new Array(newLen); var after = 0; for (var ii = 0; ii < newLen; ii++) { if (ii === idx) { newArray[ii] = val; after = -1; } else { newArray[ii] = array[ii + after]; } } return newArray; } function spliceOut(array, idx, canEdit) { var newLen = array.length - 1; if (canEdit && idx === newLen) { array.pop(); return array; } var newArray = new Array(newLen); var after = 0; for (var ii = 0; ii < newLen; ii++) { if (ii === idx) { after = 1; } newArray[ii] = array[ii + after]; } return newArray; } var MAX_ARRAY_MAP_SIZE = SIZE / 4; var MAX_BITMAP_INDEXED_SIZE = SIZE / 2; var MIN_HASH_ARRAY_MAP_SIZE = SIZE / 4; createClass(List, IndexedCollection); // @pragma Construction function List(value) { var empty = emptyList(); if (value === null || value === undefined) { return empty; } if (isList(value)) { return value; } var iter = IndexedIterable(value); var size = iter.size; if (size === 0) { return empty; } assertNotInfinite(size); if (size > 0 && size < SIZE) { return makeList(0, size, SHIFT, null, new VNode(iter.toArray())); } return empty.withMutations(function(list ) { list.setSize(size); iter.forEach(function(v, i) {return list.set(i, v)}); }); } List.of = function(/*...values*/) { return this(arguments); }; List.prototype.toString = function() { return this.__toString('List [', ']'); }; // @pragma Access List.prototype.get = function(index, notSetValue) { index = wrapIndex(this, index); if (index >= 0 && index < this.size) { index += this._origin; var node = listNodeFor(this, index); return node && node.array[index & MASK]; } return notSetValue; }; // @pragma Modification List.prototype.set = function(index, value) { return updateList(this, index, value); }; List.prototype.remove = function(index) { return !this.has(index) ? this : index === 0 ? this.shift() : index === this.size - 1 ? this.pop() : this.splice(index, 1); }; List.prototype.insert = function(index, value) { return this.splice(index, 0, value); }; List.prototype.clear = function() { if (this.size === 0) { return this; } if (this.__ownerID) { this.size = this._origin = this._capacity = 0; this._level = SHIFT; this._root = this._tail = null; this.__hash = undefined; this.__altered = true; return this; } return emptyList(); }; List.prototype.push = function(/*...values*/) { var values = arguments; var oldSize = this.size; return this.withMutations(function(list ) { setListBounds(list, 0, oldSize + values.length); for (var ii = 0; ii < values.length; ii++) { list.set(oldSize + ii, values[ii]); } }); }; List.prototype.pop = function() { return setListBounds(this, 0, -1); }; List.prototype.unshift = function(/*...values*/) { var values = arguments; return this.withMutations(function(list ) { setListBounds(list, -values.length); for (var ii = 0; ii < values.length; ii++) { list.set(ii, values[ii]); } }); }; List.prototype.shift = function() { return setListBounds(this, 1); }; // @pragma Composition List.prototype.merge = function(/*...iters*/) { return mergeIntoListWith(this, undefined, arguments); }; List.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1); return mergeIntoListWith(this, merger, iters); }; List.prototype.mergeDeep = function(/*...iters*/) { return mergeIntoListWith(this, deepMerger, arguments); }; List.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1); return mergeIntoListWith(this, deepMergerWith(merger), iters); }; List.prototype.setSize = function(size) { return setListBounds(this, 0, size); }; // @pragma Iteration List.prototype.slice = function(begin, end) { var size = this.size; if (wholeSlice(begin, end, size)) { return this; } return setListBounds( this, resolveBegin(begin, size), resolveEnd(end, size) ); }; List.prototype.__iterator = function(type, reverse) { var index = 0; var values = iterateList(this, reverse); return new Iterator(function() { var value = values(); return value === DONE ? iteratorDone() : iteratorValue(type, index++, value); }); }; List.prototype.__iterate = function(fn, reverse) { var index = 0; var values = iterateList(this, reverse); var value; while ((value = values()) !== DONE) { if (fn(value, index++, this) === false) { break; } } return index; }; List.prototype.__ensureOwner = function(ownerID) { if (ownerID === this.__ownerID) { return this; } if (!ownerID) { this.__ownerID = ownerID; return this; } return makeList(this._origin, this._capacity, this._level, this._root, this._tail, ownerID, this.__hash); }; function isList(maybeList) { return !!(maybeList && maybeList[IS_LIST_SENTINEL]); } List.isList = isList; var IS_LIST_SENTINEL = '@@__IMMUTABLE_LIST__@@'; var ListPrototype = List.prototype; ListPrototype[IS_LIST_SENTINEL] = true; ListPrototype[DELETE] = ListPrototype.remove; ListPrototype.setIn = MapPrototype.setIn; ListPrototype.deleteIn = ListPrototype.removeIn = MapPrototype.removeIn; ListPrototype.update = MapPrototype.update; ListPrototype.updateIn = MapPrototype.updateIn; ListPrototype.mergeIn = MapPrototype.mergeIn; ListPrototype.mergeDeepIn = MapPrototype.mergeDeepIn; ListPrototype.withMutations = MapPrototype.withMutations; ListPrototype.asMutable = MapPrototype.asMutable; ListPrototype.asImmutable = MapPrototype.asImmutable; ListPrototype.wasAltered = MapPrototype.wasAltered; function VNode(array, ownerID) { this.array = array; this.ownerID = ownerID; } // TODO: seems like these methods are very similar VNode.prototype.removeBefore = function(ownerID, level, index) { if (index === level ? 1 << level : 0 || this.array.length === 0) { return this; } var originIndex = (index >>> level) & MASK; if (originIndex >= this.array.length) { return new VNode([], ownerID); } var removingFirst = originIndex === 0; var newChild; if (level > 0) { var oldChild = this.array[originIndex]; newChild = oldChild && oldChild.removeBefore(ownerID, level - SHIFT, index); if (newChild === oldChild && removingFirst) { return this; } } if (removingFirst && !newChild) { return this; } var editable = editableVNode(this, ownerID); if (!removingFirst) { for (var ii = 0; ii < originIndex; ii++) { editable.array[ii] = undefined; } } if (newChild) { editable.array[originIndex] = newChild; } return editable; }; VNode.prototype.removeAfter = function(ownerID, level, index) { if (index === (level ? 1 << level : 0) || this.array.length === 0) { return this; } var sizeIndex = ((index - 1) >>> level) & MASK; if (sizeIndex >= this.array.length) { return this; } var newChild; if (level > 0) { var oldChild = this.array[sizeIndex]; newChild = oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index); if (newChild === oldChild && sizeIndex === this.array.length - 1) { return this; } } var editable = editableVNode(this, ownerID); editable.array.splice(sizeIndex + 1); if (newChild) { editable.array[sizeIndex] = newChild; } return editable; }; var DONE = {}; function iterateList(list, reverse) { var left = list._origin; var right = list._capacity; var tailPos = getTailOffset(right); var tail = list._tail; return iterateNodeOrLeaf(list._root, list._level, 0); function iterateNodeOrLeaf(node, level, offset) { return level === 0 ? iterateLeaf(node, offset) : iterateNode(node, level, offset); } function iterateLeaf(node, offset) { var array = offset === tailPos ? tail && tail.array : node && node.array; var from = offset > left ? 0 : left - offset; var to = right - offset; if (to > SIZE) { to = SIZE; } return function() { if (from === to) { return DONE; } var idx = reverse ? --to : from++; return array && array[idx]; }; } function iterateNode(node, level, offset) { var values; var array = node && node.array; var from = offset > left ? 0 : (left - offset) >> level; var to = ((right - offset) >> level) + 1; if (to > SIZE) { to = SIZE; } return function() { do { if (values) { var value = values(); if (value !== DONE) { return value; } values = null; } if (from === to) { return DONE; } var idx = reverse ? --to : from++; values = iterateNodeOrLeaf( array && array[idx], level - SHIFT, offset + (idx << level) ); } while (true); }; } } function makeList(origin, capacity, level, root, tail, ownerID, hash) { var list = Object.create(ListPrototype); list.size = capacity - origin; list._origin = origin; list._capacity = capacity; list._level = level; list._root = root; list._tail = tail; list.__ownerID = ownerID; list.__hash = hash; list.__altered = false; return list; } var EMPTY_LIST; function emptyList() { return EMPTY_LIST || (EMPTY_LIST = makeList(0, 0, SHIFT)); } function updateList(list, index, value) { index = wrapIndex(list, index); if (index !== index) { return list; } if (index >= list.size || index < 0) { return list.withMutations(function(list ) { index < 0 ? setListBounds(list, index).set(0, value) : setListBounds(list, 0, index + 1).set(index, value) }); } index += list._origin; var newTail = list._tail; var newRoot = list._root; var didAlter = MakeRef(DID_ALTER); if (index >= getTailOffset(list._capacity)) { newTail = updateVNode(newTail, list.__ownerID, 0, index, value, didAlter); } else { newRoot = updateVNode(newRoot, list.__ownerID, list._level, index, value, didAlter); } if (!didAlter.value) { return list; } if (list.__ownerID) { list._root = newRoot; list._tail = newTail; list.__hash = undefined; list.__altered = true; return list; } return makeList(list._origin, list._capacity, list._level, newRoot, newTail); } function updateVNode(node, ownerID, level, index, value, didAlter) { var idx = (index >>> level) & MASK; var nodeHas = node && idx < node.array.length; if (!nodeHas && value === undefined) { return node; } var newNode; if (level > 0) { var lowerNode = node && node.array[idx]; var newLowerNode = updateVNode(lowerNode, ownerID, level - SHIFT, index, value, didAlter); if (newLowerNode === lowerNode) { return node; } newNode = editableVNode(node, ownerID); newNode.array[idx] = newLowerNode; return newNode; } if (nodeHas && node.array[idx] === value) { return node; } SetRef(didAlter); newNode = editableVNode(node, ownerID); if (value === undefined && idx === newNode.array.length - 1) { newNode.array.pop(); } else { newNode.array[idx] = value; } return newNode; } function editableVNode(node, ownerID) { if (ownerID && node && ownerID === node.ownerID) { return node; } return new VNode(node ? node.array.slice() : [], ownerID); } function listNodeFor(list, rawIndex) { if (rawIndex >= getTailOffset(list._capacity)) { return list._tail; } if (rawIndex < 1 << (list._level + SHIFT)) { var node = list._root; var level = list._level; while (node && level > 0) { node = node.array[(rawIndex >>> level) & MASK]; level -= SHIFT; } return node; } } function setListBounds(list, begin, end) { // Sanitize begin & end using this shorthand for ToInt32(argument) // http://www.ecma-international.org/ecma-262/6.0/#sec-toint32 if (begin !== undefined) { begin = begin | 0; } if (end !== undefined) { end = end | 0; } var owner = list.__ownerID || new OwnerID(); var oldOrigin = list._origin; var oldCapacity = list._capacity; var newOrigin = oldOrigin + begin; var newCapacity = end === undefined ? oldCapacity : end < 0 ? oldCapacity + end : oldOrigin + end; if (newOrigin === oldOrigin && newCapacity === oldCapacity) { return list; } // If it's going to end after it starts, it's empty. if (newOrigin >= newCapacity) { return list.clear(); } var newLevel = list._level; var newRoot = list._root; // New origin might need creating a higher root. var offsetShift = 0; while (newOrigin + offsetShift < 0) { newRoot = new VNode(newRoot && newRoot.array.length ? [undefined, newRoot] : [], owner); newLevel += SHIFT; offsetShift += 1 << newLevel; } if (offsetShift) { newOrigin += offsetShift; oldOrigin += offsetShift; newCapacity += offsetShift; oldCapacity += offsetShift; } var oldTailOffset = getTailOffset(oldCapacity); var newTailOffset = getTailOffset(newCapacity); // New size might need creating a higher root. while (newTailOffset >= 1 << (newLevel + SHIFT)) { newRoot = new VNode(newRoot && newRoot.array.length ? [newRoot] : [], owner); newLevel += SHIFT; } // Locate or create the new tail. var oldTail = list._tail; var newTail = newTailOffset < oldTailOffset ? listNodeFor(list, newCapacity - 1) : newTailOffset > oldTailOffset ? new VNode([], owner) : oldTail; // Merge Tail into tree. if (oldTail && newTailOffset > oldTailOffset && newOrigin < oldCapacity && oldTail.array.length) { newRoot = editableVNode(newRoot, owner); var node = newRoot; for (var level = newLevel; level > SHIFT; level -= SHIFT) { var idx = (oldTailOffset >>> level) & MASK; node = node.array[idx] = editableVNode(node.array[idx], owner); } node.array[(oldTailOffset >>> SHIFT) & MASK] = oldTail; } // If the size has been reduced, there's a chance the tail needs to be trimmed. if (newCapacity < oldCapacity) { newTail = newTail && newTail.removeAfter(owner, 0, newCapacity); } // If the new origin is within the tail, then we do not need a root. if (newOrigin >= newTailOffset) { newOrigin -= newTailOffset; newCapacity -= newTailOffset; newLevel = SHIFT; newRoot = null; newTail = newTail && newTail.removeBefore(owner, 0, newOrigin); // Otherwise, if the root has been trimmed, garbage collect. } else if (newOrigin > oldOrigin || newTailOffset < oldTailOffset) { offsetShift = 0; // Identify the new top root node of the subtree of the old root. while (newRoot) { var beginIndex = (newOrigin >>> newLevel) & MASK; if (beginIndex !== (newTailOffset >>> newLevel) & MASK) { break; } if (beginIndex) { offsetShift += (1 << newLevel) * beginIndex; } newLevel -= SHIFT; newRoot = newRoot.array[beginIndex]; } // Trim the new sides of the new root. if (newRoot && newOrigin > oldOrigin) { newRoot = newRoot.removeBefore(owner, newLevel, newOrigin - offsetShift); } if (newRoot && newTailOffset < oldTailOffset) { newRoot = newRoot.removeAfter(owner, newLevel, newTailOffset - offsetShift); } if (offsetShift) { newOrigin -= offsetShift; newCapacity -= offsetShift; } } if (list.__ownerID) { list.size = newCapacity - newOrigin; list._origin = newOrigin; list._capacity = newCapacity; list._level = newLevel; list._root = newRoot; list._tail = newTail; list.__hash = undefined; list.__altered = true; return list; } return makeList(newOrigin, newCapacity, newLevel, newRoot, newTail); } function mergeIntoListWith(list, merger, iterables) { var iters = []; var maxSize = 0; for (var ii = 0; ii < iterables.length; ii++) { var value = iterables[ii]; var iter = IndexedIterable(value); if (iter.size > maxSize) { maxSize = iter.size; } if (!isIterable(value)) { iter = iter.map(function(v ) {return fromJS(v)}); } iters.push(iter); } if (maxSize > list.size) { list = list.setSize(maxSize); } return mergeIntoCollectionWith(list, merger, iters); } function getTailOffset(size) { return size < SIZE ? 0 : (((size - 1) >>> SHIFT) << SHIFT); } createClass(OrderedMap, Map); // @pragma Construction function OrderedMap(value) { return value === null || value === undefined ? emptyOrderedMap() : isOrderedMap(value) ? value : emptyOrderedMap().withMutations(function(map ) { var iter = KeyedIterable(value); assertNotInfinite(iter.size); iter.forEach(function(v, k) {return map.set(k, v)}); }); } OrderedMap.of = function(/*...values*/) { return this(arguments); }; OrderedMap.prototype.toString = function() { return this.__toString('OrderedMap {', '}'); }; // @pragma Access OrderedMap.prototype.get = function(k, notSetValue) { var index = this._map.get(k); return index !== undefined ? this._list.get(index)[1] : notSetValue; }; // @pragma Modification OrderedMap.prototype.clear = function() { if (this.size === 0) { return this; } if (this.__ownerID) { this.size = 0; this._map.clear(); this._list.clear(); return this; } return emptyOrderedMap(); }; OrderedMap.prototype.set = function(k, v) { return updateOrderedMap(this, k, v); }; OrderedMap.prototype.remove = function(k) { return updateOrderedMap(this, k, NOT_SET); }; OrderedMap.prototype.wasAltered = function() { return this._map.wasAltered() || this._list.wasAltered(); }; OrderedMap.prototype.__iterate = function(fn, reverse) {var this$0 = this; return this._list.__iterate( function(entry ) {return entry && fn(entry[1], entry[0], this$0)}, reverse ); }; OrderedMap.prototype.__iterator = function(type, reverse) { return this._list.fromEntrySeq().__iterator(type, reverse); }; OrderedMap.prototype.__ensureOwner = function(ownerID) { if (ownerID === this.__ownerID) { return this; } var newMap = this._map.__ensureOwner(ownerID); var newList = this._list.__ensureOwner(ownerID); if (!ownerID) { this.__ownerID = ownerID; this._map = newMap; this._list = newList; return this; } return makeOrderedMap(newMap, newList, ownerID, this.__hash); }; function isOrderedMap(maybeOrderedMap) { return isMap(maybeOrderedMap) && isOrdered(maybeOrderedMap); } OrderedMap.isOrderedMap = isOrderedMap; OrderedMap.prototype[IS_ORDERED_SENTINEL] = true; OrderedMap.prototype[DELETE] = OrderedMap.prototype.remove; function makeOrderedMap(map, list, ownerID, hash) { var omap = Object.create(OrderedMap.prototype); omap.size = map ? map.size : 0; omap._map = map; omap._list = list; omap.__ownerID = ownerID; omap.__hash = hash; return omap; } var EMPTY_ORDERED_MAP; function emptyOrderedMap() { return EMPTY_ORDERED_MAP || (EMPTY_ORDERED_MAP = makeOrderedMap(emptyMap(), emptyList())); } function updateOrderedMap(omap, k, v) { var map = omap._map; var list = omap._list; var i = map.get(k); var has = i !== undefined; var newMap; var newList; if (v === NOT_SET) { // removed if (!has) { return omap; } if (list.size >= SIZE && list.size >= map.size * 2) { newList = list.filter(function(entry, idx) {return entry !== undefined && i !== idx}); newMap = newList.toKeyedSeq().map(function(entry ) {return entry[0]}).flip().toMap(); if (omap.__ownerID) { newMap.__ownerID = newList.__ownerID = omap.__ownerID; } } else { newMap = map.remove(k); newList = i === list.size - 1 ? list.pop() : list.set(i, undefined); } } else { if (has) { if (v === list.get(i)[1]) { return omap; } newMap = map; newList = list.set(i, [k, v]); } else { newMap = map.set(k, list.size); newList = list.set(list.size, [k, v]); } } if (omap.__ownerID) { omap.size = newMap.size; omap._map = newMap; omap._list = newList; omap.__hash = undefined; return omap; } return makeOrderedMap(newMap, newList); } createClass(ToKeyedSequence, KeyedSeq); function ToKeyedSequence(indexed, useKeys) { this._iter = indexed; this._useKeys = useKeys; this.size = indexed.size; } ToKeyedSequence.prototype.get = function(key, notSetValue) { return this._iter.get(key, notSetValue); }; ToKeyedSequence.prototype.has = function(key) { return this._iter.has(key); }; ToKeyedSequence.prototype.valueSeq = function() { return this._iter.valueSeq(); }; ToKeyedSequence.prototype.reverse = function() {var this$0 = this; var reversedSequence = reverseFactory(this, true); if (!this._useKeys) { reversedSequence.valueSeq = function() {return this$0._iter.toSeq().reverse()}; } return reversedSequence; }; ToKeyedSequence.prototype.map = function(mapper, context) {var this$0 = this; var mappedSequence = mapFactory(this, mapper, context); if (!this._useKeys) { mappedSequence.valueSeq = function() {return this$0._iter.toSeq().map(mapper, context)}; } return mappedSequence; }; ToKeyedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; var ii; return this._iter.__iterate( this._useKeys ? function(v, k) {return fn(v, k, this$0)} : ((ii = reverse ? resolveSize(this) : 0), function(v ) {return fn(v, reverse ? --ii : ii++, this$0)}), reverse ); }; ToKeyedSequence.prototype.__iterator = function(type, reverse) { if (this._useKeys) { return this._iter.__iterator(type, reverse); } var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); var ii = reverse ? resolveSize(this) : 0; return new Iterator(function() { var step = iterator.next(); return step.done ? step : iteratorValue(type, reverse ? --ii : ii++, step.value, step); }); }; ToKeyedSequence.prototype[IS_ORDERED_SENTINEL] = true; createClass(ToIndexedSequence, IndexedSeq); function ToIndexedSequence(iter) { this._iter = iter; this.size = iter.size; } ToIndexedSequence.prototype.includes = function(value) { return this._iter.includes(value); }; ToIndexedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; var iterations = 0; return this._iter.__iterate(function(v ) {return fn(v, iterations++, this$0)}, reverse); }; ToIndexedSequence.prototype.__iterator = function(type, reverse) { var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); var iterations = 0; return new Iterator(function() { var step = iterator.next(); return step.done ? step : iteratorValue(type, iterations++, step.value, step) }); }; createClass(ToSetSequence, SetSeq); function ToSetSequence(iter) { this._iter = iter; this.size = iter.size; } ToSetSequence.prototype.has = function(key) { return this._iter.includes(key); }; ToSetSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; return this._iter.__iterate(function(v ) {return fn(v, v, this$0)}, reverse); }; ToSetSequence.prototype.__iterator = function(type, reverse) { var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); return new Iterator(function() { var step = iterator.next(); return step.done ? step : iteratorValue(type, step.value, step.value, step); }); }; createClass(FromEntriesSequence, KeyedSeq); function FromEntriesSequence(entries) { this._iter = entries; this.size = entries.size; } FromEntriesSequence.prototype.entrySeq = function() { return this._iter.toSeq(); }; FromEntriesSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; return this._iter.__iterate(function(entry ) { // Check if entry exists first so array access doesn't throw for holes // in the parent iteration. if (entry) { validateEntry(entry); var indexedIterable = isIterable(entry); return fn( indexedIterable ? entry.get(1) : entry[1], indexedIterable ? entry.get(0) : entry[0], this$0 ); } }, reverse); }; FromEntriesSequence.prototype.__iterator = function(type, reverse) { var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); return new Iterator(function() { while (true) { var step = iterator.next(); if (step.done) { return step; } var entry = step.value; // Check if entry exists first so array access doesn't throw for holes // in the parent iteration. if (entry) { validateEntry(entry); var indexedIterable = isIterable(entry); return iteratorValue( type, indexedIterable ? entry.get(0) : entry[0], indexedIterable ? entry.get(1) : entry[1], step ); } } }); }; ToIndexedSequence.prototype.cacheResult = ToKeyedSequence.prototype.cacheResult = ToSetSequence.prototype.cacheResult = FromEntriesSequence.prototype.cacheResult = cacheResultThrough; function flipFactory(iterable) { var flipSequence = makeSequence(iterable); flipSequence._iter = iterable; flipSequence.size = iterable.size; flipSequence.flip = function() {return iterable}; flipSequence.reverse = function () { var reversedSequence = iterable.reverse.apply(this); // super.reverse() reversedSequence.flip = function() {return iterable.reverse()}; return reversedSequence; }; flipSequence.has = function(key ) {return iterable.includes(key)}; flipSequence.includes = function(key ) {return iterable.has(key)}; flipSequence.cacheResult = cacheResultThrough; flipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; return iterable.__iterate(function(v, k) {return fn(k, v, this$0) !== false}, reverse); } flipSequence.__iteratorUncached = function(type, reverse) { if (type === ITERATE_ENTRIES) { var iterator = iterable.__iterator(type, reverse); return new Iterator(function() { var step = iterator.next(); if (!step.done) { var k = step.value[0]; step.value[0] = step.value[1]; step.value[1] = k; } return step; }); } return iterable.__iterator( type === ITERATE_VALUES ? ITERATE_KEYS : ITERATE_VALUES, reverse ); } return flipSequence; } function mapFactory(iterable, mapper, context) { var mappedSequence = makeSequence(iterable); mappedSequence.size = iterable.size; mappedSequence.has = function(key ) {return iterable.has(key)}; mappedSequence.get = function(key, notSetValue) { var v = iterable.get(key, NOT_SET); return v === NOT_SET ? notSetValue : mapper.call(context, v, key, iterable); }; mappedSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; return iterable.__iterate( function(v, k, c) {return fn(mapper.call(context, v, k, c), k, this$0) !== false}, reverse ); } mappedSequence.__iteratorUncached = function (type, reverse) { var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); return new Iterator(function() { var step = iterator.next(); if (step.done) { return step; } var entry = step.value; var key = entry[0]; return iteratorValue( type, key, mapper.call(context, entry[1], key, iterable), step ); }); } return mappedSequence; } function reverseFactory(iterable, useKeys) { var reversedSequence = makeSequence(iterable); reversedSequence._iter = iterable; reversedSequence.size = iterable.size; reversedSequence.reverse = function() {return iterable}; if (iterable.flip) { reversedSequence.flip = function () { var flipSequence = flipFactory(iterable); flipSequence.reverse = function() {return iterable.flip()}; return flipSequence; }; } reversedSequence.get = function(key, notSetValue) {return iterable.get(useKeys ? key : -1 - key, notSetValue)}; reversedSequence.has = function(key ) {return iterable.has(useKeys ? key : -1 - key)}; reversedSequence.includes = function(value ) {return iterable.includes(value)}; reversedSequence.cacheResult = cacheResultThrough; reversedSequence.__iterate = function (fn, reverse) {var this$0 = this; return iterable.__iterate(function(v, k) {return fn(v, k, this$0)}, !reverse); }; reversedSequence.__iterator = function(type, reverse) {return iterable.__iterator(type, !reverse)}; return reversedSequence; } function filterFactory(iterable, predicate, context, useKeys) { var filterSequence = makeSequence(iterable); if (useKeys) { filterSequence.has = function(key ) { var v = iterable.get(key, NOT_SET); return v !== NOT_SET && !!predicate.call(context, v, key, iterable); }; filterSequence.get = function(key, notSetValue) { var v = iterable.get(key, NOT_SET); return v !== NOT_SET && predicate.call(context, v, key, iterable) ? v : notSetValue; }; } filterSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; var iterations = 0; iterable.__iterate(function(v, k, c) { if (predicate.call(context, v, k, c)) { iterations++; return fn(v, useKeys ? k : iterations - 1, this$0); } }, reverse); return iterations; }; filterSequence.__iteratorUncached = function (type, reverse) { var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); var iterations = 0; return new Iterator(function() { while (true) { var step = iterator.next(); if (step.done) { return step; } var entry = step.value; var key = entry[0]; var value = entry[1]; if (predicate.call(context, value, key, iterable)) { return iteratorValue(type, useKeys ? key : iterations++, value, step); } } }); } return filterSequence; } function countByFactory(iterable, grouper, context) { var groups = Map().asMutable(); iterable.__iterate(function(v, k) { groups.update( grouper.call(context, v, k, iterable), 0, function(a ) {return a + 1} ); }); return groups.asImmutable(); } function groupByFactory(iterable, grouper, context) { var isKeyedIter = isKeyed(iterable); var groups = (isOrdered(iterable) ? OrderedMap() : Map()).asMutable(); iterable.__iterate(function(v, k) { groups.update( grouper.call(context, v, k, iterable), function(a ) {return (a = a || [], a.push(isKeyedIter ? [k, v] : v), a)} ); }); var coerce = iterableClass(iterable); return groups.map(function(arr ) {return reify(iterable, coerce(arr))}); } function sliceFactory(iterable, begin, end, useKeys) { var originalSize = iterable.size; // Sanitize begin & end using this shorthand for ToInt32(argument) // http://www.ecma-international.org/ecma-262/6.0/#sec-toint32 if (begin !== undefined) { begin = begin | 0; } if (end !== undefined) { end = end | 0; } if (wholeSlice(begin, end, originalSize)) { return iterable; } var resolvedBegin = resolveBegin(begin, originalSize); var resolvedEnd = resolveEnd(end, originalSize); // begin or end will be NaN if they were provided as negative numbers and // this iterable's size is unknown. In that case, cache first so there is // a known size and these do not resolve to NaN. if (resolvedBegin !== resolvedBegin || resolvedEnd !== resolvedEnd) { return sliceFactory(iterable.toSeq().cacheResult(), begin, end, useKeys); } // Note: resolvedEnd is undefined when the original sequence's length is // unknown and this slice did not supply an end and should contain all // elements after resolvedBegin. // In that case, resolvedSize will be NaN and sliceSize will remain undefined. var resolvedSize = resolvedEnd - resolvedBegin; var sliceSize; if (resolvedSize === resolvedSize) { sliceSize = resolvedSize < 0 ? 0 : resolvedSize; } var sliceSeq = makeSequence(iterable); // If iterable.size is undefined, the size of the realized sliceSeq is // unknown at this point unless the number of items to slice is 0 sliceSeq.size = sliceSize === 0 ? sliceSize : iterable.size && sliceSize || undefined; if (!useKeys && isSeq(iterable) && sliceSize >= 0) { sliceSeq.get = function (index, notSetValue) { index = wrapIndex(this, index); return index >= 0 && index < sliceSize ? iterable.get(index + resolvedBegin, notSetValue) : notSetValue; } } sliceSeq.__iterateUncached = function(fn, reverse) {var this$0 = this; if (sliceSize === 0) { return 0; } if (reverse) { return this.cacheResult().__iterate(fn, reverse); } var skipped = 0; var isSkipping = true; var iterations = 0; iterable.__iterate(function(v, k) { if (!(isSkipping && (isSkipping = skipped++ < resolvedBegin))) { iterations++; return fn(v, useKeys ? k : iterations - 1, this$0) !== false && iterations !== sliceSize; } }); return iterations; }; sliceSeq.__iteratorUncached = function(type, reverse) { if (sliceSize !== 0 && reverse) { return this.cacheResult().__iterator(type, reverse); } // Don't bother instantiating parent iterator if taking 0. var iterator = sliceSize !== 0 && iterable.__iterator(type, reverse); var skipped = 0; var iterations = 0; return new Iterator(function() { while (skipped++ < resolvedBegin) { iterator.next(); } if (++iterations > sliceSize) { return iteratorDone(); } var step = iterator.next(); if (useKeys || type === ITERATE_VALUES) { return step; } else if (type === ITERATE_KEYS) { return iteratorValue(type, iterations - 1, undefined, step); } else { return iteratorValue(type, iterations - 1, step.value[1], step); } }); } return sliceSeq; } function takeWhileFactory(iterable, predicate, context) { var takeSequence = makeSequence(iterable); takeSequence.__iterateUncached = function(fn, reverse) {var this$0 = this; if (reverse) { return this.cacheResult().__iterate(fn, reverse); } var iterations = 0; iterable.__iterate(function(v, k, c) {return predicate.call(context, v, k, c) && ++iterations && fn(v, k, this$0)} ); return iterations; }; takeSequence.__iteratorUncached = function(type, reverse) {var this$0 = this; if (reverse) { return this.cacheResult().__iterator(type, reverse); } var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); var iterating = true; return new Iterator(function() { if (!iterating) { return iteratorDone(); } var step = iterator.next(); if (step.done) { return step; } var entry = step.value; var k = entry[0]; var v = entry[1]; if (!predicate.call(context, v, k, this$0)) { iterating = false; return iteratorDone(); } return type === ITERATE_ENTRIES ? step : iteratorValue(type, k, v, step); }); }; return takeSequence; } function skipWhileFactory(iterable, predicate, context, useKeys) { var skipSequence = makeSequence(iterable); skipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; if (reverse) { return this.cacheResult().__iterate(fn, reverse); } var isSkipping = true; var iterations = 0; iterable.__iterate(function(v, k, c) { if (!(isSkipping && (isSkipping = predicate.call(context, v, k, c)))) { iterations++; return fn(v, useKeys ? k : iterations - 1, this$0); } }); return iterations; }; skipSequence.__iteratorUncached = function(type, reverse) {var this$0 = this; if (reverse) { return this.cacheResult().__iterator(type, reverse); } var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); var skipping = true; var iterations = 0; return new Iterator(function() { var step, k, v; do { step = iterator.next(); if (step.done) { if (useKeys || type === ITERATE_VALUES) { return step; } else if (type === ITERATE_KEYS) { return iteratorValue(type, iterations++, undefined, step); } else { return iteratorValue(type, iterations++, step.value[1], step); } } var entry = step.value; k = entry[0]; v = entry[1]; skipping && (skipping = predicate.call(context, v, k, this$0)); } while (skipping); return type === ITERATE_ENTRIES ? step : iteratorValue(type, k, v, step); }); }; return skipSequence; } function concatFactory(iterable, values) { var isKeyedIterable = isKeyed(iterable); var iters = [iterable].concat(values).map(function(v ) { if (!isIterable(v)) { v = isKeyedIterable ? keyedSeqFromValue(v) : indexedSeqFromValue(Array.isArray(v) ? v : [v]); } else if (isKeyedIterable) { v = KeyedIterable(v); } return v; }).filter(function(v ) {return v.size !== 0}); if (iters.length === 0) { return iterable; } if (iters.length === 1) { var singleton = iters[0]; if (singleton === iterable || isKeyedIterable && isKeyed(singleton) || isIndexed(iterable) && isIndexed(singleton)) { return singleton; } } var concatSeq = new ArraySeq(iters); if (isKeyedIterable) { concatSeq = concatSeq.toKeyedSeq(); } else if (!isIndexed(iterable)) { concatSeq = concatSeq.toSetSeq(); } concatSeq = concatSeq.flatten(true); concatSeq.size = iters.reduce( function(sum, seq) { if (sum !== undefined) { var size = seq.size; if (size !== undefined) { return sum + size; } } }, 0 ); return concatSeq; } function flattenFactory(iterable, depth, useKeys) { var flatSequence = makeSequence(iterable); flatSequence.__iterateUncached = function(fn, reverse) { var iterations = 0; var stopped = false; function flatDeep(iter, currentDepth) {var this$0 = this; iter.__iterate(function(v, k) { if ((!depth || currentDepth < depth) && isIterable(v)) { flatDeep(v, currentDepth + 1); } else if (fn(v, useKeys ? k : iterations++, this$0) === false) { stopped = true; } return !stopped; }, reverse); } flatDeep(iterable, 0); return iterations; } flatSequence.__iteratorUncached = function(type, reverse) { var iterator = iterable.__iterator(type, reverse); var stack = []; var iterations = 0; return new Iterator(function() { while (iterator) { var step = iterator.next(); if (step.done !== false) { iterator = stack.pop(); continue; } var v = step.value; if (type === ITERATE_ENTRIES) { v = v[1]; } if ((!depth || stack.length < depth) && isIterable(v)) { stack.push(iterator); iterator = v.__iterator(type, reverse); } else { return useKeys ? step : iteratorValue(type, iterations++, v, step); } } return iteratorDone(); }); } return flatSequence; } function flatMapFactory(iterable, mapper, context) { var coerce = iterableClass(iterable); return iterable.toSeq().map( function(v, k) {return coerce(mapper.call(context, v, k, iterable))} ).flatten(true); } function interposeFactory(iterable, separator) { var interposedSequence = makeSequence(iterable); interposedSequence.size = iterable.size && iterable.size * 2 -1; interposedSequence.__iterateUncached = function(fn, reverse) {var this$0 = this; var iterations = 0; iterable.__iterate(function(v, k) {return (!iterations || fn(separator, iterations++, this$0) !== false) && fn(v, iterations++, this$0) !== false}, reverse ); return iterations; }; interposedSequence.__iteratorUncached = function(type, reverse) { var iterator = iterable.__iterator(ITERATE_VALUES, reverse); var iterations = 0; var step; return new Iterator(function() { if (!step || iterations % 2) { step = iterator.next(); if (step.done) { return step; } } return iterations % 2 ? iteratorValue(type, iterations++, separator) : iteratorValue(type, iterations++, step.value, step); }); }; return interposedSequence; } function sortFactory(iterable, comparator, mapper) { if (!comparator) { comparator = defaultComparator; } var isKeyedIterable = isKeyed(iterable); var index = 0; var entries = iterable.toSeq().map( function(v, k) {return [k, v, index++, mapper ? mapper(v, k, iterable) : v]} ).toArray(); entries.sort(function(a, b) {return comparator(a[3], b[3]) || a[2] - b[2]}).forEach( isKeyedIterable ? function(v, i) { entries[i].length = 2; } : function(v, i) { entries[i] = v[1]; } ); return isKeyedIterable ? KeyedSeq(entries) : isIndexed(iterable) ? IndexedSeq(entries) : SetSeq(entries); } function maxFactory(iterable, comparator, mapper) { if (!comparator) { comparator = defaultComparator; } if (mapper) { var entry = iterable.toSeq() .map(function(v, k) {return [v, mapper(v, k, iterable)]}) .reduce(function(a, b) {return maxCompare(comparator, a[1], b[1]) ? b : a}); return entry && entry[0]; } else { return iterable.reduce(function(a, b) {return maxCompare(comparator, a, b) ? b : a}); } } function maxCompare(comparator, a, b) { var comp = comparator(b, a); // b is considered the new max if the comparator declares them equal, but // they are not equal and b is in fact a nullish value. return (comp === 0 && b !== a && (b === undefined || b === null || b !== b)) || comp > 0; } function zipWithFactory(keyIter, zipper, iters) { var zipSequence = makeSequence(keyIter); zipSequence.size = new ArraySeq(iters).map(function(i ) {return i.size}).min(); // Note: this a generic base implementation of __iterate in terms of // __iterator which may be more generically useful in the future. zipSequence.__iterate = function(fn, reverse) { /* generic: var iterator = this.__iterator(ITERATE_ENTRIES, reverse); var step; var iterations = 0; while (!(step = iterator.next()).done) { iterations++; if (fn(step.value[1], step.value[0], this) === false) { break; } } return iterations; */ // indexed: var iterator = this.__iterator(ITERATE_VALUES, reverse); var step; var iterations = 0; while (!(step = iterator.next()).done) { if (fn(step.value, iterations++, this) === false) { break; } } return iterations; }; zipSequence.__iteratorUncached = function(type, reverse) { var iterators = iters.map(function(i ) {return (i = Iterable(i), getIterator(reverse ? i.reverse() : i))} ); var iterations = 0; var isDone = false; return new Iterator(function() { var steps; if (!isDone) { steps = iterators.map(function(i ) {return i.next()}); isDone = steps.some(function(s ) {return s.done}); } if (isDone) { return iteratorDone(); } return iteratorValue( type, iterations++, zipper.apply(null, steps.map(function(s ) {return s.value})) ); }); }; return zipSequence } // #pragma Helper Functions function reify(iter, seq) { return isSeq(iter) ? seq : iter.constructor(seq); } function validateEntry(entry) { if (entry !== Object(entry)) { throw new TypeError('Expected [K, V] tuple: ' + entry); } } function resolveSize(iter) { assertNotInfinite(iter.size); return ensureSize(iter); } function iterableClass(iterable) { return isKeyed(iterable) ? KeyedIterable : isIndexed(iterable) ? IndexedIterable : SetIterable; } function makeSequence(iterable) { return Object.create( ( isKeyed(iterable) ? KeyedSeq : isIndexed(iterable) ? IndexedSeq : SetSeq ).prototype ); } function cacheResultThrough() { if (this._iter.cacheResult) { this._iter.cacheResult(); this.size = this._iter.size; return this; } else { return Seq.prototype.cacheResult.call(this); } } function defaultComparator(a, b) { return a > b ? 1 : a < b ? -1 : 0; } function forceIterator(keyPath) { var iter = getIterator(keyPath); if (!iter) { // Array might not be iterable in this environment, so we need a fallback // to our wrapped type. if (!isArrayLike(keyPath)) { throw new TypeError('Expected iterable or array-like: ' + keyPath); } iter = getIterator(Iterable(keyPath)); } return iter; } createClass(Record, KeyedCollection); function Record(defaultValues, name) { var hasInitialized; var RecordType = function Record(values) { if (values instanceof RecordType) { return values; } if (!(this instanceof RecordType)) { return new RecordType(values); } if (!hasInitialized) { hasInitialized = true; var keys = Object.keys(defaultValues); setProps(RecordTypePrototype, keys); RecordTypePrototype.size = keys.length; RecordTypePrototype._name = name; RecordTypePrototype._keys = keys; RecordTypePrototype._defaultValues = defaultValues; } this._map = Map(values); }; var RecordTypePrototype = RecordType.prototype = Object.create(RecordPrototype); RecordTypePrototype.constructor = RecordType; return RecordType; } Record.prototype.toString = function() { return this.__toString(recordName(this) + ' {', '}'); }; // @pragma Access Record.prototype.has = function(k) { return this._defaultValues.hasOwnProperty(k); }; Record.prototype.get = function(k, notSetValue) { if (!this.has(k)) { return notSetValue; } var defaultVal = this._defaultValues[k]; return this._map ? this._map.get(k, defaultVal) : defaultVal; }; // @pragma Modification Record.prototype.clear = function() { if (this.__ownerID) { this._map && this._map.clear(); return this; } var RecordType = this.constructor; return RecordType._empty || (RecordType._empty = makeRecord(this, emptyMap())); }; Record.prototype.set = function(k, v) { if (!this.has(k)) { throw new Error('Cannot set unknown key "' + k + '" on ' + recordName(this)); } var newMap = this._map && this._map.set(k, v); if (this.__ownerID || newMap === this._map) { return this; } return makeRecord(this, newMap); }; Record.prototype.remove = function(k) { if (!this.has(k)) { return this; } var newMap = this._map && this._map.remove(k); if (this.__ownerID || newMap === this._map) { return this; } return makeRecord(this, newMap); }; Record.prototype.wasAltered = function() { return this._map.wasAltered(); }; Record.prototype.__iterator = function(type, reverse) {var this$0 = this; return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterator(type, reverse); }; Record.prototype.__iterate = function(fn, reverse) {var this$0 = this; return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterate(fn, reverse); }; Record.prototype.__ensureOwner = function(ownerID) { if (ownerID === this.__ownerID) { return this; } var newMap = this._map && this._map.__ensureOwner(ownerID); if (!ownerID) { this.__ownerID = ownerID; this._map = newMap; return this; } return makeRecord(this, newMap, ownerID); }; var RecordPrototype = Record.prototype; RecordPrototype[DELETE] = RecordPrototype.remove; RecordPrototype.deleteIn = RecordPrototype.removeIn = MapPrototype.removeIn; RecordPrototype.merge = MapPrototype.merge; RecordPrototype.mergeWith = MapPrototype.mergeWith; RecordPrototype.mergeIn = MapPrototype.mergeIn; RecordPrototype.mergeDeep = MapPrototype.mergeDeep; RecordPrototype.mergeDeepWith = MapPrototype.mergeDeepWith; RecordPrototype.mergeDeepIn = MapPrototype.mergeDeepIn; RecordPrototype.setIn = MapPrototype.setIn; RecordPrototype.update = MapPrototype.update; RecordPrototype.updateIn = MapPrototype.updateIn; RecordPrototype.withMutations = MapPrototype.withMutations; RecordPrototype.asMutable = MapPrototype.asMutable; RecordPrototype.asImmutable = MapPrototype.asImmutable; function makeRecord(likeRecord, map, ownerID) { var record = Object.create(Object.getPrototypeOf(likeRecord)); record._map = map; record.__ownerID = ownerID; return record; } function recordName(record) { return record._name || record.constructor.name || 'Record'; } function setProps(prototype, names) { try { names.forEach(setProp.bind(undefined, prototype)); } catch (error) { // Object.defineProperty failed. Probably IE8. } } function setProp(prototype, name) { Object.defineProperty(prototype, name, { get: function() { return this.get(name); }, set: function(value) { invariant(this.__ownerID, 'Cannot set on an immutable record.'); this.set(name, value); } }); } createClass(Set, SetCollection); // @pragma Construction function Set(value) { return value === null || value === undefined ? emptySet() : isSet(value) && !isOrdered(value) ? value : emptySet().withMutations(function(set ) { var iter = SetIterable(value); assertNotInfinite(iter.size); iter.forEach(function(v ) {return set.add(v)}); }); } Set.of = function(/*...values*/) { return this(arguments); }; Set.fromKeys = function(value) { return this(KeyedIterable(value).keySeq()); }; Set.prototype.toString = function() { return this.__toString('Set {', '}'); }; // @pragma Access Set.prototype.has = function(value) { return this._map.has(value); }; // @pragma Modification Set.prototype.add = function(value) { return updateSet(this, this._map.set(value, true)); }; Set.prototype.remove = function(value) { return updateSet(this, this._map.remove(value)); }; Set.prototype.clear = function() { return updateSet(this, this._map.clear()); }; // @pragma Composition Set.prototype.union = function() {var iters = SLICE$0.call(arguments, 0); iters = iters.filter(function(x ) {return x.size !== 0}); if (iters.length === 0) { return this; } if (this.size === 0 && !this.__ownerID && iters.length === 1) { return this.constructor(iters[0]); } return this.withMutations(function(set ) { for (var ii = 0; ii < iters.length; ii++) { SetIterable(iters[ii]).forEach(function(value ) {return set.add(value)}); } }); }; Set.prototype.intersect = function() {var iters = SLICE$0.call(arguments, 0); if (iters.length === 0) { return this; } iters = iters.map(function(iter ) {return SetIterable(iter)}); var originalSet = this; return this.withMutations(function(set ) { originalSet.forEach(function(value ) { if (!iters.every(function(iter ) {return iter.includes(value)})) { set.remove(value); } }); }); }; Set.prototype.subtract = function() {var iters = SLICE$0.call(arguments, 0); if (iters.length === 0) { return this; } iters = iters.map(function(iter ) {return SetIterable(iter)}); var originalSet = this; return this.withMutations(function(set ) { originalSet.forEach(function(value ) { if (iters.some(function(iter ) {return iter.includes(value)})) { set.remove(value); } }); }); }; Set.prototype.merge = function() { return this.union.apply(this, arguments); }; Set.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1); return this.union.apply(this, iters); }; Set.prototype.sort = function(comparator) { // Late binding return OrderedSet(sortFactory(this, comparator)); }; Set.prototype.sortBy = function(mapper, comparator) { // Late binding return OrderedSet(sortFactory(this, comparator, mapper)); }; Set.prototype.wasAltered = function() { return this._map.wasAltered(); }; Set.prototype.__iterate = function(fn, reverse) {var this$0 = this; return this._map.__iterate(function(_, k) {return fn(k, k, this$0)}, reverse); }; Set.prototype.__iterator = function(type, reverse) { return this._map.map(function(_, k) {return k}).__iterator(type, reverse); }; Set.prototype.__ensureOwner = function(ownerID) { if (ownerID === this.__ownerID) { return this; } var newMap = this._map.__ensureOwner(ownerID); if (!ownerID) { this.__ownerID = ownerID; this._map = newMap; return this; } return this.__make(newMap, ownerID); }; function isSet(maybeSet) { return !!(maybeSet && maybeSet[IS_SET_SENTINEL]); } Set.isSet = isSet; var IS_SET_SENTINEL = '@@__IMMUTABLE_SET__@@'; var SetPrototype = Set.prototype; SetPrototype[IS_SET_SENTINEL] = true; SetPrototype[DELETE] = SetPrototype.remove; SetPrototype.mergeDeep = SetPrototype.merge; SetPrototype.mergeDeepWith = SetPrototype.mergeWith; SetPrototype.withMutations = MapPrototype.withMutations; SetPrototype.asMutable = MapPrototype.asMutable; SetPrototype.asImmutable = MapPrototype.asImmutable; SetPrototype.__empty = emptySet; SetPrototype.__make = makeSet; function updateSet(set, newMap) { if (set.__ownerID) { set.size = newMap.size; set._map = newMap; return set; } return newMap === set._map ? set : newMap.size === 0 ? set.__empty() : set.__make(newMap); } function makeSet(map, ownerID) { var set = Object.create(SetPrototype); set.size = map ? map.size : 0; set._map = map; set.__ownerID = ownerID; return set; } var EMPTY_SET; function emptySet() { return EMPTY_SET || (EMPTY_SET = makeSet(emptyMap())); } createClass(OrderedSet, Set); // @pragma Construction function OrderedSet(value) { return value === null || value === undefined ? emptyOrderedSet() : isOrderedSet(value) ? value : emptyOrderedSet().withMutations(function(set ) { var iter = SetIterable(value); assertNotInfinite(iter.size); iter.forEach(function(v ) {return set.add(v)}); }); } OrderedSet.of = function(/*...values*/) { return this(arguments); }; OrderedSet.fromKeys = function(value) { return this(KeyedIterable(value).keySeq()); }; OrderedSet.prototype.toString = function() { return this.__toString('OrderedSet {', '}'); }; function isOrderedSet(maybeOrderedSet) { return isSet(maybeOrderedSet) && isOrdered(maybeOrderedSet); } OrderedSet.isOrderedSet = isOrderedSet; var OrderedSetPrototype = OrderedSet.prototype; OrderedSetPrototype[IS_ORDERED_SENTINEL] = true; OrderedSetPrototype.__empty = emptyOrderedSet; OrderedSetPrototype.__make = makeOrderedSet; function makeOrderedSet(map, ownerID) { var set = Object.create(OrderedSetPrototype); set.size = map ? map.size : 0; set._map = map; set.__ownerID = ownerID; return set; } var EMPTY_ORDERED_SET; function emptyOrderedSet() { return EMPTY_ORDERED_SET || (EMPTY_ORDERED_SET = makeOrderedSet(emptyOrderedMap())); } createClass(Stack, IndexedCollection); // @pragma Construction function Stack(value) { return value === null || value === undefined ? emptyStack() : isStack(value) ? value : emptyStack().unshiftAll(value); } Stack.of = function(/*...values*/) { return this(arguments); }; Stack.prototype.toString = function() { return this.__toString('Stack [', ']'); }; // @pragma Access Stack.prototype.get = function(index, notSetValue) { var head = this._head; index = wrapIndex(this, index); while (head && index--) { head = head.next; } return head ? head.value : notSetValue; }; Stack.prototype.peek = function() { return this._head && this._head.value; }; // @pragma Modification Stack.prototype.push = function(/*...values*/) { if (arguments.length === 0) { return this; } var newSize = this.size + arguments.length; var head = this._head; for (var ii = arguments.length - 1; ii >= 0; ii--) { head = { value: arguments[ii], next: head }; } if (this.__ownerID) { this.size = newSize; this._head = head; this.__hash = undefined; this.__altered = true; return this; } return makeStack(newSize, head); }; Stack.prototype.pushAll = function(iter) { iter = IndexedIterable(iter); if (iter.size === 0) { return this; } assertNotInfinite(iter.size); var newSize = this.size; var head = this._head; iter.reverse().forEach(function(value ) { newSize++; head = { value: value, next: head }; }); if (this.__ownerID) { this.size = newSize; this._head = head; this.__hash = undefined; this.__altered = true; return this; } return makeStack(newSize, head); }; Stack.prototype.pop = function() { return this.slice(1); }; Stack.prototype.unshift = function(/*...values*/) { return this.push.apply(this, arguments); }; Stack.prototype.unshiftAll = function(iter) { return this.pushAll(iter); }; Stack.prototype.shift = function() { return this.pop.apply(this, arguments); }; Stack.prototype.clear = function() { if (this.size === 0) { return this; } if (this.__ownerID) { this.size = 0; this._head = undefined; this.__hash = undefined; this.__altered = true; return this; } return emptyStack(); }; Stack.prototype.slice = function(begin, end) { if (wholeSlice(begin, end, this.size)) { return this; } var resolvedBegin = resolveBegin(begin, this.size); var resolvedEnd = resolveEnd(end, this.size); if (resolvedEnd !== this.size) { // super.slice(begin, end); return IndexedCollection.prototype.slice.call(this, begin, end); } var newSize = this.size - resolvedBegin; var head = this._head; while (resolvedBegin--) { head = head.next; } if (this.__ownerID) { this.size = newSize; this._head = head; this.__hash = undefined; this.__altered = true; return this; } return makeStack(newSize, head); }; // @pragma Mutability Stack.prototype.__ensureOwner = function(ownerID) { if (ownerID === this.__ownerID) { return this; } if (!ownerID) { this.__ownerID = ownerID; this.__altered = false; return this; } return makeStack(this.size, this._head, ownerID, this.__hash); }; // @pragma Iteration Stack.prototype.__iterate = function(fn, reverse) { if (reverse) { return this.reverse().__iterate(fn); } var iterations = 0; var node = this._head; while (node) { if (fn(node.value, iterations++, this) === false) { break; } node = node.next; } return iterations; }; Stack.prototype.__iterator = function(type, reverse) { if (reverse) { return this.reverse().__iterator(type); } var iterations = 0; var node = this._head; return new Iterator(function() { if (node) { var value = node.value; node = node.next; return iteratorValue(type, iterations++, value); } return iteratorDone(); }); }; function isStack(maybeStack) { return !!(maybeStack && maybeStack[IS_STACK_SENTINEL]); } Stack.isStack = isStack; var IS_STACK_SENTINEL = '@@__IMMUTABLE_STACK__@@'; var StackPrototype = Stack.prototype; StackPrototype[IS_STACK_SENTINEL] = true; StackPrototype.withMutations = MapPrototype.withMutations; StackPrototype.asMutable = MapPrototype.asMutable; StackPrototype.asImmutable = MapPrototype.asImmutable; StackPrototype.wasAltered = MapPrototype.wasAltered; function makeStack(size, head, ownerID, hash) { var map = Object.create(StackPrototype); map.size = size; map._head = head; map.__ownerID = ownerID; map.__hash = hash; map.__altered = false; return map; } var EMPTY_STACK; function emptyStack() { return EMPTY_STACK || (EMPTY_STACK = makeStack(0)); } /** * Contributes additional methods to a constructor */ function mixin(ctor, methods) { var keyCopier = function(key ) { ctor.prototype[key] = methods[key]; }; Object.keys(methods).forEach(keyCopier); Object.getOwnPropertySymbols && Object.getOwnPropertySymbols(methods).forEach(keyCopier); return ctor; } Iterable.Iterator = Iterator; mixin(Iterable, { // ### Conversion to other types toArray: function() { assertNotInfinite(this.size); var array = new Array(this.size || 0); this.valueSeq().__iterate(function(v, i) { array[i] = v; }); return array; }, toIndexedSeq: function() { return new ToIndexedSequence(this); }, toJS: function() { return this.toSeq().map( function(value ) {return value && typeof value.toJS === 'function' ? value.toJS() : value} ).__toJS(); }, toJSON: function() { return this.toSeq().map( function(value ) {return value && typeof value.toJSON === 'function' ? value.toJSON() : value} ).__toJS(); }, toKeyedSeq: function() { return new ToKeyedSequence(this, true); }, toMap: function() { // Use Late Binding here to solve the circular dependency. return Map(this.toKeyedSeq()); }, toObject: function() { assertNotInfinite(this.size); var object = {}; this.__iterate(function(v, k) { object[k] = v; }); return object; }, toOrderedMap: function() { // Use Late Binding here to solve the circular dependency. return OrderedMap(this.toKeyedSeq()); }, toOrderedSet: function() { // Use Late Binding here to solve the circular dependency. return OrderedSet(isKeyed(this) ? this.valueSeq() : this); }, toSet: function() { // Use Late Binding here to solve the circular dependency. return Set(isKeyed(this) ? this.valueSeq() : this); }, toSetSeq: function() { return new ToSetSequence(this); }, toSeq: function() { return isIndexed(this) ? this.toIndexedSeq() : isKeyed(this) ? this.toKeyedSeq() : this.toSetSeq(); }, toStack: function() { // Use Late Binding here to solve the circular dependency. return Stack(isKeyed(this) ? this.valueSeq() : this); }, toList: function() { // Use Late Binding here to solve the circular dependency. return List(isKeyed(this) ? this.valueSeq() : this); }, // ### Common JavaScript methods and properties toString: function() { return '[Iterable]'; }, __toString: function(head, tail) { if (this.size === 0) { return head + tail; } return head + ' ' + this.toSeq().map(this.__toStringMapper).join(', ') + ' ' + tail; }, // ### ES6 Collection methods (ES6 Array and Map) concat: function() {var values = SLICE$0.call(arguments, 0); return reify(this, concatFactory(this, values)); }, includes: function(searchValue) { return this.some(function(value ) {return is(value, searchValue)}); }, entries: function() { return this.__iterator(ITERATE_ENTRIES); }, every: function(predicate, context) { assertNotInfinite(this.size); var returnValue = true; this.__iterate(function(v, k, c) { if (!predicate.call(context, v, k, c)) { returnValue = false; return false; } }); return returnValue; }, filter: function(predicate, context) { return reify(this, filterFactory(this, predicate, context, true)); }, find: function(predicate, context, notSetValue) { var entry = this.findEntry(predicate, context); return entry ? entry[1] : notSetValue; }, findEntry: function(predicate, context) { var found; this.__iterate(function(v, k, c) { if (predicate.call(context, v, k, c)) { found = [k, v]; return false; } }); return found; }, findLastEntry: function(predicate, context) { return this.toSeq().reverse().findEntry(predicate, context); }, forEach: function(sideEffect, context) { assertNotInfinite(this.size); return this.__iterate(context ? sideEffect.bind(context) : sideEffect); }, join: function(separator) { assertNotInfinite(this.size); separator = separator !== undefined ? '' + separator : ','; var joined = ''; var isFirst = true; this.__iterate(function(v ) { isFirst ? (isFirst = false) : (joined += separator); joined += v !== null && v !== undefined ? v.toString() : ''; }); return joined; }, keys: function() { return this.__iterator(ITERATE_KEYS); }, map: function(mapper, context) { return reify(this, mapFactory(this, mapper, context)); }, reduce: function(reducer, initialReduction, context) { assertNotInfinite(this.size); var reduction; var useFirst; if (arguments.length < 2) { useFirst = true; } else { reduction = initialReduction; } this.__iterate(function(v, k, c) { if (useFirst) { useFirst = false; reduction = v; } else { reduction = reducer.call(context, reduction, v, k, c); } }); return reduction; }, reduceRight: function(reducer, initialReduction, context) { var reversed = this.toKeyedSeq().reverse(); return reversed.reduce.apply(reversed, arguments); }, reverse: function() { return reify(this, reverseFactory(this, true)); }, slice: function(begin, end) { return reify(this, sliceFactory(this, begin, end, true)); }, some: function(predicate, context) { return !this.every(not(predicate), context); }, sort: function(comparator) { return reify(this, sortFactory(this, comparator)); }, values: function() { return this.__iterator(ITERATE_VALUES); }, // ### More sequential methods butLast: function() { return this.slice(0, -1); }, isEmpty: function() { return this.size !== undefined ? this.size === 0 : !this.some(function() {return true}); }, count: function(predicate, context) { return ensureSize( predicate ? this.toSeq().filter(predicate, context) : this ); }, countBy: function(grouper, context) { return countByFactory(this, grouper, context); }, equals: function(other) { return deepEqual(this, other); }, entrySeq: function() { var iterable = this; if (iterable._cache) { // We cache as an entries array, so we can just return the cache! return new ArraySeq(iterable._cache); } var entriesSequence = iterable.toSeq().map(entryMapper).toIndexedSeq(); entriesSequence.fromEntrySeq = function() {return iterable.toSeq()}; return entriesSequence; }, filterNot: function(predicate, context) { return this.filter(not(predicate), context); }, findLast: function(predicate, context, notSetValue) { return this.toKeyedSeq().reverse().find(predicate, context, notSetValue); }, first: function() { return this.find(returnTrue); }, flatMap: function(mapper, context) { return reify(this, flatMapFactory(this, mapper, context)); }, flatten: function(depth) { return reify(this, flattenFactory(this, depth, true)); }, fromEntrySeq: function() { return new FromEntriesSequence(this); }, get: function(searchKey, notSetValue) { return this.find(function(_, key) {return is(key, searchKey)}, undefined, notSetValue); }, getIn: function(searchKeyPath, notSetValue) { var nested = this; // Note: in an ES6 environment, we would prefer: // for (var key of searchKeyPath) { var iter = forceIterator(searchKeyPath); var step; while (!(step = iter.next()).done) { var key = step.value; nested = nested && nested.get ? nested.get(key, NOT_SET) : NOT_SET; if (nested === NOT_SET) { return notSetValue; } } return nested; }, groupBy: function(grouper, context) { return groupByFactory(this, grouper, context); }, has: function(searchKey) { return this.get(searchKey, NOT_SET) !== NOT_SET; }, hasIn: function(searchKeyPath) { return this.getIn(searchKeyPath, NOT_SET) !== NOT_SET; }, isSubset: function(iter) { iter = typeof iter.includes === 'function' ? iter : Iterable(iter); return this.every(function(value ) {return iter.includes(value)}); }, isSuperset: function(iter) { iter = typeof iter.isSubset === 'function' ? iter : Iterable(iter); return iter.isSubset(this); }, keySeq: function() { return this.toSeq().map(keyMapper).toIndexedSeq(); }, last: function() { return this.toSeq().reverse().first(); }, max: function(comparator) { return maxFactory(this, comparator); }, maxBy: function(mapper, comparator) { return maxFactory(this, comparator, mapper); }, min: function(comparator) { return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator); }, minBy: function(mapper, comparator) { return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator, mapper); }, rest: function() { return this.slice(1); }, skip: function(amount) { return this.slice(Math.max(0, amount)); }, skipLast: function(amount) { return reify(this, this.toSeq().reverse().skip(amount).reverse()); }, skipWhile: function(predicate, context) { return reify(this, skipWhileFactory(this, predicate, context, true)); }, skipUntil: function(predicate, context) { return this.skipWhile(not(predicate), context); }, sortBy: function(mapper, comparator) { return reify(this, sortFactory(this, comparator, mapper)); }, take: function(amount) { return this.slice(0, Math.max(0, amount)); }, takeLast: function(amount) { return reify(this, this.toSeq().reverse().take(amount).reverse()); }, takeWhile: function(predicate, context) { return reify(this, takeWhileFactory(this, predicate, context)); }, takeUntil: function(predicate, context) { return this.takeWhile(not(predicate), context); }, valueSeq: function() { return this.toIndexedSeq(); }, // ### Hashable Object hashCode: function() { return this.__hash || (this.__hash = hashIterable(this)); } // ### Internal // abstract __iterate(fn, reverse) // abstract __iterator(type, reverse) }); // var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@'; // var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@'; // var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@'; // var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@'; var IterablePrototype = Iterable.prototype; IterablePrototype[IS_ITERABLE_SENTINEL] = true; IterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.values; IterablePrototype.__toJS = IterablePrototype.toArray; IterablePrototype.__toStringMapper = quoteString; IterablePrototype.inspect = IterablePrototype.toSource = function() { return this.toString(); }; IterablePrototype.chain = IterablePrototype.flatMap; IterablePrototype.contains = IterablePrototype.includes; // Temporary warning about using length (function () { try { Object.defineProperty(IterablePrototype, 'length', { get: function () { if (!Iterable.noLengthWarning) { var stack; try { throw new Error(); } catch (error) { stack = error.stack; } if (stack.indexOf('_wrapObject') === -1) { console && console.warn && console.warn( 'iterable.length has been deprecated, '+ 'use iterable.size or iterable.count(). '+ 'This warning will become a silent error in a future version. ' + stack ); return this.size; } } } }); } catch (e) {} })(); mixin(KeyedIterable, { // ### More sequential methods flip: function() { return reify(this, flipFactory(this)); }, findKey: function(predicate, context) { var entry = this.findEntry(predicate, context); return entry && entry[0]; }, findLastKey: function(predicate, context) { return this.toSeq().reverse().findKey(predicate, context); }, keyOf: function(searchValue) { return this.findKey(function(value ) {return is(value, searchValue)}); }, lastKeyOf: function(searchValue) { return this.findLastKey(function(value ) {return is(value, searchValue)}); }, mapEntries: function(mapper, context) {var this$0 = this; var iterations = 0; return reify(this, this.toSeq().map( function(v, k) {return mapper.call(context, [k, v], iterations++, this$0)} ).fromEntrySeq() ); }, mapKeys: function(mapper, context) {var this$0 = this; return reify(this, this.toSeq().flip().map( function(k, v) {return mapper.call(context, k, v, this$0)} ).flip() ); } }); var KeyedIterablePrototype = KeyedIterable.prototype; KeyedIterablePrototype[IS_KEYED_SENTINEL] = true; KeyedIterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.entries; KeyedIterablePrototype.__toJS = IterablePrototype.toObject; KeyedIterablePrototype.__toStringMapper = function(v, k) {return JSON.stringify(k) + ': ' + quoteString(v)}; mixin(IndexedIterable, { // ### Conversion to other types toKeyedSeq: function() { return new ToKeyedSequence(this, false); }, // ### ES6 Collection methods (ES6 Array and Map) filter: function(predicate, context) { return reify(this, filterFactory(this, predicate, context, false)); }, findIndex: function(predicate, context) { var entry = this.findEntry(predicate, context); return entry ? entry[0] : -1; }, indexOf: function(searchValue) { var key = this.toKeyedSeq().keyOf(searchValue); return key === undefined ? -1 : key; }, lastIndexOf: function(searchValue) { var key = this.toKeyedSeq().reverse().keyOf(searchValue); return key === undefined ? -1 : key; // var index = // return this.toSeq().reverse().indexOf(searchValue); }, reverse: function() { return reify(this, reverseFactory(this, false)); }, slice: function(begin, end) { return reify(this, sliceFactory(this, begin, end, false)); }, splice: function(index, removeNum /*, ...values*/) { var numArgs = arguments.length; removeNum = Math.max(removeNum | 0, 0); if (numArgs === 0 || (numArgs === 2 && !removeNum)) { return this; } // If index is negative, it should resolve relative to the size of the // collection. However size may be expensive to compute if not cached, so // only call count() if the number is in fact negative. index = resolveBegin(index, index < 0 ? this.count() : this.size); var spliced = this.slice(0, index); return reify( this, numArgs === 1 ? spliced : spliced.concat(arrCopy(arguments, 2), this.slice(index + removeNum)) ); }, // ### More collection methods findLastIndex: function(predicate, context) { var key = this.toKeyedSeq().findLastKey(predicate, context); return key === undefined ? -1 : key; }, first: function() { return this.get(0); }, flatten: function(depth) { return reify(this, flattenFactory(this, depth, false)); }, get: function(index, notSetValue) { index = wrapIndex(this, index); return (index < 0 || (this.size === Infinity || (this.size !== undefined && index > this.size))) ? notSetValue : this.find(function(_, key) {return key === index}, undefined, notSetValue); }, has: function(index) { index = wrapIndex(this, index); return index >= 0 && (this.size !== undefined ? this.size === Infinity || index < this.size : this.indexOf(index) !== -1 ); }, interpose: function(separator) { return reify(this, interposeFactory(this, separator)); }, interleave: function(/*...iterables*/) { var iterables = [this].concat(arrCopy(arguments)); var zipped = zipWithFactory(this.toSeq(), IndexedSeq.of, iterables); var interleaved = zipped.flatten(true); if (zipped.size) { interleaved.size = zipped.size * iterables.length; } return reify(this, interleaved); }, last: function() { return this.get(-1); }, skipWhile: function(predicate, context) { return reify(this, skipWhileFactory(this, predicate, context, false)); }, zip: function(/*, ...iterables */) { var iterables = [this].concat(arrCopy(arguments)); return reify(this, zipWithFactory(this, defaultZipper, iterables)); }, zipWith: function(zipper/*, ...iterables */) { var iterables = arrCopy(arguments); iterables[0] = this; return reify(this, zipWithFactory(this, zipper, iterables)); } }); IndexedIterable.prototype[IS_INDEXED_SENTINEL] = true; IndexedIterable.prototype[IS_ORDERED_SENTINEL] = true; mixin(SetIterable, { // ### ES6 Collection methods (ES6 Array and Map) get: function(value, notSetValue) { return this.has(value) ? value : notSetValue; }, includes: function(value) { return this.has(value); }, // ### More sequential methods keySeq: function() { return this.valueSeq(); } }); SetIterable.prototype.has = IterablePrototype.includes; // Mixin subclasses mixin(KeyedSeq, KeyedIterable.prototype); mixin(IndexedSeq, IndexedIterable.prototype); mixin(SetSeq, SetIterable.prototype); mixin(KeyedCollection, KeyedIterable.prototype); mixin(IndexedCollection, IndexedIterable.prototype); mixin(SetCollection, SetIterable.prototype); // #pragma Helper functions function keyMapper(v, k) { return k; } function entryMapper(v, k) { return [k, v]; } function not(predicate) { return function() { return !predicate.apply(this, arguments); } } function neg(predicate) { return function() { return -predicate.apply(this, arguments); } } function quoteString(value) { return typeof value === 'string' ? JSON.stringify(value) : value; } function defaultZipper() { return arrCopy(arguments); } function defaultNegComparator(a, b) { return a < b ? 1 : a > b ? -1 : 0; } function hashIterable(iterable) { if (iterable.size === Infinity) { return 0; } var ordered = isOrdered(iterable); var keyed = isKeyed(iterable); var h = ordered ? 1 : 0; var size = iterable.__iterate( keyed ? ordered ? function(v, k) { h = 31 * h + hashMerge(hash(v), hash(k)) | 0; } : function(v, k) { h = h + hashMerge(hash(v), hash(k)) | 0; } : ordered ? function(v ) { h = 31 * h + hash(v) | 0; } : function(v ) { h = h + hash(v) | 0; } ); return murmurHashOfSize(size, h); } function murmurHashOfSize(size, h) { h = imul(h, 0xCC9E2D51); h = imul(h << 15 | h >>> -15, 0x1B873593); h = imul(h << 13 | h >>> -13, 5); h = (h + 0xE6546B64 | 0) ^ size; h = imul(h ^ h >>> 16, 0x85EBCA6B); h = imul(h ^ h >>> 13, 0xC2B2AE35); h = smi(h ^ h >>> 16); return h; } function hashMerge(a, b) { return a ^ b + 0x9E3779B9 + (a << 6) + (a >> 2) | 0; // int } var Immutable = { Iterable: Iterable, Seq: Seq, Collection: Collection, Map: Map, OrderedMap: OrderedMap, List: List, Stack: Stack, Set: Set, OrderedSet: OrderedSet, Record: Record, Range: Range, Repeat: Repeat, is: is, fromJS: fromJS }; return Immutable; })); },{}],221:[function(require,module,exports){ // Utility protocol for measuring when a stateChange takes effect. var RandomID = require('./randomid.js'); var Network = require('./network.js').Network; var Route = require('./route.js'); var Patch = require('./patch.js'); var $Ack = new Route.$Special('ack'); function Ack(metaLevel, id) { this.metaLevel = metaLevel || 0; this.id = id || RandomID.randomId(16); this.done = false; } Ack.prototype.arm = function () { Network.stateChange(Patch.sub([$Ack, this.id], this.metaLevel)); Network.send([$Ack, this.id], this.metaLevel); }; Ack.prototype.disarm = function () { Network.stateChange(Patch.unsub([$Ack, this.id], this.metaLevel)); }; Ack.prototype.check = function (e) { if (!this.done) { if (e.type === 'message') { var m = Patch.stripAtMeta(e.message, this.metaLevel); if (m && m[0] === $Ack && m[1] === this.id) { this.disarm(); this.done = true; } } } return this.done; }; /////////////////////////////////////////////////////////////////////////// module.exports.$Ack = $Ack; module.exports.Ack = Ack; },{"./network.js":229,"./patch.js":230,"./randomid.js":231,"./route.js":233}],222:[function(require,module,exports){ 'use strict'; var Immutable = require('immutable'); var Network = require('./network.js').Network; var Mux = require('./mux.js'); var Patch = require('./patch.js'); var Route = require('./route.js'); var Util = require('./util.js'); //--------------------------------------------------------------------------- function spawnActor(state, bootFn) { Network.spawn(new Actor(state, bootFn)); } function Actor(state, bootFn) { this.state = state; this.facets = Immutable.Set(); this.mux = new Mux.Mux(); this.boot = function() { bootFn.call(this.state); this.checkForTermination(); }; } Actor.prototype.handleEvent = function(e) { this.facets.forEach(function (f) { f.handleEvent(e); }); this.checkForTermination(); }; Actor.prototype.addFacet = function(facet) { this.facets = this.facets.add(facet); }; Actor.prototype.removeFacet = function(facet) { this.facets = this.facets.remove(facet); }; Actor.prototype.checkForTermination = function() { if (this.facets.isEmpty()) { Network.exit(); } }; //--------------------------------------------------------------------------- function createFacet() { return new Facet(Network.activeBehavior()); } function Facet(actor) { this.actor = actor; this.endpoints = Immutable.Map(); this.initBlocks = Immutable.List(); this.doneBlocks = Immutable.List(); } Facet.prototype.handleEvent = function(e) { var facet = this; this.endpoints.forEach(function(endpoint) { endpoint.handlerFn.call(facet.actor.state, e); }); this.refresh(); }; Facet.prototype.addAssertion = function(assertionFn) { return this.addEndpoint(new Endpoint(assertionFn, function(e) {})); }; Facet.prototype.onEvent = function(isTerminal, eventType, subscriptionFn, projectionFn, handlerFn) { var facet = this; switch (eventType) { case 'message': return this.addEndpoint(new Endpoint(subscriptionFn, function(e) { if (e.type === 'message') { var proj = projectionFn.call(facet.actor.state); var spec = Patch.prependAtMeta(proj.assertion, proj.metalevel); var match = Route.matchPattern(e.message, spec); // console.log(match); if (match) { if (isTerminal) { facet.terminate(); } Util.kwApply(handlerFn, facet.actor.state, match); } } })); case 'asserted': /* fall through */ case 'retracted': return this.addEndpoint(new Endpoint(subscriptionFn, function(e) { if (e.type === 'stateChange') { var proj = projectionFn.call(facet.actor.state); var spec = Patch.prependAtMeta(proj.assertion, proj.metalevel); var compiledSpec = Route.compileProjection(spec); var objects = Route.projectObjects(eventType === 'asserted' ? e.patch.added : e.patch.removed, compiledSpec); if (objects && objects.size > 0) { // console.log(objects.toArray()); if (isTerminal) { facet.terminate(); } objects.forEach(function (o) { Util.kwApply(handlerFn, facet.actor.state, o); }); } } })); case 'risingEdge': var endpoint = new Endpoint(function() { return Patch.emptyPatch; }, function(e) { var newValue = subscriptionFn.call(facet.actor.state); if (newValue && !this.currentValue) { if (isTerminal) { facet.terminate(); } handlerFn.call(facet.actor.state); } this.currentValue = newValue; }); endpoint.currentValue = false; return this.addEndpoint(endpoint); default: throw new Error("Unsupported Facet eventType: " + eventType); } }; Facet.prototype.addEndpoint = function(endpoint) { var patch = endpoint.subscriptionFn.call(this.actor.state); var r = this.actor.mux.addStream(patch); this.endpoints = this.endpoints.set(r.pid, endpoint); Network.stateChange(r.deltaAggregate); return this; // for chaining }; Facet.prototype.addInitBlock = function(thunk) { this.initBlocks = this.initBlocks.push(thunk); return this; }; Facet.prototype.addDoneBlock = function(thunk) { this.doneBlocks = this.doneBlocks.push(thunk); return this; }; Facet.prototype.refresh = function() { var facet = this; var aggregate = Patch.emptyPatch; this.endpoints.forEach(function(endpoint, eid) { var patch = Patch.retract(Syndicate.__).andThen(endpoint.subscriptionFn.call(facet.actor.state)); var r = facet.actor.mux.updateStream(eid, patch); aggregate = aggregate.andThen(r.deltaAggregate); }); Network.stateChange(aggregate); }; Facet.prototype.completeBuild = function() { var facet = this; this.actor.addFacet(this); this.initBlocks.forEach(function(b) { b.call(facet.actor.state); }); }; Facet.prototype.terminate = function() { var facet = this; var aggregate = Patch.emptyPatch; this.endpoints.forEach(function(endpoint, eid) { var r = facet.actor.mux.removeStream(eid); aggregate = aggregate.andThen(r.deltaAggregate); }); Network.stateChange(aggregate); this.endpoints = Immutable.Map(); this.actor.removeFacet(this); this.doneBlocks.forEach(function(b) { b.call(facet.actor.state); }); }; //--------------------------------------------------------------------------- function Endpoint(subscriptionFn, handlerFn) { this.subscriptionFn = subscriptionFn; this.handlerFn = handlerFn; } //--------------------------------------------------------------------------- module.exports.spawnActor = spawnActor; module.exports.createFacet = createFacet; },{"./mux.js":228,"./network.js":229,"./patch.js":230,"./route.js":233,"./util.js":235,"immutable":220}],223:[function(require,module,exports){ var Immutable = require('immutable'); var Route = require('./route.js'); var Patch = require('./patch.js'); var Util = require('./util.js'); function DemandMatcher(demandSpec, supplySpec, options) { options = Util.extend({ metaLevel: 0, onDemandIncrease: function (captures) { console.error("Syndicate: Unhandled increase in demand", captures); }, onSupplyDecrease: function (captures) { console.error("Syndicate: Unhandled decrease in supply", captures); } }, options); this.metaLevel = options.metaLevel; this.onDemandIncrease = options.onDemandIncrease; this.onSupplyDecrease = options.onSupplyDecrease; this.demandSpec = demandSpec; this.supplySpec = supplySpec; this.demandPattern = Route.projectionToPattern(demandSpec); this.supplyPattern = Route.projectionToPattern(supplySpec); this.demandProjection = Route.compileProjection(Patch.prependAtMeta(demandSpec, this.metaLevel)); this.supplyProjection = Route.compileProjection(Patch.prependAtMeta(supplySpec, this.metaLevel)); this.currentDemand = Immutable.Set(); this.currentSupply = Immutable.Set(); } DemandMatcher.prototype.boot = function () { return Patch.sub(this.demandPattern, this.metaLevel) .andThen(Patch.sub(this.supplyPattern, this.metaLevel)); }; DemandMatcher.prototype.handleEvent = function (e) { if (e.type === "stateChange") { this.handlePatch(e.patch); } }; DemandMatcher.prototype.handlePatch = function (p) { var self = this; var addedDemand = Route.trieKeys(Route.project(p.added, self.demandProjection)); var removedDemand = Route.trieKeys(Route.project(p.removed, self.demandProjection)); var addedSupply = Route.trieKeys(Route.project(p.added, self.supplyProjection)); var removedSupply = Route.trieKeys(Route.project(p.removed, self.supplyProjection)); if (addedDemand === null) { throw new Error("Syndicate: wildcard demand detected:\n" + self.demandSpec + "\n" + p.pretty()); } if (addedSupply === null) { throw new Error("Syndicate: wildcard supply detected:\n" + self.supplySpec + "\n" + p.pretty()); } self.currentSupply = self.currentSupply.union(addedSupply); self.currentDemand = self.currentDemand.subtract(removedDemand); removedSupply.forEach(function (captures) { if (self.currentDemand.has(captures)) { self.onSupplyDecrease(Route.captureToObject(captures, self.supplyProjection)); } }); addedDemand.forEach(function (captures) { if (!self.currentSupply.has(captures)) { self.onDemandIncrease(Route.captureToObject(captures, self.demandProjection)); } }); self.currentSupply = self.currentSupply.subtract(removedSupply); self.currentDemand = self.currentDemand.union(addedDemand); }; /////////////////////////////////////////////////////////////////////////// module.exports.DemandMatcher = DemandMatcher; },{"./patch.js":230,"./route.js":233,"./util.js":235,"immutable":220}],224:[function(require,module,exports){ // DOM fragment display driver var Patch = require("./patch.js"); var DemandMatcher = require('./demand-matcher.js').DemandMatcher; var Ack = require('./ack.js').Ack; var Seal = require('./seal.js').Seal; var Network_ = require("./network.js"); var Network = Network_.Network; var __ = Network_.__; var _$ = Network_._$; function spawnDOMDriver(domWrapFunction, jQueryWrapFunction) { domWrapFunction = domWrapFunction || defaultWrapFunction; var spec = domWrapFunction(_$('selector'), _$('fragmentClass'), _$('fragmentSpec')); Network.spawn( new DemandMatcher(spec, Patch.advertise(spec), { onDemandIncrease: function (c) { Network.spawn(new DOMFragment(c.selector, c.fragmentClass, c.fragmentSpec, domWrapFunction, jQueryWrapFunction)); } })); } function defaultWrapFunction(selector, fragmentClass, fragmentSpec) { return ["DOM", selector, fragmentClass, fragmentSpec]; } function DOMFragment(selector, fragmentClass, fragmentSpec, domWrapFunction, jQueryWrapFunction) { this.selector = selector; this.fragmentClass = fragmentClass; this.fragmentSpec = fragmentSpec; this.domWrapFunction = domWrapFunction; this.jQueryWrapFunction = jQueryWrapFunction; this.demandExists = false; this.subscriptionEstablished = new Ack(); this.nodes = this.buildNodes(); } DOMFragment.prototype.boot = function () { var self = this; var specification = self.domWrapFunction(self.selector, self.fragmentClass, self.fragmentSpec); Network.spawn(new Network(function () { Syndicate.JQuery.spawnJQueryDriver(self.selector+" > ."+self.fragmentClass, 1, self.jQueryWrapFunction); Network.spawn({ demandExists: false, subscriptionEstablished: new Ack(1), boot: function () { this.subscriptionEstablished.arm(); return Patch.sub(Patch.advertise(specification), 1); }, handleEvent: function (e) { this.subscriptionEstablished.check(e); if (e.type === "stateChange") { if (e.patch.hasAdded()) this.demandExists = true; if (e.patch.hasRemoved()) this.demandExists = false; } if (this.subscriptionEstablished.done && !this.demandExists) { Network.exitNetwork(); } } }); })); this.subscriptionEstablished.arm(); return Patch.sub(specification).andThen(Patch.pub(specification)); }; DOMFragment.prototype.handleEvent = function (e) { this.subscriptionEstablished.check(e); if (e.type === "stateChange") { if (e.patch.hasAdded()) this.demandExists = true; if (e.patch.hasRemoved()) this.demandExists = false; } if (this.subscriptionEstablished.done && !this.demandExists) { for (var i = 0; i < this.nodes.length; i++) { var n = this.nodes[i]; n.parentNode.removeChild(n); } Network.exit(); } }; /////////////////////////////////////////////////////////////////////////// function isAttributes(x) { return Array.isArray(x) && ((x.length === 0) || Array.isArray(x[0])); } DOMFragment.prototype.interpretSpec = function (spec) { // Fragment specs are roughly JSON-equivalents of SXML. // spec ::== ["tag", [["attr", "value"], ...], spec, spec, ...] // | ["tag", spec, spec, ...] // | "cdata" if (typeof(spec) === "string" || typeof(spec) === "number") { return document.createTextNode(spec); } else if ($.isArray(spec)) { var tagName = spec[0]; var hasAttrs = isAttributes(spec[1]); var attrs = hasAttrs ? spec[1] : {}; var kidIndex = hasAttrs ? 2 : 1; // Wow! Such XSS! Many hacks! So vulnerability! Amaze! var n = document.createElement(tagName); for (var i = 0; i < attrs.length; i++) { n.setAttribute(attrs[i][0], attrs[i][1]); } for (var i = kidIndex; i < spec.length; i++) { n.appendChild(this.interpretSpec(spec[i])); } return n; } else { throw new Error("Ill-formed DOM specification"); } }; DOMFragment.prototype.buildNodes = function () { var self = this; var nodes = []; $(self.selector).each(function (index, domNode) { var n = self.interpretSpec(self.fragmentSpec.sealContents); if ('classList' in n) { n.classList.add(self.fragmentClass); } domNode.appendChild(n); nodes.push(n); }); return nodes; }; /////////////////////////////////////////////////////////////////////////// module.exports.spawnDOMDriver = spawnDOMDriver; module.exports.defaultWrapFunction = defaultWrapFunction; },{"./ack.js":221,"./demand-matcher.js":223,"./network.js":229,"./patch.js":230,"./seal.js":234}],225:[function(require,module,exports){ "use strict"; var Immutable = require('immutable'); var Network = require('./network.js').Network; function Ground(bootFn) { var self = this; this.stepperId = null; this.baseStack = Immutable.List.of({ network: this, activePid: -1 }); Network.withNetworkStack(this.baseStack, function () { self.network = new Network(bootFn); }); } Ground.prototype.step = function () { var self = this; return Network.withNetworkStack(this.baseStack, function () { return self.network.step(); }); }; Ground.prototype.checkPid = function (pid) { if (pid !== -1) console.error('Weird pid in Ground', pid); }; Ground.prototype.markRunnable = function (pid) { this.checkPid(pid); this.startStepping(); }; Ground.prototype.startStepping = function () { var self = this; if (this.stepperId) return; if (this.step()) { this.stepperId = setTimeout(function () { self.stepperId = null; self.startStepping(); }, 0); } return this; // because the syndicatec compiler chains startStepping after the ctor }; Ground.prototype.stopStepping = function () { if (this.stepperId) { clearTimeout(this.stepperId); this.stepperId = null; } }; Ground.prototype.kill = function (pid, exn) { this.checkPid(pid); console.log("Ground network terminated"); this.stopStepping(); }; Ground.prototype.enqueueAction = function (pid, action) { this.checkPid(pid); switch (action.type) { case 'stateChange': if (action.patch.isNonEmpty()) { console.error('You have subscribed to a nonexistent event source.', action.patch.pretty()); } break; case 'message': console.error('You have sent a message into the outer void.', action); break; default: console.error('Internal error: unexpected action at ground level', action); break; } }; /////////////////////////////////////////////////////////////////////////// module.exports.Ground = Ground; },{"./network.js":229,"immutable":220}],226:[function(require,module,exports){ // JQuery event driver var Patch = require("./patch.js"); var DemandMatcher = require('./demand-matcher.js').DemandMatcher; var Network_ = require("./network.js"); var Network = Network_.Network; var __ = Network_.__; var _$ = Network_._$; function spawnJQueryDriver(baseSelector, metaLevel, wrapFunction) { metaLevel = metaLevel || 0; wrapFunction = wrapFunction || defaultWrapFunction; Network.spawn( new DemandMatcher(Patch.observe(wrapFunction(_$('selector'), _$('eventName'), __)), Patch.advertise(wrapFunction(_$('selector'), _$('eventName'), __)), { metaLevel: metaLevel, onDemandIncrease: function (c) { Network.spawn(new JQueryEventRouter(baseSelector, c.selector, c.eventName, metaLevel, wrapFunction)); } })); } function defaultWrapFunction(selector, eventName, eventValue) { return ["jQuery", selector, eventName, eventValue]; } function JQueryEventRouter(baseSelector, selector, eventName, metaLevel, wrapFunction) { var self = this; this.baseSelector = baseSelector || null; this.selector = selector; this.eventName = eventName; this.metaLevel = metaLevel || 0; this.wrapFunction = wrapFunction || defaultWrapFunction; this.preventDefault = (this.eventName.charAt(0) !== "+"); this.handler = Network.wrap(function (e) { Network.send(self.wrapFunction(self.selector, self.eventName, e), self.metaLevel); if (self.preventDefault) e.preventDefault(); return !self.preventDefault; }); this.computeNodes().on(this.preventDefault ? this.eventName : this.eventName.substring(1), this.handler); } JQueryEventRouter.prototype.boot = function () { return Patch.pub(this.wrapFunction(this.selector, this.eventName, __), this.metaLevel) .andThen(Patch.sub(Patch.observe(this.wrapFunction(this.selector, this.eventName, __)), this.metaLevel)); }; JQueryEventRouter.prototype.handleEvent = function (e) { if (e.type === "stateChange" && e.patch.hasRemoved()) { this.computeNodes().off(this.eventName, this.handler); Network.exit(); } }; JQueryEventRouter.prototype.computeNodes = function () { if (this.baseSelector) { return $(this.baseSelector).children(this.selector).addBack(this.selector); } else { return $(this.selector); } }; function simplifyDOMEvent(e) { var keys = []; for (var k in e) { var v = e[k]; if (typeof v === 'object') continue; if (typeof v === 'function') continue; keys.push(k); } keys.sort(); var simplified = []; for (var i = 0; i < keys.length; i++) { simplified.push([keys[i], e[keys[i]]]); } return simplified; } /////////////////////////////////////////////////////////////////////////// module.exports.spawnJQueryDriver = spawnJQueryDriver; module.exports.simplifyDOMEvent = simplifyDOMEvent; module.exports.defaultWrapFunction = defaultWrapFunction; },{"./demand-matcher.js":223,"./network.js":229,"./patch.js":230}],227:[function(require,module,exports){ "use strict"; function copyKeys(keys, to, from) { for (var i = 0; i < keys.length; i++) { to[keys[i]] = from[keys[i]]; } } module.exports = require("./network.js"); module.exports.Route = require("./route.js"); copyKeys(['__', '_$', '$Capture', '$Special', 'is_emptyTrie', 'emptyTrie', 'embeddedTrie', 'compilePattern', 'compileProjection', 'project', 'projectObjects', 'prettyTrie'], module.exports, module.exports.Route); var Seal = require('./seal.js') copyKeys(['Seal', 'seal'], module.exports, Seal); module.exports.DemandMatcher = require('./demand-matcher.js').DemandMatcher; module.exports.Ack = require('./ack.js').Ack; module.exports.RandomID = require('./randomid.js'); module.exports.DOM = require("./dom-driver.js"); module.exports.JQuery = require("./jquery-driver.js"); // module.exports.RoutingTableWidget = require("./routing-table-widget.js"); // module.exports.WebSocket = require("./websocket-driver.js"); module.exports.Reflect = require("./reflect.js"); module.exports.Patch = require("./patch.js"); copyKeys(['emptyPatch', 'observe', 'atMeta', 'advertise', 'isObserve', 'isAtMeta', 'isAdvertise', 'assert', 'retract', 'sub', 'unsub', 'pub', 'unpub', 'patchSeq'], module.exports, module.exports.Patch); module.exports.Ground = require("./ground.js").Ground; module.exports.Actor = require("./actor.js"); // module.exports.Spy = require("./spy.js").Spy; // module.exports.WakeDetector = require("./wake-detector.js").WakeDetector; // var Worker = require("./worker.js"); // module.exports.Worker = Worker.Worker; // module.exports.WorkerGround = Worker.WorkerGround; },{"./ack.js":221,"./actor.js":222,"./demand-matcher.js":223,"./dom-driver.js":224,"./ground.js":225,"./jquery-driver.js":226,"./network.js":229,"./patch.js":230,"./randomid.js":231,"./reflect.js":232,"./route.js":233,"./seal.js":234}],228:[function(require,module,exports){ "use strict"; var Immutable = require('immutable'); var Route = require('./route.js'); var Patch = require('./patch.js'); function Mux(nextPid, routingTable, interestTable) { this.nextPid = nextPid || 0; this.routingTable = routingTable || Route.emptyTrie; this.interestTable = interestTable || Immutable.Map(); // pid -> Trie } Mux.prototype.shallowCopy = function () { return new Mux(this.nextPid, this.routingTable, this.interestTable); }; Mux.prototype.addStream = function (initialPatch) { var newPid = this.nextPid++; return this.updateStream(newPid, initialPatch); }; Mux.prototype.removeStream = function (pid) { return this.updateStream(pid, Patch.removeEverythingPatch); }; Mux.prototype.updateStream = function (pid, unclampedPatch) { var oldInterests = this.interestsOf(pid); var oldRoutingTable = this.routingTable; var delta = unclampedPatch.label(Immutable.Set.of(pid)).limit(oldInterests); var deltaAggregate = delta.computeAggregate(pid, oldRoutingTable); var newInterests = delta.applyTo(oldInterests); var newRoutingTable = delta.applyTo(oldRoutingTable); this.routingTable = newRoutingTable; if (Route.is_emptyTrie(newInterests)) { this.interestTable = this.interestTable.remove(pid); } else { this.interestTable = this.interestTable.set(pid, newInterests); } return { pid: pid, delta: delta, deltaAggregate: deltaAggregate }; }; var atMetaEverything = Route.compilePattern(true, Patch.atMeta(Route.__)); var atMetaBranchKeys = Immutable.List([Route.SOA, Patch.$AtMeta]); var onlyMeta = Immutable.Set.of("meta"); function echoCancelledTrie(t) { return Route.subtract(t, atMetaEverything, function (v1, v2) { return v1.has("meta") ? onlyMeta : null; }); } function computeEvents(oldMux, newMux, updateStreamResult) { var actingPid = updateStreamResult.pid; var delta = updateStreamResult.delta; var deltaAggregate = updateStreamResult.deltaAggregate; var deltaAggregateNoEcho = (actingPid === "meta") ? delta // because echo-cancellation means that meta-SCNs are always new information : new Patch.Patch(Route.triePruneBranch(deltaAggregate.added, atMetaBranchKeys), Route.triePruneBranch(deltaAggregate.removed, atMetaBranchKeys)); var oldRoutingTable = oldMux.routingTable; var newRoutingTable = newMux.routingTable; var affectedPids = computeAffectedPids(oldRoutingTable, deltaAggregateNoEcho).add(actingPid).remove("meta"); return { eventMap: Immutable.Map().withMutations(function (result) { affectedPids.forEach(function (pid) { var patchForPid; if (pid === actingPid) { var part1 = new Patch.Patch( echoCancelledTrie(Patch.biasedIntersection(newRoutingTable, delta.added)), echoCancelledTrie(Patch.biasedIntersection(oldRoutingTable, delta.removed))); var part2 = new Patch.Patch(Patch.biasedIntersection(deltaAggregateNoEcho.added, newMux.interestsOf(pid)), Patch.biasedIntersection(deltaAggregateNoEcho.removed, oldMux.interestsOf(pid))); patchForPid = part1.unsafeUnion(part2); } else { patchForPid = deltaAggregateNoEcho.viewFrom(oldMux.interestsOf(pid)); } if (patchForPid.isNonEmpty()) { result.set(pid, patchForPid); } }); }), metaEvents: (actingPid === "meta") ? Immutable.List() : Immutable.List.of(delta.computeAggregate(actingPid, oldRoutingTable, true).drop()) }; } function computeAffectedPids(routingTable, delta) { var cover = Route._union(delta.added, delta.removed); routingTable = Route.trieStep(routingTable, Route.SOA); routingTable = Route.trieStep(routingTable, Patch.$Observe); return Route.matchTrie(cover, routingTable, Immutable.Set(), function (v, r, acc) { return acc.union(Route.trieStep(r, Route.EOA).value); }); } Mux.prototype.routeMessage = function (body) { if (Route.matchValue(this.routingTable, body) === null) { return Route.matchValue(this.routingTable, Patch.observe(body)) || Immutable.Set(); } else { // Some other stream has declared body return Immutable.Set(); } }; Mux.prototype.interestsOf = function (pid) { return this.interestTable.get(pid, Route.emptyTrie); }; /////////////////////////////////////////////////////////////////////////// module.exports.Mux = Mux; module.exports.computeEvents = computeEvents; module.exports.computeAffectedPids = computeAffectedPids; },{"./patch.js":230,"./route.js":233,"immutable":220}],229:[function(require,module,exports){ "use strict"; var Immutable = require('immutable'); var Route = require('./route.js'); var Patch = require('./patch.js'); var Mux = require('./mux.js'); /*---------------------------------------------------------------------------*/ /* Events and Actions */ function stateChange(patch) { return { type: 'stateChange', patch: patch }; } function message(body) { return { type: 'message', message: body }; } function spawn(behavior) { return { type: 'spawn', behavior: behavior }; } function terminate() { return { type: 'terminate' }; } function terminateNetwork() { return { type: 'terminateNetwork' }; } /*---------------------------------------------------------------------------*/ /* Network */ function Network(bootFn) { this.pendingActions = Immutable.List(); // of [pid, Action] this.processTable = Immutable.Map(); // pid -> Behavior this.runnablePids = Immutable.Set(); // of pid this.mux = new Mux.Mux(); this.onStateChange = function (mux, deltaAggregate) {}; this.asChild('meta', function () { return bootFn() }, true); } // Class state and methods Network.stack = Immutable.List(); Network.current = function () { return Network.stack.last().network; }; Network.activePid = function () { return Network.stack.last().activePid; }; Network.activeBehavior = function () { var entry = Network.stack.last(); var p = entry.network.processTable.get(entry.activePid); return p ? p.behavior : null; }; Network.withNetworkStack = function (stack, f) { var oldStack = Network.stack; Network.stack = stack; var result; try { result = f(); } catch (e) { Network.stack = oldStack; throw e; } Network.stack = oldStack; return result; }; Network.wrap = function (f) { var savedStack = Network.stack; return function () { var actuals = arguments; return Network.withNetworkStack(savedStack, function () { var result = Network.current().asChild(Network.activePid(), function () { return f.apply(null, actuals); }); Network.stack.reverse().forEach(function (entry) { entry.network.markRunnable(entry.activePid); }); return result; }); }; }; Network.enqueueAction = function (action) { var entry = Network.stack.last(); entry.network.enqueueAction(entry.activePid, action); }; Network.send = function (body, metaLevel) { Network.enqueueAction(message(Patch.prependAtMeta(body, metaLevel || 0))); }; Network.stateChange = function (patch) { Network.enqueueAction(stateChange(patch)); }; Network.spawn = function (behavior) { Network.enqueueAction(spawn(behavior)); }; Network.exit = function (exn) { Network.current().kill(Network.activePid(), exn); }; Network.exitNetwork = function () { Network.enqueueAction(terminateNetwork()); }; Network.inertBehavior = { handleEvent: function (e) {} }; // Instance methods Network.prototype.asChild = function (pid, f, omitLivenessCheck) { var self = this; var p = this.processTable.get(pid, null); if (!omitLivenessCheck && (p === null)) { console.warn("Network.asChild eliding invocation of dead process", pid); return; } return Network.withNetworkStack( Network.stack.push({ network: this, activePid: pid }), function () { try { return f(p); } catch (e) { self.kill(pid, e); } }); }; Network.prototype.kill = function (pid, exn) { if (exn && exn.stack) { console.log("Process exiting", pid, exn, exn.stack); } else { console.log("Process exiting", pid, exn); } var p = this.processTable.get(pid); this.processTable = this.processTable.set(pid, { behavior: Network.inertBehavior }); if (p) { if (p.behavior.trapexit) { this.asChild(pid, function () { return p.behavior.trapexit(exn); }, true); } this.enqueueAction(pid, terminate()); } }; Network.prototype.boot = function () { // Needed in order for a new Network to be marked as "runnable", so // its initial actions get performed. }; Network.prototype.handleEvent = function (e) { switch (e.type) { case 'stateChange': this.enqueueAction('meta', stateChange(e.patch.lift())); break; case 'message': this.enqueueAction('meta', message(Patch.atMeta(e.message))); break; default: var exn = new Error("Event type " + e.type + " not understood"); exn.event = e; throw exn; } return true; }; Network.prototype.step = function () { return this.dispatchActions() && this.runRunnablePids() && ((this.pendingActions.size > 0) || (this.runnablePids.size > 0)); }; Network.prototype.enqueueAction = function (pid, action) { this.pendingActions = this.pendingActions.push([pid, action]); }; Network.prototype.dispatchActions = function () { var self = this; var actionQueue = this.pendingActions; this.pendingActions = Immutable.List(); var alive = true; actionQueue.forEach(function (entry) { var pid = entry[0]; var action = entry[1]; if (!self.interpretAction(pid, action)) { alive = false; return false; } }); return alive; }; Network.prototype.markRunnable = function (pid) { this.runnablePids = this.runnablePids.add(pid); }; Network.prototype.runRunnablePids = function () { var self = this; var pidSet = this.runnablePids; this.runnablePids = Immutable.Set(); pidSet.forEach(function (pid) { var childBusy = self.asChild(pid, function (p) { return p.behavior.step // exists, haven't called it yet && p.behavior.step(); }); if (childBusy) self.markRunnable(pid); }); return true; }; Network.prototype.interpretAction = function (pid, action) { var self = this; switch (action.type) { case 'stateChange': var oldMux = this.mux.shallowCopy(); this.deliverPatches(oldMux, this.mux.updateStream(pid, action.patch)); return true; case 'message': if (Patch.isObserve(action.message)) { console.warn('Process ' + pid + ' send message containing query', action.message); } if (pid !== 'meta' && Patch.isAtMeta(action.message)) { Network.send(action.message[1]); } else { this.mux.routeMessage(action.message).forEach(function (pid) { self.deliverEvent(pid, action); }); } return true; case 'spawn': var oldMux = this.mux.shallowCopy(); var p = { behavior: action.behavior }; var pid = this.mux.nextPid; this.processTable = this.processTable.set(pid, p); var initialPatch = Patch.emptyPatch; if (p.behavior.boot) { initialPatch = this.asChild(pid, function () { return p.behavior.boot() }); initialPatch = initialPatch || Patch.emptyPatch; this.markRunnable(pid); } this.deliverPatches(oldMux, this.mux.addStream(initialPatch)); return true; case 'terminate': var oldMux = this.mux.shallowCopy(); this.deliverPatches(oldMux, this.mux.removeStream(pid)); console.log("Process exit complete", pid); this.processTable = this.processTable.remove(pid); return true; case 'terminateNetwork': Network.exit(); return false; default: var exn = new Error("Action type " + action.type + " not understood"); exn.action = action; throw exn; } }; Network.prototype.deliverPatches = function (oldMux, updateStreamResult) { var self = this; var events = Mux.computeEvents(oldMux, this.mux, updateStreamResult); events.eventMap.forEach(function (patch, pid) { self.deliverEvent(pid, stateChange(patch)); }); events.metaEvents.forEach(Network.stateChange); this.onStateChange(this.mux, updateStreamResult.deltaAggregate); }; Network.prototype.deliverEvent = function (pid, event) { var childBusy = this.asChild(pid, function (p) { return p.behavior.handleEvent(event); }); if (childBusy) this.markRunnable(pid); }; /////////////////////////////////////////////////////////////////////////// module.exports.stateChange = stateChange; module.exports.message = message; module.exports.spawn = spawn; module.exports.terminate = terminate; module.exports.terminateNetwork = terminateNetwork; module.exports.Network = Network; },{"./mux.js":228,"./patch.js":230,"./route.js":233,"immutable":220}],230:[function(require,module,exports){ "use strict"; var Route = require("./route.js"); var Immutable = require("immutable"); var __ = Route.__; var _$ = Route._$; function Patch(added, removed) { this.added = added; this.removed = removed; } var emptyPatch = new Patch(Route.emptyTrie, Route.emptyTrie); var removeEverythingPatch = new Patch(Route.emptyTrie, Route.compilePattern(true, __)); var $Observe = new Route.$Special("$Observe"); var $AtMeta = new Route.$Special("$AtMeta"); var $Advertise = new Route.$Special("$Advertise"); function observe(p) { return [$Observe, p]; } function atMeta(p) { return [$AtMeta, p]; } function advertise(p) { return [$Advertise, p]; } function isObserve(p) { return p[0] === $Observe; } function isAtMeta(p) { return p[0] === $AtMeta; } function isAdvertise(p) { return p[0] === $Advertise; } function prependAtMeta(p, level) { while (level--) { p = atMeta(p); } return p; } function stripAtMeta(p, level) { while (level--) { if (p.length === 2 && p[0] === $AtMeta) { p = p[1]; } else { return null; } } return p; } function observeAtMeta(p, level) { if (level === 0) { return Route.compilePattern(true, observe(p)); } else { return Route._union( Route.compilePattern(true, observe(prependAtMeta(p, level))), Route.compilePattern(true, atMeta(Route.embeddedTrie(observeAtMeta(p, level - 1))))); } } function _check(p) { if (p instanceof Patch) { throw new Error("Cannot construct patch pattern using an embedded patch"); } return p; } function assert(p, metaLevel) { return new Patch(Route.compilePattern(true, prependAtMeta(_check(p), metaLevel || 0)), Route.emptyTrie); } function retract(p, metaLevel) { return new Patch(Route.emptyTrie, Route.compilePattern(true, prependAtMeta(_check(p), metaLevel || 0))); } function sub(p, metaLevel) { return new Patch(observeAtMeta(_check(p), metaLevel || 0), Route.emptyTrie); } function unsub(p, metaLevel) { return new Patch(Route.emptyTrie, observeAtMeta(_check(p), metaLevel || 0)); } function pub(p, metaLevel) { return assert(advertise(_check(p)), metaLevel); } function unpub(p, metaLevel) { return retract(advertise(_check(p)), metaLevel); } /////////////////////////////////////////////////////////////////////////// Patch.prototype.equals = function (other) { if (!(other instanceof Patch)) return false; return Immutable.is(this.added, other.added) && Immutable.is(this.removed, other.removed); }; Patch.prototype.isEmpty = function () { return this.added === Route.emptyTrie && this.removed === Route.emptyTrie; }; Patch.prototype.isNonEmpty = function () { return !this.isEmpty(); }; Patch.prototype.hasAdded = function () { return this.added !== Route.emptyTrie; }; Patch.prototype.hasRemoved = function () { return this.removed !== Route.emptyTrie; }; Patch.prototype.lift = function () { return new Patch(Route.compilePattern(true, atMeta(Route.embeddedTrie(this.added))), Route.compilePattern(true, atMeta(Route.embeddedTrie(this.removed)))); }; var atMetaProj = Route.compileProjection(atMeta(_$)); Patch.prototype.drop = function () { return new Patch(Route.project(this.added, atMetaProj), Route.project(this.removed, atMetaProj)); }; Patch.prototype.strip = function () { return new Patch(Route.relabel(this.added, function (v) { return true; }), Route.relabel(this.removed, function (v) { return true; })); }; Patch.prototype.label = function (labelValue) { return new Patch(Route.relabel(this.added, function (v) { return labelValue; }), Route.relabel(this.removed, function (v) { return labelValue; })); }; Patch.prototype.limit = function (bound) { return new Patch(Route.subtract(this.added, bound, function (v1, v2) { return null; }), Route.intersect(this.removed, bound, function (v1, v2) { return v1; })); }; var metaLabelSet = Immutable.Set(["meta"]); Patch.prototype.computeAggregate = function (label, base, removeMeta /* optional flag */) { return new Patch(Route.subtract(this.added, base, addCombiner), Route.subtract(this.removed, base, removeCombiner)); function addCombiner(v1, v2) { if (removeMeta && Immutable.is(v2, metaLabelSet)) { return v1; } else { return null; } } function removeCombiner(v1, v2) { if (v2.size === 1) { return v1; } else { if (removeMeta && v2.size === 2 && v2.has("meta")) { return v1; } else { return null; } } } }; Patch.prototype.applyTo = function (base) { return Route._union(Route.subtract(base, this.removed), this.added); }; Patch.prototype.updateInterests = function (base) { return Route._union(Route.subtract(base, this.removed, function (v1, v2) { return null; }), this.added, function (v1, v2) { return true; }); }; Patch.prototype.unapplyTo = function (base) { return Route._union(Route.subtract(base, this.added), this.removed); }; Patch.prototype.andThen = function (nextPatch) { return new Patch(nextPatch.updateInterests(this.added), Route._union(Route.subtract(this.removed, nextPatch.added, function (v1, v2) { return null; }), nextPatch.removed, function (v1, v2) { return true; })); }; function patchSeq(/* patch, patch, ... */) { var p = emptyPatch; for (var i = 0; i < arguments.length; i++) { p = p.andThen(arguments[i]); } return p; } function computePatch(oldBase, newBase) { return new Patch(Route.subtract(newBase, oldBase), Route.subtract(oldBase, newBase)); } function biasedIntersection(object, subject) { subject = Route.trieStep(subject, Route.SOA); subject = Route.trieStep(subject, $Observe); return Route.intersect(object, subject, function (v1, v2) { return true; }, function (v, r) { return Route.trieStep(r, Route.EOA); }); } Patch.prototype.viewFrom = function (interests) { return new Patch(biasedIntersection(this.added, interests), biasedIntersection(this.removed, interests)); }; Patch.prototype.unsafeUnion = function (other) { // Unsafe because does not necessarily preserve invariant that added // and removed are disjoint. return new Patch(Route._union(this.added, other.added), Route._union(this.removed, other.removed)); }; Patch.prototype.project = function (compiledProjection) { return new Patch(Route.project(this.added, compiledProjection), Route.project(this.removed, compiledProjection)); }; Patch.prototype.projectObjects = function (compiledProjection) { return [Route.projectObjects(this.added, compiledProjection), Route.projectObjects(this.removed, compiledProjection)]; }; Patch.prototype.pretty = function () { return ("<<<<<<<< Removed:\n" + Route.prettyTrie(this.removed) + "\n" + "======== Added:\n" + Route.prettyTrie(this.added) + "\n" + ">>>>>>>>"); } /////////////////////////////////////////////////////////////////////////// module.exports.Patch = Patch; module.exports.emptyPatch = emptyPatch; module.exports.removeEverythingPatch = removeEverythingPatch; module.exports.$Observe = $Observe; module.exports.$AtMeta = $AtMeta; module.exports.$Advertise = $Advertise; module.exports.observe = observe; module.exports.atMeta = atMeta; module.exports.advertise = advertise; module.exports.isObserve = isObserve; module.exports.isAtMeta = isAtMeta; module.exports.isAdvertise = isAdvertise; module.exports.prependAtMeta = prependAtMeta; module.exports.stripAtMeta = stripAtMeta; module.exports.observeAtMeta = observeAtMeta; module.exports.assert = assert; module.exports.retract = retract; module.exports.sub = sub; module.exports.unsub = unsub; module.exports.pub = pub; module.exports.unpub = unpub; module.exports.patchSeq = patchSeq; module.exports.computePatch = computePatch; module.exports.biasedIntersection = biasedIntersection; },{"./route.js":233,"immutable":220}],231:[function(require,module,exports){ var randomId; if ((typeof window !== 'undefined') && (typeof window.crypto !== 'undefined') && (typeof window.crypto.getRandomValues !== 'undefined')) { randomId = function (byteCount) { var buf = new Uint8Array(byteCount); window.crypto.getRandomValues(buf); return btoa(String.fromCharCode.apply(null, buf)).replace(/=/g,''); }; } else { var crypto; try { crypto = require('crypto'); } catch (e) {} if ((typeof crypto !== 'undefined') && (typeof crypto.randomBytes !== 'undefined')) { randomId = function (byteCount) { return crypto.randomBytes(byteCount).base64Slice().replace(/=/g,''); }; } else { console.warn('No suitable implementation for RandomID.randomId available.'); } } module.exports.randomId = randomId; },{"crypto":6}],232:[function(require,module,exports){ "use strict"; // Reflection on function formal parameter lists. // This module is based on Angular's "injector" code, // https://github.com/angular/angular.js/blob/master/src/auto/injector.js, // MIT licensed, and hence: // Copyright (c) 2010-2014 Google, Inc. http://angularjs.org // Copyright (c) 2014 Tony Garnock-Jones var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m; var FN_ARG_SPLIT = /,/; var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; function formalParameters(fn) { var result = []; var fnText = fn.toString().replace(STRIP_COMMENTS, ''); var argDecl = fnText.match(FN_ARGS); var args = argDecl[1].split(FN_ARG_SPLIT); for (var i = 0; i < args.length; i++) { var trimmed = args[i].trim(); if (trimmed) { result.push(trimmed); } } return result; } module.exports.formalParameters = formalParameters; },{}],233:[function(require,module,exports){ "use strict"; var Immutable = require("immutable"); function makeStructureConstructor(label, argumentNames) { var $SyndicateMeta$ = { label: label, arguments: argumentNames }; return function() { var result = {"$SyndicateMeta$": $SyndicateMeta$}; for (var i = 0; i < argumentNames.length; i++) { result[argumentNames[i]] = arguments[i]; } return result; }; } function isStructure(s) { return (s !== null) && (typeof s === 'object') && ("$SyndicateMeta$" in s); } function structureToArray(s) { var result = [s.$SyndicateMeta$.label]; var args = s.$SyndicateMeta$.arguments; for (var i = 0; i < args.length; i++) { result.push(s[args[i]]); } return result; } function $Special(name) { this.name = name; } var __ = new $Special("wildcard"); /* wildcard marker */ var SOA = new $Special("["); // start of array var EOA = new $Special("]"); // end of array function die(message) { throw new Error(message); } function $Embedded(trie) { this.trie = trie; } function embeddedTrie(trie) { return new $Embedded(trie); } // The name argument should be a string or null; it defaults to null. // The pattern argument defaults to wildcard, __. function $Capture(name, pattern) { this.name = name || null; this.pattern = (typeof pattern === 'undefined' ? __ : pattern); } // Abbreviation: _$(...) <==> new $Capture(...) function _$(name, pattern) { return new $Capture(name, pattern); } function isCapture(x) { return x instanceof $Capture || x === _$; } function captureName(x) { return x instanceof $Capture ? x.name : null; } function capturePattern(x) { return x instanceof $Capture ? x.pattern : __; } var SOC = new $Special("{"); // start of capture var EOC = new $Special("}"); // end of capture function $Success(value) { this.value = value; } $Success.prototype.equals = function (other) { if (!(other instanceof $Success)) return false; return Immutable.is(this.value, other.value); }; function $WildcardSequence(trie) { this.trie = trie; } $WildcardSequence.prototype.equals = function (other) { if (!(other instanceof $WildcardSequence)) return false; return Immutable.is(this.trie, other.trie); }; function is_emptyTrie(m) { return Immutable.is(m, emptyTrie); } /////////////////////////////////////////////////////////////////////////// // Constructors var emptyTrie = Immutable.Map(); function rsuccess(v) { return (v === null) ? emptyTrie : new $Success(v); } function rseq(e, r) { if (r === emptyTrie) return emptyTrie; return emptyTrie.set(e, r); } function rwild(r) { return rseq(__, r); } function rwildseq(r) { return (r === emptyTrie) ? emptyTrie : new $WildcardSequence(r); } /////////////////////////////////////////////////////////////////////////// function compilePattern(v, p) { if (!p) die("compilePattern: missing pattern"); return walk(p, rseq(EOA, rsuccess(v))); function walk(p, acc) { if (p === __) return rwild(acc); if (Array.isArray(p)) { acc = rseq(EOA, acc); for (var i = p.length - 1; i >= 0; i--) { acc = walk(p[i], acc); } return rseq(SOA, acc); } if (Immutable.List.isList(p)) { acc = rseq(EOA, acc); p.reverse().forEach(function (element) { acc = walk(element, acc); }); return rseq(SOA, acc); } if (isStructure(p)) { var args = p.$SyndicateMeta$.arguments; acc = rseq(EOA, acc); for (var i = args.length - 1; i >= 0; i--) { acc = walk(p[args[i]], acc); } acc = rseq(p.$SyndicateMeta$.label, acc); return rseq(SOA, acc); } if (p instanceof $Embedded) { return appendTrie(p.trie, function (v) { return acc; }); } else { return rseq(p, acc); } } } function matchPattern(v, p) { var captureCount = 0; var result = {}; try { walk(v, p); } catch (e) { if (e.matchPatternFailed) return null; throw e; } result.length = captureCount; return result; function walk(v, p) { if (p === v) return; if (p === __) return; if (isStructure(p)) { p = structureToArray(p); } if (isStructure(v)) { v = structureToArray(v); } if (Array.isArray(p) && Array.isArray(v) && p.length === v.length) { for (var i = 0; i < p.length; i++) { walk(v[i], p[i]); } return; } if (isCapture(p)) { var thisCapture = captureCount++; walk(v, capturePattern(p)); result[captureName(p) || ('$' + thisCapture)] = v; return; } if (p instanceof $Embedded) { die("$Embedded patterns not supported in matchPattern()"); } throw {matchPatternFailed: true}; } } function rupdate(r, key, k) { var oldWild = r.get(__, emptyTrie); if (Immutable.is(k, oldWild)) { return r.remove(key); } else { return r.set(key, k); } } function rlookup(r, key) { return r.get(key, emptyTrie); } function rlookupWild(r, key) { var result = r.get(key, false); if (result) return result; var wildEdge = rlookup(r, __); if (is_keyOpen(key)) return rwildseq(wildEdge); if (is_keyClose(key)) return (wildEdge instanceof $WildcardSequence) ? wildEdge.trie : emptyTrie; return wildEdge; } function is_keyOpen(k) { return k === SOA; } function is_keyClose(k) { return k === EOA; } function is_keyNormal(k) { return !(is_keyOpen(k) || is_keyClose(k)); } /////////////////////////////////////////////////////////////////////////// var unionSuccessesDefault = function (v1, v2) { if (v1 === true) return v2; if (v2 === true) return v1; return v1.union(v2); }; var intersectSuccessesDefault = function (v1, v2) { return v1; }; var subtractSuccessesDefault = function (v1, v2) { var r = v1.subtract(v2); if (r.isEmpty()) return null; return r; }; var matchTrieSuccesses = function (v1, v2, acc) { return acc.union(v2); }; var projectSuccess = function (v) { return v; }; /////////////////////////////////////////////////////////////////////////// function expandWildseq(r) { return union(rwild(rwildseq(r)), rseq(EOA, r)); } function union(o1, o2, unionSuccessesOpt) { var unionSuccesses = unionSuccessesOpt || unionSuccessesDefault; return merge(o1, o2); function merge(o1, o2) { if (is_emptyTrie(o1)) return o2; if (is_emptyTrie(o2)) return o1; return walk(o1, o2); } function walk(r1, r2) { if (r1 instanceof $WildcardSequence) { if (r2 instanceof $WildcardSequence) { return rwildseq(walk(r1.trie, r2.trie)); } r1 = expandWildseq(r1.trie); } else if (r2 instanceof $WildcardSequence) { r2 = expandWildseq(r2.trie); } if (r1 instanceof $Success) { if (r2 instanceof $Success) { return rsuccess(unionSuccesses(r1.value, r2.value)); } else { die("Route.union: left short!"); } } else if (r2 instanceof $Success) { die("Route.union: right short!"); } var w = merge(rlookup(r1, __), rlookup(r2, __)); var target; function examineKey(key) { if ((key !== __) && !target.has(key)) { target = rupdate(target, key, merge(rlookupWild(r1, key), rlookupWild(r2, key))); } } if (is_emptyTrie(w)) { var smaller = r1.size < r2.size ? r1 : r2; var larger = r1.size < r2.size ? r2 : r1; target = larger; smaller.forEach(function (val, key) { var k = merge(rlookup(smaller, key), rlookup(larger, key)); target = rupdate(target, key, k); }); } else { target = rwild(w); r1.forEach(function (val, key) { examineKey(key) }); r2.forEach(function (val, key) { examineKey(key) }); } return target; } } function unionN() { var acc = emptyTrie; for (var i = 0; i < arguments.length; i++) { acc = union(acc, arguments[i]); } return acc; } function intersect(o1, o2, intersectSuccessesOpt, leftShortOpt) { var intersectSuccesses = intersectSuccessesOpt || intersectSuccessesDefault; var leftShort = leftShortOpt || function (v, r) { die("Route.intersect: left side short!"); }; return walk(o1, o2); function walkFlipped(r2, r1) { return walk(r1, r2); } function walk(r1, r2) { // INVARIANT: r1 is a part of the original o1, and // likewise for r2. This is so that the first arg to // intersectSuccesses always comes from r1, and the second // from r2. if (is_emptyTrie(r1)) return emptyTrie; if (is_emptyTrie(r2)) return emptyTrie; if (r1 instanceof $WildcardSequence) { if (r2 instanceof $WildcardSequence) { return rwildseq(walk(r1.trie, r2.trie)); } r1 = expandWildseq(r1.trie); } else if (r2 instanceof $WildcardSequence) { r2 = expandWildseq(r2.trie); } if (r1 instanceof $Success) { if (r2 instanceof $Success) { return rsuccess(intersectSuccesses(r1.value, r2.value)); } else { return leftShort(r1.value, r2); } } var w1 = rlookup(r1, __); var w2 = rlookup(r2, __); var w = walk(w1, w2); var target = emptyTrie; function examineKey(key) { if ((key !== __) && !target.has(key)) { target = rupdate(target, key, walk(rlookupWild(r1, key), rlookupWild(r2, key))); } } if (is_emptyTrie(w1)) { if (is_emptyTrie(w2)) { (r1.size < r2.size ? r1 : r2).forEach(function (val, key) { examineKey(key) }); } else { r1.forEach(function (val, key) { examineKey(key) }); } } else { if (is_emptyTrie(w2)) { r2.forEach(function (val, key) { examineKey(key) }); } else { target = rupdate(target, __, w); r1.forEach(function (val, key) { examineKey(key) }); r2.forEach(function (val, key) { examineKey(key) }); } } return target; } } // The subtractSuccesses function should return null to signal "no // remaining success values". function subtract(o1, o2, subtractSuccessesOpt) { var subtractSuccesses = subtractSuccessesOpt || subtractSuccessesDefault; return walk(o1, o2); function walkFlipped(r2, r1) { return walk(r1, r2); } function walk(r1, r2) { if (is_emptyTrie(r1)) { return emptyTrie; } else { if (is_emptyTrie(r2)) { return r1; } } if (r1 instanceof $WildcardSequence) { if (r2 instanceof $WildcardSequence) { return rwildseq(walk(r1.trie, r2.trie)); } r1 = expandWildseq(r1.trie); } else if (r2 instanceof $WildcardSequence) { r2 = expandWildseq(r2.trie); } if (r1 instanceof $Success && r2 instanceof $Success) { return rsuccess(subtractSuccesses(r1.value, r2.value)); } var w1 = rlookup(r1, __); var w2 = rlookup(r2, __); var w = walk(w1, w2); var target; function examineKey(key) { if (key !== __) { var k1 = rlookupWild(r1, key); var k2 = rlookupWild(r2, key); var updatedK = walk(k1, k2); // Here we ensure a "minimal" remainder in cases // where after an erasure, a particular key's // continuation is the same as the wildcard's // continuation. TODO: the equals check may // be expensive. If so, how can it be made // cheaper? if (is_keyOpen(key)) { target = rupdate(target, key, ((updatedK instanceof $WildcardSequence) && Immutable.is(updatedK.trie, w)) ? w : updatedK); } else { target = rupdate(target, key, updatedK); } } } if (is_emptyTrie(w2)) { target = r1; r2.forEach(function (val, key) { examineKey(key) }); } else { target = emptyTrie; target = rupdate(target, __, w); r1.forEach(function (val, key) { examineKey(key) }); r2.forEach(function (val, key) { examineKey(key) }); } return collapseWildcardSequences(target); } } function collapseWildcardSequences(target) { // Here, the target is complete. If it has only two keys, // one wild and one is_keyClose, and wild's continuation // is a $WildcardSequence and the other continuation is // identical to the sequence's continuation, then replace // the whole thing with a nested $WildcardSequence. // (We know w === rlookup(target, __) from before.) // // TODO: I suspect actually this applies even if there are // more than two keys, so long as all their continuations // are identical and there's at least one is_keyClose // alongside a wild. if (target.size === 2) { var finalW = rlookup(target, __); if (finalW instanceof $WildcardSequence) { target.forEach(function (k, key) { if ((key !== __) && is_keyClose(key)) { if (Immutable.is(k, finalW.trie)) { target = finalW; return false; // terminate the iteration early } } }); } } return target; } // Returns null on failed match, otherwise the appropriate success // value contained in the trie r. function matchValue(r, v) { var failureResult = null; var vs = Immutable.List.of(v); var stack = [Immutable.List()]; while (!is_emptyTrie(r)) { if (r instanceof $WildcardSequence) { if (stack.length === 0) return failureResult; vs = stack.pop(); r = r.trie; continue; } if (r instanceof $Success) { if (vs.size === 0 && stack.length === 0) return r.value; return failureResult; } if (vs.size === 0) { if (stack.length === 0) return failureResult; vs = stack.pop(); r = rlookup(r, EOA); continue; } var v = vs.first(); vs = vs.shift(); if (typeof v === 'string' && v.substring(0, 2) === '__') { die("Cannot match special string starting with __"); } if (Array.isArray(v)) { if (r.has(SOA)) { r = rlookup(r, SOA); stack.push(vs); vs = Immutable.List(v); } else { r = rlookup(r, __); } } else if (isStructure(v)) { if (r.has(SOA)) { r = rlookup(r, SOA); stack.push(vs); vs = Immutable.List.of(v.$SyndicateMeta$.label); var args = v.$SyndicateMeta$.arguments; for (var i = 0; i < args.length; i++) { vs = vs.push(v[args[i]]); } } else { r = rlookup(r, __); } } else { if (r.has(v)) { r = rlookup(r, v); } else { r = rlookup(r, __); } } } return failureResult; } function matchTrie(o1, o2, seed, leftShortOpt) { var acc = typeof seed === 'undefined' ? Immutable.Set() : seed; // variable updated imperatively var leftShort = leftShortOpt || function (v, r, acc) { die("Route.matchTrie: left side short!"); }; walk(o1, o2); return acc; function walkFlipped(r2, r1) { return walk(r1, r2); } function walk(r1, r2) { if (is_emptyTrie(r1) || is_emptyTrie(r2)) return; if (r1 instanceof $WildcardSequence) { if (r2 instanceof $WildcardSequence) { walk(r1.trie, r2.trie); return; } r1 = expandWildseq(r1.trie); } else if (r2 instanceof $WildcardSequence) { r2 = expandWildseq(r2.trie); } if (r1 instanceof $Success) { if (r2 instanceof $Success) { acc = matchTrieSuccesses(r1.value, r2.value, acc); } else { acc = leftShort(r1.value, r2, acc); } return; } else if (r2 instanceof $Success) { die("Route.matchTrie: right side short!"); } var w1 = rlookup(r1, __); var w2 = rlookup(r2, __); walk(w1, w2); function examineKey(key) { if (key !== __) { var k1 = rlookup(r1, key); var k2 = rlookup(r2, key); if (is_emptyTrie(k1)) { if (is_emptyTrie(k2)) { return; } else { walkWild(walk, w1, key, k2); } } else { if (is_emptyTrie(k2)) { walkWild(walkFlipped, w2, key, k1); } else { walk(k1, k2); } } } } // Optimize similarly to intersect(). if (is_emptyTrie(w1)) { if (is_emptyTrie(w2)) { (r1.size < r2.size ? r1 : r2).forEach(function (val, key) { examineKey(key) }); } else { r1.forEach(function (val, key) { examineKey(key) }); } } else { if (is_emptyTrie(w2)) { r2.forEach(function (val, key) { examineKey(key) }); } else { r1.forEach(function (val, key) { examineKey(key) }); r2.forEach(function (val, key) { examineKey(key) }); } } } function walkWild(walker, w, key, k) { if (is_emptyTrie(w)) return; if (is_keyOpen(key)) { walker(rwildseq(w), k); return; } if (is_keyClose(key)) { if (w instanceof $WildcardSequence) walker(w.trie, k); return; } walker(w, k); } } function appendTrie(m, mTailFn) { return walk(m); function walk(m) { if (is_emptyTrie(m)) return emptyTrie; if (m instanceof $WildcardSequence) return rwildseq(walk(m.trie)); if (m instanceof $Success) die("Ill-formed trie"); var target = emptyTrie; m.forEach(function (k, key) { if (is_keyClose(key) && (k instanceof $Success)) { target = union(target, mTailFn(k.value)); } else { target = rupdate(target, key, walk(k)); } }); return target; } } function triePruneBranch(m, keys) { if (keys.isEmpty()) return emptyTrie; if (is_emptyTrie(m)) return emptyTrie; if (m instanceof $WildcardSequence) { return collapseWildcardSequences(triePruneBranch(expandWildseq(m.trie), keys)); } if (m instanceof $Success) return m; var key = keys.first(); var rest = keys.shift(); return rupdate(m, key, triePruneBranch(rlookupWild(m, key), rest)); } function trieStep(m, key) { if (is_emptyTrie(m)) return emptyTrie; if (m instanceof $WildcardSequence) return (is_keyClose(key) ? m.trie : m); if (m instanceof $Success) return emptyTrie; return rlookupWild(m, key); } function relabel(m, f) { return walk(m); function walk(m) { if (is_emptyTrie(m)) return emptyTrie; if (m instanceof $WildcardSequence) return rwildseq(walk(m.trie)); if (m instanceof $Success) return rsuccess(f(m.value)); var target = emptyTrie; m.forEach(function (k, key) { target = rupdate(target, key, walk(k)); }); return target; } } function compileProjection(/* projection, projection, ... */) { var names = []; var acc = []; for (var i = 0; i < arguments.length; i++) { walk(arguments[i]); } acc.push(EOA); return {names: names, spec: acc}; function walk(p) { if (isCapture(p)) { names.push(captureName(p)); acc.push(SOC); walk(capturePattern(p)); acc.push(EOC); return; } if (Array.isArray(p)) { acc.push(SOA); for (var i = 0; i < p.length; i++) { walk(p[i]); } acc.push(EOA); return; } if (isStructure(p)) { acc.push(SOA); acc.push(p.$SyndicateMeta$.label); var args = p.$SyndicateMeta$.arguments; for (var i = 0; i < args.length; i++) { walk(p[args[i]]); } acc.push(EOA); return; } if (p instanceof $Embedded) { die("Cannot embed trie in projection"); } else { acc.push(p); } } } function projectionToPattern(p) { return walk(p); function walk(p) { if (isCapture(p)) return walk(capturePattern(p)); if (Array.isArray(p)) { var result = []; for (var i = 0; i < p.length; i++) { result.push(walk(p[i])); } return result; } if (isStructure(p)) { var result = {"$SyndicateMeta$": p.$SyndicateMeta$}; var args = p.$SyndicateMeta$.arguments; for (var i = 0; i < args.length; i++) { result[args[i]] = walk(p[args[i]]); } return result; } if (p instanceof $Embedded) { return p.trie; } else { return p; } } } function project(m, compiledProjection) { var spec = compiledProjection.spec; return walk(false, m, 0); function walk(isCapturing, m, specIndex) { if (specIndex >= spec.length) { if (isCapturing) die("Bad specification: unclosed capture"); if (m instanceof $Success) { return rseq(EOA, rsuccess(projectSuccess(m.value))); } else { return emptyTrie; } } if (is_emptyTrie(m)) return emptyTrie; var item = spec[specIndex]; var nextIndex = specIndex + 1; if (item === EOC) { if (!isCapturing) die("Bad specification: unexpected EOC"); return walk(false, m, nextIndex); } if (item === SOC) { if (isCapturing) die("Bad specification: nested capture"); return walk(true, m, nextIndex); } if (item === __) { if (m instanceof $WildcardSequence) { if (isCapturing) { return rwild(walk(isCapturing, m, nextIndex)); } else { return walk(isCapturing, m, nextIndex); } } if (m instanceof $Success) { return emptyTrie; } var target; if (isCapturing) { target = emptyTrie; target = rupdate(target, __, walk(isCapturing, rlookup(m, __), nextIndex)); m.forEach(function (mk, key) { if (key !== __) { if (is_keyOpen(key)) { target = rupdate(target, key, captureNested(mk, function (mk2) { return walk(isCapturing, mk2, nextIndex); })); } else if (is_keyClose(key)) { // do nothing } else { target = rupdate(target, key, walk(isCapturing, mk, nextIndex)); } } }); } else { target = walk(isCapturing, rlookup(m, __), nextIndex); m.forEach(function (mk, key) { if (key !== __) { if (is_keyOpen(key)) { target = union(target, skipNested(mk, function (mk2) { return walk(isCapturing, mk2, nextIndex); })); } else if (is_keyClose(key)) { // do nothing } else { target = union(target, walk(isCapturing, mk, nextIndex)); } } }); } return target; } var result; if (m instanceof $WildcardSequence) { if (is_keyOpen(item)) { result = walk(isCapturing, rwildseq(m), nextIndex); } else if (is_keyClose(item)) { result = walk(isCapturing, m.trie, nextIndex); } else { result = walk(isCapturing, m, nextIndex); } } else if (m instanceof $Success) { result = emptyTrie; } else { if (is_keyOpen(item)) { result = walk(isCapturing, rwildseq(rlookup(m, __)), nextIndex); } else if (is_keyClose(item)) { result = emptyTrie; } else { result = walk(isCapturing, rlookup(m, __), nextIndex); } result = union(result, walk(isCapturing, rlookup(m, item), nextIndex)); } if (isCapturing) { result = rseq(item, result); } return result; } function captureNested(m, cont) { if (m instanceof $WildcardSequence) { return rwildseq(cont(m.trie)); } if (is_emptyTrie(m) || (m instanceof $Success)) { return emptyTrie; } var target = emptyTrie; target = rupdate(target, __, captureNested(rlookup(m, __), cont)); m.forEach(function (mk, key) { if (key !== __) { if (is_keyOpen(key)) { target = rupdate(target, key, captureNested(mk, function (mk2) { return captureNested(mk2, cont); })); } else if (is_keyClose(key)) { target = rupdate(target, key, cont(mk)); } else { target = rupdate(target, key, captureNested(mk, cont)); } } }); return target; } function skipNested(m, cont) { if (m instanceof $WildcardSequence) { return cont(m.trie); } if (is_emptyTrie(m) || (m instanceof $Success)) { return emptyTrie; } var target = skipNested(rlookup(m, __), cont); m.forEach(function (mk, key) { if (key !== __) { if (is_keyOpen(key)) { target = union(target, skipNested(mk, function (mk2) { return skipNested(mk2, cont) })); } else if (is_keyClose(key)) { target = union(target, cont(mk)); } else { target = union(target, skipNested(mk, cont)); } } }); return target; } } function trieKeys(m) { if (is_emptyTrie(m)) return Immutable.Set(); var result = walkSeq(m, function (vss, vsk) { return vss; }); if (result === null) return null; return Immutable.Set(result); function walk(m, k) { if (m instanceof $WildcardSequence) return null; if (m instanceof $Success) return []; if (m.has(__)) return null; var acc = []; m.forEach(function (mk, key) { var piece; if (is_keyOpen(key)) { piece = walkSeq(mk, function (vss, vsk) { var acc = []; for (var i = 0; i < vss.length; i++) { var vs = vss[i]; acc = acc.concat(k(transformSeqs(vs, key), vsk)); } return acc; }); } else if (is_keyClose(key)) { die("trieKeys: internal error: unexpected key-close"); } else { piece = k(key, mk); } if (piece === null) return null; acc = acc.concat(piece); }); return acc; } function walkSeq(m, k) { if (m instanceof $WildcardSequence) return null; if (m instanceof $Success) return k([], emptyTrie); // TODO: ?? if (m.has(__)) return null; var acc = []; m.forEach(function (mk, key) { var piece; if (is_keyClose(key)) { piece = k([Immutable.List()], mk); } else { piece = walk(rseq(key, mk), function (v, vk) { return walkSeq(vk, function (vss, vsk) { var acc = []; for (var i = 0; i < vss.length; i++) { acc.push(vss[i].unshift(v)); } return k(acc, vsk); }); }); } if (piece === null) return null; acc = acc.concat(piece); }); return acc; } function transformSeqs(vs, opener) { if (opener === SOA) return vs; die("Internal error: unknown opener " + opener); } } function captureToObject(captures, compiledProjection) { var d = {}; captures.forEach(function (key, index) { d[compiledProjection.names[index] || ('$' + index)] = key; }); return d; } function trieKeysToObjects(trieKeysResult, compiledProjection) { if (trieKeysResult === null) return null; return trieKeysResult.toList().map(function (e) { return captureToObject(e, compiledProjection); }); } function projectObjects(m, compiledProjection) { return trieKeysToObjects(trieKeys(project(m, compiledProjection)), compiledProjection); } function prettyTrie(m, initialIndent) { var acc = []; walk(initialIndent || 0, m); return acc.join(''); function walk(i, m) { if (m instanceof $WildcardSequence) { acc.push("...>"); walk(i + 4, m.trie); return; } if (m instanceof $Success) { var v = m.value; if (Immutable.Set.isSet(v)) { v = v.toArray(); } acc.push("{" + JSON.stringify(v) + "}"); return; } if (m.size === 0) { acc.push("::: nothing"); return; } var needSep = false; m.toOrderedMap() .sortBy(function (k, key) { return key }) .forEach(function (k, key) { if (needSep) { acc.push("\n"); acc.push(indentStr(i)); } else { needSep = true; } acc.push(" "); if (key === __) key = '★'; else if (key === SOA) key = '<'; else if (key === EOA) key = '>'; else if (key instanceof $Special) key = key.name; else key = JSON.stringify(key); acc.push(key); walk(i + key.length + 1, k); }); } function indentStr(i) { return new Array(i + 1).join(' '); // eww } } /////////////////////////////////////////////////////////////////////////// module.exports.__ = __; module.exports.SOA = SOA; module.exports.EOA = EOA; module.exports.$Capture = $Capture; module.exports.$Special = $Special; module.exports.makeStructureConstructor = makeStructureConstructor; module.exports._$ = _$; module.exports.is_emptyTrie = is_emptyTrie; module.exports.emptyTrie = emptyTrie; module.exports.embeddedTrie = embeddedTrie; module.exports.compilePattern = compilePattern; module.exports.matchPattern = matchPattern; module.exports._union = union; module.exports.union = unionN; module.exports.intersect = intersect; module.exports.subtract = subtract; module.exports.matchValue = matchValue; module.exports.matchTrie = matchTrie; module.exports.appendTrie = appendTrie; module.exports.triePruneBranch = triePruneBranch; module.exports.trieStep = trieStep; module.exports.relabel = relabel; module.exports.compileProjection = compileProjection; module.exports.projectionToPattern = projectionToPattern; module.exports.project = project; module.exports.trieKeys = trieKeys; module.exports.captureToObject = captureToObject; module.exports.trieKeysToObjects = trieKeysToObjects; module.exports.projectObjects = projectObjects; module.exports.prettyTrie = prettyTrie; // For testing module.exports._testing = { rsuccess: rsuccess, rseq: rseq, rwild: rwild, rwildseq: rwildseq }; },{"immutable":220}],234:[function(require,module,exports){ var Immutable = require('immutable'); function Seal(contents) { this.sealContents = contents; Object.freeze(this); } Seal.prototype.equals = function (other) { if (!(other instanceof Seal)) return false; return Immutable.is(this.sealContents, other.sealContents); }; function seal(contents) { return new Seal(contents); } module.exports.Seal = Seal; module.exports.seal = seal; },{"immutable":220}],235:[function(require,module,exports){ "use strict"; var Reflect = require("./reflect.js"); module.exports.extend = function (what, _with) { for (var prop in _with) { if (_with.hasOwnProperty(prop)) { what[prop] = _with[prop]; } } return what; }; module.exports.kwApply = function (f, thisArg, args) { var formals = Reflect.formalParameters(f); var actuals = [] for (var i = 0; i < formals.length; i++) { var formal = formals[i]; if (!(formal in args)) { throw new Error("Function parameter '"+formal+"' not present in args"); } actuals.push(args[formal]); } return f.apply(thisArg, actuals); }; },{"./reflect.js":232}]},{},[227])(227) }); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlL2VtcHR5LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWIvYjY0LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2lzYXJyYXkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9hZXMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9hdXRoQ2lwaGVyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2RlY3J5cHRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2VuY3J5cHRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2doYXNoLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jYmMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jZmIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jZmIxLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2ZiOC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL2N0ci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL2VjYi5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL29mYi5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL25vZGVfbW9kdWxlcy9idWZmZXIteG9yL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbm9kZV9tb2R1bGVzL2NpcGhlci1iYXNlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvc3RyZWFtQ2lwaGVyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1kZXMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWRlcy9tb2Rlcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktZGVzL25vZGVfbW9kdWxlcy9jaXBoZXItYmFzZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktZGVzL25vZGVfbW9kdWxlcy9kZXMuanMvbGliL2Rlcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktZGVzL25vZGVfbW9kdWxlcy9kZXMuanMvbGliL2Rlcy9jYmMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWRlcy9ub2RlX21vZHVsZXMvZGVzLmpzL2xpYi9kZXMvY2lwaGVyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1kZXMvbm9kZV9tb2R1bGVzL2Rlcy5qcy9saWIvZGVzL2Rlcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktZGVzL25vZGVfbW9kdWxlcy9kZXMuanMvbGliL2Rlcy9lZGUuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWRlcy9ub2RlX21vZHVsZXMvZGVzLmpzL2xpYi9kZXMvdXRpbHMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWRlcy9ub2RlX21vZHVsZXMvZGVzLmpzL25vZGVfbW9kdWxlcy9taW5pbWFsaXN0aWMtYXNzZXJ0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvZXZwX2J5dGVzdG9rZXkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9hbGdvcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9jdXJ2ZXMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvYm4uanMvbGliL2JuLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktcnNhL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvY3VydmUvYmFzZS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvY3VydmUvZWR3YXJkcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvY3VydmUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2N1cnZlL21vbnQuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2N1cnZlL3Nob3J0LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9jdXJ2ZXMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2VjL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9lYy9rZXkuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2VjL3NpZ25hdHVyZS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvZWRkc2EvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2VkZHNhL2tleS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvZWRkc2Evc2lnbmF0dXJlLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9obWFjLWRyYmcuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL3ByZWNvbXB1dGVkL3NlY3AyNTZrMS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvdXRpbHMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbm9kZV9tb2R1bGVzL2Jyb3JhbmQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2guanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvY29tbW9uLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL2htYWMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvcmlwZW1kLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC91dGlscy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9wYWNrYWdlLmpzb24iLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9hZXNpZC5qc29uIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvYXNuMS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL2ZpeFByb2MuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvYXBpLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvYmFzZS9idWZmZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9iYXNlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvYmFzZS9ub2RlLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvYmFzZS9yZXBvcnRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2NvbnN0YW50cy9kZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9jb25zdGFudHMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9kZWNvZGVycy9kZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9kZWNvZGVycy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2RlY29kZXJzL3BlbS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2VuY29kZXJzL2Rlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2VuY29kZXJzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvZW5jb2RlcnMvcGVtLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2Flcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9hdXRoQ2lwaGVyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2RlY3J5cHRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9lbmNyeXB0ZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvZ2hhc2guanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2ZiLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL2NmYjEuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2ZiOC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jdHIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvb2ZiLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL25vZGVfbW9kdWxlcy9idWZmZXIteG9yL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL25vZGVfbW9kdWxlcy9jaXBoZXItYmFzZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9zdHJlYW1DaXBoZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvZXZwX2J5dGVzdG9rZXkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9zaWduLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vdmVyaWZ5LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtZWNkaC9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9oZWxwZXJzLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9tZDUuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL25vZGVfbW9kdWxlcy9jaXBoZXItYmFzZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3JlYXRlLWhhc2gvbm9kZV9tb2R1bGVzL3JpcGVtZDE2MC9saWIvcmlwZW1kMTYwLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9ub2RlX21vZHVsZXMvc2hhLmpzL2hhc2guanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL25vZGVfbW9kdWxlcy9zaGEuanMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL25vZGVfbW9kdWxlcy9zaGEuanMvc2hhLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9ub2RlX21vZHVsZXMvc2hhLmpzL3NoYTEuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL25vZGVfbW9kdWxlcy9zaGEuanMvc2hhMjI0LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9ub2RlX21vZHVsZXMvc2hhLmpzL3NoYTI1Ni5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3JlYXRlLWhhc2gvbm9kZV9tb2R1bGVzL3NoYS5qcy9zaGEzODQuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL25vZGVfbW9kdWxlcy9zaGEuanMvc2hhNTEyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaG1hYy9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9kaWZmaWUtaGVsbG1hbi9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9kaWZmaWUtaGVsbG1hbi9saWIvZGguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2RpZmZpZS1oZWxsbWFuL2xpYi9nZW5lcmF0ZVByaW1lLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9kaWZmaWUtaGVsbG1hbi9saWIvcHJpbWVzLmpzb24iLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2RpZmZpZS1oZWxsbWFuL25vZGVfbW9kdWxlcy9taWxsZXItcmFiaW4vbGliL21yLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wYmtkZjIvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbWdmLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1yc2EvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL2ZpeFByb2MuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvYWVzLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvYXV0aENpcGhlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2RlY3J5cHRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2VuY3J5cHRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2doYXNoLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2ZiLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2ZiMS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL2NmYjguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jdHIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9vZmIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9ub2RlX21vZHVsZXMvYnVmZmVyLXhvci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL25vZGVfbW9kdWxlcy9jaXBoZXItYmFzZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL3N0cmVhbUNpcGhlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2V2cF9ieXRlc3Rva2V5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9wcml2YXRlRGVjcnlwdC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvcHVibGljRW5jcnlwdC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvd2l0aFB1YmxpYy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQveG9yLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yYW5kb21ieXRlcy9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2V2ZW50cy9ldmVudHMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9pbnNlcnQtbW9kdWxlLWdsb2JhbHMvbm9kZV9tb2R1bGVzL2lzLWJ1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9pc2FycmF5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vZHVwbGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9kdXBsZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3Bhc3N0aHJvdWdoLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9yZWFkYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV93cml0YWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbm9kZV9tb2R1bGVzL2NvcmUtdXRpbC1pcy9saWIvdXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbm9kZV9tb2R1bGVzL3Byb2Nlc3MtbmV4dGljay1hcmdzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9ub2RlX21vZHVsZXMvdXRpbC1kZXByZWNhdGUvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vcGFzc3Rocm91Z2guanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS90cmFuc2Zvcm0uanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3dyaXRhYmxlLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3ZtLWJyb3dzZXJpZnkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvdm0tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvaW5kZXhvZi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9pbW11dGFibGUvZGlzdC9pbW11dGFibGUuanMiLCJzcmMvYWNrLmpzIiwic3JjL2FjdG9yLmpzIiwic3JjL2RlbWFuZC1tYXRjaGVyLmpzIiwic3JjL2RvbS1kcml2ZXIuanMiLCJzcmMvZ3JvdW5kLmpzIiwic3JjL2pxdWVyeS1kcml2ZXIuanMiLCJzcmMvbWFpbi5qcyIsInNyYy9tdXguanMiLCJzcmMvbmV0d29yay5qcyIsInNyYy9wYXRjaC5qcyIsInNyYy9yYW5kb21pZC5qcyIsInNyYy9yZWZsZWN0LmpzIiwic3JjL3JvdXRlLmpzIiwic3JjL3NlYWwuanMiLCJzcmMvdXRpbC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBOzs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM5NkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN6RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDakxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNqR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDeklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMxSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzFGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMxRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0lBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaFFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN4RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3ZHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNyMEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9WQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMVpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzc0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOU5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzV3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNySEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3JHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsbUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMVNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNqTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ2pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDeklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMxSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7QUNsR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzFGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDcEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN6TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN2R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDMUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDcERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDM0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzFGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNsTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNyRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDcEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUM3SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDMVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNwRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3BLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2pIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNoRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7O0FDeENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDckdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2pMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDakdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN6SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzFIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7OztBQ2xHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDMUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNwRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzNHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzlGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzRkE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDLzhCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDck1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2poQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzNHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNuRUE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBOztBQ0RBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyM0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0lBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIiLCIvKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1wcm90byAqL1xuXG4ndXNlIHN0cmljdCdcblxudmFyIGJhc2U2NCA9IHJlcXVpcmUoJ2Jhc2U2NC1qcycpXG52YXIgaWVlZTc1NCA9IHJlcXVpcmUoJ2llZWU3NTQnKVxudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpc2FycmF5JylcblxuZXhwb3J0cy5CdWZmZXIgPSBCdWZmZXJcbmV4cG9ydHMuU2xvd0J1ZmZlciA9IFNsb3dCdWZmZXJcbmV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMgPSA1MFxuQnVmZmVyLnBvb2xTaXplID0gODE5MiAvLyBub3QgdXNlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uXG5cbnZhciByb290UGFyZW50ID0ge31cblxuLyoqXG4gKiBJZiBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgOlxuICogICA9PT0gdHJ1ZSAgICBVc2UgVWludDhBcnJheSBpbXBsZW1lbnRhdGlvbiAoZmFzdGVzdClcbiAqICAgPT09IGZhbHNlICAgVXNlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiAobW9zdCBjb21wYXRpYmxlLCBldmVuIElFNilcbiAqXG4gKiBCcm93c2VycyB0aGF0IHN1cHBvcnQgdHlwZWQgYXJyYXlzIGFyZSBJRSAxMCssIEZpcmVmb3ggNCssIENocm9tZSA3KywgU2FmYXJpIDUuMSssXG4gKiBPcGVyYSAxMS42KywgaU9TIDQuMisuXG4gKlxuICogRHVlIHRvIHZhcmlvdXMgYnJvd3NlciBidWdzLCBzb21ldGltZXMgdGhlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiB3aWxsIGJlIHVzZWQgZXZlblxuICogd2hlbiB0aGUgYnJvd3NlciBzdXBwb3J0cyB0eXBlZCBhcnJheXMuXG4gKlxuICogTm90ZTpcbiAqXG4gKiAgIC0gRmlyZWZveCA0LTI5IGxhY2tzIHN1cHBvcnQgZm9yIGFkZGluZyBuZXcgcHJvcGVydGllcyB0byBgVWludDhBcnJheWAgaW5zdGFuY2VzLFxuICogICAgIFNlZTogaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9Njk1NDM4LlxuICpcbiAqICAgLSBDaHJvbWUgOS0xMCBpcyBtaXNzaW5nIHRoZSBgVHlwZWRBcnJheS5wcm90b3R5cGUuc3ViYXJyYXlgIGZ1bmN0aW9uLlxuICpcbiAqICAgLSBJRTEwIGhhcyBhIGJyb2tlbiBgVHlwZWRBcnJheS5wcm90b3R5cGUuc3ViYXJyYXlgIGZ1bmN0aW9uIHdoaWNoIHJldHVybnMgYXJyYXlzIG9mXG4gKiAgICAgaW5jb3JyZWN0IGxlbmd0aCBpbiBzb21lIHNpdHVhdGlvbnMuXG5cbiAqIFdlIGRldGVjdCB0aGVzZSBidWdneSBicm93c2VycyBhbmQgc2V0IGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGAgdG8gYGZhbHNlYCBzbyB0aGV5XG4gKiBnZXQgdGhlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiwgd2hpY2ggaXMgc2xvd2VyIGJ1dCBiZWhhdmVzIGNvcnJlY3RseS5cbiAqL1xuQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgPSBnbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVCAhPT0gdW5kZWZpbmVkXG4gID8gZ2xvYmFsLlRZUEVEX0FSUkFZX1NVUFBPUlRcbiAgOiB0eXBlZEFycmF5U3VwcG9ydCgpXG5cbmZ1bmN0aW9uIHR5cGVkQXJyYXlTdXBwb3J0ICgpIHtcbiAgdHJ5IHtcbiAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoMSlcbiAgICBhcnIuZm9vID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gNDIgfVxuICAgIHJldHVybiBhcnIuZm9vKCkgPT09IDQyICYmIC8vIHR5cGVkIGFycmF5IGluc3RhbmNlcyBjYW4gYmUgYXVnbWVudGVkXG4gICAgICAgIHR5cGVvZiBhcnIuc3ViYXJyYXkgPT09ICdmdW5jdGlvbicgJiYgLy8gY2hyb21lIDktMTAgbGFjayBgc3ViYXJyYXlgXG4gICAgICAgIGFyci5zdWJhcnJheSgxLCAxKS5ieXRlTGVuZ3RoID09PSAwIC8vIGllMTAgaGFzIGJyb2tlbiBgc3ViYXJyYXlgXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5mdW5jdGlvbiBrTWF4TGVuZ3RoICgpIHtcbiAgcmV0dXJuIEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUXG4gICAgPyAweDdmZmZmZmZmXG4gICAgOiAweDNmZmZmZmZmXG59XG5cbi8qKlxuICogVGhlIEJ1ZmZlciBjb25zdHJ1Y3RvciByZXR1cm5zIGluc3RhbmNlcyBvZiBgVWludDhBcnJheWAgdGhhdCBoYXZlIHRoZWlyXG4gKiBwcm90b3R5cGUgY2hhbmdlZCB0byBgQnVmZmVyLnByb3RvdHlwZWAuIEZ1cnRoZXJtb3JlLCBgQnVmZmVyYCBpcyBhIHN1YmNsYXNzIG9mXG4gKiBgVWludDhBcnJheWAsIHNvIHRoZSByZXR1cm5lZCBpbnN0YW5jZXMgd2lsbCBoYXZlIGFsbCB0aGUgbm9kZSBgQnVmZmVyYCBtZXRob2RzXG4gKiBhbmQgdGhlIGBVaW50OEFycmF5YCBtZXRob2RzLiBTcXVhcmUgYnJhY2tldCBub3RhdGlvbiB3b3JrcyBhcyBleHBlY3RlZCAtLSBpdFxuICogcmV0dXJucyBhIHNpbmdsZSBvY3RldC5cbiAqXG4gKiBUaGUgYFVpbnQ4QXJyYXlgIHByb3RvdHlwZSByZW1haW5zIHVubW9kaWZpZWQuXG4gKi9cbmZ1bmN0aW9uIEJ1ZmZlciAoYXJnKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBCdWZmZXIpKSB7XG4gICAgLy8gQXZvaWQgZ29pbmcgdGhyb3VnaCBhbiBBcmd1bWVudHNBZGFwdG9yVHJhbXBvbGluZSBpbiB0aGUgY29tbW9uIGNhc2UuXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSByZXR1cm4gbmV3IEJ1ZmZlcihhcmcsIGFyZ3VtZW50c1sxXSlcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcihhcmcpXG4gIH1cblxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpcy5sZW5ndGggPSAwXG4gICAgdGhpcy5wYXJlbnQgPSB1bmRlZmluZWRcbiAgfVxuXG4gIC8vIENvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gZnJvbU51bWJlcih0aGlzLCBhcmcpXG4gIH1cblxuICAvLyBTbGlnaHRseSBsZXNzIGNvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh0aGlzLCBhcmcsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogJ3V0ZjgnKVxuICB9XG5cbiAgLy8gVW51c3VhbC5cbiAgcmV0dXJuIGZyb21PYmplY3QodGhpcywgYXJnKVxufVxuXG4vLyBUT0RPOiBMZWdhY3ksIG5vdCBuZWVkZWQgYW55bW9yZS4gUmVtb3ZlIGluIG5leHQgbWFqb3IgdmVyc2lvbi5cbkJ1ZmZlci5fYXVnbWVudCA9IGZ1bmN0aW9uIChhcnIpIHtcbiAgYXJyLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgcmV0dXJuIGFyclxufVxuXG5mdW5jdGlvbiBmcm9tTnVtYmVyICh0aGF0LCBsZW5ndGgpIHtcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aCA8IDAgPyAwIDogY2hlY2tlZChsZW5ndGgpIHwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoYXRbaV0gPSAwXG4gICAgfVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHRoYXQsIHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIC8vIEFzc3VtcHRpb246IGJ5dGVMZW5ndGgoKSByZXR1cm4gdmFsdWUgaXMgYWx3YXlzIDwga01heExlbmd0aC5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG5cbiAgdGhhdC53cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0ICh0aGF0LCBvYmplY3QpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihvYmplY3QpKSByZXR1cm4gZnJvbUJ1ZmZlcih0aGF0LCBvYmplY3QpXG5cbiAgaWYgKGlzQXJyYXkob2JqZWN0KSkgcmV0dXJuIGZyb21BcnJheSh0aGF0LCBvYmplY3QpXG5cbiAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbXVzdCBzdGFydCB3aXRoIG51bWJlciwgYnVmZmVyLCBhcnJheSBvciBzdHJpbmcnKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAob2JqZWN0LmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICByZXR1cm4gZnJvbVR5cGVkQXJyYXkodGhhdCwgb2JqZWN0KVxuICAgIH1cbiAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgIHJldHVybiBmcm9tQXJyYXlCdWZmZXIodGhhdCwgb2JqZWN0KVxuICAgIH1cbiAgfVxuXG4gIGlmIChvYmplY3QubGVuZ3RoKSByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmplY3QpXG5cbiAgcmV0dXJuIGZyb21Kc29uT2JqZWN0KHRoYXQsIG9iamVjdClcbn1cblxuZnVuY3Rpb24gZnJvbUJ1ZmZlciAodGhhdCwgYnVmZmVyKSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGJ1ZmZlci5sZW5ndGgpIHwgMFxuICB0aGF0ID0gYWxsb2NhdGUodGhhdCwgbGVuZ3RoKVxuICBidWZmZXIuY29weSh0aGF0LCAwLCAwLCBsZW5ndGgpXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8vIER1cGxpY2F0ZSBvZiBmcm9tQXJyYXkoKSB0byBrZWVwIGZyb21BcnJheSgpIG1vbm9tb3JwaGljLlxuZnVuY3Rpb24gZnJvbVR5cGVkQXJyYXkgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIC8vIFRydW5jYXRpbmcgdGhlIGVsZW1lbnRzIGlzIHByb2JhYmx5IG5vdCB3aGF0IHBlb3BsZSBleHBlY3QgZnJvbSB0eXBlZFxuICAvLyBhcnJheXMgd2l0aCBCWVRFU19QRVJfRUxFTUVOVCA+IDEgYnV0IGl0J3MgY29tcGF0aWJsZSB3aXRoIHRoZSBiZWhhdmlvclxuICAvLyBvZiB0aGUgb2xkIEJ1ZmZlciBjb25zdHJ1Y3Rvci5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAodGhhdCwgYXJyYXkpIHtcbiAgYXJyYXkuYnl0ZUxlbmd0aCAvLyB0aGlzIHRocm93cyBpZiBgYXJyYXlgIGlzIG5vdCBhIHZhbGlkIEFycmF5QnVmZmVyXG5cbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgdGhhdCA9IG5ldyBVaW50OEFycmF5KGFycmF5KVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0ID0gZnJvbVR5cGVkQXJyYXkodGhhdCwgbmV3IFVpbnQ4QXJyYXkoYXJyYXkpKVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGF0W2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG4vLyBEZXNlcmlhbGl6ZSB7IHR5cGU6ICdCdWZmZXInLCBkYXRhOiBbMSwyLDMsLi4uXSB9IGludG8gYSBCdWZmZXIgb2JqZWN0LlxuLy8gUmV0dXJucyBhIHplcm8tbGVuZ3RoIGJ1ZmZlciBmb3IgaW5wdXRzIHRoYXQgZG9uJ3QgY29uZm9ybSB0byB0aGUgc3BlYy5cbmZ1bmN0aW9uIGZyb21Kc29uT2JqZWN0ICh0aGF0LCBvYmplY3QpIHtcbiAgdmFyIGFycmF5XG4gIHZhciBsZW5ndGggPSAwXG5cbiAgaWYgKG9iamVjdC50eXBlID09PSAnQnVmZmVyJyAmJiBpc0FycmF5KG9iamVjdC5kYXRhKSkge1xuICAgIGFycmF5ID0gb2JqZWN0LmRhdGFcbiAgICBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIH1cbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gIEJ1ZmZlci5wcm90b3R5cGUuX19wcm90b19fID0gVWludDhBcnJheS5wcm90b3R5cGVcbiAgQnVmZmVyLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXlcbn0gZWxzZSB7XG4gIC8vIHByZS1zZXQgZm9yIHZhbHVlcyB0aGF0IG1heSBleGlzdCBpbiB0aGUgZnV0dXJlXG4gIEJ1ZmZlci5wcm90b3R5cGUubGVuZ3RoID0gdW5kZWZpbmVkXG4gIEJ1ZmZlci5wcm90b3R5cGUucGFyZW50ID0gdW5kZWZpbmVkXG59XG5cbmZ1bmN0aW9uIGFsbG9jYXRlICh0aGF0LCBsZW5ndGgpIHtcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgdGhhdCA9IG5ldyBVaW50OEFycmF5KGxlbmd0aClcbiAgICB0aGF0Ll9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIGFuIG9iamVjdCBpbnN0YW5jZSBvZiB0aGUgQnVmZmVyIGNsYXNzXG4gICAgdGhhdC5sZW5ndGggPSBsZW5ndGhcbiAgfVxuXG4gIHZhciBmcm9tUG9vbCA9IGxlbmd0aCAhPT0gMCAmJiBsZW5ndGggPD0gQnVmZmVyLnBvb2xTaXplID4+PiAxXG4gIGlmIChmcm9tUG9vbCkgdGhhdC5wYXJlbnQgPSByb290UGFyZW50XG5cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gY2hlY2tlZCAobGVuZ3RoKSB7XG4gIC8vIE5vdGU6IGNhbm5vdCB1c2UgYGxlbmd0aCA8IGtNYXhMZW5ndGhgIGhlcmUgYmVjYXVzZSB0aGF0IGZhaWxzIHdoZW5cbiAgLy8gbGVuZ3RoIGlzIE5hTiAod2hpY2ggaXMgb3RoZXJ3aXNlIGNvZXJjZWQgdG8gemVyby4pXG4gIGlmIChsZW5ndGggPj0ga01heExlbmd0aCgpKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gYWxsb2NhdGUgQnVmZmVyIGxhcmdlciB0aGFuIG1heGltdW0gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgJ3NpemU6IDB4JyArIGtNYXhMZW5ndGgoKS50b1N0cmluZygxNikgKyAnIGJ5dGVzJylcbiAgfVxuICByZXR1cm4gbGVuZ3RoIHwgMFxufVxuXG5mdW5jdGlvbiBTbG93QnVmZmVyIChzdWJqZWN0LCBlbmNvZGluZykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU2xvd0J1ZmZlcikpIHJldHVybiBuZXcgU2xvd0J1ZmZlcihzdWJqZWN0LCBlbmNvZGluZylcblxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcihzdWJqZWN0LCBlbmNvZGluZylcbiAgZGVsZXRlIGJ1Zi5wYXJlbnRcbiAgcmV0dXJuIGJ1ZlxufVxuXG5CdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiBpc0J1ZmZlciAoYikge1xuICByZXR1cm4gISEoYiAhPSBudWxsICYmIGIuX2lzQnVmZmVyKVxufVxuXG5CdWZmZXIuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGEsIGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYSkgfHwgIUJ1ZmZlci5pc0J1ZmZlcihiKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50cyBtdXN0IGJlIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGEgPT09IGIpIHJldHVybiAwXG5cbiAgdmFyIHggPSBhLmxlbmd0aFxuICB2YXIgeSA9IGIubGVuZ3RoXG5cbiAgdmFyIGkgPSAwXG4gIHZhciBsZW4gPSBNYXRoLm1pbih4LCB5KVxuICB3aGlsZSAoaSA8IGxlbikge1xuICAgIGlmIChhW2ldICE9PSBiW2ldKSBicmVha1xuXG4gICAgKytpXG4gIH1cblxuICBpZiAoaSAhPT0gbGVuKSB7XG4gICAgeCA9IGFbaV1cbiAgICB5ID0gYltpXVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG5CdWZmZXIuaXNFbmNvZGluZyA9IGZ1bmN0aW9uIGlzRW5jb2RpbmcgKGVuY29kaW5nKSB7XG4gIHN3aXRjaCAoU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICdyYXcnOlxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5CdWZmZXIuY29uY2F0ID0gZnVuY3Rpb24gY29uY2F0IChsaXN0LCBsZW5ndGgpIHtcbiAgaWYgKCFpc0FycmF5KGxpc3QpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdsaXN0IGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycy4nKVxuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKDApXG4gIH1cblxuICB2YXIgaVxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBsZW5ndGggPSAwXG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxlbmd0aCArPSBsaXN0W2ldLmxlbmd0aFxuICAgIH1cbiAgfVxuXG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKGxlbmd0aClcbiAgdmFyIHBvcyA9IDBcbiAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaXRlbSA9IGxpc3RbaV1cbiAgICBpdGVtLmNvcHkoYnVmLCBwb3MpXG4gICAgcG9zICs9IGl0ZW0ubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZlxufVxuXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2Ygc3RyaW5nICE9PSAnc3RyaW5nJykgc3RyaW5nID0gJycgKyBzdHJpbmdcblxuICB2YXIgbGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAobGVuID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIFVzZSBhIGZvciBsb29wIHRvIGF2b2lkIHJlY3Vyc2lvblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgIC8vIERlcHJlY2F0ZWRcbiAgICAgIGNhc2UgJ3Jhdyc6XG4gICAgICBjYXNlICdyYXdzJzpcbiAgICAgICAgcmV0dXJuIGxlblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIGxlbiAqIDJcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBsZW4gPj4+IDFcbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aCAvLyBhc3N1bWUgdXRmOFxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuQnVmZmVyLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5cbmZ1bmN0aW9uIHNsb3dUb1N0cmluZyAoZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcblxuICBzdGFydCA9IHN0YXJ0IHwgMFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPT09IEluZmluaXR5ID8gdGhpcy5sZW5ndGggOiBlbmQgfCAwXG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcbiAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKGVuZCA8PSBzdGFydCkgcmV0dXJuICcnXG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gYmluYXJ5U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1dGYxNmxlU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbi8vIFRoZSBwcm9wZXJ0eSBpcyB1c2VkIGJ5IGBCdWZmZXIuaXNCdWZmZXJgIGFuZCBgaXMtYnVmZmVyYCAoaW4gU2FmYXJpIDUtNykgdG8gZGV0ZWN0XG4vLyBCdWZmZXIgaW5zdGFuY2VzLlxuQnVmZmVyLnByb3RvdHlwZS5faXNCdWZmZXIgPSB0cnVlXG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCB8IDBcbiAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHNsb3dUb1N0cmluZy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiB0cnVlXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKSA9PT0gMFxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgdmFyIHN0ciA9ICcnXG4gIHZhciBtYXggPSBleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTXG4gIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICBzdHIgPSB0aGlzLnRvU3RyaW5nKCdoZXgnLCAwLCBtYXgpLm1hdGNoKC8uezJ9L2cpLmpvaW4oJyAnKVxuICAgIGlmICh0aGlzLmxlbmd0aCA+IG1heCkgc3RyICs9ICcgLi4uICdcbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIHN0ciArICc+J1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiAwXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbiBpbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQpIHtcbiAgaWYgKGJ5dGVPZmZzZXQgPiAweDdmZmZmZmZmKSBieXRlT2Zmc2V0ID0gMHg3ZmZmZmZmZlxuICBlbHNlIGlmIChieXRlT2Zmc2V0IDwgLTB4ODAwMDAwMDApIGJ5dGVPZmZzZXQgPSAtMHg4MDAwMDAwMFxuICBieXRlT2Zmc2V0ID4+PSAwXG5cbiAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gLTFcbiAgaWYgKGJ5dGVPZmZzZXQgPj0gdGhpcy5sZW5ndGgpIHJldHVybiAtMVxuXG4gIC8vIE5lZ2F0aXZlIG9mZnNldHMgc3RhcnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwKSBieXRlT2Zmc2V0ID0gTWF0aC5tYXgodGhpcy5sZW5ndGggKyBieXRlT2Zmc2V0LCAwKVxuXG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIGlmICh2YWwubGVuZ3RoID09PSAwKSByZXR1cm4gLTEgLy8gc3BlY2lhbCBjYXNlOiBsb29raW5nIGZvciBlbXB0eSBzdHJpbmcgYWx3YXlzIGZhaWxzXG4gICAgcmV0dXJuIFN0cmluZy5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgfVxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbCkpIHtcbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgfVxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbCh0aGlzLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YodGhpcywgWyB2YWwgXSwgYnl0ZU9mZnNldClcbiAgfVxuXG4gIGZ1bmN0aW9uIGFycmF5SW5kZXhPZiAoYXJyLCB2YWwsIGJ5dGVPZmZzZXQpIHtcbiAgICB2YXIgZm91bmRJbmRleCA9IC0xXG4gICAgZm9yICh2YXIgaSA9IDA7IGJ5dGVPZmZzZXQgKyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYXJyW2J5dGVPZmZzZXQgKyBpXSA9PT0gdmFsW2ZvdW5kSW5kZXggPT09IC0xID8gMCA6IGkgLSBmb3VuZEluZGV4XSkge1xuICAgICAgICBpZiAoZm91bmRJbmRleCA9PT0gLTEpIGZvdW5kSW5kZXggPSBpXG4gICAgICAgIGlmIChpIC0gZm91bmRJbmRleCArIDEgPT09IHZhbC5sZW5ndGgpIHJldHVybiBieXRlT2Zmc2V0ICsgZm91bmRJbmRleFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm91bmRJbmRleCA9IC0xXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAtMVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyJylcbn1cblxuZnVuY3Rpb24gaGV4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG4gIHZhciByZW1haW5pbmcgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cblxuICAvLyBtdXN0IGJlIGFuIGV2ZW4gbnVtYmVyIG9mIGRpZ2l0c1xuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAoc3RyTGVuICUgMiAhPT0gMCkgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKVxuXG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMlxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGFyc2VkID0gcGFyc2VJbnQoc3RyaW5nLnN1YnN0cihpICogMiwgMiksIDE2KVxuICAgIGlmIChpc05hTihwYXJzZWQpKSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaGV4IHN0cmluZycpXG4gICAgYnVmW29mZnNldCArIGldID0gcGFyc2VkXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYXNjaWlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBiaW5hcnlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBhc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmFzZTY0V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIHVjczJXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiB3cml0ZSAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZylcbiAgaWYgKG9mZnNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBvZmZzZXRbLCBsZW5ndGhdWywgZW5jb2RpbmddKVxuICB9IGVsc2UgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gICAgaWYgKGlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGxlbmd0aCA9IGxlbmd0aCB8IDBcbiAgICAgIGlmIChlbmNvZGluZyA9PT0gdW5kZWZpbmVkKSBlbmNvZGluZyA9ICd1dGY4J1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICAvLyBsZWdhY3kgd3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0LCBsZW5ndGgpIC0gcmVtb3ZlIGluIHYwLjEzXG4gIH0gZWxzZSB7XG4gICAgdmFyIHN3YXAgPSBlbmNvZGluZ1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgb2Zmc2V0ID0gbGVuZ3RoIHwgMFxuICAgIGxlbmd0aCA9IHN3YXBcbiAgfVxuXG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldFxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgfHwgbGVuZ3RoID4gcmVtYWluaW5nKSBsZW5ndGggPSByZW1haW5pbmdcblxuICBpZiAoKHN0cmluZy5sZW5ndGggPiAwICYmIChsZW5ndGggPCAwIHx8IG9mZnNldCA8IDApKSB8fCBvZmZzZXQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdhdHRlbXB0IHRvIHdyaXRlIG91dHNpZGUgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gYmluYXJ5V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgLy8gV2FybmluZzogbWF4TGVuZ3RoIG5vdCB0YWtlbiBpbnRvIGFjY291bnQgaW4gYmFzZTY0V3JpdGVcbiAgICAgICAgcmV0dXJuIGJhc2U2NFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1Y3MyV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnQnVmZmVyJyxcbiAgICBkYXRhOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnIgfHwgdGhpcywgMClcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXNlNjRTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGlmIChzdGFydCA9PT0gMCAmJiBlbmQgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYuc2xpY2Uoc3RhcnQsIGVuZCkpXG4gIH1cbn1cblxuZnVuY3Rpb24gdXRmOFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuICB2YXIgcmVzID0gW11cblxuICB2YXIgaSA9IHN0YXJ0XG4gIHdoaWxlIChpIDwgZW5kKSB7XG4gICAgdmFyIGZpcnN0Qnl0ZSA9IGJ1ZltpXVxuICAgIHZhciBjb2RlUG9pbnQgPSBudWxsXG4gICAgdmFyIGJ5dGVzUGVyU2VxdWVuY2UgPSAoZmlyc3RCeXRlID4gMHhFRikgPyA0XG4gICAgICA6IChmaXJzdEJ5dGUgPiAweERGKSA/IDNcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4QkYpID8gMlxuICAgICAgOiAxXG5cbiAgICBpZiAoaSArIGJ5dGVzUGVyU2VxdWVuY2UgPD0gZW5kKSB7XG4gICAgICB2YXIgc2Vjb25kQnl0ZSwgdGhpcmRCeXRlLCBmb3VydGhCeXRlLCB0ZW1wQ29kZVBvaW50XG5cbiAgICAgIHN3aXRjaCAoYnl0ZXNQZXJTZXF1ZW5jZSkge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgaWYgKGZpcnN0Qnl0ZSA8IDB4ODApIHtcbiAgICAgICAgICAgIGNvZGVQb2ludCA9IGZpcnN0Qnl0ZVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweDFGKSA8PCAweDYgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0YpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHhDIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAodGhpcmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3RkYgJiYgKHRlbXBDb2RlUG9pbnQgPCAweEQ4MDAgfHwgdGVtcENvZGVQb2ludCA+IDB4REZGRikpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgZm91cnRoQnl0ZSA9IGJ1ZltpICsgM11cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKGZvdXJ0aEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4MTIgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4QyB8ICh0aGlyZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAoZm91cnRoQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4RkZGRiAmJiB0ZW1wQ29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29kZVBvaW50ID09PSBudWxsKSB7XG4gICAgICAvLyB3ZSBkaWQgbm90IGdlbmVyYXRlIGEgdmFsaWQgY29kZVBvaW50IHNvIGluc2VydCBhXG4gICAgICAvLyByZXBsYWNlbWVudCBjaGFyIChVK0ZGRkQpIGFuZCBhZHZhbmNlIG9ubHkgMSBieXRlXG4gICAgICBjb2RlUG9pbnQgPSAweEZGRkRcbiAgICAgIGJ5dGVzUGVyU2VxdWVuY2UgPSAxXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPiAweEZGRkYpIHtcbiAgICAgIC8vIGVuY29kZSB0byB1dGYxNiAoc3Vycm9nYXRlIHBhaXIgZGFuY2UpXG4gICAgICBjb2RlUG9pbnQgLT0gMHgxMDAwMFxuICAgICAgcmVzLnB1c2goY29kZVBvaW50ID4+PiAxMCAmIDB4M0ZGIHwgMHhEODAwKVxuICAgICAgY29kZVBvaW50ID0gMHhEQzAwIHwgY29kZVBvaW50ICYgMHgzRkZcbiAgICB9XG5cbiAgICByZXMucHVzaChjb2RlUG9pbnQpXG4gICAgaSArPSBieXRlc1BlclNlcXVlbmNlXG4gIH1cblxuICByZXR1cm4gZGVjb2RlQ29kZVBvaW50c0FycmF5KHJlcylcbn1cblxuLy8gQmFzZWQgb24gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjI3NDcyNzIvNjgwNzQyLCB0aGUgYnJvd3NlciB3aXRoXG4vLyB0aGUgbG93ZXN0IGxpbWl0IGlzIENocm9tZSwgd2l0aCAweDEwMDAwIGFyZ3MuXG4vLyBXZSBnbyAxIG1hZ25pdHVkZSBsZXNzLCBmb3Igc2FmZXR5XG52YXIgTUFYX0FSR1VNRU5UU19MRU5HVEggPSAweDEwMDBcblxuZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50c0FycmF5IChjb2RlUG9pbnRzKSB7XG4gIHZhciBsZW4gPSBjb2RlUG9pbnRzLmxlbmd0aFxuICBpZiAobGVuIDw9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjb2RlUG9pbnRzKSAvLyBhdm9pZCBleHRyYSBzbGljZSgpXG4gIH1cblxuICAvLyBEZWNvZGUgaW4gY2h1bmtzIHRvIGF2b2lkIFwiY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkXCIuXG4gIHZhciByZXMgPSAnJ1xuICB2YXIgaSA9IDBcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShcbiAgICAgIFN0cmluZyxcbiAgICAgIGNvZGVQb2ludHMuc2xpY2UoaSwgaSArPSBNQVhfQVJHVU1FTlRTX0xFTkdUSClcbiAgICApXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSAmIDB4N0YpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBiaW5hcnlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBoZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgYnl0ZXNbaSArIDFdICogMjU2KVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IH5+c3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB+fmVuZFxuXG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCArPSBsZW5cbiAgICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgfSBlbHNlIGlmIChzdGFydCA+IGxlbikge1xuICAgIHN0YXJ0ID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5cbiAgICBpZiAoZW5kIDwgMCkgZW5kID0gMFxuICB9IGVsc2UgaWYgKGVuZCA+IGxlbikge1xuICAgIGVuZCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIHZhciBuZXdCdWZcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgbmV3QnVmID0gdGhpcy5zdWJhcnJheShzdGFydCwgZW5kKVxuICAgIG5ld0J1Zi5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgdmFyIHNsaWNlTGVuID0gZW5kIC0gc3RhcnRcbiAgICBuZXdCdWYgPSBuZXcgQnVmZmVyKHNsaWNlTGVuLCB1bmRlZmluZWQpXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGljZUxlbjsgaSsrKSB7XG4gICAgICBuZXdCdWZbaV0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH1cblxuICBpZiAobmV3QnVmLmxlbmd0aCkgbmV3QnVmLnBhcmVudCA9IHRoaXMucGFyZW50IHx8IHRoaXNcblxuICByZXR1cm4gbmV3QnVmXG59XG5cbi8qXG4gKiBOZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGJ1ZmZlciBpc24ndCB0cnlpbmcgdG8gd3JpdGUgb3V0IG9mIGJvdW5kcy5cbiAqL1xuZnVuY3Rpb24gY2hlY2tPZmZzZXQgKG9mZnNldCwgZXh0LCBsZW5ndGgpIHtcbiAgaWYgKChvZmZzZXQgJSAxKSAhPT0gMCB8fCBvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb2Zmc2V0IGlzIG5vdCB1aW50JylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RyeWluZyB0byBhY2Nlc3MgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEUgPSBmdW5jdGlvbiByZWFkVUludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50QkUgPSBmdW5jdGlvbiByZWFkVUludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuICB9XG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXVxuICB2YXIgbXVsID0gMVxuICB3aGlsZSAoYnl0ZUxlbmd0aCA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gcmVhZFVJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2TEUgPSBmdW5jdGlvbiByZWFkVUludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDgpIHwgdGhpc1tvZmZzZXQgKyAxXVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAoKHRoaXNbb2Zmc2V0XSkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpKSArXG4gICAgICAodGhpc1tvZmZzZXQgKyAzXSAqIDB4MTAwMDAwMClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiByZWFkVUludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSAqIDB4MTAwMDAwMCkgK1xuICAgICgodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICB0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRMRSA9IGZ1bmN0aW9uIHJlYWRJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRCRSA9IGZ1bmN0aW9uIHJlYWRJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aFxuICB2YXIgbXVsID0gMVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWldXG4gIHdoaWxlIChpID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0taV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24gcmVhZEludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgaWYgKCEodGhpc1tvZmZzZXRdICYgMHg4MCkpIHJldHVybiAodGhpc1tvZmZzZXRdKVxuICByZXR1cm4gKCgweGZmIC0gdGhpc1tvZmZzZXRdICsgMSkgKiAtMSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkUgPSBmdW5jdGlvbiByZWFkSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAxXSB8ICh0aGlzW29mZnNldF0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24gcmVhZEludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDNdIDw8IDI0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gcmVhZEludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCAyNCkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFID0gZnVuY3Rpb24gcmVhZEZsb2F0TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFID0gZnVuY3Rpb24gcmVhZEZsb2F0QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiByZWFkRG91YmxlTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDUyLCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDUyLCA4KVxufVxuXG5mdW5jdGlvbiBjaGVja0ludCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2J1ZmZlciBtdXN0IGJlIGEgQnVmZmVyIGluc3RhbmNlJylcbiAgaWYgKHZhbHVlID4gbWF4IHx8IHZhbHVlIDwgbWluKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndmFsdWUgaXMgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignaW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlVUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCksIDApXG5cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlVUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCksIDApXG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVVSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweGZmLCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDE2IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZiArIHZhbHVlICsgMVxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGJ1Zi5sZW5ndGggLSBvZmZzZXQsIDIpOyBpIDwgajsgaSsrKSB7XG4gICAgYnVmW29mZnNldCArIGldID0gKHZhbHVlICYgKDB4ZmYgPDwgKDggKiAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSkpKSA+Pj5cbiAgICAgIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpICogOFxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDMyIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCA0KTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSA+Pj4gKGxpdHRsZUVuZGlhbiA/IGkgOiAzIC0gaSkgKiA4KSAmIDB4ZmZcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSAwXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSB2YWx1ZSA8IDAgPyAxIDogMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50QkUgPSBmdW5jdGlvbiB3cml0ZUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IHZhbHVlIDwgMCA/IDEgOiAwXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbiB3cml0ZUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHg3ZiwgLTB4ODApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmICsgdmFsdWUgKyAxXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbmZ1bmN0aW9uIGNoZWNrSUVFRTc1NCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignaW5kZXggb3V0IG9mIHJhbmdlJylcbiAgaWYgKG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdpbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5mdW5jdGlvbiB3cml0ZUZsb2F0IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDQsIDMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgsIC0zLjQwMjgyMzQ2NjM4NTI4ODZlKzM4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDIzLCA0KVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRMRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdEJFID0gZnVuY3Rpb24gd3JpdGVGbG9hdEJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRG91YmxlIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDgsIDEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4LCAtMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgNTIsIDgpXG4gIHJldHVybiBvZmZzZXQgKyA4XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVMRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUJFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuLy8gY29weSh0YXJnZXRCdWZmZXIsIHRhcmdldFN0YXJ0PTAsIHNvdXJjZVN0YXJ0PTAsIHNvdXJjZUVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gY29weSAodGFyZ2V0LCB0YXJnZXRTdGFydCwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgJiYgZW5kICE9PSAwKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0U3RhcnQgPj0gdGFyZ2V0Lmxlbmd0aCkgdGFyZ2V0U3RhcnQgPSB0YXJnZXQubGVuZ3RoXG4gIGlmICghdGFyZ2V0U3RhcnQpIHRhcmdldFN0YXJ0ID0gMFxuICBpZiAoZW5kID4gMCAmJiBlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICAvLyBDb3B5IDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVybiAwXG4gIGlmICh0YXJnZXQubGVuZ3RoID09PSAwIHx8IHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIEZhdGFsIGVycm9yIGNvbmRpdGlvbnNcbiAgaWYgKHRhcmdldFN0YXJ0IDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCd0YXJnZXRTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgfVxuICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID49IHRoaXMubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc291cmNlU3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChlbmQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc291cmNlRW5kIG91dCBvZiBib3VuZHMnKVxuXG4gIC8vIEFyZSB3ZSBvb2I/XG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCA8IGVuZCAtIHN0YXJ0KSB7XG4gICAgZW5kID0gdGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0ICsgc3RhcnRcbiAgfVxuXG4gIHZhciBsZW4gPSBlbmQgLSBzdGFydFxuICB2YXIgaVxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQgJiYgc3RhcnQgPCB0YXJnZXRTdGFydCAmJiB0YXJnZXRTdGFydCA8IGVuZCkge1xuICAgIC8vIGRlc2NlbmRpbmcgY29weSBmcm9tIGVuZFxuICAgIGZvciAoaSA9IGxlbiAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIGlmIChsZW4gPCAxMDAwIHx8ICFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIGFzY2VuZGluZyBjb3B5IGZyb20gc3RhcnRcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIFVpbnQ4QXJyYXkucHJvdG90eXBlLnNldC5jYWxsKFxuICAgICAgdGFyZ2V0LFxuICAgICAgdGhpcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBsZW4pLFxuICAgICAgdGFyZ2V0U3RhcnRcbiAgICApXG4gIH1cblxuICByZXR1cm4gbGVuXG59XG5cbi8vIGZpbGwodmFsdWUsIHN0YXJ0PTAsIGVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5maWxsID0gZnVuY3Rpb24gZmlsbCAodmFsdWUsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCF2YWx1ZSkgdmFsdWUgPSAwXG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCkgZW5kID0gdGhpcy5sZW5ndGhcblxuICBpZiAoZW5kIDwgc3RhcnQpIHRocm93IG5ldyBSYW5nZUVycm9yKCdlbmQgPCBzdGFydCcpXG5cbiAgLy8gRmlsbCAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm5cbiAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID49IHRoaXMubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChlbmQgPCAwIHx8IGVuZCA+IHRoaXMubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignZW5kIG91dCBvZiBib3VuZHMnKVxuXG4gIHZhciBpXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgdGhpc1tpXSA9IHZhbHVlXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBieXRlcyA9IHV0ZjhUb0J5dGVzKHZhbHVlLnRvU3RyaW5nKCkpXG4gICAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aFxuICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICAgIHRoaXNbaV0gPSBieXRlc1tpICUgbGVuXVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzXG59XG5cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT1cblxudmFyIElOVkFMSURfQkFTRTY0X1JFID0gL1teK1xcLzAtOUEtWmEtei1fXS9nXG5cbmZ1bmN0aW9uIGJhc2U2NGNsZWFuIChzdHIpIHtcbiAgLy8gTm9kZSBzdHJpcHMgb3V0IGludmFsaWQgY2hhcmFjdGVycyBsaWtlIFxcbiBhbmQgXFx0IGZyb20gdGhlIHN0cmluZywgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHN0ciA9IHN0cmluZ3RyaW0oc3RyKS5yZXBsYWNlKElOVkFMSURfQkFTRTY0X1JFLCAnJylcbiAgLy8gTm9kZSBjb252ZXJ0cyBzdHJpbmdzIHdpdGggbGVuZ3RoIDwgMiB0byAnJ1xuICBpZiAoc3RyLmxlbmd0aCA8IDIpIHJldHVybiAnJ1xuICAvLyBOb2RlIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBiYXNlNjQgc3RyaW5ncyAobWlzc2luZyB0cmFpbGluZyA9PT0pLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgd2hpbGUgKHN0ci5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgc3RyID0gc3RyICsgJz0nXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG5mdW5jdGlvbiBzdHJpbmd0cmltIChzdHIpIHtcbiAgaWYgKHN0ci50cmltKSByZXR1cm4gc3RyLnRyaW0oKVxuICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKVxufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzIChzdHJpbmcsIHVuaXRzKSB7XG4gIHVuaXRzID0gdW5pdHMgfHwgSW5maW5pdHlcbiAgdmFyIGNvZGVQb2ludFxuICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcbiAgdmFyIGJ5dGVzID0gW11cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgY29kZVBvaW50ID0gc3RyaW5nLmNoYXJDb2RlQXQoaSlcblxuICAgIC8vIGlzIHN1cnJvZ2F0ZSBjb21wb25lbnRcbiAgICBpZiAoY29kZVBvaW50ID4gMHhEN0ZGICYmIGNvZGVQb2ludCA8IDB4RTAwMCkge1xuICAgICAgLy8gbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICghbGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgICAvLyBubyBsZWFkIHlldFxuICAgICAgICBpZiAoY29kZVBvaW50ID4gMHhEQkZGKSB7XG4gICAgICAgICAgLy8gdW5leHBlY3RlZCB0cmFpbFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSBpZiAoaSArIDEgPT09IGxlbmd0aCkge1xuICAgICAgICAgIC8vIHVucGFpcmVkIGxlYWRcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmFsaWQgbGVhZFxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gMiBsZWFkcyBpbiBhIHJvd1xuICAgICAgaWYgKGNvZGVQb2ludCA8IDB4REMwMCkge1xuICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyB2YWxpZCBzdXJyb2dhdGUgcGFpclxuICAgICAgY29kZVBvaW50ID0gKGxlYWRTdXJyb2dhdGUgLSAweEQ4MDAgPDwgMTAgfCBjb2RlUG9pbnQgLSAweERDMDApICsgMHgxMDAwMFxuICAgIH0gZWxzZSBpZiAobGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgLy8gdmFsaWQgYm1wIGNoYXIsIGJ1dCBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgfVxuXG4gICAgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcblxuICAgIC8vIGVuY29kZSB1dGY4XG4gICAgaWYgKGNvZGVQb2ludCA8IDB4ODApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMSkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChjb2RlUG9pbnQpXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDgwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2IHwgMHhDMCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyB8IDB4RTAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDQpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDEyIHwgMHhGMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb2RlIHBvaW50JylcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnl0ZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgLy8gTm9kZSdzIGNvZGUgc2VlbXMgdG8gYmUgZG9pbmcgdGhpcyBhbmQgbm90ICYgMHg3Ri4uXG4gICAgYnl0ZUFycmF5LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkgJiAweEZGKVxuICB9XG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVRvQnl0ZXMgKHN0ciwgdW5pdHMpIHtcbiAgdmFyIGMsIGhpLCBsb1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcblxuICAgIGMgPSBzdHIuY2hhckNvZGVBdChpKVxuICAgIGhpID0gYyA+PiA4XG4gICAgbG8gPSBjICUgMjU2XG4gICAgYnl0ZUFycmF5LnB1c2gobG8pXG4gICAgYnl0ZUFycmF5LnB1c2goaGkpXG4gIH1cblxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMgKHN0cikge1xuICByZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKChpICsgb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKSBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG4iLCI7KGZ1bmN0aW9uIChleHBvcnRzKSB7XG4gICd1c2Ugc3RyaWN0J1xuXG4gIHZhciBsb29rdXAgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLydcblxuICB2YXIgQXJyID0gKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJylcbiAgICA/IFVpbnQ4QXJyYXlcbiAgICA6IEFycmF5XG5cbiAgdmFyIFBMVVMgPSAnKycuY2hhckNvZGVBdCgwKVxuICB2YXIgU0xBU0ggPSAnLycuY2hhckNvZGVBdCgwKVxuICB2YXIgTlVNQkVSID0gJzAnLmNoYXJDb2RlQXQoMClcbiAgdmFyIExPV0VSID0gJ2EnLmNoYXJDb2RlQXQoMClcbiAgdmFyIFVQUEVSID0gJ0EnLmNoYXJDb2RlQXQoMClcbiAgdmFyIFBMVVNfVVJMX1NBRkUgPSAnLScuY2hhckNvZGVBdCgwKVxuICB2YXIgU0xBU0hfVVJMX1NBRkUgPSAnXycuY2hhckNvZGVBdCgwKVxuXG4gIGZ1bmN0aW9uIGRlY29kZSAoZWx0KSB7XG4gICAgdmFyIGNvZGUgPSBlbHQuY2hhckNvZGVBdCgwKVxuICAgIGlmIChjb2RlID09PSBQTFVTIHx8IGNvZGUgPT09IFBMVVNfVVJMX1NBRkUpIHJldHVybiA2MiAvLyAnKydcbiAgICBpZiAoY29kZSA9PT0gU0xBU0ggfHwgY29kZSA9PT0gU0xBU0hfVVJMX1NBRkUpIHJldHVybiA2MyAvLyAnLydcbiAgICBpZiAoY29kZSA8IE5VTUJFUikgcmV0dXJuIC0xIC8vIG5vIG1hdGNoXG4gICAgaWYgKGNvZGUgPCBOVU1CRVIgKyAxMCkgcmV0dXJuIGNvZGUgLSBOVU1CRVIgKyAyNiArIDI2XG4gICAgaWYgKGNvZGUgPCBVUFBFUiArIDI2KSByZXR1cm4gY29kZSAtIFVQUEVSXG4gICAgaWYgKGNvZGUgPCBMT1dFUiArIDI2KSByZXR1cm4gY29kZSAtIExPV0VSICsgMjZcbiAgfVxuXG4gIGZ1bmN0aW9uIGI2NFRvQnl0ZUFycmF5IChiNjQpIHtcbiAgICB2YXIgaSwgaiwgbCwgdG1wLCBwbGFjZUhvbGRlcnMsIGFyclxuXG4gICAgaWYgKGI2NC5sZW5ndGggJSA0ID4gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN0cmluZy4gTGVuZ3RoIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA0JylcbiAgICB9XG5cbiAgICAvLyB0aGUgbnVtYmVyIG9mIGVxdWFsIHNpZ25zIChwbGFjZSBob2xkZXJzKVxuICAgIC8vIGlmIHRoZXJlIGFyZSB0d28gcGxhY2Vob2xkZXJzLCB0aGFuIHRoZSB0d28gY2hhcmFjdGVycyBiZWZvcmUgaXRcbiAgICAvLyByZXByZXNlbnQgb25lIGJ5dGVcbiAgICAvLyBpZiB0aGVyZSBpcyBvbmx5IG9uZSwgdGhlbiB0aGUgdGhyZWUgY2hhcmFjdGVycyBiZWZvcmUgaXQgcmVwcmVzZW50IDIgYnl0ZXNcbiAgICAvLyB0aGlzIGlzIGp1c3QgYSBjaGVhcCBoYWNrIHRvIG5vdCBkbyBpbmRleE9mIHR3aWNlXG4gICAgdmFyIGxlbiA9IGI2NC5sZW5ndGhcbiAgICBwbGFjZUhvbGRlcnMgPSBiNjQuY2hhckF0KGxlbiAtIDIpID09PSAnPScgPyAyIDogYjY0LmNoYXJBdChsZW4gLSAxKSA9PT0gJz0nID8gMSA6IDBcblxuICAgIC8vIGJhc2U2NCBpcyA0LzMgKyB1cCB0byB0d28gY2hhcmFjdGVycyBvZiB0aGUgb3JpZ2luYWwgZGF0YVxuICAgIGFyciA9IG5ldyBBcnIoYjY0Lmxlbmd0aCAqIDMgLyA0IC0gcGxhY2VIb2xkZXJzKVxuXG4gICAgLy8gaWYgdGhlcmUgYXJlIHBsYWNlaG9sZGVycywgb25seSBnZXQgdXAgdG8gdGhlIGxhc3QgY29tcGxldGUgNCBjaGFyc1xuICAgIGwgPSBwbGFjZUhvbGRlcnMgPiAwID8gYjY0Lmxlbmd0aCAtIDQgOiBiNjQubGVuZ3RoXG5cbiAgICB2YXIgTCA9IDBcblxuICAgIGZ1bmN0aW9uIHB1c2ggKHYpIHtcbiAgICAgIGFycltMKytdID0gdlxuICAgIH1cblxuICAgIGZvciAoaSA9IDAsIGogPSAwOyBpIDwgbDsgaSArPSA0LCBqICs9IDMpIHtcbiAgICAgIHRtcCA9IChkZWNvZGUoYjY0LmNoYXJBdChpKSkgPDwgMTgpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAxKSkgPDwgMTIpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAyKSkgPDwgNikgfCBkZWNvZGUoYjY0LmNoYXJBdChpICsgMykpXG4gICAgICBwdXNoKCh0bXAgJiAweEZGMDAwMCkgPj4gMTYpXG4gICAgICBwdXNoKCh0bXAgJiAweEZGMDApID4+IDgpXG4gICAgICBwdXNoKHRtcCAmIDB4RkYpXG4gICAgfVxuXG4gICAgaWYgKHBsYWNlSG9sZGVycyA9PT0gMikge1xuICAgICAgdG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAyKSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMSkpID4+IDQpXG4gICAgICBwdXNoKHRtcCAmIDB4RkYpXG4gICAgfSBlbHNlIGlmIChwbGFjZUhvbGRlcnMgPT09IDEpIHtcbiAgICAgIHRtcCA9IChkZWNvZGUoYjY0LmNoYXJBdChpKSkgPDwgMTApIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAxKSkgPDwgNCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDIpKSA+PiAyKVxuICAgICAgcHVzaCgodG1wID4+IDgpICYgMHhGRilcbiAgICAgIHB1c2godG1wICYgMHhGRilcbiAgICB9XG5cbiAgICByZXR1cm4gYXJyXG4gIH1cblxuICBmdW5jdGlvbiB1aW50OFRvQmFzZTY0ICh1aW50OCkge1xuICAgIHZhciBpXG4gICAgdmFyIGV4dHJhQnl0ZXMgPSB1aW50OC5sZW5ndGggJSAzIC8vIGlmIHdlIGhhdmUgMSBieXRlIGxlZnQsIHBhZCAyIGJ5dGVzXG4gICAgdmFyIG91dHB1dCA9ICcnXG4gICAgdmFyIHRlbXAsIGxlbmd0aFxuXG4gICAgZnVuY3Rpb24gZW5jb2RlIChudW0pIHtcbiAgICAgIHJldHVybiBsb29rdXAuY2hhckF0KG51bSlcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0cmlwbGV0VG9CYXNlNjQgKG51bSkge1xuICAgICAgcmV0dXJuIGVuY29kZShudW0gPj4gMTggJiAweDNGKSArIGVuY29kZShudW0gPj4gMTIgJiAweDNGKSArIGVuY29kZShudW0gPj4gNiAmIDB4M0YpICsgZW5jb2RlKG51bSAmIDB4M0YpXG4gICAgfVxuXG4gICAgLy8gZ28gdGhyb3VnaCB0aGUgYXJyYXkgZXZlcnkgdGhyZWUgYnl0ZXMsIHdlJ2xsIGRlYWwgd2l0aCB0cmFpbGluZyBzdHVmZiBsYXRlclxuICAgIGZvciAoaSA9IDAsIGxlbmd0aCA9IHVpbnQ4Lmxlbmd0aCAtIGV4dHJhQnl0ZXM7IGkgPCBsZW5ndGg7IGkgKz0gMykge1xuICAgICAgdGVtcCA9ICh1aW50OFtpXSA8PCAxNikgKyAodWludDhbaSArIDFdIDw8IDgpICsgKHVpbnQ4W2kgKyAyXSlcbiAgICAgIG91dHB1dCArPSB0cmlwbGV0VG9CYXNlNjQodGVtcClcbiAgICB9XG5cbiAgICAvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG4gICAgc3dpdGNoIChleHRyYUJ5dGVzKSB7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHRlbXAgPSB1aW50OFt1aW50OC5sZW5ndGggLSAxXVxuICAgICAgICBvdXRwdXQgKz0gZW5jb2RlKHRlbXAgPj4gMilcbiAgICAgICAgb3V0cHV0ICs9IGVuY29kZSgodGVtcCA8PCA0KSAmIDB4M0YpXG4gICAgICAgIG91dHB1dCArPSAnPT0nXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlIDI6XG4gICAgICAgIHRlbXAgPSAodWludDhbdWludDgubGVuZ3RoIC0gMl0gPDwgOCkgKyAodWludDhbdWludDgubGVuZ3RoIC0gMV0pXG4gICAgICAgIG91dHB1dCArPSBlbmNvZGUodGVtcCA+PiAxMClcbiAgICAgICAgb3V0cHV0ICs9IGVuY29kZSgodGVtcCA+PiA0KSAmIDB4M0YpXG4gICAgICAgIG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPDwgMikgJiAweDNGKVxuICAgICAgICBvdXRwdXQgKz0gJz0nXG4gICAgICAgIGJyZWFrXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVha1xuICAgIH1cblxuICAgIHJldHVybiBvdXRwdXRcbiAgfVxuXG4gIGV4cG9ydHMudG9CeXRlQXJyYXkgPSBiNjRUb0J5dGVBcnJheVxuICBleHBvcnRzLmZyb21CeXRlQXJyYXkgPSB1aW50OFRvQmFzZTY0XG59KHR5cGVvZiBleHBvcnRzID09PSAndW5kZWZpbmVkJyA/ICh0aGlzLmJhc2U2NGpzID0ge30pIDogZXhwb3J0cykpXG4iLCJleHBvcnRzLnJlYWQgPSBmdW5jdGlvbiAoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbVxuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSBlICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgZSA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gbUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhc1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSlcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pXG4gICAgZSA9IGUgLSBlQmlhc1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pXG59XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGNcbiAgdmFyIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gZSArIGVCaWFzXG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSB2YWx1ZSAqIE1hdGgucG93KDIsIGVCaWFzIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IDBcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KSB7fVxuXG4gIGUgPSAoZSA8PCBtTGVuKSB8IG1cbiAgZUxlbiArPSBtTGVuXG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cblxuICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjhcbn1cbiIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChhcnIpID09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIiwiJ3VzZSBzdHJpY3QnXG5cbmV4cG9ydHMucmFuZG9tQnl0ZXMgPSBleHBvcnRzLnJuZyA9IGV4cG9ydHMucHNldWRvUmFuZG9tQnl0ZXMgPSBleHBvcnRzLnBybmcgPSByZXF1aXJlKCdyYW5kb21ieXRlcycpXG5leHBvcnRzLmNyZWF0ZUhhc2ggPSBleHBvcnRzLkhhc2ggPSByZXF1aXJlKCdjcmVhdGUtaGFzaCcpXG5leHBvcnRzLmNyZWF0ZUhtYWMgPSBleHBvcnRzLkhtYWMgPSByZXF1aXJlKCdjcmVhdGUtaG1hYycpXG5cbnZhciBoYXNoZXMgPSBbJ3NoYTEnLCAnc2hhMjI0JywgJ3NoYTI1NicsICdzaGEzODQnLCAnc2hhNTEyJywgJ21kNScsICdybWQxNjAnXS5jb25jYXQoT2JqZWN0LmtleXMocmVxdWlyZSgnYnJvd3NlcmlmeS1zaWduL2FsZ29zJykpKVxuZXhwb3J0cy5nZXRIYXNoZXMgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBoYXNoZXNcbn1cblxudmFyIHAgPSByZXF1aXJlKCdwYmtkZjInKVxuZXhwb3J0cy5wYmtkZjIgPSBwLnBia2RmMlxuZXhwb3J0cy5wYmtkZjJTeW5jID0gcC5wYmtkZjJTeW5jXG5cbnZhciBhZXMgPSByZXF1aXJlKCdicm93c2VyaWZ5LWNpcGhlcicpXG47W1xuICAnQ2lwaGVyJyxcbiAgJ2NyZWF0ZUNpcGhlcicsXG4gICdDaXBoZXJpdicsXG4gICdjcmVhdGVDaXBoZXJpdicsXG4gICdEZWNpcGhlcicsXG4gICdjcmVhdGVEZWNpcGhlcicsXG4gICdEZWNpcGhlcml2JyxcbiAgJ2NyZWF0ZURlY2lwaGVyaXYnLFxuICAnZ2V0Q2lwaGVycycsXG4gICdsaXN0Q2lwaGVycydcbl0uZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gIGV4cG9ydHNba2V5XSA9IGFlc1trZXldXG59KVxuXG52YXIgZGggPSByZXF1aXJlKCdkaWZmaWUtaGVsbG1hbicpXG47W1xuICAnRGlmZmllSGVsbG1hbkdyb3VwJyxcbiAgJ2NyZWF0ZURpZmZpZUhlbGxtYW5Hcm91cCcsXG4gICdnZXREaWZmaWVIZWxsbWFuJyxcbiAgJ2NyZWF0ZURpZmZpZUhlbGxtYW4nLFxuICAnRGlmZmllSGVsbG1hbidcbl0uZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gIGV4cG9ydHNba2V5XSA9IGRoW2tleV1cbn0pXG5cbnZhciBzaWduID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1zaWduJylcbjtbXG4gICdjcmVhdGVTaWduJyxcbiAgJ1NpZ24nLFxuICAnY3JlYXRlVmVyaWZ5JyxcbiAgJ1ZlcmlmeSdcbl0uZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gIGV4cG9ydHNba2V5XSA9IHNpZ25ba2V5XVxufSlcblxuZXhwb3J0cy5jcmVhdGVFQ0RIID0gcmVxdWlyZSgnY3JlYXRlLWVjZGgnKVxuXG52YXIgcHVibGljRW5jcnlwdCA9IHJlcXVpcmUoJ3B1YmxpYy1lbmNyeXB0JylcblxuO1tcbiAgJ3B1YmxpY0VuY3J5cHQnLFxuICAncHJpdmF0ZUVuY3J5cHQnLFxuICAncHVibGljRGVjcnlwdCcsXG4gICdwcml2YXRlRGVjcnlwdCdcbl0uZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gIGV4cG9ydHNba2V5XSA9IHB1YmxpY0VuY3J5cHRba2V5XVxufSlcblxuLy8gdGhlIGxlYXN0IEkgY2FuIGRvIGlzIG1ha2UgZXJyb3IgbWVzc2FnZXMgZm9yIHRoZSByZXN0IG9mIHRoZSBub2RlLmpzL2NyeXB0byBhcGkuXG47W1xuICAnY3JlYXRlQ3JlZGVudGlhbHMnXG5dLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgZXhwb3J0c1tuYW1lXSA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoW1xuICAgICAgJ3NvcnJ5LCAnICsgbmFtZSArICcgaXMgbm90IGltcGxlbWVudGVkIHlldCcsXG4gICAgICAnd2UgYWNjZXB0IHB1bGwgcmVxdWVzdHMnLFxuICAgICAgJ2h0dHBzOi8vZ2l0aHViLmNvbS9jcnlwdG8tYnJvd3NlcmlmeS9jcnlwdG8tYnJvd3NlcmlmeSdcbiAgICBdLmpvaW4oJ1xcbicpKVxuICB9XG59KVxuIiwidmFyIGVidGsgPSByZXF1aXJlKCdldnBfYnl0ZXN0b2tleScpXG52YXIgYWVzID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1hZXMvYnJvd3NlcicpXG52YXIgREVTID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1kZXMnKVxudmFyIGRlc01vZGVzID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1kZXMvbW9kZXMnKVxudmFyIGFlc01vZGVzID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1hZXMvbW9kZXMnKVxuZnVuY3Rpb24gY3JlYXRlQ2lwaGVyIChzdWl0ZSwgcGFzc3dvcmQpIHtcbiAgdmFyIGtleUxlbiwgaXZMZW5cbiAgc3VpdGUgPSBzdWl0ZS50b0xvd2VyQ2FzZSgpXG4gIGlmIChhZXNNb2Rlc1tzdWl0ZV0pIHtcbiAgICBrZXlMZW4gPSBhZXNNb2Rlc1tzdWl0ZV0ua2V5XG4gICAgaXZMZW4gPSBhZXNNb2Rlc1tzdWl0ZV0uaXZcbiAgfSBlbHNlIGlmIChkZXNNb2Rlc1tzdWl0ZV0pIHtcbiAgICBrZXlMZW4gPSBkZXNNb2Rlc1tzdWl0ZV0ua2V5ICogOFxuICAgIGl2TGVuID0gZGVzTW9kZXNbc3VpdGVdLml2XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBzdWl0ZSB0eXBlJylcbiAgfVxuICB2YXIga2V5cyA9IGVidGsocGFzc3dvcmQsIGZhbHNlLCBrZXlMZW4sIGl2TGVuKVxuICByZXR1cm4gY3JlYXRlQ2lwaGVyaXYoc3VpdGUsIGtleXMua2V5LCBrZXlzLml2KVxufVxuZnVuY3Rpb24gY3JlYXRlRGVjaXBoZXIgKHN1aXRlLCBwYXNzd29yZCkge1xuICB2YXIga2V5TGVuLCBpdkxlblxuICBzdWl0ZSA9IHN1aXRlLnRvTG93ZXJDYXNlKClcbiAgaWYgKGFlc01vZGVzW3N1aXRlXSkge1xuICAgIGtleUxlbiA9IGFlc01vZGVzW3N1aXRlXS5rZXlcbiAgICBpdkxlbiA9IGFlc01vZGVzW3N1aXRlXS5pdlxuICB9IGVsc2UgaWYgKGRlc01vZGVzW3N1aXRlXSkge1xuICAgIGtleUxlbiA9IGRlc01vZGVzW3N1aXRlXS5rZXkgKiA4XG4gICAgaXZMZW4gPSBkZXNNb2Rlc1tzdWl0ZV0uaXZcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuICB9XG4gIHZhciBrZXlzID0gZWJ0ayhwYXNzd29yZCwgZmFsc2UsIGtleUxlbiwgaXZMZW4pXG4gIHJldHVybiBjcmVhdGVEZWNpcGhlcml2KHN1aXRlLCBrZXlzLmtleSwga2V5cy5pdilcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2lwaGVyaXYgKHN1aXRlLCBrZXksIGl2KSB7XG4gIHN1aXRlID0gc3VpdGUudG9Mb3dlckNhc2UoKVxuICBpZiAoYWVzTW9kZXNbc3VpdGVdKSB7XG4gICAgcmV0dXJuIGFlcy5jcmVhdGVDaXBoZXJpdihzdWl0ZSwga2V5LCBpdilcbiAgfSBlbHNlIGlmIChkZXNNb2Rlc1tzdWl0ZV0pIHtcbiAgICByZXR1cm4gbmV3IERFUyh7XG4gICAgICBrZXk6IGtleSxcbiAgICAgIGl2OiBpdixcbiAgICAgIG1vZGU6IHN1aXRlXG4gICAgfSlcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuICB9XG59XG5mdW5jdGlvbiBjcmVhdGVEZWNpcGhlcml2IChzdWl0ZSwga2V5LCBpdikge1xuICBzdWl0ZSA9IHN1aXRlLnRvTG93ZXJDYXNlKClcbiAgaWYgKGFlc01vZGVzW3N1aXRlXSkge1xuICAgIHJldHVybiBhZXMuY3JlYXRlRGVjaXBoZXJpdihzdWl0ZSwga2V5LCBpdilcbiAgfSBlbHNlIGlmIChkZXNNb2Rlc1tzdWl0ZV0pIHtcbiAgICByZXR1cm4gbmV3IERFUyh7XG4gICAgICBrZXk6IGtleSxcbiAgICAgIGl2OiBpdixcbiAgICAgIG1vZGU6IHN1aXRlLFxuICAgICAgZGVjcnlwdDogdHJ1ZVxuICAgIH0pXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBzdWl0ZSB0eXBlJylcbiAgfVxufVxuZXhwb3J0cy5jcmVhdGVDaXBoZXIgPSBleHBvcnRzLkNpcGhlciA9IGNyZWF0ZUNpcGhlclxuZXhwb3J0cy5jcmVhdGVDaXBoZXJpdiA9IGV4cG9ydHMuQ2lwaGVyaXYgPSBjcmVhdGVDaXBoZXJpdlxuZXhwb3J0cy5jcmVhdGVEZWNpcGhlciA9IGV4cG9ydHMuRGVjaXBoZXIgPSBjcmVhdGVEZWNpcGhlclxuZXhwb3J0cy5jcmVhdGVEZWNpcGhlcml2ID0gZXhwb3J0cy5EZWNpcGhlcml2ID0gY3JlYXRlRGVjaXBoZXJpdlxuZnVuY3Rpb24gZ2V0Q2lwaGVycyAoKSB7XG4gIHJldHVybiBPYmplY3Qua2V5cyhkZXNNb2RlcykuY29uY2F0KGFlcy5nZXRDaXBoZXJzKCkpXG59XG5leHBvcnRzLmxpc3RDaXBoZXJzID0gZXhwb3J0cy5nZXRDaXBoZXJzID0gZ2V0Q2lwaGVyc1xuIiwiLy8gYmFzZWQgb24gdGhlIGFlcyBpbXBsaW1lbnRhdGlvbiBpbiB0cmlwbGUgc2VjXG4vLyBodHRwczovL2dpdGh1Yi5jb20va2V5YmFzZS90cmlwbGVzZWNcblxuLy8gd2hpY2ggaXMgaW4gdHVybiBiYXNlZCBvbiB0aGUgb25lIGZyb20gY3J5cHRvLWpzXG4vLyBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qcy9cblxudmFyIHVpbnRfbWF4ID0gTWF0aC5wb3coMiwgMzIpXG5mdW5jdGlvbiBmaXh1cF91aW50MzIgKHgpIHtcbiAgdmFyIHJldCwgeF9wb3NcbiAgcmV0ID0geCA+IHVpbnRfbWF4IHx8IHggPCAwID8gKHhfcG9zID0gTWF0aC5hYnMoeCkgJSB1aW50X21heCwgeCA8IDAgPyB1aW50X21heCAtIHhfcG9zIDogeF9wb3MpIDogeFxuICByZXR1cm4gcmV0XG59XG5mdW5jdGlvbiBzY3J1Yl92ZWMgKHYpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB2Lmxlbmd0aDsgdisrKSB7XG4gICAgdltpXSA9IDBcbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cblxuZnVuY3Rpb24gR2xvYmFsICgpIHtcbiAgdGhpcy5TQk9YID0gW11cbiAgdGhpcy5JTlZfU0JPWCA9IFtdXG4gIHRoaXMuU1VCX01JWCA9IFtbXSwgW10sIFtdLCBbXV1cbiAgdGhpcy5JTlZfU1VCX01JWCA9IFtbXSwgW10sIFtdLCBbXV1cbiAgdGhpcy5pbml0KClcbiAgdGhpcy5SQ09OID0gWzB4MDAsIDB4MDEsIDB4MDIsIDB4MDQsIDB4MDgsIDB4MTAsIDB4MjAsIDB4NDAsIDB4ODAsIDB4MWIsIDB4MzZdXG59XG5cbkdsb2JhbC5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGQsIGksIHN4LCB0LCB4LCB4MiwgeDQsIHg4LCB4aSwgX2lcbiAgZCA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIF9pLCBfcmVzdWx0c1xuICAgIF9yZXN1bHRzID0gW11cbiAgICBmb3IgKGkgPSBfaSA9IDA7IF9pIDwgMjU2OyBpID0gKytfaSkge1xuICAgICAgaWYgKGkgPCAxMjgpIHtcbiAgICAgICAgX3Jlc3VsdHMucHVzaChpIDw8IDEpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfcmVzdWx0cy5wdXNoKChpIDw8IDEpIF4gMHgxMWIpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBfcmVzdWx0c1xuICB9KSgpXG4gIHggPSAwXG4gIHhpID0gMFxuICBmb3IgKGkgPSBfaSA9IDA7IF9pIDwgMjU2OyBpID0gKytfaSkge1xuICAgIHN4ID0geGkgXiAoeGkgPDwgMSkgXiAoeGkgPDwgMikgXiAoeGkgPDwgMykgXiAoeGkgPDwgNClcbiAgICBzeCA9IChzeCA+Pj4gOCkgXiAoc3ggJiAweGZmKSBeIDB4NjNcbiAgICB0aGlzLlNCT1hbeF0gPSBzeFxuICAgIHRoaXMuSU5WX1NCT1hbc3hdID0geFxuICAgIHgyID0gZFt4XVxuICAgIHg0ID0gZFt4Ml1cbiAgICB4OCA9IGRbeDRdXG4gICAgdCA9IChkW3N4XSAqIDB4MTAxKSBeIChzeCAqIDB4MTAxMDEwMClcbiAgICB0aGlzLlNVQl9NSVhbMF1beF0gPSAodCA8PCAyNCkgfCAodCA+Pj4gOClcbiAgICB0aGlzLlNVQl9NSVhbMV1beF0gPSAodCA8PCAxNikgfCAodCA+Pj4gMTYpXG4gICAgdGhpcy5TVUJfTUlYWzJdW3hdID0gKHQgPDwgOCkgfCAodCA+Pj4gMjQpXG4gICAgdGhpcy5TVUJfTUlYWzNdW3hdID0gdFxuICAgIHQgPSAoeDggKiAweDEwMTAxMDEpIF4gKHg0ICogMHgxMDAwMSkgXiAoeDIgKiAweDEwMSkgXiAoeCAqIDB4MTAxMDEwMClcbiAgICB0aGlzLklOVl9TVUJfTUlYWzBdW3N4XSA9ICh0IDw8IDI0KSB8ICh0ID4+PiA4KVxuICAgIHRoaXMuSU5WX1NVQl9NSVhbMV1bc3hdID0gKHQgPDwgMTYpIHwgKHQgPj4+IDE2KVxuICAgIHRoaXMuSU5WX1NVQl9NSVhbMl1bc3hdID0gKHQgPDwgOCkgfCAodCA+Pj4gMjQpXG4gICAgdGhpcy5JTlZfU1VCX01JWFszXVtzeF0gPSB0XG4gICAgaWYgKHggPT09IDApIHtcbiAgICAgIHggPSB4aSA9IDFcbiAgICB9IGVsc2Uge1xuICAgICAgeCA9IHgyIF4gZFtkW2RbeDggXiB4Ml1dXVxuICAgICAgeGkgXj0gZFtkW3hpXV1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWVcbn1cblxudmFyIEcgPSBuZXcgR2xvYmFsKClcblxuQUVTLmJsb2NrU2l6ZSA9IDQgKiA0XG5cbkFFUy5wcm90b3R5cGUuYmxvY2tTaXplID0gQUVTLmJsb2NrU2l6ZVxuXG5BRVMua2V5U2l6ZSA9IDI1NiAvIDhcblxuQUVTLnByb3RvdHlwZS5rZXlTaXplID0gQUVTLmtleVNpemVcblxuZnVuY3Rpb24gYnVmZmVyVG9BcnJheSAoYnVmKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoIC8gNFxuICB2YXIgb3V0ID0gbmV3IEFycmF5KGxlbilcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgb3V0W2ldID0gYnVmLnJlYWRVSW50MzJCRShpICogNClcbiAgfVxuICByZXR1cm4gb3V0XG59XG5mdW5jdGlvbiBBRVMgKGtleSkge1xuICB0aGlzLl9rZXkgPSBidWZmZXJUb0FycmF5KGtleSlcbiAgdGhpcy5fZG9SZXNldCgpXG59XG5cbkFFUy5wcm90b3R5cGUuX2RvUmVzZXQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBpbnZLc1Jvdywga2V5U2l6ZSwga2V5V29yZHMsIGtzUm93LCBrc1Jvd3MsIHRcbiAga2V5V29yZHMgPSB0aGlzLl9rZXlcbiAga2V5U2l6ZSA9IGtleVdvcmRzLmxlbmd0aFxuICB0aGlzLl9uUm91bmRzID0ga2V5U2l6ZSArIDZcbiAga3NSb3dzID0gKHRoaXMuX25Sb3VuZHMgKyAxKSAqIDRcbiAgdGhpcy5fa2V5U2NoZWR1bGUgPSBbXVxuICBmb3IgKGtzUm93ID0gMDsga3NSb3cgPCBrc1Jvd3M7IGtzUm93KyspIHtcbiAgICB0aGlzLl9rZXlTY2hlZHVsZVtrc1Jvd10gPSBrc1JvdyA8IGtleVNpemUgPyBrZXlXb3Jkc1trc1Jvd10gOiAodCA9IHRoaXMuX2tleVNjaGVkdWxlW2tzUm93IC0gMV0sIChrc1JvdyAlIGtleVNpemUpID09PSAwID8gKHQgPSAodCA8PCA4KSB8ICh0ID4+PiAyNCksIHQgPSAoRy5TQk9YW3QgPj4+IDI0XSA8PCAyNCkgfCAoRy5TQk9YWyh0ID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoRy5TQk9YWyh0ID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgRy5TQk9YW3QgJiAweGZmXSwgdCBePSBHLlJDT05bKGtzUm93IC8ga2V5U2l6ZSkgfCAwXSA8PCAyNCkgOiBrZXlTaXplID4gNiAmJiBrc1JvdyAlIGtleVNpemUgPT09IDQgPyB0ID0gKEcuU0JPWFt0ID4+PiAyNF0gPDwgMjQpIHwgKEcuU0JPWFsodCA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKEcuU0JPWFsodCA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IEcuU0JPWFt0ICYgMHhmZl0gOiB2b2lkIDAsIHRoaXMuX2tleVNjaGVkdWxlW2tzUm93IC0ga2V5U2l6ZV0gXiB0KVxuICB9XG4gIHRoaXMuX2ludktleVNjaGVkdWxlID0gW11cbiAgZm9yIChpbnZLc1JvdyA9IDA7IGludktzUm93IDwga3NSb3dzOyBpbnZLc1JvdysrKSB7XG4gICAga3NSb3cgPSBrc1Jvd3MgLSBpbnZLc1Jvd1xuICAgIHQgPSB0aGlzLl9rZXlTY2hlZHVsZVtrc1JvdyAtIChpbnZLc1JvdyAlIDQgPyAwIDogNCldXG4gICAgdGhpcy5faW52S2V5U2NoZWR1bGVbaW52S3NSb3ddID0gaW52S3NSb3cgPCA0IHx8IGtzUm93IDw9IDQgPyB0IDogRy5JTlZfU1VCX01JWFswXVtHLlNCT1hbdCA+Pj4gMjRdXSBeIEcuSU5WX1NVQl9NSVhbMV1bRy5TQk9YWyh0ID4+PiAxNikgJiAweGZmXV0gXiBHLklOVl9TVUJfTUlYWzJdW0cuU0JPWFsodCA+Pj4gOCkgJiAweGZmXV0gXiBHLklOVl9TVUJfTUlYWzNdW0cuU0JPWFt0ICYgMHhmZl1dXG4gIH1cbiAgcmV0dXJuIHRydWVcbn1cblxuQUVTLnByb3RvdHlwZS5lbmNyeXB0QmxvY2sgPSBmdW5jdGlvbiAoTSkge1xuICBNID0gYnVmZmVyVG9BcnJheShuZXcgQnVmZmVyKE0pKVxuICB2YXIgb3V0ID0gdGhpcy5fZG9DcnlwdEJsb2NrKE0sIHRoaXMuX2tleVNjaGVkdWxlLCBHLlNVQl9NSVgsIEcuU0JPWClcbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoMTYpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFswXSwgMClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzFdLCA0KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMl0sIDgpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFszXSwgMTIpXG4gIHJldHVybiBidWZcbn1cblxuQUVTLnByb3RvdHlwZS5kZWNyeXB0QmxvY2sgPSBmdW5jdGlvbiAoTSkge1xuICBNID0gYnVmZmVyVG9BcnJheShuZXcgQnVmZmVyKE0pKVxuICB2YXIgdGVtcCA9IFtNWzNdLCBNWzFdXVxuICBNWzFdID0gdGVtcFswXVxuICBNWzNdID0gdGVtcFsxXVxuICB2YXIgb3V0ID0gdGhpcy5fZG9DcnlwdEJsb2NrKE0sIHRoaXMuX2ludktleVNjaGVkdWxlLCBHLklOVl9TVUJfTUlYLCBHLklOVl9TQk9YKVxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcigxNilcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzBdLCAwKVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbM10sIDQpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsyXSwgOClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzFdLCAxMilcbiAgcmV0dXJuIGJ1ZlxufVxuXG5BRVMucHJvdG90eXBlLnNjcnViID0gZnVuY3Rpb24gKCkge1xuICBzY3J1Yl92ZWModGhpcy5fa2V5U2NoZWR1bGUpXG4gIHNjcnViX3ZlYyh0aGlzLl9pbnZLZXlTY2hlZHVsZSlcbiAgc2NydWJfdmVjKHRoaXMuX2tleSlcbn1cblxuQUVTLnByb3RvdHlwZS5fZG9DcnlwdEJsb2NrID0gZnVuY3Rpb24gKE0sIGtleVNjaGVkdWxlLCBTVUJfTUlYLCBTQk9YKSB7XG4gIHZhciBrc1JvdywgczAsIHMxLCBzMiwgczMsIHQwLCB0MSwgdDIsIHQzXG5cbiAgczAgPSBNWzBdIF4ga2V5U2NoZWR1bGVbMF1cbiAgczEgPSBNWzFdIF4ga2V5U2NoZWR1bGVbMV1cbiAgczIgPSBNWzJdIF4ga2V5U2NoZWR1bGVbMl1cbiAgczMgPSBNWzNdIF4ga2V5U2NoZWR1bGVbM11cbiAga3NSb3cgPSA0XG4gIGZvciAodmFyIHJvdW5kID0gMTsgcm91bmQgPCB0aGlzLl9uUm91bmRzOyByb3VuZCsrKSB7XG4gICAgdDAgPSBTVUJfTUlYWzBdW3MwID4+PiAyNF0gXiBTVUJfTUlYWzFdWyhzMSA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYWzJdWyhzMiA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhbM11bczMgJiAweGZmXSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gICAgdDEgPSBTVUJfTUlYWzBdW3MxID4+PiAyNF0gXiBTVUJfTUlYWzFdWyhzMiA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYWzJdWyhzMyA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhbM11bczAgJiAweGZmXSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gICAgdDIgPSBTVUJfTUlYWzBdW3MyID4+PiAyNF0gXiBTVUJfTUlYWzFdWyhzMyA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYWzJdWyhzMCA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhbM11bczEgJiAweGZmXSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gICAgdDMgPSBTVUJfTUlYWzBdW3MzID4+PiAyNF0gXiBTVUJfTUlYWzFdWyhzMCA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYWzJdWyhzMSA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhbM11bczIgJiAweGZmXSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gICAgczAgPSB0MFxuICAgIHMxID0gdDFcbiAgICBzMiA9IHQyXG4gICAgczMgPSB0M1xuICB9XG4gIHQwID0gKChTQk9YW3MwID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMxID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczIgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MzICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgdDEgPSAoKFNCT1hbczEgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczIgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMyA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczAgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICB0MiA9ICgoU0JPWFtzMiA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMyA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMwID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMSAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gIHQzID0gKChTQk9YW3MzID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMwID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczEgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MyICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgcmV0dXJuIFtcbiAgICBmaXh1cF91aW50MzIodDApLFxuICAgIGZpeHVwX3VpbnQzMih0MSksXG4gICAgZml4dXBfdWludDMyKHQyKSxcbiAgICBmaXh1cF91aW50MzIodDMpXG4gIF1cbn1cblxuZXhwb3J0cy5BRVMgPSBBRVNcbiIsInZhciBhZXMgPSByZXF1aXJlKCcuL2FlcycpXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEdIQVNIID0gcmVxdWlyZSgnLi9naGFzaCcpXG52YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG5pbmhlcml0cyhTdHJlYW1DaXBoZXIsIFRyYW5zZm9ybSlcbm1vZHVsZS5leHBvcnRzID0gU3RyZWFtQ2lwaGVyXG5cbmZ1bmN0aW9uIFN0cmVhbUNpcGhlciAobW9kZSwga2V5LCBpdiwgZGVjcnlwdCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3RyZWFtQ2lwaGVyKSkge1xuICAgIHJldHVybiBuZXcgU3RyZWFtQ2lwaGVyKG1vZGUsIGtleSwgaXYpXG4gIH1cbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5fZmluSUQgPSBCdWZmZXIuY29uY2F0KFtpdiwgbmV3IEJ1ZmZlcihbMCwgMCwgMCwgMV0pXSlcbiAgaXYgPSBCdWZmZXIuY29uY2F0KFtpdiwgbmV3IEJ1ZmZlcihbMCwgMCwgMCwgMl0pXSlcbiAgdGhpcy5fY2lwaGVyID0gbmV3IGFlcy5BRVMoa2V5KVxuICB0aGlzLl9wcmV2ID0gbmV3IEJ1ZmZlcihpdi5sZW5ndGgpXG4gIHRoaXMuX2NhY2hlID0gbmV3IEJ1ZmZlcignJylcbiAgdGhpcy5fc2VjQ2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxuICB0aGlzLl9kZWNyeXB0ID0gZGVjcnlwdFxuICB0aGlzLl9hbGVuID0gMFxuICB0aGlzLl9sZW4gPSAwXG4gIGl2LmNvcHkodGhpcy5fcHJldilcbiAgdGhpcy5fbW9kZSA9IG1vZGVcbiAgdmFyIGggPSBuZXcgQnVmZmVyKDQpXG4gIGguZmlsbCgwKVxuICB0aGlzLl9naGFzaCA9IG5ldyBHSEFTSCh0aGlzLl9jaXBoZXIuZW5jcnlwdEJsb2NrKGgpKVxuICB0aGlzLl9hdXRoVGFnID0gbnVsbFxuICB0aGlzLl9jYWxsZWQgPSBmYWxzZVxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gIGlmICghdGhpcy5fY2FsbGVkICYmIHRoaXMuX2FsZW4pIHtcbiAgICB2YXIgcnVtcCA9IDE2IC0gKHRoaXMuX2FsZW4gJSAxNilcbiAgICBpZiAocnVtcCA8IDE2KSB7XG4gICAgICBydW1wID0gbmV3IEJ1ZmZlcihydW1wKVxuICAgICAgcnVtcC5maWxsKDApXG4gICAgICB0aGlzLl9naGFzaC51cGRhdGUocnVtcClcbiAgICB9XG4gIH1cbiAgdGhpcy5fY2FsbGVkID0gdHJ1ZVxuICB2YXIgb3V0ID0gdGhpcy5fbW9kZS5lbmNyeXB0KHRoaXMsIGNodW5rKVxuICBpZiAodGhpcy5fZGVjcnlwdCkge1xuICAgIHRoaXMuX2doYXNoLnVwZGF0ZShjaHVuaylcbiAgfSBlbHNlIHtcbiAgICB0aGlzLl9naGFzaC51cGRhdGUob3V0KVxuICB9XG4gIHRoaXMuX2xlbiArPSBjaHVuay5sZW5ndGhcbiAgcmV0dXJuIG91dFxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLl9kZWNyeXB0ICYmICF0aGlzLl9hdXRoVGFnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBzdGF0ZSBvciB1bmFibGUgdG8gYXV0aGVudGljYXRlIGRhdGEnKVxuICB9XG4gIHZhciB0YWcgPSB4b3IodGhpcy5fZ2hhc2guZmluYWwodGhpcy5fYWxlbiAqIDgsIHRoaXMuX2xlbiAqIDgpLCB0aGlzLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHRoaXMuX2ZpbklEKSlcbiAgaWYgKHRoaXMuX2RlY3J5cHQpIHtcbiAgICBpZiAoeG9yVGVzdCh0YWcsIHRoaXMuX2F1dGhUYWcpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIHN0YXRlIG9yIHVuYWJsZSB0byBhdXRoZW50aWNhdGUgZGF0YScpXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRoaXMuX2F1dGhUYWcgPSB0YWdcbiAgfVxuICB0aGlzLl9jaXBoZXIuc2NydWIoKVxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5nZXRBdXRoVGFnID0gZnVuY3Rpb24gZ2V0QXV0aFRhZyAoKSB7XG4gIGlmICghdGhpcy5fZGVjcnlwdCAmJiBCdWZmZXIuaXNCdWZmZXIodGhpcy5fYXV0aFRhZykpIHtcbiAgICByZXR1cm4gdGhpcy5fYXV0aFRhZ1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignQXR0ZW1wdGluZyB0byBnZXQgYXV0aCB0YWcgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxuICB9XG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLnNldEF1dGhUYWcgPSBmdW5jdGlvbiBzZXRBdXRoVGFnICh0YWcpIHtcbiAgaWYgKHRoaXMuX2RlY3J5cHQpIHtcbiAgICB0aGlzLl9hdXRoVGFnID0gdGFnXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIHNldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG4gIH1cbn1cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuc2V0QUFEID0gZnVuY3Rpb24gc2V0QUFEIChidWYpIHtcbiAgaWYgKCF0aGlzLl9jYWxsZWQpIHtcbiAgICB0aGlzLl9naGFzaC51cGRhdGUoYnVmKVxuICAgIHRoaXMuX2FsZW4gKz0gYnVmLmxlbmd0aFxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignQXR0ZW1wdGluZyB0byBzZXQgQUFEIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbiAgfVxufVxuZnVuY3Rpb24geG9yVGVzdCAoYSwgYikge1xuICB2YXIgb3V0ID0gMFxuICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSB7XG4gICAgb3V0KytcbiAgfVxuICB2YXIgbGVuID0gTWF0aC5taW4oYS5sZW5ndGgsIGIubGVuZ3RoKVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXQgKz0gKGFbaV0gXiBiW2ldKVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsInZhciBjaXBoZXJzID0gcmVxdWlyZSgnLi9lbmNyeXB0ZXInKVxuZXhwb3J0cy5jcmVhdGVDaXBoZXIgPSBleHBvcnRzLkNpcGhlciA9IGNpcGhlcnMuY3JlYXRlQ2lwaGVyXG5leHBvcnRzLmNyZWF0ZUNpcGhlcml2ID0gZXhwb3J0cy5DaXBoZXJpdiA9IGNpcGhlcnMuY3JlYXRlQ2lwaGVyaXZcbnZhciBkZWNpcGhlcnMgPSByZXF1aXJlKCcuL2RlY3J5cHRlcicpXG5leHBvcnRzLmNyZWF0ZURlY2lwaGVyID0gZXhwb3J0cy5EZWNpcGhlciA9IGRlY2lwaGVycy5jcmVhdGVEZWNpcGhlclxuZXhwb3J0cy5jcmVhdGVEZWNpcGhlcml2ID0gZXhwb3J0cy5EZWNpcGhlcml2ID0gZGVjaXBoZXJzLmNyZWF0ZURlY2lwaGVyaXZcbnZhciBtb2RlcyA9IHJlcXVpcmUoJy4vbW9kZXMnKVxuZnVuY3Rpb24gZ2V0Q2lwaGVycyAoKSB7XG4gIHJldHVybiBPYmplY3Qua2V5cyhtb2Rlcylcbn1cbmV4cG9ydHMubGlzdENpcGhlcnMgPSBleHBvcnRzLmdldENpcGhlcnMgPSBnZXRDaXBoZXJzXG4iLCJ2YXIgYWVzID0gcmVxdWlyZSgnLi9hZXMnKVxudmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ2NpcGhlci1iYXNlJylcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBtb2RlcyA9IHJlcXVpcmUoJy4vbW9kZXMnKVxudmFyIFN0cmVhbUNpcGhlciA9IHJlcXVpcmUoJy4vc3RyZWFtQ2lwaGVyJylcbnZhciBBdXRoQ2lwaGVyID0gcmVxdWlyZSgnLi9hdXRoQ2lwaGVyJylcbnZhciBlYnRrID0gcmVxdWlyZSgnZXZwX2J5dGVzdG9rZXknKVxuXG5pbmhlcml0cyhEZWNpcGhlciwgVHJhbnNmb3JtKVxuZnVuY3Rpb24gRGVjaXBoZXIgKG1vZGUsIGtleSwgaXYpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIERlY2lwaGVyKSkge1xuICAgIHJldHVybiBuZXcgRGVjaXBoZXIobW9kZSwga2V5LCBpdilcbiAgfVxuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuICB0aGlzLl9jYWNoZSA9IG5ldyBTcGxpdHRlcigpXG4gIHRoaXMuX2xhc3QgPSB2b2lkIDBcbiAgdGhpcy5fY2lwaGVyID0gbmV3IGFlcy5BRVMoa2V5KVxuICB0aGlzLl9wcmV2ID0gbmV3IEJ1ZmZlcihpdi5sZW5ndGgpXG4gIGl2LmNvcHkodGhpcy5fcHJldilcbiAgdGhpcy5fbW9kZSA9IG1vZGVcbiAgdGhpcy5fYXV0b3BhZGRpbmcgPSB0cnVlXG59XG5EZWNpcGhlci5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuX2NhY2hlLmFkZChkYXRhKVxuICB2YXIgY2h1bmtcbiAgdmFyIHRoaW5nXG4gIHZhciBvdXQgPSBbXVxuICB3aGlsZSAoKGNodW5rID0gdGhpcy5fY2FjaGUuZ2V0KHRoaXMuX2F1dG9wYWRkaW5nKSkpIHtcbiAgICB0aGluZyA9IHRoaXMuX21vZGUuZGVjcnlwdCh0aGlzLCBjaHVuaylcbiAgICBvdXQucHVzaCh0aGluZylcbiAgfVxuICByZXR1cm4gQnVmZmVyLmNvbmNhdChvdXQpXG59XG5EZWNpcGhlci5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICB2YXIgY2h1bmsgPSB0aGlzLl9jYWNoZS5mbHVzaCgpXG4gIGlmICh0aGlzLl9hdXRvcGFkZGluZykge1xuICAgIHJldHVybiB1bnBhZCh0aGlzLl9tb2RlLmRlY3J5cHQodGhpcywgY2h1bmspKVxuICB9IGVsc2UgaWYgKGNodW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhIG5vdCBtdWx0aXBsZSBvZiBibG9jayBsZW5ndGgnKVxuICB9XG59XG5EZWNpcGhlci5wcm90b3R5cGUuc2V0QXV0b1BhZGRpbmcgPSBmdW5jdGlvbiAoc2V0VG8pIHtcbiAgdGhpcy5fYXV0b3BhZGRpbmcgPSAhIXNldFRvXG4gIHJldHVybiB0aGlzXG59XG5mdW5jdGlvbiBTcGxpdHRlciAoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTcGxpdHRlcikpIHtcbiAgICByZXR1cm4gbmV3IFNwbGl0dGVyKClcbiAgfVxuICB0aGlzLmNhY2hlID0gbmV3IEJ1ZmZlcignJylcbn1cblNwbGl0dGVyLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB0aGlzLmNhY2hlID0gQnVmZmVyLmNvbmNhdChbdGhpcy5jYWNoZSwgZGF0YV0pXG59XG5cblNwbGl0dGVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoYXV0b1BhZGRpbmcpIHtcbiAgdmFyIG91dFxuICBpZiAoYXV0b1BhZGRpbmcpIHtcbiAgICBpZiAodGhpcy5jYWNoZS5sZW5ndGggPiAxNikge1xuICAgICAgb3V0ID0gdGhpcy5jYWNoZS5zbGljZSgwLCAxNilcbiAgICAgIHRoaXMuY2FjaGUgPSB0aGlzLmNhY2hlLnNsaWNlKDE2KVxuICAgICAgcmV0dXJuIG91dFxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAodGhpcy5jYWNoZS5sZW5ndGggPj0gMTYpIHtcbiAgICAgIG91dCA9IHRoaXMuY2FjaGUuc2xpY2UoMCwgMTYpXG4gICAgICB0aGlzLmNhY2hlID0gdGhpcy5jYWNoZS5zbGljZSgxNilcbiAgICAgIHJldHVybiBvdXRcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bGxcbn1cblNwbGl0dGVyLnByb3RvdHlwZS5mbHVzaCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGVcbiAgfVxufVxuZnVuY3Rpb24gdW5wYWQgKGxhc3QpIHtcbiAgdmFyIHBhZGRlZCA9IGxhc3RbMTVdXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IHBhZGRlZCkge1xuICAgIGlmIChsYXN0WyhpICsgKDE2IC0gcGFkZGVkKSldICE9PSBwYWRkZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5hYmxlIHRvIGRlY3J5cHQgZGF0YScpXG4gICAgfVxuICB9XG4gIGlmIChwYWRkZWQgPT09IDE2KSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgcmV0dXJuIGxhc3Quc2xpY2UoMCwgMTYgLSBwYWRkZWQpXG59XG5cbnZhciBtb2RlbGlzdCA9IHtcbiAgRUNCOiByZXF1aXJlKCcuL21vZGVzL2VjYicpLFxuICBDQkM6IHJlcXVpcmUoJy4vbW9kZXMvY2JjJyksXG4gIENGQjogcmVxdWlyZSgnLi9tb2Rlcy9jZmInKSxcbiAgQ0ZCODogcmVxdWlyZSgnLi9tb2Rlcy9jZmI4JyksXG4gIENGQjE6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiMScpLFxuICBPRkI6IHJlcXVpcmUoJy4vbW9kZXMvb2ZiJyksXG4gIENUUjogcmVxdWlyZSgnLi9tb2Rlcy9jdHInKSxcbiAgR0NNOiByZXF1aXJlKCcuL21vZGVzL2N0cicpXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZURlY2lwaGVyaXYgKHN1aXRlLCBwYXNzd29yZCwgaXYpIHtcbiAgdmFyIGNvbmZpZyA9IG1vZGVzW3N1aXRlLnRvTG93ZXJDYXNlKCldXG4gIGlmICghY29uZmlnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBzdWl0ZSB0eXBlJylcbiAgfVxuICBpZiAodHlwZW9mIGl2ID09PSAnc3RyaW5nJykge1xuICAgIGl2ID0gbmV3IEJ1ZmZlcihpdilcbiAgfVxuICBpZiAodHlwZW9mIHBhc3N3b3JkID09PSAnc3RyaW5nJykge1xuICAgIHBhc3N3b3JkID0gbmV3IEJ1ZmZlcihwYXNzd29yZClcbiAgfVxuICBpZiAocGFzc3dvcmQubGVuZ3RoICE9PSBjb25maWcua2V5IC8gOCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQga2V5IGxlbmd0aCAnICsgcGFzc3dvcmQubGVuZ3RoKVxuICB9XG4gIGlmIChpdi5sZW5ndGggIT09IGNvbmZpZy5pdikge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgaXYgbGVuZ3RoICcgKyBpdi5sZW5ndGgpXG4gIH1cbiAgaWYgKGNvbmZpZy50eXBlID09PSAnc3RyZWFtJykge1xuICAgIHJldHVybiBuZXcgU3RyZWFtQ2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2LCB0cnVlKVxuICB9IGVsc2UgaWYgKGNvbmZpZy50eXBlID09PSAnYXV0aCcpIHtcbiAgICByZXR1cm4gbmV3IEF1dGhDaXBoZXIobW9kZWxpc3RbY29uZmlnLm1vZGVdLCBwYXNzd29yZCwgaXYsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG5ldyBEZWNpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdilcbn1cblxuZnVuY3Rpb24gY3JlYXRlRGVjaXBoZXIgKHN1aXRlLCBwYXNzd29yZCkge1xuICB2YXIgY29uZmlnID0gbW9kZXNbc3VpdGUudG9Mb3dlckNhc2UoKV1cbiAgaWYgKCFjb25maWcpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuICB9XG4gIHZhciBrZXlzID0gZWJ0ayhwYXNzd29yZCwgZmFsc2UsIGNvbmZpZy5rZXksIGNvbmZpZy5pdilcbiAgcmV0dXJuIGNyZWF0ZURlY2lwaGVyaXYoc3VpdGUsIGtleXMua2V5LCBrZXlzLml2KVxufVxuZXhwb3J0cy5jcmVhdGVEZWNpcGhlciA9IGNyZWF0ZURlY2lwaGVyXG5leHBvcnRzLmNyZWF0ZURlY2lwaGVyaXYgPSBjcmVhdGVEZWNpcGhlcml2XG4iLCJ2YXIgYWVzID0gcmVxdWlyZSgnLi9hZXMnKVxudmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ2NpcGhlci1iYXNlJylcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBtb2RlcyA9IHJlcXVpcmUoJy4vbW9kZXMnKVxudmFyIGVidGsgPSByZXF1aXJlKCdldnBfYnl0ZXN0b2tleScpXG52YXIgU3RyZWFtQ2lwaGVyID0gcmVxdWlyZSgnLi9zdHJlYW1DaXBoZXInKVxudmFyIEF1dGhDaXBoZXIgPSByZXF1aXJlKCcuL2F1dGhDaXBoZXInKVxuaW5oZXJpdHMoQ2lwaGVyLCBUcmFuc2Zvcm0pXG5mdW5jdGlvbiBDaXBoZXIgKG1vZGUsIGtleSwgaXYpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIENpcGhlcikpIHtcbiAgICByZXR1cm4gbmV3IENpcGhlcihtb2RlLCBrZXksIGl2KVxuICB9XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG4gIHRoaXMuX2NhY2hlID0gbmV3IFNwbGl0dGVyKClcbiAgdGhpcy5fY2lwaGVyID0gbmV3IGFlcy5BRVMoa2V5KVxuICB0aGlzLl9wcmV2ID0gbmV3IEJ1ZmZlcihpdi5sZW5ndGgpXG4gIGl2LmNvcHkodGhpcy5fcHJldilcbiAgdGhpcy5fbW9kZSA9IG1vZGVcbiAgdGhpcy5fYXV0b3BhZGRpbmcgPSB0cnVlXG59XG5DaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB0aGlzLl9jYWNoZS5hZGQoZGF0YSlcbiAgdmFyIGNodW5rXG4gIHZhciB0aGluZ1xuICB2YXIgb3V0ID0gW11cbiAgd2hpbGUgKChjaHVuayA9IHRoaXMuX2NhY2hlLmdldCgpKSkge1xuICAgIHRoaW5nID0gdGhpcy5fbW9kZS5lbmNyeXB0KHRoaXMsIGNodW5rKVxuICAgIG91dC5wdXNoKHRoaW5nKVxuICB9XG4gIHJldHVybiBCdWZmZXIuY29uY2F0KG91dClcbn1cbkNpcGhlci5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICB2YXIgY2h1bmsgPSB0aGlzLl9jYWNoZS5mbHVzaCgpXG4gIGlmICh0aGlzLl9hdXRvcGFkZGluZykge1xuICAgIGNodW5rID0gdGhpcy5fbW9kZS5lbmNyeXB0KHRoaXMsIGNodW5rKVxuICAgIHRoaXMuX2NpcGhlci5zY3J1YigpXG4gICAgcmV0dXJuIGNodW5rXG4gIH0gZWxzZSBpZiAoY2h1bmsudG9TdHJpbmcoJ2hleCcpICE9PSAnMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAnKSB7XG4gICAgdGhpcy5fY2lwaGVyLnNjcnViKClcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RhdGEgbm90IG11bHRpcGxlIG9mIGJsb2NrIGxlbmd0aCcpXG4gIH1cbn1cbkNpcGhlci5wcm90b3R5cGUuc2V0QXV0b1BhZGRpbmcgPSBmdW5jdGlvbiAoc2V0VG8pIHtcbiAgdGhpcy5fYXV0b3BhZGRpbmcgPSAhIXNldFRvXG4gIHJldHVybiB0aGlzXG59XG5cbmZ1bmN0aW9uIFNwbGl0dGVyICgpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNwbGl0dGVyKSkge1xuICAgIHJldHVybiBuZXcgU3BsaXR0ZXIoKVxuICB9XG4gIHRoaXMuY2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxufVxuU3BsaXR0ZXIucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuY2FjaGUgPSBCdWZmZXIuY29uY2F0KFt0aGlzLmNhY2hlLCBkYXRhXSlcbn1cblxuU3BsaXR0ZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoID4gMTUpIHtcbiAgICB2YXIgb3V0ID0gdGhpcy5jYWNoZS5zbGljZSgwLCAxNilcbiAgICB0aGlzLmNhY2hlID0gdGhpcy5jYWNoZS5zbGljZSgxNilcbiAgICByZXR1cm4gb3V0XG4gIH1cbiAgcmV0dXJuIG51bGxcbn1cblNwbGl0dGVyLnByb3RvdHlwZS5mbHVzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGxlbiA9IDE2IC0gdGhpcy5jYWNoZS5sZW5ndGhcbiAgdmFyIHBhZEJ1ZmYgPSBuZXcgQnVmZmVyKGxlbilcblxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBwYWRCdWZmLndyaXRlVUludDgobGVuLCBpKVxuICB9XG4gIHZhciBvdXQgPSBCdWZmZXIuY29uY2F0KFt0aGlzLmNhY2hlLCBwYWRCdWZmXSlcbiAgcmV0dXJuIG91dFxufVxudmFyIG1vZGVsaXN0ID0ge1xuICBFQ0I6IHJlcXVpcmUoJy4vbW9kZXMvZWNiJyksXG4gIENCQzogcmVxdWlyZSgnLi9tb2Rlcy9jYmMnKSxcbiAgQ0ZCOiByZXF1aXJlKCcuL21vZGVzL2NmYicpLFxuICBDRkI4OiByZXF1aXJlKCcuL21vZGVzL2NmYjgnKSxcbiAgQ0ZCMTogcmVxdWlyZSgnLi9tb2Rlcy9jZmIxJyksXG4gIE9GQjogcmVxdWlyZSgnLi9tb2Rlcy9vZmInKSxcbiAgQ1RSOiByZXF1aXJlKCcuL21vZGVzL2N0cicpLFxuICBHQ006IHJlcXVpcmUoJy4vbW9kZXMvY3RyJylcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2lwaGVyaXYgKHN1aXRlLCBwYXNzd29yZCwgaXYpIHtcbiAgdmFyIGNvbmZpZyA9IG1vZGVzW3N1aXRlLnRvTG93ZXJDYXNlKCldXG4gIGlmICghY29uZmlnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBzdWl0ZSB0eXBlJylcbiAgfVxuICBpZiAodHlwZW9mIGl2ID09PSAnc3RyaW5nJykge1xuICAgIGl2ID0gbmV3IEJ1ZmZlcihpdilcbiAgfVxuICBpZiAodHlwZW9mIHBhc3N3b3JkID09PSAnc3RyaW5nJykge1xuICAgIHBhc3N3b3JkID0gbmV3IEJ1ZmZlcihwYXNzd29yZClcbiAgfVxuICBpZiAocGFzc3dvcmQubGVuZ3RoICE9PSBjb25maWcua2V5IC8gOCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQga2V5IGxlbmd0aCAnICsgcGFzc3dvcmQubGVuZ3RoKVxuICB9XG4gIGlmIChpdi5sZW5ndGggIT09IGNvbmZpZy5pdikge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgaXYgbGVuZ3RoICcgKyBpdi5sZW5ndGgpXG4gIH1cbiAgaWYgKGNvbmZpZy50eXBlID09PSAnc3RyZWFtJykge1xuICAgIHJldHVybiBuZXcgU3RyZWFtQ2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2KVxuICB9IGVsc2UgaWYgKGNvbmZpZy50eXBlID09PSAnYXV0aCcpIHtcbiAgICByZXR1cm4gbmV3IEF1dGhDaXBoZXIobW9kZWxpc3RbY29uZmlnLm1vZGVdLCBwYXNzd29yZCwgaXYpXG4gIH1cbiAgcmV0dXJuIG5ldyBDaXBoZXIobW9kZWxpc3RbY29uZmlnLm1vZGVdLCBwYXNzd29yZCwgaXYpXG59XG5mdW5jdGlvbiBjcmVhdGVDaXBoZXIgKHN1aXRlLCBwYXNzd29yZCkge1xuICB2YXIgY29uZmlnID0gbW9kZXNbc3VpdGUudG9Mb3dlckNhc2UoKV1cbiAgaWYgKCFjb25maWcpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuICB9XG4gIHZhciBrZXlzID0gZWJ0ayhwYXNzd29yZCwgZmFsc2UsIGNvbmZpZy5rZXksIGNvbmZpZy5pdilcbiAgcmV0dXJuIGNyZWF0ZUNpcGhlcml2KHN1aXRlLCBrZXlzLmtleSwga2V5cy5pdilcbn1cblxuZXhwb3J0cy5jcmVhdGVDaXBoZXJpdiA9IGNyZWF0ZUNpcGhlcml2XG5leHBvcnRzLmNyZWF0ZUNpcGhlciA9IGNyZWF0ZUNpcGhlclxuIiwidmFyIHplcm9zID0gbmV3IEJ1ZmZlcigxNilcbnplcm9zLmZpbGwoMClcbm1vZHVsZS5leHBvcnRzID0gR0hBU0hcbmZ1bmN0aW9uIEdIQVNIIChrZXkpIHtcbiAgdGhpcy5oID0ga2V5XG4gIHRoaXMuc3RhdGUgPSBuZXcgQnVmZmVyKDE2KVxuICB0aGlzLnN0YXRlLmZpbGwoMClcbiAgdGhpcy5jYWNoZSA9IG5ldyBCdWZmZXIoJycpXG59XG4vLyBmcm9tIGh0dHA6Ly9iaXR3aXNlc2hpZnRsZWZ0LmdpdGh1Yi5pby9zamNsL2RvYy9zeW1ib2xzL3NyYy9jb3JlX2djbS5qcy5odG1sXG4vLyBieSBKdWhvIFbDpGjDpC1IZXJ0dHVhXG5HSEFTSC5wcm90b3R5cGUuZ2hhc2ggPSBmdW5jdGlvbiAoYmxvY2spIHtcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgYmxvY2subGVuZ3RoKSB7XG4gICAgdGhpcy5zdGF0ZVtpXSBePSBibG9ja1tpXVxuICB9XG4gIHRoaXMuX211bHRpcGx5KClcbn1cblxuR0hBU0gucHJvdG90eXBlLl9tdWx0aXBseSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIFZpID0gdG9BcnJheSh0aGlzLmgpXG4gIHZhciBaaSA9IFswLCAwLCAwLCAwXVxuICB2YXIgaiwgeGksIGxzYl9WaVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCAxMjgpIHtcbiAgICB4aSA9ICh0aGlzLnN0YXRlW35+KGkgLyA4KV0gJiAoMSA8PCAoNyAtIGkgJSA4KSkpICE9PSAwXG4gICAgaWYgKHhpKSB7XG4gICAgICAvLyBaX2krMSA9IFpfaSBeIFZfaVxuICAgICAgWmkgPSB4b3IoWmksIFZpKVxuICAgIH1cblxuICAgIC8vIFN0b3JlIHRoZSB2YWx1ZSBvZiBMU0IoVl9pKVxuICAgIGxzYl9WaSA9IChWaVszXSAmIDEpICE9PSAwXG5cbiAgICAvLyBWX2krMSA9IFZfaSA+PiAxXG4gICAgZm9yIChqID0gMzsgaiA+IDA7IGotLSkge1xuICAgICAgVmlbal0gPSAoVmlbal0gPj4+IDEpIHwgKChWaVtqIC0gMV0gJiAxKSA8PCAzMSlcbiAgICB9XG4gICAgVmlbMF0gPSBWaVswXSA+Pj4gMVxuXG4gICAgLy8gSWYgTFNCKFZfaSkgaXMgMSwgVl9pKzEgPSAoVl9pID4+IDEpIF4gUlxuICAgIGlmIChsc2JfVmkpIHtcbiAgICAgIFZpWzBdID0gVmlbMF0gXiAoMHhlMSA8PCAyNClcbiAgICB9XG4gIH1cbiAgdGhpcy5zdGF0ZSA9IGZyb21BcnJheShaaSlcbn1cbkdIQVNILnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoYnVmKSB7XG4gIHRoaXMuY2FjaGUgPSBCdWZmZXIuY29uY2F0KFt0aGlzLmNhY2hlLCBidWZdKVxuICB2YXIgY2h1bmtcbiAgd2hpbGUgKHRoaXMuY2FjaGUubGVuZ3RoID49IDE2KSB7XG4gICAgY2h1bmsgPSB0aGlzLmNhY2hlLnNsaWNlKDAsIDE2KVxuICAgIHRoaXMuY2FjaGUgPSB0aGlzLmNhY2hlLnNsaWNlKDE2KVxuICAgIHRoaXMuZ2hhc2goY2h1bmspXG4gIH1cbn1cbkdIQVNILnByb3RvdHlwZS5maW5hbCA9IGZ1bmN0aW9uIChhYmwsIGJsKSB7XG4gIGlmICh0aGlzLmNhY2hlLmxlbmd0aCkge1xuICAgIHRoaXMuZ2hhc2goQnVmZmVyLmNvbmNhdChbdGhpcy5jYWNoZSwgemVyb3NdLCAxNikpXG4gIH1cbiAgdGhpcy5naGFzaChmcm9tQXJyYXkoW1xuICAgIDAsIGFibCxcbiAgICAwLCBibFxuICBdKSlcbiAgcmV0dXJuIHRoaXMuc3RhdGVcbn1cblxuZnVuY3Rpb24gdG9BcnJheSAoYnVmKSB7XG4gIHJldHVybiBbXG4gICAgYnVmLnJlYWRVSW50MzJCRSgwKSxcbiAgICBidWYucmVhZFVJbnQzMkJFKDQpLFxuICAgIGJ1Zi5yZWFkVUludDMyQkUoOCksXG4gICAgYnVmLnJlYWRVSW50MzJCRSgxMilcbiAgXVxufVxuZnVuY3Rpb24gZnJvbUFycmF5IChvdXQpIHtcbiAgb3V0ID0gb3V0Lm1hcChmaXh1cF91aW50MzIpXG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKDE2KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMF0sIDApXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsxXSwgNClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzJdLCA4KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbM10sIDEyKVxuICByZXR1cm4gYnVmXG59XG52YXIgdWludF9tYXggPSBNYXRoLnBvdygyLCAzMilcbmZ1bmN0aW9uIGZpeHVwX3VpbnQzMiAoeCkge1xuICB2YXIgcmV0LCB4X3Bvc1xuICByZXQgPSB4ID4gdWludF9tYXggfHwgeCA8IDAgPyAoeF9wb3MgPSBNYXRoLmFicyh4KSAlIHVpbnRfbWF4LCB4IDwgMCA/IHVpbnRfbWF4IC0geF9wb3MgOiB4X3BvcykgOiB4XG4gIHJldHVybiByZXRcbn1cbmZ1bmN0aW9uIHhvciAoYSwgYikge1xuICByZXR1cm4gW1xuICAgIGFbMF0gXiBiWzBdLFxuICAgIGFbMV0gXiBiWzFdLFxuICAgIGFbMl0gXiBiWzJdLFxuICAgIGFbM10gXiBiWzNdXG4gIF1cbn1cbiIsImV4cG9ydHNbJ2Flcy0xMjgtZWNiJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMTI4LFxuICBpdjogMCxcbiAgbW9kZTogJ0VDQicsXG4gIHR5cGU6ICdibG9jaydcbn1cbmV4cG9ydHNbJ2Flcy0xOTItZWNiJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMTkyLFxuICBpdjogMCxcbiAgbW9kZTogJ0VDQicsXG4gIHR5cGU6ICdibG9jaydcbn1cbmV4cG9ydHNbJ2Flcy0yNTYtZWNiJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMjU2LFxuICBpdjogMCxcbiAgbW9kZTogJ0VDQicsXG4gIHR5cGU6ICdibG9jaydcbn1cbmV4cG9ydHNbJ2Flcy0xMjgtY2JjJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMTI4LFxuICBpdjogMTYsXG4gIG1vZGU6ICdDQkMnLFxuICB0eXBlOiAnYmxvY2snXG59XG5leHBvcnRzWydhZXMtMTkyLWNiYyddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDE5MixcbiAgaXY6IDE2LFxuICBtb2RlOiAnQ0JDJyxcbiAgdHlwZTogJ2Jsb2NrJ1xufVxuZXhwb3J0c1snYWVzLTI1Ni1jYmMnXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAyNTYsXG4gIGl2OiAxNixcbiAgbW9kZTogJ0NCQycsXG4gIHR5cGU6ICdibG9jaydcbn1cbmV4cG9ydHNbJ2FlczEyOCddID0gZXhwb3J0c1snYWVzLTEyOC1jYmMnXVxuZXhwb3J0c1snYWVzMTkyJ10gPSBleHBvcnRzWydhZXMtMTkyLWNiYyddXG5leHBvcnRzWydhZXMyNTYnXSA9IGV4cG9ydHNbJ2Flcy0yNTYtY2JjJ11cbmV4cG9ydHNbJ2Flcy0xMjgtY2ZiJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMTI4LFxuICBpdjogMTYsXG4gIG1vZGU6ICdDRkInLFxuICB0eXBlOiAnc3RyZWFtJ1xufVxuZXhwb3J0c1snYWVzLTE5Mi1jZmInXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxOTIsXG4gIGl2OiAxNixcbiAgbW9kZTogJ0NGQicsXG4gIHR5cGU6ICdzdHJlYW0nXG59XG5leHBvcnRzWydhZXMtMjU2LWNmYiddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDI1NixcbiAgaXY6IDE2LFxuICBtb2RlOiAnQ0ZCJyxcbiAgdHlwZTogJ3N0cmVhbSdcbn1cbmV4cG9ydHNbJ2Flcy0xMjgtY2ZiOCddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDEyOCxcbiAgaXY6IDE2LFxuICBtb2RlOiAnQ0ZCOCcsXG4gIHR5cGU6ICdzdHJlYW0nXG59XG5leHBvcnRzWydhZXMtMTkyLWNmYjgnXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxOTIsXG4gIGl2OiAxNixcbiAgbW9kZTogJ0NGQjgnLFxuICB0eXBlOiAnc3RyZWFtJ1xufVxuZXhwb3J0c1snYWVzLTI1Ni1jZmI4J10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMjU2LFxuICBpdjogMTYsXG4gIG1vZGU6ICdDRkI4JyxcbiAgdHlwZTogJ3N0cmVhbSdcbn1cbmV4cG9ydHNbJ2Flcy0xMjgtY2ZiMSddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDEyOCxcbiAgaXY6IDE2LFxuICBtb2RlOiAnQ0ZCMScsXG4gIHR5cGU6ICdzdHJlYW0nXG59XG5leHBvcnRzWydhZXMtMTkyLWNmYjEnXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxOTIsXG4gIGl2OiAxNixcbiAgbW9kZTogJ0NGQjEnLFxuICB0eXBlOiAnc3RyZWFtJ1xufVxuZXhwb3J0c1snYWVzLTI1Ni1jZmIxJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMjU2LFxuICBpdjogMTYsXG4gIG1vZGU6ICdDRkIxJyxcbiAgdHlwZTogJ3N0cmVhbSdcbn1cbmV4cG9ydHNbJ2Flcy0xMjgtb2ZiJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMTI4LFxuICBpdjogMTYsXG4gIG1vZGU6ICdPRkInLFxuICB0eXBlOiAnc3RyZWFtJ1xufVxuZXhwb3J0c1snYWVzLTE5Mi1vZmInXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxOTIsXG4gIGl2OiAxNixcbiAgbW9kZTogJ09GQicsXG4gIHR5cGU6ICdzdHJlYW0nXG59XG5leHBvcnRzWydhZXMtMjU2LW9mYiddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDI1NixcbiAgaXY6IDE2LFxuICBtb2RlOiAnT0ZCJyxcbiAgdHlwZTogJ3N0cmVhbSdcbn1cbmV4cG9ydHNbJ2Flcy0xMjgtY3RyJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMTI4LFxuICBpdjogMTYsXG4gIG1vZGU6ICdDVFInLFxuICB0eXBlOiAnc3RyZWFtJ1xufVxuZXhwb3J0c1snYWVzLTE5Mi1jdHInXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxOTIsXG4gIGl2OiAxNixcbiAgbW9kZTogJ0NUUicsXG4gIHR5cGU6ICdzdHJlYW0nXG59XG5leHBvcnRzWydhZXMtMjU2LWN0ciddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDI1NixcbiAgaXY6IDE2LFxuICBtb2RlOiAnQ1RSJyxcbiAgdHlwZTogJ3N0cmVhbSdcbn1cbmV4cG9ydHNbJ2Flcy0xMjgtZ2NtJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMTI4LFxuICBpdjogMTIsXG4gIG1vZGU6ICdHQ00nLFxuICB0eXBlOiAnYXV0aCdcbn1cbmV4cG9ydHNbJ2Flcy0xOTItZ2NtJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMTkyLFxuICBpdjogMTIsXG4gIG1vZGU6ICdHQ00nLFxuICB0eXBlOiAnYXV0aCdcbn1cbmV4cG9ydHNbJ2Flcy0yNTYtZ2NtJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMjU2LFxuICBpdjogMTIsXG4gIG1vZGU6ICdHQ00nLFxuICB0eXBlOiAnYXV0aCdcbn1cbiIsInZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcblxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGJsb2NrKSB7XG4gIHZhciBkYXRhID0geG9yKGJsb2NrLCBzZWxmLl9wcmV2KVxuXG4gIHNlbGYuX3ByZXYgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKGRhdGEpXG4gIHJldHVybiBzZWxmLl9wcmV2XG59XG5cbmV4cG9ydHMuZGVjcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBibG9jaykge1xuICB2YXIgcGFkID0gc2VsZi5fcHJldlxuXG4gIHNlbGYuX3ByZXYgPSBibG9ja1xuICB2YXIgb3V0ID0gc2VsZi5fY2lwaGVyLmRlY3J5cHRCbG9jayhibG9jaylcblxuICByZXR1cm4geG9yKG91dCwgcGFkKVxufVxuIiwidmFyIHhvciA9IHJlcXVpcmUoJ2J1ZmZlci14b3InKVxuXG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgZGF0YSwgZGVjcnlwdCkge1xuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcignJylcbiAgdmFyIGxlblxuXG4gIHdoaWxlIChkYXRhLmxlbmd0aCkge1xuICAgIGlmIChzZWxmLl9jYWNoZS5sZW5ndGggPT09IDApIHtcbiAgICAgIHNlbGYuX2NhY2hlID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhzZWxmLl9wcmV2KVxuICAgICAgc2VsZi5fcHJldiA9IG5ldyBCdWZmZXIoJycpXG4gICAgfVxuXG4gICAgaWYgKHNlbGYuX2NhY2hlLmxlbmd0aCA8PSBkYXRhLmxlbmd0aCkge1xuICAgICAgbGVuID0gc2VsZi5fY2FjaGUubGVuZ3RoXG4gICAgICBvdXQgPSBCdWZmZXIuY29uY2F0KFtvdXQsIGVuY3J5cHRTdGFydChzZWxmLCBkYXRhLnNsaWNlKDAsIGxlbiksIGRlY3J5cHQpXSlcbiAgICAgIGRhdGEgPSBkYXRhLnNsaWNlKGxlbilcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0ID0gQnVmZmVyLmNvbmNhdChbb3V0LCBlbmNyeXB0U3RhcnQoc2VsZiwgZGF0YSwgZGVjcnlwdCldKVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gb3V0XG59XG5mdW5jdGlvbiBlbmNyeXB0U3RhcnQgKHNlbGYsIGRhdGEsIGRlY3J5cHQpIHtcbiAgdmFyIGxlbiA9IGRhdGEubGVuZ3RoXG4gIHZhciBvdXQgPSB4b3IoZGF0YSwgc2VsZi5fY2FjaGUpXG4gIHNlbGYuX2NhY2hlID0gc2VsZi5fY2FjaGUuc2xpY2UobGVuKVxuICBzZWxmLl9wcmV2ID0gQnVmZmVyLmNvbmNhdChbc2VsZi5fcHJldiwgZGVjcnlwdCA/IGRhdGEgOiBvdXRdKVxuICByZXR1cm4gb3V0XG59XG4iLCJmdW5jdGlvbiBlbmNyeXB0Qnl0ZSAoc2VsZiwgYnl0ZVBhcmFtLCBkZWNyeXB0KSB7XG4gIHZhciBwYWRcbiAgdmFyIGkgPSAtMVxuICB2YXIgbGVuID0gOFxuICB2YXIgb3V0ID0gMFxuICB2YXIgYml0LCB2YWx1ZVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgcGFkID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhzZWxmLl9wcmV2KVxuICAgIGJpdCA9IChieXRlUGFyYW0gJiAoMSA8PCAoNyAtIGkpKSkgPyAweDgwIDogMFxuICAgIHZhbHVlID0gcGFkWzBdIF4gYml0XG4gICAgb3V0ICs9ICgodmFsdWUgJiAweDgwKSA+PiAoaSAlIDgpKVxuICAgIHNlbGYuX3ByZXYgPSBzaGlmdEluKHNlbGYuX3ByZXYsIGRlY3J5cHQgPyBiaXQgOiB2YWx1ZSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgY2h1bmssIGRlY3J5cHQpIHtcbiAgdmFyIGxlbiA9IGNodW5rLmxlbmd0aFxuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihsZW4pXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dFtpXSA9IGVuY3J5cHRCeXRlKHNlbGYsIGNodW5rW2ldLCBkZWNyeXB0KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbmZ1bmN0aW9uIHNoaWZ0SW4gKGJ1ZmZlciwgdmFsdWUpIHtcbiAgdmFyIGxlbiA9IGJ1ZmZlci5sZW5ndGhcbiAgdmFyIGkgPSAtMVxuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihidWZmZXIubGVuZ3RoKVxuICBidWZmZXIgPSBCdWZmZXIuY29uY2F0KFtidWZmZXIsIG5ldyBCdWZmZXIoW3ZhbHVlXSldKVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgb3V0W2ldID0gYnVmZmVyW2ldIDw8IDEgfCBidWZmZXJbaSArIDFdID4+ICg3KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsImZ1bmN0aW9uIGVuY3J5cHRCeXRlIChzZWxmLCBieXRlUGFyYW0sIGRlY3J5cHQpIHtcbiAgdmFyIHBhZCA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soc2VsZi5fcHJldilcbiAgdmFyIG91dCA9IHBhZFswXSBeIGJ5dGVQYXJhbVxuICBzZWxmLl9wcmV2ID0gQnVmZmVyLmNvbmNhdChbc2VsZi5fcHJldi5zbGljZSgxKSwgbmV3IEJ1ZmZlcihbZGVjcnlwdCA/IGJ5dGVQYXJhbSA6IG91dF0pXSlcbiAgcmV0dXJuIG91dFxufVxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGNodW5rLCBkZWNyeXB0KSB7XG4gIHZhciBsZW4gPSBjaHVuay5sZW5ndGhcbiAgdmFyIG91dCA9IG5ldyBCdWZmZXIobGVuKVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXRbaV0gPSBlbmNyeXB0Qnl0ZShzZWxmLCBjaHVua1tpXSwgZGVjcnlwdClcbiAgfVxuICByZXR1cm4gb3V0XG59XG4iLCJ2YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG5cbmZ1bmN0aW9uIGluY3IzMiAoaXYpIHtcbiAgdmFyIGxlbiA9IGl2Lmxlbmd0aFxuICB2YXIgaXRlbVxuICB3aGlsZSAobGVuLS0pIHtcbiAgICBpdGVtID0gaXYucmVhZFVJbnQ4KGxlbilcbiAgICBpZiAoaXRlbSA9PT0gMjU1KSB7XG4gICAgICBpdi53cml0ZVVJbnQ4KDAsIGxlbilcbiAgICB9IGVsc2Uge1xuICAgICAgaXRlbSsrXG4gICAgICBpdi53cml0ZVVJbnQ4KGl0ZW0sIGxlbilcbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGdldEJsb2NrIChzZWxmKSB7XG4gIHZhciBvdXQgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gIGluY3IzMihzZWxmLl9wcmV2KVxuICByZXR1cm4gb3V0XG59XG5cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBjaHVuaykge1xuICB3aGlsZSAoc2VsZi5fY2FjaGUubGVuZ3RoIDwgY2h1bmsubGVuZ3RoKSB7XG4gICAgc2VsZi5fY2FjaGUgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9jYWNoZSwgZ2V0QmxvY2soc2VsZildKVxuICB9XG4gIHZhciBwYWQgPSBzZWxmLl9jYWNoZS5zbGljZSgwLCBjaHVuay5sZW5ndGgpXG4gIHNlbGYuX2NhY2hlID0gc2VsZi5fY2FjaGUuc2xpY2UoY2h1bmsubGVuZ3RoKVxuICByZXR1cm4geG9yKGNodW5rLCBwYWQpXG59XG4iLCJleHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgYmxvY2spIHtcbiAgcmV0dXJuIHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soYmxvY2spXG59XG5leHBvcnRzLmRlY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgYmxvY2spIHtcbiAgcmV0dXJuIHNlbGYuX2NpcGhlci5kZWNyeXB0QmxvY2soYmxvY2spXG59XG4iLCJ2YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG5cbmZ1bmN0aW9uIGdldEJsb2NrIChzZWxmKSB7XG4gIHNlbGYuX3ByZXYgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gIHJldHVybiBzZWxmLl9wcmV2XG59XG5cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBjaHVuaykge1xuICB3aGlsZSAoc2VsZi5fY2FjaGUubGVuZ3RoIDwgY2h1bmsubGVuZ3RoKSB7XG4gICAgc2VsZi5fY2FjaGUgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9jYWNoZSwgZ2V0QmxvY2soc2VsZildKVxuICB9XG5cbiAgdmFyIHBhZCA9IHNlbGYuX2NhY2hlLnNsaWNlKDAsIGNodW5rLmxlbmd0aClcbiAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jYWNoZS5zbGljZShjaHVuay5sZW5ndGgpXG4gIHJldHVybiB4b3IoY2h1bmssIHBhZClcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24geG9yIChhLCBiKSB7XG4gIHZhciBsZW5ndGggPSBNYXRoLm1pbihhLmxlbmd0aCwgYi5sZW5ndGgpXG4gIHZhciBidWZmZXIgPSBuZXcgQnVmZmVyKGxlbmd0aClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgYnVmZmVyW2ldID0gYVtpXSBeIGJbaV1cbiAgfVxuXG4gIHJldHVybiBidWZmZXJcbn1cbiIsInZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdzdHJlYW0nKS5UcmFuc2Zvcm1cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXInKS5TdHJpbmdEZWNvZGVyXG5tb2R1bGUuZXhwb3J0cyA9IENpcGhlckJhc2VcbmluaGVyaXRzKENpcGhlckJhc2UsIFRyYW5zZm9ybSlcbmZ1bmN0aW9uIENpcGhlckJhc2UgKGhhc2hNb2RlKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG4gIHRoaXMuaGFzaE1vZGUgPSB0eXBlb2YgaGFzaE1vZGUgPT09ICdzdHJpbmcnXG4gIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgdGhpc1toYXNoTW9kZV0gPSB0aGlzLl9maW5hbE9yRGlnZXN0XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5maW5hbCA9IHRoaXMuX2ZpbmFsT3JEaWdlc3RcbiAgfVxuICB0aGlzLl9kZWNvZGVyID0gbnVsbFxuICB0aGlzLl9lbmNvZGluZyA9IG51bGxcbn1cbkNpcGhlckJhc2UucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhLCBpbnB1dEVuYywgb3V0cHV0RW5jKSB7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICBkYXRhID0gbmV3IEJ1ZmZlcihkYXRhLCBpbnB1dEVuYylcbiAgfVxuICB2YXIgb3V0RGF0YSA9IHRoaXMuX3VwZGF0ZShkYXRhKVxuICBpZiAodGhpcy5oYXNoTW9kZSkge1xuICAgIHJldHVybiB0aGlzXG4gIH1cbiAgaWYgKG91dHB1dEVuYykge1xuICAgIG91dERhdGEgPSB0aGlzLl90b1N0cmluZyhvdXREYXRhLCBvdXRwdXRFbmMpXG4gIH1cbiAgcmV0dXJuIG91dERhdGFcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuc2V0QXV0b1BhZGRpbmcgPSBmdW5jdGlvbiAoKSB7fVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5nZXRBdXRoVGFnID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3RyeWluZyB0byBnZXQgYXV0aCB0YWcgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBdXRoVGFnID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3RyeWluZyB0byBzZXQgYXV0aCB0YWcgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBQUQgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIHNldCBhYWQgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24gKGRhdGEsIF8sIG5leHQpIHtcbiAgdmFyIGVyclxuICB0cnkge1xuICAgIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgICB0aGlzLl91cGRhdGUoZGF0YSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wdXNoKHRoaXMuX3VwZGF0ZShkYXRhKSlcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBlcnIgPSBlXG4gIH0gZmluYWxseSB7XG4gICAgbmV4dChlcnIpXG4gIH1cbn1cbkNpcGhlckJhc2UucHJvdG90eXBlLl9mbHVzaCA9IGZ1bmN0aW9uIChkb25lKSB7XG4gIHZhciBlcnJcbiAgdHJ5IHtcbiAgICB0aGlzLnB1c2godGhpcy5fZmluYWwoKSlcbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfSBmaW5hbGx5IHtcbiAgICBkb25lKGVycilcbiAgfVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZpbmFsT3JEaWdlc3QgPSBmdW5jdGlvbiAob3V0cHV0RW5jKSB7XG4gIHZhciBvdXREYXRhID0gdGhpcy5fZmluYWwoKSB8fCBuZXcgQnVmZmVyKCcnKVxuICBpZiAob3V0cHV0RW5jKSB7XG4gICAgb3V0RGF0YSA9IHRoaXMuX3RvU3RyaW5nKG91dERhdGEsIG91dHB1dEVuYywgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb3V0RGF0YVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fdG9TdHJpbmcgPSBmdW5jdGlvbiAodmFsdWUsIGVuYywgZmluYWwpIHtcbiAgaWYgKCF0aGlzLl9kZWNvZGVyKSB7XG4gICAgdGhpcy5fZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKGVuYylcbiAgICB0aGlzLl9lbmNvZGluZyA9IGVuY1xuICB9XG4gIGlmICh0aGlzLl9lbmNvZGluZyAhPT0gZW5jKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjYW5cXCd0IHN3aXRjaCBlbmNvZGluZ3MnKVxuICB9XG4gIHZhciBvdXQgPSB0aGlzLl9kZWNvZGVyLndyaXRlKHZhbHVlKVxuICBpZiAoZmluYWwpIHtcbiAgICBvdXQgKz0gdGhpcy5fZGVjb2Rlci5lbmQoKVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsInZhciBhZXMgPSByZXF1aXJlKCcuL2FlcycpXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxuXG5pbmhlcml0cyhTdHJlYW1DaXBoZXIsIFRyYW5zZm9ybSlcbm1vZHVsZS5leHBvcnRzID0gU3RyZWFtQ2lwaGVyXG5mdW5jdGlvbiBTdHJlYW1DaXBoZXIgKG1vZGUsIGtleSwgaXYsIGRlY3J5cHQpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFN0cmVhbUNpcGhlcikpIHtcbiAgICByZXR1cm4gbmV3IFN0cmVhbUNpcGhlcihtb2RlLCBrZXksIGl2KVxuICB9XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG4gIHRoaXMuX2NpcGhlciA9IG5ldyBhZXMuQUVTKGtleSlcbiAgdGhpcy5fcHJldiA9IG5ldyBCdWZmZXIoaXYubGVuZ3RoKVxuICB0aGlzLl9jYWNoZSA9IG5ldyBCdWZmZXIoJycpXG4gIHRoaXMuX3NlY0NhY2hlID0gbmV3IEJ1ZmZlcignJylcbiAgdGhpcy5fZGVjcnlwdCA9IGRlY3J5cHRcbiAgaXYuY29weSh0aGlzLl9wcmV2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gIHJldHVybiB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmssIHRoaXMuX2RlY3J5cHQpXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fY2lwaGVyLnNjcnViKClcbn1cbiIsInZhciBDaXBoZXJCYXNlID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGRlcyA9IHJlcXVpcmUoJ2Rlcy5qcycpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG5cbnZhciBtb2RlcyA9IHtcbiAgJ2Rlcy1lZGUzLWNiYyc6IGRlcy5DQkMuaW5zdGFudGlhdGUoZGVzLkVERSksXG4gICdkZXMtZWRlMyc6IGRlcy5FREUsXG4gICdkZXMtZWRlLWNiYyc6IGRlcy5DQkMuaW5zdGFudGlhdGUoZGVzLkVERSksXG4gICdkZXMtZWRlJzogZGVzLkVERSxcbiAgJ2Rlcy1jYmMnOiBkZXMuQ0JDLmluc3RhbnRpYXRlKGRlcy5ERVMpLFxuICAnZGVzLWVjYic6IGRlcy5ERVNcbn1cbm1vZGVzLmRlcyA9IG1vZGVzWydkZXMtY2JjJ11cbm1vZGVzLmRlczMgPSBtb2Rlc1snZGVzLWVkZTMtY2JjJ11cbm1vZHVsZS5leHBvcnRzID0gREVTXG5pbmhlcml0cyhERVMsIENpcGhlckJhc2UpXG5mdW5jdGlvbiBERVMgKG9wdHMpIHtcbiAgQ2lwaGVyQmFzZS5jYWxsKHRoaXMpXG4gIHZhciBtb2RlTmFtZSA9IG9wdHMubW9kZS50b0xvd2VyQ2FzZSgpXG4gIHZhciBtb2RlID0gbW9kZXNbbW9kZU5hbWVdXG4gIHZhciB0eXBlXG4gIGlmIChvcHRzLmRlY3J5cHQpIHtcbiAgICB0eXBlID0gJ2RlY3J5cHQnXG4gIH0gZWxzZSB7XG4gICAgdHlwZSA9ICdlbmNyeXB0J1xuICB9XG4gIHZhciBrZXkgPSBvcHRzLmtleVxuICBpZiAobW9kZU5hbWUgPT09ICdkZXMtZWRlJyB8fCBtb2RlTmFtZSA9PT0gJ2Rlcy1lZGUtY2JjJykge1xuICAgIGtleSA9IEJ1ZmZlci5jb25jYXQoW2tleSwga2V5LnNsaWNlKDAsIDgpXSlcbiAgfVxuICB2YXIgaXYgPSBvcHRzLml2XG4gIHRoaXMuX2RlcyA9IG1vZGUuY3JlYXRlKHtcbiAgICBrZXk6IGtleSxcbiAgICBpdjogaXYsXG4gICAgdHlwZTogdHlwZVxuICB9KVxufVxuREVTLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgcmV0dXJuIG5ldyBCdWZmZXIodGhpcy5fZGVzLnVwZGF0ZShkYXRhKSlcbn1cbkRFUy5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gbmV3IEJ1ZmZlcih0aGlzLl9kZXMuZmluYWwoKSlcbn1cbiIsImV4cG9ydHNbJ2Rlcy1lY2InXSA9IHtcbiAga2V5OiA4LFxuICBpdjogMFxufVxuZXhwb3J0c1snZGVzLWNiYyddID0gZXhwb3J0cy5kZXMgPSB7XG4gIGtleTogOCxcbiAgaXY6IDhcbn1cbmV4cG9ydHNbJ2Rlcy1lZGUzLWNiYyddID0gZXhwb3J0cy5kZXMzID0ge1xuICBrZXk6IDI0LFxuICBpdjogOFxufVxuZXhwb3J0c1snZGVzLWVkZTMnXSA9IHtcbiAga2V5OiAyNCxcbiAgaXY6IDBcbn1cbmV4cG9ydHNbJ2Rlcy1lZGUtY2JjJ10gPSB7XG4gIGtleTogMTYsXG4gIGl2OiA4XG59XG5leHBvcnRzWydkZXMtZWRlJ10gPSB7XG4gIGtleTogMTYsXG4gIGl2OiAwXG59XG4iLCJ2YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnc3RyZWFtJykuVHJhbnNmb3JtXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgU3RyaW5nRGVjb2RlciA9IHJlcXVpcmUoJ3N0cmluZ19kZWNvZGVyJykuU3RyaW5nRGVjb2RlclxubW9kdWxlLmV4cG9ydHMgPSBDaXBoZXJCYXNlXG5pbmhlcml0cyhDaXBoZXJCYXNlLCBUcmFuc2Zvcm0pXG5mdW5jdGlvbiBDaXBoZXJCYXNlIChoYXNoTW9kZSkge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuICB0aGlzLmhhc2hNb2RlID0gdHlwZW9mIGhhc2hNb2RlID09PSAnc3RyaW5nJ1xuICBpZiAodGhpcy5oYXNoTW9kZSkge1xuICAgIHRoaXNbaGFzaE1vZGVdID0gdGhpcy5fZmluYWxPckRpZ2VzdFxuICB9IGVsc2Uge1xuICAgIHRoaXMuZmluYWwgPSB0aGlzLl9maW5hbE9yRGlnZXN0XG4gIH1cbiAgdGhpcy5fZGVjb2RlciA9IG51bGxcbiAgdGhpcy5fZW5jb2RpbmcgPSBudWxsXG59XG5DaXBoZXJCYXNlLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSwgaW5wdXRFbmMsIG91dHB1dEVuYykge1xuICBpZiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgZGF0YSA9IG5ldyBCdWZmZXIoZGF0YSwgaW5wdXRFbmMpXG4gIH1cbiAgdmFyIG91dERhdGEgPSB0aGlzLl91cGRhdGUoZGF0YSlcbiAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICByZXR1cm4gdGhpc1xuICB9XG4gIGlmIChvdXRwdXRFbmMpIHtcbiAgICBvdXREYXRhID0gdGhpcy5fdG9TdHJpbmcob3V0RGF0YSwgb3V0cHV0RW5jKVxuICB9XG4gIHJldHVybiBvdXREYXRhXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEF1dG9QYWRkaW5nID0gZnVuY3Rpb24gKCkge31cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuZ2V0QXV0aFRhZyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gZ2V0IGF1dGggdGFnIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuc2V0QXV0aFRhZyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gc2V0IGF1dGggdGFnIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuc2V0QUFEID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3RyeWluZyB0byBzZXQgYWFkIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChkYXRhLCBfLCBuZXh0KSB7XG4gIHZhciBlcnJcbiAgdHJ5IHtcbiAgICBpZiAodGhpcy5oYXNoTW9kZSkge1xuICAgICAgdGhpcy5fdXBkYXRlKGRhdGEpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHVzaCh0aGlzLl91cGRhdGUoZGF0YSkpXG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyID0gZVxuICB9IGZpbmFsbHkge1xuICAgIG5leHQoZXJyKVxuICB9XG59XG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fZmx1c2ggPSBmdW5jdGlvbiAoZG9uZSkge1xuICB2YXIgZXJyXG4gIHRyeSB7XG4gICAgdGhpcy5wdXNoKHRoaXMuX2ZpbmFsKCkpXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBlcnIgPSBlXG4gIH0gZmluYWxseSB7XG4gICAgZG9uZShlcnIpXG4gIH1cbn1cbkNpcGhlckJhc2UucHJvdG90eXBlLl9maW5hbE9yRGlnZXN0ID0gZnVuY3Rpb24gKG91dHB1dEVuYykge1xuICB2YXIgb3V0RGF0YSA9IHRoaXMuX2ZpbmFsKCkgfHwgbmV3IEJ1ZmZlcignJylcbiAgaWYgKG91dHB1dEVuYykge1xuICAgIG91dERhdGEgPSB0aGlzLl90b1N0cmluZyhvdXREYXRhLCBvdXRwdXRFbmMsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG91dERhdGFcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX3RvU3RyaW5nID0gZnVuY3Rpb24gKHZhbHVlLCBlbmMsIGZpbmFsKSB7XG4gIGlmICghdGhpcy5fZGVjb2Rlcikge1xuICAgIHRoaXMuX2RlY29kZXIgPSBuZXcgU3RyaW5nRGVjb2RlcihlbmMpXG4gICAgdGhpcy5fZW5jb2RpbmcgPSBlbmNcbiAgfVxuICBpZiAodGhpcy5fZW5jb2RpbmcgIT09IGVuYykge1xuICAgIHRocm93IG5ldyBFcnJvcignY2FuXFwndCBzd2l0Y2ggZW5jb2RpbmdzJylcbiAgfVxuICB2YXIgb3V0ID0gdGhpcy5fZGVjb2Rlci53cml0ZSh2YWx1ZSlcbiAgaWYgKGZpbmFsKSB7XG4gICAgb3V0ICs9IHRoaXMuX2RlY29kZXIuZW5kKClcbiAgfVxuICByZXR1cm4gb3V0XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMudXRpbHMgPSByZXF1aXJlKCcuL2Rlcy91dGlscycpO1xuZXhwb3J0cy5DaXBoZXIgPSByZXF1aXJlKCcuL2Rlcy9jaXBoZXInKTtcbmV4cG9ydHMuREVTID0gcmVxdWlyZSgnLi9kZXMvZGVzJyk7XG5leHBvcnRzLkNCQyA9IHJlcXVpcmUoJy4vZGVzL2NiYycpO1xuZXhwb3J0cy5FREUgPSByZXF1aXJlKCcuL2Rlcy9lZGUnKTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbnZhciBwcm90byA9IHt9O1xuXG5mdW5jdGlvbiBDQkNTdGF0ZShpdikge1xuICBhc3NlcnQuZXF1YWwoaXYubGVuZ3RoLCA4LCAnSW52YWxpZCBJViBsZW5ndGgnKTtcblxuICB0aGlzLml2ID0gbmV3IEFycmF5KDgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuaXYubGVuZ3RoOyBpKyspXG4gICAgdGhpcy5pdltpXSA9IGl2W2ldO1xufVxuXG5mdW5jdGlvbiBpbnN0YW50aWF0ZShCYXNlKSB7XG4gIGZ1bmN0aW9uIENCQyhvcHRpb25zKSB7XG4gICAgQmFzZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuICAgIHRoaXMuX2NiY0luaXQoKTtcbiAgfVxuICBpbmhlcml0cyhDQkMsIEJhc2UpO1xuXG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvdG8pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICBDQkMucHJvdG90eXBlW2tleV0gPSBwcm90b1trZXldO1xuICB9XG5cbiAgQ0JDLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShvcHRpb25zKSB7XG4gICAgcmV0dXJuIG5ldyBDQkMob3B0aW9ucyk7XG4gIH07XG5cbiAgcmV0dXJuIENCQztcbn1cblxuZXhwb3J0cy5pbnN0YW50aWF0ZSA9IGluc3RhbnRpYXRlO1xuXG5wcm90by5fY2JjSW5pdCA9IGZ1bmN0aW9uIF9jYmNJbml0KCkge1xuICB2YXIgc3RhdGUgPSBuZXcgQ0JDU3RhdGUodGhpcy5vcHRpb25zLml2KTtcbiAgdGhpcy5fY2JjU3RhdGUgPSBzdGF0ZTtcbn07XG5cbnByb3RvLl91cGRhdGUgPSBmdW5jdGlvbiBfdXBkYXRlKGlucCwgaW5PZmYsIG91dCwgb3V0T2ZmKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2NiY1N0YXRlO1xuICB2YXIgc3VwZXJQcm90byA9IHRoaXMuY29uc3RydWN0b3Iuc3VwZXJfLnByb3RvdHlwZTtcblxuICB2YXIgaXYgPSBzdGF0ZS5pdjtcbiAgaWYgKHRoaXMudHlwZSA9PT0gJ2VuY3J5cHQnKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJsb2NrU2l6ZTsgaSsrKVxuICAgICAgaXZbaV0gXj0gaW5wW2luT2ZmICsgaV07XG5cbiAgICBzdXBlclByb3RvLl91cGRhdGUuY2FsbCh0aGlzLCBpdiwgMCwgb3V0LCBvdXRPZmYpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJsb2NrU2l6ZTsgaSsrKVxuICAgICAgaXZbaV0gPSBvdXRbb3V0T2ZmICsgaV07XG4gIH0gZWxzZSB7XG4gICAgc3VwZXJQcm90by5fdXBkYXRlLmNhbGwodGhpcywgaW5wLCBpbk9mZiwgb3V0LCBvdXRPZmYpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJsb2NrU2l6ZTsgaSsrKVxuICAgICAgb3V0W291dE9mZiArIGldIF49IGl2W2ldO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJsb2NrU2l6ZTsgaSsrKVxuICAgICAgaXZbaV0gPSBpbnBbaW5PZmYgKyBpXTtcbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcblxuZnVuY3Rpb24gQ2lwaGVyKG9wdGlvbnMpIHtcbiAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcblxuICB0aGlzLnR5cGUgPSB0aGlzLm9wdGlvbnMudHlwZTtcbiAgdGhpcy5ibG9ja1NpemUgPSA4O1xuICB0aGlzLl9pbml0KCk7XG5cbiAgdGhpcy5idWZmZXIgPSBuZXcgQXJyYXkodGhpcy5ibG9ja1NpemUpO1xuICB0aGlzLmJ1ZmZlck9mZiA9IDA7XG59XG5tb2R1bGUuZXhwb3J0cyA9IENpcGhlcjtcblxuQ2lwaGVyLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uIF9pbml0KCkge1xuICAvLyBNaWdodCBiZSBvdmVycmlkZWRcbn07XG5cbkNpcGhlci5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKGRhdGEpIHtcbiAgaWYgKGRhdGEubGVuZ3RoID09PSAwKVxuICAgIHJldHVybiBbXTtcblxuICBpZiAodGhpcy50eXBlID09PSAnZGVjcnlwdCcpXG4gICAgcmV0dXJuIHRoaXMuX3VwZGF0ZURlY3J5cHQoZGF0YSk7XG4gIGVsc2VcbiAgICByZXR1cm4gdGhpcy5fdXBkYXRlRW5jcnlwdChkYXRhKTtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuX2J1ZmZlciA9IGZ1bmN0aW9uIF9idWZmZXIoZGF0YSwgb2ZmKSB7XG4gIC8vIEFwcGVuZCBkYXRhIHRvIGJ1ZmZlclxuICB2YXIgbWluID0gTWF0aC5taW4odGhpcy5idWZmZXIubGVuZ3RoIC0gdGhpcy5idWZmZXJPZmYsIGRhdGEubGVuZ3RoIC0gb2ZmKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtaW47IGkrKylcbiAgICB0aGlzLmJ1ZmZlclt0aGlzLmJ1ZmZlck9mZiArIGldID0gZGF0YVtvZmYgKyBpXTtcbiAgdGhpcy5idWZmZXJPZmYgKz0gbWluO1xuXG4gIC8vIFNoaWZ0IG5leHRcbiAgcmV0dXJuIG1pbjtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuX2ZsdXNoQnVmZmVyID0gZnVuY3Rpb24gX2ZsdXNoQnVmZmVyKG91dCwgb2ZmKSB7XG4gIHRoaXMuX3VwZGF0ZSh0aGlzLmJ1ZmZlciwgMCwgb3V0LCBvZmYpO1xuICB0aGlzLmJ1ZmZlck9mZiA9IDA7XG4gIHJldHVybiB0aGlzLmJsb2NrU2l6ZTtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuX3VwZGF0ZUVuY3J5cHQgPSBmdW5jdGlvbiBfdXBkYXRlRW5jcnlwdChkYXRhKSB7XG4gIHZhciBpbnB1dE9mZiA9IDA7XG4gIHZhciBvdXRwdXRPZmYgPSAwO1xuXG4gIHZhciBjb3VudCA9ICgodGhpcy5idWZmZXJPZmYgKyBkYXRhLmxlbmd0aCkgLyB0aGlzLmJsb2NrU2l6ZSkgfCAwO1xuICB2YXIgb3V0ID0gbmV3IEFycmF5KGNvdW50ICogdGhpcy5ibG9ja1NpemUpO1xuXG4gIGlmICh0aGlzLmJ1ZmZlck9mZiAhPT0gMCkge1xuICAgIGlucHV0T2ZmICs9IHRoaXMuX2J1ZmZlcihkYXRhLCBpbnB1dE9mZik7XG5cbiAgICBpZiAodGhpcy5idWZmZXJPZmYgPT09IHRoaXMuYnVmZmVyLmxlbmd0aClcbiAgICAgIG91dHB1dE9mZiArPSB0aGlzLl9mbHVzaEJ1ZmZlcihvdXQsIG91dHB1dE9mZik7XG4gIH1cblxuICAvLyBXcml0ZSBibG9ja3NcbiAgdmFyIG1heCA9IGRhdGEubGVuZ3RoIC0gKChkYXRhLmxlbmd0aCAtIGlucHV0T2ZmKSAlIHRoaXMuYmxvY2tTaXplKTtcbiAgZm9yICg7IGlucHV0T2ZmIDwgbWF4OyBpbnB1dE9mZiArPSB0aGlzLmJsb2NrU2l6ZSkge1xuICAgIHRoaXMuX3VwZGF0ZShkYXRhLCBpbnB1dE9mZiwgb3V0LCBvdXRwdXRPZmYpO1xuICAgIG91dHB1dE9mZiArPSB0aGlzLmJsb2NrU2l6ZTtcbiAgfVxuXG4gIC8vIFF1ZXVlIHJlc3RcbiAgZm9yICg7IGlucHV0T2ZmIDwgZGF0YS5sZW5ndGg7IGlucHV0T2ZmKyssIHRoaXMuYnVmZmVyT2ZmKyspXG4gICAgdGhpcy5idWZmZXJbdGhpcy5idWZmZXJPZmZdID0gZGF0YVtpbnB1dE9mZl07XG5cbiAgcmV0dXJuIG91dDtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuX3VwZGF0ZURlY3J5cHQgPSBmdW5jdGlvbiBfdXBkYXRlRGVjcnlwdChkYXRhKSB7XG4gIHZhciBpbnB1dE9mZiA9IDA7XG4gIHZhciBvdXRwdXRPZmYgPSAwO1xuXG4gIHZhciBjb3VudCA9IE1hdGguY2VpbCgodGhpcy5idWZmZXJPZmYgKyBkYXRhLmxlbmd0aCkgLyB0aGlzLmJsb2NrU2l6ZSkgLSAxO1xuICB2YXIgb3V0ID0gbmV3IEFycmF5KGNvdW50ICogdGhpcy5ibG9ja1NpemUpO1xuXG4gIC8vIFRPRE8oaW5kdXRueSk6IG9wdGltaXplIGl0LCB0aGlzIGlzIGZhciBmcm9tIG9wdGltYWxcbiAgZm9yICg7IGNvdW50ID4gMDsgY291bnQtLSkge1xuICAgIGlucHV0T2ZmICs9IHRoaXMuX2J1ZmZlcihkYXRhLCBpbnB1dE9mZik7XG4gICAgb3V0cHV0T2ZmICs9IHRoaXMuX2ZsdXNoQnVmZmVyKG91dCwgb3V0cHV0T2ZmKTtcbiAgfVxuXG4gIC8vIEJ1ZmZlciByZXN0IG9mIHRoZSBpbnB1dFxuICBpbnB1dE9mZiArPSB0aGlzLl9idWZmZXIoZGF0YSwgaW5wdXRPZmYpO1xuXG4gIHJldHVybiBvdXQ7XG59O1xuXG5DaXBoZXIucHJvdG90eXBlLmZpbmFsID0gZnVuY3Rpb24gZmluYWwoYnVmZmVyKSB7XG4gIHZhciBmaXJzdDtcbiAgaWYgKGJ1ZmZlcilcbiAgICBmaXJzdCA9IHRoaXMudXBkYXRlKGJ1ZmZlcik7XG5cbiAgdmFyIGxhc3Q7XG4gIGlmICh0aGlzLnR5cGUgPT09ICdlbmNyeXB0JylcbiAgICBsYXN0ID0gdGhpcy5fZmluYWxFbmNyeXB0KCk7XG4gIGVsc2VcbiAgICBsYXN0ID0gdGhpcy5fZmluYWxEZWNyeXB0KCk7XG5cbiAgaWYgKGZpcnN0KVxuICAgIHJldHVybiBmaXJzdC5jb25jYXQobGFzdCk7XG4gIGVsc2VcbiAgICByZXR1cm4gbGFzdDtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuX3BhZCA9IGZ1bmN0aW9uIF9wYWQoYnVmZmVyLCBvZmYpIHtcbiAgaWYgKG9mZiA9PT0gMClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgd2hpbGUgKG9mZiA8IGJ1ZmZlci5sZW5ndGgpXG4gICAgYnVmZmVyW29mZisrXSA9IDA7XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5DaXBoZXIucHJvdG90eXBlLl9maW5hbEVuY3J5cHQgPSBmdW5jdGlvbiBfZmluYWxFbmNyeXB0KCkge1xuICBpZiAoIXRoaXMuX3BhZCh0aGlzLmJ1ZmZlciwgdGhpcy5idWZmZXJPZmYpKVxuICAgIHJldHVybiBbXTtcblxuICB2YXIgb3V0ID0gbmV3IEFycmF5KHRoaXMuYmxvY2tTaXplKTtcbiAgdGhpcy5fdXBkYXRlKHRoaXMuYnVmZmVyLCAwLCBvdXQsIDApO1xuICByZXR1cm4gb3V0O1xufTtcblxuQ2lwaGVyLnByb3RvdHlwZS5fdW5wYWQgPSBmdW5jdGlvbiBfdW5wYWQoYnVmZmVyKSB7XG4gIHJldHVybiBidWZmZXI7XG59O1xuXG5DaXBoZXIucHJvdG90eXBlLl9maW5hbERlY3J5cHQgPSBmdW5jdGlvbiBfZmluYWxEZWNyeXB0KCkge1xuICBhc3NlcnQuZXF1YWwodGhpcy5idWZmZXJPZmYsIHRoaXMuYmxvY2tTaXplLCAnTm90IGVub3VnaCBkYXRhIHRvIGRlY3J5cHQnKTtcbiAgdmFyIG91dCA9IG5ldyBBcnJheSh0aGlzLmJsb2NrU2l6ZSk7XG4gIHRoaXMuX2ZsdXNoQnVmZmVyKG91dCwgMCk7XG5cbiAgcmV0dXJuIHRoaXMuX3VucGFkKG91dCk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxudmFyIGRlcyA9IHJlcXVpcmUoJy4uL2RlcycpO1xudmFyIHV0aWxzID0gZGVzLnV0aWxzO1xudmFyIENpcGhlciA9IGRlcy5DaXBoZXI7XG5cbmZ1bmN0aW9uIERFU1N0YXRlKCkge1xuICB0aGlzLnRtcCA9IG5ldyBBcnJheSgyKTtcbiAgdGhpcy5rZXlzID0gbnVsbDtcbn1cblxuZnVuY3Rpb24gREVTKG9wdGlvbnMpIHtcbiAgQ2lwaGVyLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgdmFyIHN0YXRlID0gbmV3IERFU1N0YXRlKCk7XG4gIHRoaXMuX2Rlc1N0YXRlID0gc3RhdGU7XG5cbiAgdGhpcy5kZXJpdmVLZXlzKHN0YXRlLCBvcHRpb25zLmtleSk7XG59XG5pbmhlcml0cyhERVMsIENpcGhlcik7XG5tb2R1bGUuZXhwb3J0cyA9IERFUztcblxuREVTLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShvcHRpb25zKSB7XG4gIHJldHVybiBuZXcgREVTKG9wdGlvbnMpO1xufTtcblxudmFyIHNoaWZ0VGFibGUgPSBbXG4gIDEsIDEsIDIsIDIsIDIsIDIsIDIsIDIsXG4gIDEsIDIsIDIsIDIsIDIsIDIsIDIsIDFcbl07XG5cbkRFUy5wcm90b3R5cGUuZGVyaXZlS2V5cyA9IGZ1bmN0aW9uIGRlcml2ZUtleXMoc3RhdGUsIGtleSkge1xuICBzdGF0ZS5rZXlzID0gbmV3IEFycmF5KDE2ICogMik7XG5cbiAgYXNzZXJ0LmVxdWFsKGtleS5sZW5ndGgsIHRoaXMuYmxvY2tTaXplLCAnSW52YWxpZCBrZXkgbGVuZ3RoJyk7XG5cbiAgdmFyIGtMID0gdXRpbHMucmVhZFVJbnQzMkJFKGtleSwgMCk7XG4gIHZhciBrUiA9IHV0aWxzLnJlYWRVSW50MzJCRShrZXksIDQpO1xuXG4gIHV0aWxzLnBjMShrTCwga1IsIHN0YXRlLnRtcCwgMCk7XG4gIGtMID0gc3RhdGUudG1wWzBdO1xuICBrUiA9IHN0YXRlLnRtcFsxXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdGF0ZS5rZXlzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgdmFyIHNoaWZ0ID0gc2hpZnRUYWJsZVtpID4+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+IDA7XG59O1xuXG5leHBvcnRzLnBhZFNwbGl0ID0gZnVuY3Rpb24gcGFkU3BsaXQobnVtLCBzaXplLCBncm91cCkge1xuICB2YXIgc3RyID0gbnVtLnRvU3RyaW5nKDIpO1xuICB3aGlsZSAoc3RyLmxlbmd0aCA8IHNpemUpXG4gICAgc3RyID0gJzAnICsgc3RyO1xuXG4gIHZhciBvdXQgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyBpICs9IGdyb3VwKVxuICAgIG91dC5wdXNoKHN0ci5zbGljZShpLCBpICsgZ3JvdXApKTtcbiAgcmV0dXJuIG91dC5qb2luKCcgJyk7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBhc3NlcnQ7XG5cbmZ1bmN0aW9uIGFzc2VydCh2YWwsIG1zZykge1xuICBpZiAoIXZhbClcbiAgICB0aHJvdyBuZXcgRXJyb3IobXNnIHx8ICdBc3NlcnRpb24gZmFpbGVkJyk7XG59XG5cbmFzc2VydC5lcXVhbCA9IGZ1bmN0aW9uIGFzc2VydEVxdWFsKGwsIHIsIG1zZykge1xuICBpZiAobCAhPSByKVxuICAgIHRocm93IG5ldyBFcnJvcihtc2cgfHwgKCdBc3NlcnRpb24gZmFpbGVkOiAnICsgbCArICcgIT0gJyArIHIpKTtcbn07XG4iLCJ2YXIgbWQ1ID0gcmVxdWlyZSgnY3JlYXRlLWhhc2gvbWQ1Jylcbm1vZHVsZS5leHBvcnRzID0gRVZQX0J5dGVzVG9LZXlcbmZ1bmN0aW9uIEVWUF9CeXRlc1RvS2V5IChwYXNzd29yZCwgc2FsdCwga2V5TGVuLCBpdkxlbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihwYXNzd29yZCkpIHtcbiAgICBwYXNzd29yZCA9IG5ldyBCdWZmZXIocGFzc3dvcmQsICdiaW5hcnknKVxuICB9XG4gIGlmIChzYWx0ICYmICFCdWZmZXIuaXNCdWZmZXIoc2FsdCkpIHtcbiAgICBzYWx0ID0gbmV3IEJ1ZmZlcihzYWx0LCAnYmluYXJ5JylcbiAgfVxuICBrZXlMZW4gPSBrZXlMZW4gLyA4XG4gIGl2TGVuID0gaXZMZW4gfHwgMFxuICB2YXIga2kgPSAwXG4gIHZhciBpaSA9IDBcbiAgdmFyIGtleSA9IG5ldyBCdWZmZXIoa2V5TGVuKVxuICB2YXIgaXYgPSBuZXcgQnVmZmVyKGl2TGVuKVxuICB2YXIgYWRkbWQgPSAwXG4gIHZhciBtZF9idWZcbiAgdmFyIGlcbiAgdmFyIGJ1ZnMgPSBbXVxuICB3aGlsZSAodHJ1ZSkge1xuICAgIGlmIChhZGRtZCsrID4gMCkge1xuICAgICAgYnVmcy5wdXNoKG1kX2J1ZilcbiAgICB9XG4gICAgYnVmcy5wdXNoKHBhc3N3b3JkKVxuICAgIGlmIChzYWx0KSB7XG4gICAgICBidWZzLnB1c2goc2FsdClcbiAgICB9XG4gICAgbWRfYnVmID0gbWQ1KEJ1ZmZlci5jb25jYXQoYnVmcykpXG4gICAgYnVmcyA9IFtdXG4gICAgaSA9IDBcbiAgICBpZiAoa2V5TGVuID4gMCkge1xuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgaWYgKGtleUxlbiA9PT0gMCkge1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGkgPT09IG1kX2J1Zi5sZW5ndGgpIHtcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICAgIGtleVtraSsrXSA9IG1kX2J1ZltpXVxuICAgICAgICBrZXlMZW4tLVxuICAgICAgICBpKytcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGl2TGVuID4gMCAmJiBpICE9PSBtZF9idWYubGVuZ3RoKSB7XG4gICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBpZiAoaXZMZW4gPT09IDApIHtcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICAgIGlmIChpID09PSBtZF9idWYubGVuZ3RoKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBpdltpaSsrXSA9IG1kX2J1ZltpXVxuICAgICAgICBpdkxlbi0tXG4gICAgICAgIGkrK1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoa2V5TGVuID09PSAwICYmIGl2TGVuID09PSAwKSB7XG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuICBmb3IgKGkgPSAwOyBpIDwgbWRfYnVmLmxlbmd0aDsgaSsrKSB7XG4gICAgbWRfYnVmW2ldID0gMFxuICB9XG4gIHJldHVybiB7XG4gICAga2V5OiBrZXksXG4gICAgaXY6IGl2XG4gIH1cbn1cbiIsIid1c2Ugc3RyaWN0J1xuZXhwb3J0c1snUlNBLVNIQTIyNCddID0gZXhwb3J0cy5zaGEyMjRXaXRoUlNBRW5jcnlwdGlvbiA9IHtcbiAgc2lnbjogJ3JzYScsXG4gIGhhc2g6ICdzaGEyMjQnLFxuICBpZDogbmV3IEJ1ZmZlcignMzAyZDMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjA0MDUwMDA0MWMnLCAnaGV4Jylcbn1cbmV4cG9ydHNbJ1JTQS1TSEEyNTYnXSA9IGV4cG9ydHMuc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24gPSB7XG4gIHNpZ246ICdyc2EnLFxuICBoYXNoOiAnc2hhMjU2JyxcbiAgaWQ6IG5ldyBCdWZmZXIoJzMwMzEzMDBkMDYwOTYwODY0ODAxNjUwMzA0MDIwMTA1MDAwNDIwJywgJ2hleCcpXG59XG5leHBvcnRzWydSU0EtU0hBMzg0J10gPSBleHBvcnRzLnNoYTM4NFdpdGhSU0FFbmNyeXB0aW9uID0ge1xuICBzaWduOiAncnNhJyxcbiAgaGFzaDogJ3NoYTM4NCcsXG4gIGlkOiBuZXcgQnVmZmVyKCczMDQxMzAwZDA2MDk2MDg2NDgwMTY1MDMwNDAyMDIwNTAwMDQzMCcsICdoZXgnKVxufVxuZXhwb3J0c1snUlNBLVNIQTUxMiddID0gZXhwb3J0cy5zaGE1MTJXaXRoUlNBRW5jcnlwdGlvbiA9IHtcbiAgc2lnbjogJ3JzYScsXG4gIGhhc2g6ICdzaGE1MTInLFxuICBpZDogbmV3IEJ1ZmZlcignMzA1MTMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjAzMDUwMDA0NDAnLCAnaGV4Jylcbn1cbmV4cG9ydHNbJ1JTQS1TSEExJ10gPSB7XG4gIHNpZ246ICdyc2EnLFxuICBoYXNoOiAnc2hhMScsXG4gIGlkOiBuZXcgQnVmZmVyKCczMDIxMzAwOTA2MDUyYjBlMDMwMjFhMDUwMDA0MTQnLCAnaGV4Jylcbn1cbmV4cG9ydHNbJ2VjZHNhLXdpdGgtU0hBMSddID0ge1xuICBzaWduOiAnZWNkc2EnLFxuICBoYXNoOiAnc2hhMScsXG4gIGlkOiBuZXcgQnVmZmVyKCcnLCAnaGV4Jylcbn1cblxuZXhwb3J0cy5EU0EgPSBleHBvcnRzWydEU0EtU0hBMSddID0gZXhwb3J0c1snRFNBLVNIQSddID0ge1xuICBzaWduOiAnZHNhJyxcbiAgaGFzaDogJ3NoYTEnLFxuICBpZDogbmV3IEJ1ZmZlcignJywgJ2hleCcpXG59XG5leHBvcnRzWydEU0EtU0hBMjI0J10gPSBleHBvcnRzWydEU0EtV0lUSC1TSEEyMjQnXSA9IHtcbiAgc2lnbjogJ2RzYScsXG4gIGhhc2g6ICdzaGEyMjQnLFxuICBpZDogbmV3IEJ1ZmZlcignJywgJ2hleCcpXG59XG5leHBvcnRzWydEU0EtU0hBMjU2J10gPSBleHBvcnRzWydEU0EtV0lUSC1TSEEyNTYnXSA9IHtcbiAgc2lnbjogJ2RzYScsXG4gIGhhc2g6ICdzaGEyNTYnLFxuICBpZDogbmV3IEJ1ZmZlcignJywgJ2hleCcpXG59XG5leHBvcnRzWydEU0EtU0hBMzg0J10gPSBleHBvcnRzWydEU0EtV0lUSC1TSEEzODQnXSA9IHtcbiAgc2lnbjogJ2RzYScsXG4gIGhhc2g6ICdzaGEzODQnLFxuICBpZDogbmV3IEJ1ZmZlcignJywgJ2hleCcpXG59XG5leHBvcnRzWydEU0EtU0hBNTEyJ10gPSBleHBvcnRzWydEU0EtV0lUSC1TSEE1MTInXSA9IHtcbiAgc2lnbjogJ2RzYScsXG4gIGhhc2g6ICdzaGE1MTInLFxuICBpZDogbmV3IEJ1ZmZlcignJywgJ2hleCcpXG59XG5leHBvcnRzWydEU0EtUklQRU1EMTYwJ10gPSB7XG4gIHNpZ246ICdkc2EnLFxuICBoYXNoOiAncm1kMTYwJyxcbiAgaWQ6IG5ldyBCdWZmZXIoJycsICdoZXgnKVxufVxuZXhwb3J0c1snUlNBLVJJUEVNRDE2MCddID0gZXhwb3J0cy5yaXBlbWQxNjBXaXRoUlNBID0ge1xuICBzaWduOiAncnNhJyxcbiAgaGFzaDogJ3JtZDE2MCcsXG4gIGlkOiBuZXcgQnVmZmVyKCczMDIxMzAwOTA2MDUyYjI0MDMwMjAxMDUwMDA0MTQnLCAnaGV4Jylcbn1cbmV4cG9ydHNbJ1JTQS1NRDUnXSA9IGV4cG9ydHMubWQ1V2l0aFJTQUVuY3J5cHRpb24gPSB7XG4gIHNpZ246ICdyc2EnLFxuICBoYXNoOiAnbWQ1JyxcbiAgaWQ6IG5ldyBCdWZmZXIoJzMwMjAzMDBjMDYwODJhODY0ODg2ZjcwZDAyMDUwNTAwMDQxMCcsICdoZXgnKVxufVxuIiwidmFyIF9hbGdvcyA9IHJlcXVpcmUoJy4vYWxnb3MnKVxudmFyIGNyZWF0ZUhhc2ggPSByZXF1aXJlKCdjcmVhdGUtaGFzaCcpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgc2lnbiA9IHJlcXVpcmUoJy4vc2lnbicpXG52YXIgc3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJylcbnZhciB2ZXJpZnkgPSByZXF1aXJlKCcuL3ZlcmlmeScpXG5cbnZhciBhbGdvcyA9IHt9XG5PYmplY3Qua2V5cyhfYWxnb3MpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICBhbGdvc1trZXldID0gYWxnb3Nba2V5LnRvTG93ZXJDYXNlKCldID0gX2FsZ29zW2tleV1cbn0pXG5cbmZ1bmN0aW9uIFNpZ24gKGFsZ29yaXRobSkge1xuICBzdHJlYW0uV3JpdGFibGUuY2FsbCh0aGlzKVxuXG4gIHZhciBkYXRhID0gYWxnb3NbYWxnb3JpdGhtXVxuICBpZiAoIWRhdGEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gbWVzc2FnZSBkaWdlc3QnKVxuICB9XG5cbiAgdGhpcy5faGFzaFR5cGUgPSBkYXRhLmhhc2hcbiAgdGhpcy5faGFzaCA9IGNyZWF0ZUhhc2goZGF0YS5oYXNoKVxuICB0aGlzLl90YWcgPSBkYXRhLmlkXG4gIHRoaXMuX3NpZ25UeXBlID0gZGF0YS5zaWduXG59XG5pbmhlcml0cyhTaWduLCBzdHJlYW0uV3JpdGFibGUpXG5cblNpZ24ucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uIF93cml0ZSAoZGF0YSwgXywgZG9uZSkge1xuICB0aGlzLl9oYXNoLnVwZGF0ZShkYXRhKVxuICBkb25lKClcbn1cblxuU2lnbi5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlIChkYXRhLCBlbmMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIGRhdGEgPSBuZXcgQnVmZmVyKGRhdGEsIGVuYylcbiAgfVxuXG4gIHRoaXMuX2hhc2gudXBkYXRlKGRhdGEpXG4gIHJldHVybiB0aGlzXG59XG5cblNpZ24ucHJvdG90eXBlLnNpZ24gPSBmdW5jdGlvbiBzaWduTWV0aG9kIChrZXksIGVuYykge1xuICB0aGlzLmVuZCgpXG4gIHZhciBoYXNoID0gdGhpcy5faGFzaC5kaWdlc3QoKVxuICB2YXIgc2lnID0gc2lnbihCdWZmZXIuY29uY2F0KFt0aGlzLl90YWcsIGhhc2hdKSwga2V5LCB0aGlzLl9oYXNoVHlwZSwgdGhpcy5fc2lnblR5cGUpXG5cbiAgcmV0dXJuIGVuYyA/IHNpZy50b1N0cmluZyhlbmMpIDogc2lnXG59XG5cbmZ1bmN0aW9uIFZlcmlmeSAoYWxnb3JpdGhtKSB7XG4gIHN0cmVhbS5Xcml0YWJsZS5jYWxsKHRoaXMpXG5cbiAgdmFyIGRhdGEgPSBhbGdvc1thbGdvcml0aG1dXG4gIGlmICghZGF0YSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBtZXNzYWdlIGRpZ2VzdCcpXG4gIH1cblxuICB0aGlzLl9oYXNoID0gY3JlYXRlSGFzaChkYXRhLmhhc2gpXG4gIHRoaXMuX3RhZyA9IGRhdGEuaWRcbiAgdGhpcy5fc2lnblR5cGUgPSBkYXRhLnNpZ25cbn1cbmluaGVyaXRzKFZlcmlmeSwgc3RyZWFtLldyaXRhYmxlKVxuXG5WZXJpZnkucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uIF93cml0ZSAoZGF0YSwgXywgZG9uZSkge1xuICB0aGlzLl9oYXNoLnVwZGF0ZShkYXRhKVxuXG4gIGRvbmUoKVxufVxuXG5WZXJpZnkucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIHVwZGF0ZSAoZGF0YSwgZW5jKSB7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICBkYXRhID0gbmV3IEJ1ZmZlcihkYXRhLCBlbmMpXG4gIH1cblxuICB0aGlzLl9oYXNoLnVwZGF0ZShkYXRhKVxuICByZXR1cm4gdGhpc1xufVxuXG5WZXJpZnkucHJvdG90eXBlLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeU1ldGhvZCAoa2V5LCBzaWcsIGVuYykge1xuICBpZiAodHlwZW9mIHNpZyA9PT0gJ3N0cmluZycpIHtcbiAgICBzaWcgPSBuZXcgQnVmZmVyKHNpZywgZW5jKVxuICB9XG5cbiAgdGhpcy5lbmQoKVxuICB2YXIgaGFzaCA9IHRoaXMuX2hhc2guZGlnZXN0KClcblxuICByZXR1cm4gdmVyaWZ5KHNpZywgQnVmZmVyLmNvbmNhdChbdGhpcy5fdGFnLCBoYXNoXSksIGtleSwgdGhpcy5fc2lnblR5cGUpXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVNpZ24gKGFsZ29yaXRobSkge1xuICByZXR1cm4gbmV3IFNpZ24oYWxnb3JpdGhtKVxufVxuXG5mdW5jdGlvbiBjcmVhdGVWZXJpZnkgKGFsZ29yaXRobSkge1xuICByZXR1cm4gbmV3IFZlcmlmeShhbGdvcml0aG0pXG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBTaWduOiBjcmVhdGVTaWduLFxuICBWZXJpZnk6IGNyZWF0ZVZlcmlmeSxcbiAgY3JlYXRlU2lnbjogY3JlYXRlU2lnbixcbiAgY3JlYXRlVmVyaWZ5OiBjcmVhdGVWZXJpZnlcbn1cbiIsIid1c2Ugc3RyaWN0J1xuZXhwb3J0c1snMS4zLjEzMi4wLjEwJ10gPSAnc2VjcDI1NmsxJ1xuXG5leHBvcnRzWycxLjMuMTMyLjAuMzMnXSA9ICdwMjI0J1xuXG5leHBvcnRzWycxLjIuODQwLjEwMDQ1LjMuMS4xJ10gPSAncDE5MidcblxuZXhwb3J0c1snMS4yLjg0MC4xMDA0NS4zLjEuNyddID0gJ3AyNTYnXG5cbmV4cG9ydHNbJzEuMy4xMzIuMC4zNCddID0gJ3AzODQnXG5cbmV4cG9ydHNbJzEuMy4xMzIuMC4zNSddID0gJ3A1MjEnXG4iLCIoZnVuY3Rpb24gKG1vZHVsZSwgZXhwb3J0cykge1xuICAndXNlIHN0cmljdCc7XG5cbiAgLy8gVXRpbHNcbiAgZnVuY3Rpb24gYXNzZXJ0ICh2YWwsIG1zZykge1xuICAgIGlmICghdmFsKSB0aHJvdyBuZXcgRXJyb3IobXNnIHx8ICdBc3NlcnRpb24gZmFpbGVkJyk7XG4gIH1cblxuICAvLyBDb3VsZCB1c2UgYGluaGVyaXRzYCBtb2R1bGUsIGJ1dCBkb24ndCB3YW50IHRvIG1vdmUgZnJvbSBzaW5nbGUgZmlsZVxuICAvLyBhcmNoaXRlY3R1cmUgeWV0LlxuICBmdW5jdGlvbiBpbmhlcml0cyAoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3I7XG4gICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge307XG4gICAgVGVtcEN0b3IucHJvdG90eXBlID0gc3VwZXJDdG9yLnByb3RvdHlwZTtcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpO1xuICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvcjtcbiAgfVxuXG4gIC8vIEJOXG5cbiAgZnVuY3Rpb24gQk4gKG51bWJlciwgYmFzZSwgZW5kaWFuKSB7XG4gICAgLy8gTWF5IGJlIGBuZXcgQk4oYm4pYCA/XG4gICAgaWYgKG51bWJlciAhPT0gbnVsbCAmJlxuICAgICAgdHlwZW9mIG51bWJlciA9PT0gJ29iamVjdCcgJiZcbiAgICAgIEFycmF5LmlzQXJyYXkobnVtYmVyLndvcmRzKSkge1xuICAgICAgcmV0dXJuIG51bWJlcjtcbiAgICB9XG5cbiAgICB0aGlzLm5lZ2F0aXZlID0gMDtcbiAgICB0aGlzLndvcmRzID0gbnVsbDtcbiAgICB0aGlzLmxlbmd0aCA9IDA7XG5cbiAgICAvLyBSZWR1Y3Rpb24gY29udGV4dFxuICAgIHRoaXMucmVkID0gbnVsbDtcblxuICAgIGlmIChudW1iZXIgIT09IG51bGwpIHtcbiAgICAgIGlmIChiYXNlID09PSAnbGUnIHx8IGJhc2UgPT09ICdiZScpIHtcbiAgICAgICAgZW5kaWFuID0gYmFzZTtcbiAgICAgICAgYmFzZSA9IDEwO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9pbml0KG51bWJlciB8fCAwLCBiYXNlIHx8IDEwLCBlbmRpYW4gfHwgJ2JlJyk7XG4gICAgfVxuICB9XG4gIGlmICh0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0Jykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gQk47XG4gIH0gZWxzZSB7XG4gICAgZXhwb3J0cy5CTiA9IEJOO1xuICB9XG5cbiAgQk4uQk4gPSBCTjtcbiAgQk4ud29yZFNpemUgPSAyNjtcblxuICB2YXIgQnVmZmVyO1xuICB0cnkge1xuICAgIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcbiAgfSBjYXRjaCAoZSkge1xuICB9XG5cbiAgQk4ubWF4ID0gZnVuY3Rpb24gbWF4IChsZWZ0LCByaWdodCkge1xuICAgIGlmIChsZWZ0LmNtcChyaWdodCkgPiAwKSByZXR1cm4gbGVmdDtcbiAgICByZXR1cm4gcmlnaHQ7XG4gIH07XG5cbiAgQk4ubWluID0gZnVuY3Rpb24gbWluIChsZWZ0LCByaWdodCkge1xuICAgIGlmIChsZWZ0LmNtcChyaWdodCkgPCAwKSByZXR1cm4gbGVmdDtcbiAgICByZXR1cm4gcmlnaHQ7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24gaW5pdCAobnVtYmVyLCBiYXNlLCBlbmRpYW4pIHtcbiAgICBpZiAodHlwZW9mIG51bWJlciA9PT0gJ251bWJlcicpIHtcbiAgICAgIHJldHVybiB0aGlzLl9pbml0TnVtYmVyKG51bWJlciwgYmFzZSwgZW5kaWFuKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG51bWJlciA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHJldHVybiB0aGlzLl9pbml0QXJyYXkobnVtYmVyLCBiYXNlLCBlbmRpYW4pO1xuICAgIH1cblxuICAgIGlmIChiYXNlID09PSAnaGV4Jykge1xuICAgICAgYmFzZSA9IDE2O1xuICAgIH1cbiAgICBhc3NlcnQoYmFzZSA9PT0gKGJhc2UgfCAwKSAmJiBiYXNlID49IDIgJiYgYmFzZSA8PSAzNik7XG5cbiAgICBudW1iZXIgPSBudW1iZXIudG9TdHJpbmcoKS5yZXBsYWNlKC9cXHMrL2csICcnKTtcbiAgICB2YXIgc3RhcnQgPSAwO1xuICAgIGlmIChudW1iZXJbMF0gPT09ICctJykge1xuICAgICAgc3RhcnQrKztcbiAgICB9XG5cbiAgICBpZiAoYmFzZSA9PT0gMTYpIHtcbiAgICAgIHRoaXMuX3BhcnNlSGV4KG51bWJlciwgc3RhcnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9wYXJzZUJhc2UobnVtYmVyLCBiYXNlLCBzdGFydCk7XG4gICAgfVxuXG4gICAgaWYgKG51bWJlclswXSA9PT0gJy0nKSB7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMTtcbiAgICB9XG5cbiAgICB0aGlzLnN0cmlwKCk7XG5cbiAgICBpZiAoZW5kaWFuICE9PSAnbGUnKSByZXR1cm47XG5cbiAgICB0aGlzLl9pbml0QXJyYXkodGhpcy50b0FycmF5KCksIGJhc2UsIGVuZGlhbik7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLl9pbml0TnVtYmVyID0gZnVuY3Rpb24gX2luaXROdW1iZXIgKG51bWJlciwgYmFzZSwgZW5kaWFuKSB7XG4gICAgaWYgKG51bWJlciA8IDApIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAxO1xuICAgICAgbnVtYmVyID0gLW51bWJlcjtcbiAgICB9XG4gICAgaWYgKG51bWJlciA8IDB4NDAwMDAwMCkge1xuICAgICAgdGhpcy53b3JkcyA9IFsgbnVtYmVyICYgMHgzZmZmZmZmIF07XG4gICAgICB0aGlzLmxlbmd0aCA9IDE7XG4gICAgfSBlbHNlIGlmIChudW1iZXIgPCAweDEwMDAwMDAwMDAwMDAwKSB7XG4gICAgICB0aGlzLndvcmRzID0gW1xuICAgICAgICBudW1iZXIgJiAweDNmZmZmZmYsXG4gICAgICAgIChudW1iZXIgLyAweDQwMDAwMDApICYgMHgzZmZmZmZmXG4gICAgICBdO1xuICAgICAgdGhpcy5sZW5ndGggPSAyO1xuICAgIH0gZWxzZSB7XG4gICAgICBhc3NlcnQobnVtYmVyIDwgMHgyMDAwMDAwMDAwMDAwMCk7IC8vIDIgXiA1MyAodW5zYWZlKVxuICAgICAgdGhpcy53b3JkcyA9IFtcbiAgICAgICAgbnVtYmVyICYgMHgzZmZmZmZmLFxuICAgICAgICAobnVtYmVyIC8gMHg0MDAwMDAwKSAmIDB4M2ZmZmZmZixcbiAgICAgICAgMVxuICAgICAgXTtcbiAgICAgIHRoaXMubGVuZ3RoID0gMztcbiAgICB9XG5cbiAgICBpZiAoZW5kaWFuICE9PSAnbGUnKSByZXR1cm47XG5cbiAgICAvLyBSZXZlcnNlIHRoZSBieXRlc1xuICAgIHRoaXMuX2luaXRBcnJheSh0aGlzLnRvQXJyYXkoKSwgYmFzZSwgZW5kaWFuKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuX2luaXRBcnJheSA9IGZ1bmN0aW9uIF9pbml0QXJyYXkgKG51bWJlciwgYmFzZSwgZW5kaWFuKSB7XG4gICAgLy8gUGVyaGFwcyBhIFVpbnQ4QXJyYXlcbiAgICBhc3NlcnQodHlwZW9mIG51bWJlci5sZW5ndGggPT09ICdudW1iZXInKTtcbiAgICBpZiAobnVtYmVyLmxlbmd0aCA8PSAwKSB7XG4gICAgICB0aGlzLndvcmRzID0gWyAwIF07XG4gICAgICB0aGlzLmxlbmd0aCA9IDE7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB0aGlzLmxlbmd0aCA9IE1hdGguY2VpbChudW1iZXIubGVuZ3RoIC8gMyk7XG4gICAgdGhpcy53b3JkcyA9IG5ldyBBcnJheSh0aGlzLmxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gMDtcbiAgICB9XG5cbiAgICB2YXIgaiwgdztcbiAgICB2YXIgb2ZmID0gMDtcbiAgICBpZiAoZW5kaWFuID09PSAnYmUnKSB7XG4gICAgICBmb3IgKGkgPSBudW1iZXIubGVuZ3RoIC0gMSwgaiA9IDA7IGkgPj0gMDsgaSAtPSAzKSB7XG4gICAgICAgIHcgPSBudW1iZXJbaV0gfCAobnVtYmVyW2kgLSAxXSA8PCA4KSB8IChudW1iZXJbaSAtIDJdIDw8IDE2KTtcbiAgICAgICAgdGhpcy53b3Jkc1tqXSB8PSAodyA8PCBvZmYpICYgMHgzZmZmZmZmO1xuICAgICAgICB0aGlzLndvcmRzW2ogKyAxXSA9ICh3ID4+PiAoMjYgLSBvZmYpKSAmIDB4M2ZmZmZmZjtcbiAgICAgICAgb2ZmICs9IDI0O1xuICAgICAgICBpZiAob2ZmID49IDI2KSB7XG4gICAgICAgICAgb2ZmIC09IDI2O1xuICAgICAgICAgIGorKztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZW5kaWFuID09PSAnbGUnKSB7XG4gICAgICBmb3IgKGkgPSAwLCBqID0gMDsgaSA8IG51bWJlci5sZW5ndGg7IGkgKz0gMykge1xuICAgICAgICB3ID0gbnVtYmVyW2ldIHwgKG51bWJlcltpICsgMV0gPDwgOCkgfCAobnVtYmVyW2kgKyAyXSA8PCAxNik7XG4gICAgICAgIHRoaXMud29yZHNbal0gfD0gKHcgPDwgb2ZmKSAmIDB4M2ZmZmZmZjtcbiAgICAgICAgdGhpcy53b3Jkc1tqICsgMV0gPSAodyA+Pj4gKDI2IC0gb2ZmKSkgJiAweDNmZmZmZmY7XG4gICAgICAgIG9mZiArPSAyNDtcbiAgICAgICAgaWYgKG9mZiA+PSAyNikge1xuICAgICAgICAgIG9mZiAtPSAyNjtcbiAgICAgICAgICBqKys7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBmdW5jdGlvbiBwYXJzZUhleCAoc3RyLCBzdGFydCwgZW5kKSB7XG4gICAgdmFyIHIgPSAwO1xuICAgIHZhciBsZW4gPSBNYXRoLm1pbihzdHIubGVuZ3RoLCBlbmQpO1xuICAgIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICB2YXIgYyA9IHN0ci5jaGFyQ29kZUF0KGkpIC0gNDg7XG5cbiAgICAgIHIgPDw9IDQ7XG5cbiAgICAgIC8vICdhJyAtICdmJ1xuICAgICAgaWYgKGMgPj0gNDkgJiYgYyA8PSA1NCkge1xuICAgICAgICByIHw9IGMgLSA0OSArIDB4YTtcblxuICAgICAgLy8gJ0EnIC0gJ0YnXG4gICAgICB9IGVsc2UgaWYgKGMgPj0gMTcgJiYgYyA8PSAyMikge1xuICAgICAgICByIHw9IGMgLSAxNyArIDB4YTtcblxuICAgICAgLy8gJzAnIC0gJzknXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByIHw9IGMgJiAweGY7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByO1xuICB9XG5cbiAgQk4ucHJvdG90eXBlLl9wYXJzZUhleCA9IGZ1bmN0aW9uIF9wYXJzZUhleCAobnVtYmVyLCBzdGFydCkge1xuICAgIC8vIENyZWF0ZSBwb3NzaWJseSBiaWdnZXIgYXJyYXkgdG8gZW5zdXJlIHRoYXQgaXQgZml0cyB0aGUgbnVtYmVyXG4gICAgdGhpcy5sZW5ndGggPSBNYXRoLmNlaWwoKG51bWJlci5sZW5ndGggLSBzdGFydCkgLyA2KTtcbiAgICB0aGlzLndvcmRzID0gbmV3IEFycmF5KHRoaXMubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMud29yZHNbaV0gPSAwO1xuICAgIH1cblxuICAgIHZhciBqLCB3O1xuICAgIC8vIFNjYW4gMjQtYml0IGNodW5rcyBhbmQgYWRkIHRoZW0gdG8gdGhlIG51bWJlclxuICAgIHZhciBvZmYgPSAwO1xuICAgIGZvciAoaSA9IG51bWJlci5sZW5ndGggLSA2LCBqID0gMDsgaSA+PSBzdGFydDsgaSAtPSA2KSB7XG4gICAgICB3ID0gcGFyc2VIZXgobnVtYmVyLCBpLCBpICsgNik7XG4gICAgICB0aGlzLndvcmRzW2pdIHw9ICh3IDw8IG9mZikgJiAweDNmZmZmZmY7XG4gICAgICB0aGlzLndvcmRzW2ogKyAxXSB8PSB3ID4+PiAoMjYgLSBvZmYpICYgMHgzZmZmZmY7XG4gICAgICBvZmYgKz0gMjQ7XG4gICAgICBpZiAob2ZmID49IDI2KSB7XG4gICAgICAgIG9mZiAtPSAyNjtcbiAgICAgICAgaisrO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaSArIDYgIT09IHN0YXJ0KSB7XG4gICAgICB3ID0gcGFyc2VIZXgobnVtYmVyLCBzdGFydCwgaSArIDYpO1xuICAgICAgdGhpcy53b3Jkc1tqXSB8PSAodyA8PCBvZmYpICYgMHgzZmZmZmZmO1xuICAgICAgdGhpcy53b3Jkc1tqICsgMV0gfD0gdyA+Pj4gKDI2IC0gb2ZmKSAmIDB4M2ZmZmZmO1xuICAgIH1cbiAgICB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgZnVuY3Rpb24gcGFyc2VCYXNlIChzdHIsIHN0YXJ0LCBlbmQsIG11bCkge1xuICAgIHZhciByID0gMDtcbiAgICB2YXIgbGVuID0gTWF0aC5taW4oc3RyLmxlbmd0aCwgZW5kKTtcbiAgICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBsZW47IGkrKykge1xuICAgICAgdmFyIGMgPSBzdHIuY2hhckNvZGVBdChpKSAtIDQ4O1xuXG4gICAgICByICo9IG11bDtcblxuICAgICAgLy8gJ2EnXG4gICAgICBpZiAoYyA+PSA0OSkge1xuICAgICAgICByICs9IGMgLSA0OSArIDB4YTtcblxuICAgICAgLy8gJ0EnXG4gICAgICB9IGVsc2UgaWYgKGMgPj0gMTcpIHtcbiAgICAgICAgciArPSBjIC0gMTcgKyAweGE7XG5cbiAgICAgIC8vICcwJyAtICc5J1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgciArPSBjO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcjtcbiAgfVxuXG4gIEJOLnByb3RvdHlwZS5fcGFyc2VCYXNlID0gZnVuY3Rpb24gX3BhcnNlQmFzZSAobnVtYmVyLCBiYXNlLCBzdGFydCkge1xuICAgIC8vIEluaXRpYWxpemUgYXMgemVyb1xuICAgIHRoaXMud29yZHMgPSBbIDAgXTtcbiAgICB0aGlzLmxlbmd0aCA9IDE7XG5cbiAgICAvLyBGaW5kIGxlbmd0aCBvZiBsaW1iIGluIGJhc2VcbiAgICBmb3IgKHZhciBsaW1iTGVuID0gMCwgbGltYlBvdyA9IDE7IGxpbWJQb3cgPD0gMHgzZmZmZmZmOyBsaW1iUG93ICo9IGJhc2UpIHtcbiAgICAgIGxpbWJMZW4rKztcbiAgICB9XG4gICAgbGltYkxlbi0tO1xuICAgIGxpbWJQb3cgPSAobGltYlBvdyAvIGJhc2UpIHwgMDtcblxuICAgIHZhciB0b3RhbCA9IG51bWJlci5sZW5ndGggLSBzdGFydDtcbiAgICB2YXIgbW9kID0gdG90YWwgJSBsaW1iTGVuO1xuICAgIHZhciBlbmQgPSBNYXRoLm1pbih0b3RhbCwgdG90YWwgLSBtb2QpICsgc3RhcnQ7XG5cbiAgICB2YXIgd29yZCA9IDA7XG4gICAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpICs9IGxpbWJMZW4pIHtcbiAgICAgIHdvcmQgPSBwYXJzZUJhc2UobnVtYmVyLCBpLCBpICsgbGltYkxlbiwgYmFzZSk7XG5cbiAgICAgIHRoaXMuaW11bG4obGltYlBvdyk7XG4gICAgICBpZiAodGhpcy53b3Jkc1swXSArIHdvcmQgPCAweDQwMDAwMDApIHtcbiAgICAgICAgdGhpcy53b3Jkc1swXSArPSB3b3JkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5faWFkZG4od29yZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG1vZCAhPT0gMCkge1xuICAgICAgdmFyIHBvdyA9IDE7XG4gICAgICB3b3JkID0gcGFyc2VCYXNlKG51bWJlciwgaSwgbnVtYmVyLmxlbmd0aCwgYmFzZSk7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBtb2Q7IGkrKykge1xuICAgICAgICBwb3cgKj0gYmFzZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5pbXVsbihwb3cpO1xuICAgICAgaWYgKHRoaXMud29yZHNbMF0gKyB3b3JkIDwgMHg0MDAwMDAwKSB7XG4gICAgICAgIHRoaXMud29yZHNbMF0gKz0gd29yZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2lhZGRuKHdvcmQpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBCTi5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uIGNvcHkgKGRlc3QpIHtcbiAgICBkZXN0LndvcmRzID0gbmV3IEFycmF5KHRoaXMubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGRlc3Qud29yZHNbaV0gPSB0aGlzLndvcmRzW2ldO1xuICAgIH1cbiAgICBkZXN0Lmxlbmd0aCA9IHRoaXMubGVuZ3RoO1xuICAgIGRlc3QubmVnYXRpdmUgPSB0aGlzLm5lZ2F0aXZlO1xuICAgIGRlc3QucmVkID0gdGhpcy5yZWQ7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gY2xvbmUgKCkge1xuICAgIHZhciByID0gbmV3IEJOKG51bGwpO1xuICAgIHRoaXMuY29weShyKTtcbiAgICByZXR1cm4gcjtcbiAgfTtcblxuICAvLyBSZW1vdmUgbGVhZGluZyBgMGAgZnJvbSBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLnN0cmlwID0gZnVuY3Rpb24gc3RyaXAgKCkge1xuICAgIHdoaWxlICh0aGlzLmxlbmd0aCA+IDEgJiYgdGhpcy53b3Jkc1t0aGlzLmxlbmd0aCAtIDFdID09PSAwKSB7XG4gICAgICB0aGlzLmxlbmd0aC0tO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fbm9ybVNpZ24oKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuX25vcm1TaWduID0gZnVuY3Rpb24gX25vcm1TaWduICgpIHtcbiAgICAvLyAtMCA9IDBcbiAgICBpZiAodGhpcy5sZW5ndGggPT09IDEgJiYgdGhpcy53b3Jkc1swXSA9PT0gMCkge1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDA7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCAoKSB7XG4gICAgcmV0dXJuICh0aGlzLnJlZCA/ICc8Qk4tUjogJyA6ICc8Qk46ICcpICsgdGhpcy50b1N0cmluZygxNikgKyAnPic7XG4gIH07XG5cbiAgLypcblxuICB2YXIgemVyb3MgPSBbXTtcbiAgdmFyIGdyb3VwU2l6ZXMgPSBbXTtcbiAgdmFyIGdyb3VwQmFzZXMgPSBbXTtcblxuICB2YXIgcyA9ICcnO1xuICB2YXIgaSA9IC0xO1xuICB3aGlsZSAoKytpIDwgQk4ud29yZFNpemUpIHtcbiAgICB6ZXJvc1tpXSA9IHM7XG4gICAgcyArPSAnMCc7XG4gIH1cbiAgZ3JvdXBTaXplc1swXSA9IDA7XG4gIGdyb3VwU2l6ZXNbMV0gPSAwO1xuICBncm91cEJhc2VzWzBdID0gMDtcbiAgZ3JvdXBCYXNlc1sxXSA9IDA7XG4gIHZhciBiYXNlID0gMiAtIDE7XG4gIHdoaWxlICgrK2Jhc2UgPCAzNiArIDEpIHtcbiAgICB2YXIgZ3JvdXBTaXplID0gMDtcbiAgICB2YXIgZ3JvdXBCYXNlID0gMTtcbiAgICB3aGlsZSAoZ3JvdXBCYXNlIDwgKDEgPDwgQk4ud29yZFNpemUpIC8gYmFzZSkge1xuICAgICAgZ3JvdXBCYXNlICo9IGJhc2U7XG4gICAgICBncm91cFNpemUgKz0gMTtcbiAgICB9XG4gICAgZ3JvdXBTaXplc1tiYXNlXSA9IGdyb3VwU2l6ZTtcbiAgICBncm91cEJhc2VzW2Jhc2VdID0gZ3JvdXBCYXNlO1xuICB9XG5cbiAgKi9cblxuICB2YXIgemVyb3MgPSBbXG4gICAgJycsXG4gICAgJzAnLFxuICAgICcwMCcsXG4gICAgJzAwMCcsXG4gICAgJzAwMDAnLFxuICAgICcwMDAwMCcsXG4gICAgJzAwMDAwMCcsXG4gICAgJzAwMDAwMDAnLFxuICAgICcwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAnXG4gIF07XG5cbiAgdmFyIGdyb3VwU2l6ZXMgPSBbXG4gICAgMCwgMCxcbiAgICAyNSwgMTYsIDEyLCAxMSwgMTAsIDksIDgsXG4gICAgOCwgNywgNywgNywgNywgNiwgNixcbiAgICA2LCA2LCA2LCA2LCA2LCA1LCA1LFxuICAgIDUsIDUsIDUsIDUsIDUsIDUsIDUsXG4gICAgNSwgNSwgNSwgNSwgNSwgNSwgNVxuICBdO1xuXG4gIHZhciBncm91cEJhc2VzID0gW1xuICAgIDAsIDAsXG4gICAgMzM1NTQ0MzIsIDQzMDQ2NzIxLCAxNjc3NzIxNiwgNDg4MjgxMjUsIDYwNDY2MTc2LCA0MDM1MzYwNywgMTY3NzcyMTYsXG4gICAgNDMwNDY3MjEsIDEwMDAwMDAwLCAxOTQ4NzE3MSwgMzU4MzE4MDgsIDYyNzQ4NTE3LCA3NTI5NTM2LCAxMTM5MDYyNSxcbiAgICAxNjc3NzIxNiwgMjQxMzc1NjksIDM0MDEyMjI0LCA0NzA0NTg4MSwgNjQwMDAwMDAsIDQwODQxMDEsIDUxNTM2MzIsXG4gICAgNjQzNjM0MywgNzk2MjYyNCwgOTc2NTYyNSwgMTE4ODEzNzYsIDE0MzQ4OTA3LCAxNzIxMDM2OCwgMjA1MTExNDksXG4gICAgMjQzMDAwMDAsIDI4NjI5MTUxLCAzMzU1NDQzMiwgMzkxMzUzOTMsIDQ1NDM1NDI0LCA1MjUyMTg3NSwgNjA0NjYxNzZcbiAgXTtcblxuICBCTi5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoYmFzZSwgcGFkZGluZykge1xuICAgIGJhc2UgPSBiYXNlIHx8IDEwO1xuICAgIHBhZGRpbmcgPSBwYWRkaW5nIHwgMCB8fCAxO1xuXG4gICAgdmFyIG91dDtcbiAgICBpZiAoYmFzZSA9PT0gMTYgfHwgYmFzZSA9PT0gJ2hleCcpIHtcbiAgICAgIG91dCA9ICcnO1xuICAgICAgdmFyIG9mZiA9IDA7XG4gICAgICB2YXIgY2FycnkgPSAwO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciB3ID0gdGhpcy53b3Jkc1tpXTtcbiAgICAgICAgdmFyIHdvcmQgPSAoKCh3IDw8IG9mZikgfCBjYXJyeSkgJiAweGZmZmZmZikudG9TdHJpbmcoMTYpO1xuICAgICAgICBjYXJyeSA9ICh3ID4+PiAoMjQgLSBvZmYpKSAmIDB4ZmZmZmZmO1xuICAgICAgICBpZiAoY2FycnkgIT09IDAgfHwgaSAhPT0gdGhpcy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgb3V0ID0gemVyb3NbNiAtIHdvcmQubGVuZ3RoXSArIHdvcmQgKyBvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb3V0ID0gd29yZCArIG91dDtcbiAgICAgICAgfVxuICAgICAgICBvZmYgKz0gMjtcbiAgICAgICAgaWYgKG9mZiA+PSAyNikge1xuICAgICAgICAgIG9mZiAtPSAyNjtcbiAgICAgICAgICBpLS07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChjYXJyeSAhPT0gMCkge1xuICAgICAgICBvdXQgPSBjYXJyeS50b1N0cmluZygxNikgKyBvdXQ7XG4gICAgICB9XG4gICAgICB3aGlsZSAob3V0Lmxlbmd0aCAlIHBhZGRpbmcgIT09IDApIHtcbiAgICAgICAgb3V0ID0gJzAnICsgb3V0O1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDApIHtcbiAgICAgICAgb3V0ID0gJy0nICsgb3V0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG91dDtcbiAgICB9XG5cbiAgICBpZiAoYmFzZSA9PT0gKGJhc2UgfCAwKSAmJiBiYXNlID49IDIgJiYgYmFzZSA8PSAzNikge1xuICAgICAgLy8gdmFyIGdyb3VwU2l6ZSA9IE1hdGguZmxvb3IoQk4ud29yZFNpemUgKiBNYXRoLkxOMiAvIE1hdGgubG9nKGJhc2UpKTtcbiAgICAgIHZhciBncm91cFNpemUgPSBncm91cFNpemVzW2Jhc2VdO1xuICAgICAgLy8gdmFyIGdyb3VwQmFzZSA9IE1hdGgucG93KGJhc2UsIGdyb3VwU2l6ZSk7XG4gICAgICB2YXIgZ3JvdXBCYXNlID0gZ3JvdXBCYXNlc1tiYXNlXTtcbiAgICAgIG91dCA9ICcnO1xuICAgICAgdmFyIGMgPSB0aGlzLmNsb25lKCk7XG4gICAgICBjLm5lZ2F0aXZlID0gMDtcbiAgICAgIHdoaWxlICghYy5pc1plcm8oKSkge1xuICAgICAgICB2YXIgciA9IGMubW9kbihncm91cEJhc2UpLnRvU3RyaW5nKGJhc2UpO1xuICAgICAgICBjID0gYy5pZGl2bihncm91cEJhc2UpO1xuXG4gICAgICAgIGlmICghYy5pc1plcm8oKSkge1xuICAgICAgICAgIG91dCA9IHplcm9zW2dyb3VwU2l6ZSAtIHIubGVuZ3RoXSArIHIgKyBvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb3V0ID0gciArIG91dDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHRoaXMuaXNaZXJvKCkpIHtcbiAgICAgICAgb3V0ID0gJzAnICsgb3V0O1xuICAgICAgfVxuICAgICAgd2hpbGUgKG91dC5sZW5ndGggJSBwYWRkaW5nICE9PSAwKSB7XG4gICAgICAgIG91dCA9ICcwJyArIG91dDtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICAgIG91dCA9ICctJyArIG91dDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvdXQ7XG4gICAgfVxuXG4gICAgYXNzZXJ0KGZhbHNlLCAnQmFzZSBzaG91bGQgYmUgYmV0d2VlbiAyIGFuZCAzNicpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS50b051bWJlciA9IGZ1bmN0aW9uIHRvTnVtYmVyICgpIHtcbiAgICB2YXIgbGVuZ3RoID0gdGhpcy5iaXRMZW5ndGgoKTtcbiAgICB2YXIgcmV0O1xuICAgIGlmIChsZW5ndGggPD0gMjYpIHtcbiAgICAgIHJldCA9IHRoaXMud29yZHNbMF07XG4gICAgfSBlbHNlIGlmIChsZW5ndGggPD0gNTIpIHtcbiAgICAgIHJldCA9ICh0aGlzLndvcmRzWzFdICogMHg0MDAwMDAwKSArIHRoaXMud29yZHNbMF07XG4gICAgfSBlbHNlIGlmIChsZW5ndGggPT09IDUzKSB7XG4gICAgICAvLyBOT1RFOiBhdCB0aGlzIHN0YWdlIGl0IGlzIGtub3duIHRoYXQgdGhlIHRvcCBiaXQgaXMgc2V0XG4gICAgICByZXQgPSAweDEwMDAwMDAwMDAwMDAwICsgKHRoaXMud29yZHNbMV0gKiAweDQwMDAwMDApICsgdGhpcy53b3Jkc1swXTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXNzZXJ0KGZhbHNlLCAnTnVtYmVyIGNhbiBvbmx5IHNhZmVseSBzdG9yZSB1cCB0byA1MyBiaXRzJyk7XG4gICAgfVxuICAgIHJldHVybiAodGhpcy5uZWdhdGl2ZSAhPT0gMCkgPyAtcmV0IDogcmV0O1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04gKCkge1xuICAgIHJldHVybiB0aGlzLnRvU3RyaW5nKDE2KTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUudG9CdWZmZXIgPSBmdW5jdGlvbiB0b0J1ZmZlciAoZW5kaWFuLCBsZW5ndGgpIHtcbiAgICBhc3NlcnQodHlwZW9mIEJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcpO1xuICAgIHJldHVybiBuZXcgQnVmZmVyKHRoaXMudG9BcnJheShlbmRpYW4sIGxlbmd0aCkpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS50b0FycmF5ID0gZnVuY3Rpb24gdG9BcnJheSAoZW5kaWFuLCBsZW5ndGgpIHtcbiAgICB2YXIgYnl0ZUxlbmd0aCA9IHRoaXMuYnl0ZUxlbmd0aCgpO1xuICAgIHZhciByZXFMZW5ndGggPSBsZW5ndGggfHwgTWF0aC5tYXgoMSwgYnl0ZUxlbmd0aCk7XG4gICAgYXNzZXJ0KGJ5dGVMZW5ndGggPD0gcmVxTGVuZ3RoLCAnYnl0ZSBhcnJheSBsb25nZXIgdGhhbiBkZXNpcmVkIGxlbmd0aCcpO1xuICAgIGFzc2VydChyZXFMZW5ndGggPiAwLCAnUmVxdWVzdGVkIGFycmF5IGxlbmd0aCA8PSAwJyk7XG5cbiAgICB0aGlzLnN0cmlwKCk7XG4gICAgdmFyIGxpdHRsZUVuZGlhbiA9IGVuZGlhbiA9PT0gJ2xlJztcbiAgICB2YXIgcmVzID0gbmV3IEFycmF5KHJlcUxlbmd0aCk7XG5cbiAgICB2YXIgYiwgaTtcbiAgICB2YXIgcSA9IHRoaXMuY2xvbmUoKTtcbiAgICBpZiAoIWxpdHRsZUVuZGlhbikge1xuICAgICAgLy8gQXNzdW1lIGJpZy1lbmRpYW5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCByZXFMZW5ndGggLSBieXRlTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcmVzW2ldID0gMDtcbiAgICAgIH1cblxuICAgICAgZm9yIChpID0gMDsgIXEuaXNaZXJvKCk7IGkrKykge1xuICAgICAgICBiID0gcS5hbmRsbigweGZmKTtcbiAgICAgICAgcS5pdXNocm4oOCk7XG5cbiAgICAgICAgcmVzW3JlcUxlbmd0aCAtIGkgLSAxXSA9IGI7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoaSA9IDA7ICFxLmlzWmVybygpOyBpKyspIHtcbiAgICAgICAgYiA9IHEuYW5kbG4oMHhmZik7XG4gICAgICAgIHEuaXVzaHJuKDgpO1xuXG4gICAgICAgIHJlc1tpXSA9IGI7XG4gICAgICB9XG5cbiAgICAgIGZvciAoOyBpIDwgcmVxTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcmVzW2ldID0gMDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIGlmIChNYXRoLmNsejMyKSB7XG4gICAgQk4ucHJvdG90eXBlLl9jb3VudEJpdHMgPSBmdW5jdGlvbiBfY291bnRCaXRzICh3KSB7XG4gICAgICByZXR1cm4gMzIgLSBNYXRoLmNsejMyKHcpO1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgQk4ucHJvdG90eXBlLl9jb3VudEJpdHMgPSBmdW5jdGlvbiBfY291bnRCaXRzICh3KSB7XG4gICAgICB2YXIgdCA9IHc7XG4gICAgICB2YXIgciA9IDA7XG4gICAgICBpZiAodCA+PSAweDEwMDApIHtcbiAgICAgICAgciArPSAxMztcbiAgICAgICAgdCA+Pj49IDEzO1xuICAgICAgfVxuICAgICAgaWYgKHQgPj0gMHg0MCkge1xuICAgICAgICByICs9IDc7XG4gICAgICAgIHQgPj4+PSA3O1xuICAgICAgfVxuICAgICAgaWYgKHQgPj0gMHg4KSB7XG4gICAgICAgIHIgKz0gNDtcbiAgICAgICAgdCA+Pj49IDQ7XG4gICAgICB9XG4gICAgICBpZiAodCA+PSAweDAyKSB7XG4gICAgICAgIHIgKz0gMjtcbiAgICAgICAgdCA+Pj49IDI7XG4gICAgICB9XG4gICAgICByZXR1cm4gciArIHQ7XG4gICAgfTtcbiAgfVxuXG4gIEJOLnByb3RvdHlwZS5femVyb0JpdHMgPSBmdW5jdGlvbiBfemVyb0JpdHMgKHcpIHtcbiAgICAvLyBTaG9ydC1jdXRcbiAgICBpZiAodyA9PT0gMCkgcmV0dXJuIDI2O1xuXG4gICAgdmFyIHQgPSB3O1xuICAgIHZhciByID0gMDtcbiAgICBpZiAoKHQgJiAweDFmZmYpID09PSAwKSB7XG4gICAgICByICs9IDEzO1xuICAgICAgdCA+Pj49IDEzO1xuICAgIH1cbiAgICBpZiAoKHQgJiAweDdmKSA9PT0gMCkge1xuICAgICAgciArPSA3O1xuICAgICAgdCA+Pj49IDc7XG4gICAgfVxuICAgIGlmICgodCAmIDB4ZikgPT09IDApIHtcbiAgICAgIHIgKz0gNDtcbiAgICAgIHQgPj4+PSA0O1xuICAgIH1cbiAgICBpZiAoKHQgJiAweDMpID09PSAwKSB7XG4gICAgICByICs9IDI7XG4gICAgICB0ID4+Pj0gMjtcbiAgICB9XG4gICAgaWYgKCh0ICYgMHgxKSA9PT0gMCkge1xuICAgICAgcisrO1xuICAgIH1cbiAgICByZXR1cm4gcjtcbiAgfTtcblxuICAvLyBSZXR1cm4gbnVtYmVyIG9mIHVzZWQgYml0cyBpbiBhIEJOXG4gIEJOLnByb3RvdHlwZS5iaXRMZW5ndGggPSBmdW5jdGlvbiBiaXRMZW5ndGggKCkge1xuICAgIHZhciB3ID0gdGhpcy53b3Jkc1t0aGlzLmxlbmd0aCAtIDFdO1xuICAgIHZhciBoaSA9IHRoaXMuX2NvdW50Qml0cyh3KTtcbiAgICByZXR1cm4gKHRoaXMubGVuZ3RoIC0gMSkgKiAyNiArIGhpO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHRvQml0QXJyYXkgKG51bSkge1xuICAgIHZhciB3ID0gbmV3IEFycmF5KG51bS5iaXRMZW5ndGgoKSk7XG5cbiAgICBmb3IgKHZhciBiaXQgPSAwOyBiaXQgPCB3Lmxlbmd0aDsgYml0KyspIHtcbiAgICAgIHZhciBvZmYgPSAoYml0IC8gMjYpIHwgMDtcbiAgICAgIHZhciB3Yml0ID0gYml0ICUgMjY7XG5cbiAgICAgIHdbYml0XSA9IChudW0ud29yZHNbb2ZmXSAmICgxIDw8IHdiaXQpKSA+Pj4gd2JpdDtcbiAgICB9XG5cbiAgICByZXR1cm4gdztcbiAgfVxuXG4gIC8vIE51bWJlciBvZiB0cmFpbGluZyB6ZXJvIGJpdHNcbiAgQk4ucHJvdG90eXBlLnplcm9CaXRzID0gZnVuY3Rpb24gemVyb0JpdHMgKCkge1xuICAgIGlmICh0aGlzLmlzWmVybygpKSByZXR1cm4gMDtcblxuICAgIHZhciByID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBiID0gdGhpcy5femVyb0JpdHModGhpcy53b3Jkc1tpXSk7XG4gICAgICByICs9IGI7XG4gICAgICBpZiAoYiAhPT0gMjYpIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gcjtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuYnl0ZUxlbmd0aCA9IGZ1bmN0aW9uIGJ5dGVMZW5ndGggKCkge1xuICAgIHJldHVybiBNYXRoLmNlaWwodGhpcy5iaXRMZW5ndGgoKSAvIDgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS50b1R3b3MgPSBmdW5jdGlvbiB0b1R3b3MgKHdpZHRoKSB7XG4gICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIHJldHVybiB0aGlzLmFicygpLmlub3RuKHdpZHRoKS5pYWRkbigxKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZnJvbVR3b3MgPSBmdW5jdGlvbiBmcm9tVHdvcyAod2lkdGgpIHtcbiAgICBpZiAodGhpcy50ZXN0bih3aWR0aCAtIDEpKSB7XG4gICAgICByZXR1cm4gdGhpcy5ub3RuKHdpZHRoKS5pYWRkbigxKS5pbmVnKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNsb25lKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmlzTmVnID0gZnVuY3Rpb24gaXNOZWcgKCkge1xuICAgIHJldHVybiB0aGlzLm5lZ2F0aXZlICE9PSAwO1xuICB9O1xuXG4gIC8vIFJldHVybiBuZWdhdGl2ZSBjbG9uZSBvZiBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLm5lZyA9IGZ1bmN0aW9uIG5lZyAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pbmVnKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmluZWcgPSBmdW5jdGlvbiBpbmVnICgpIHtcbiAgICBpZiAoIXRoaXMuaXNaZXJvKCkpIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgXj0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvLyBPciBgbnVtYCB3aXRoIGB0aGlzYCBpbi1wbGFjZVxuICBCTi5wcm90b3R5cGUuaXVvciA9IGZ1bmN0aW9uIGl1b3IgKG51bSkge1xuICAgIHdoaWxlICh0aGlzLmxlbmd0aCA8IG51bS5sZW5ndGgpIHtcbiAgICAgIHRoaXMud29yZHNbdGhpcy5sZW5ndGgrK10gPSAwO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbnVtLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gdGhpcy53b3Jkc1tpXSB8IG51bS53b3Jkc1tpXTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5pb3IgPSBmdW5jdGlvbiBpb3IgKG51bSkge1xuICAgIGFzc2VydCgodGhpcy5uZWdhdGl2ZSB8IG51bS5uZWdhdGl2ZSkgPT09IDApO1xuICAgIHJldHVybiB0aGlzLml1b3IobnVtKTtcbiAgfTtcblxuICAvLyBPciBgbnVtYCB3aXRoIGB0aGlzYFxuICBCTi5wcm90b3R5cGUub3IgPSBmdW5jdGlvbiBvciAobnVtKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkgcmV0dXJuIHRoaXMuY2xvbmUoKS5pb3IobnVtKTtcbiAgICByZXR1cm4gbnVtLmNsb25lKCkuaW9yKHRoaXMpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS51b3IgPSBmdW5jdGlvbiB1b3IgKG51bSkge1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHJldHVybiB0aGlzLmNsb25lKCkuaXVvcihudW0pO1xuICAgIHJldHVybiBudW0uY2xvbmUoKS5pdW9yKHRoaXMpO1xuICB9O1xuXG4gIC8vIEFuZCBgbnVtYCB3aXRoIGB0aGlzYCBpbi1wbGFjZVxuICBCTi5wcm90b3R5cGUuaXVhbmQgPSBmdW5jdGlvbiBpdWFuZCAobnVtKSB7XG4gICAgLy8gYiA9IG1pbi1sZW5ndGgobnVtLCB0aGlzKVxuICAgIHZhciBiO1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHtcbiAgICAgIGIgPSBudW07XG4gICAgfSBlbHNlIHtcbiAgICAgIGIgPSB0aGlzO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYi5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IHRoaXMud29yZHNbaV0gJiBudW0ud29yZHNbaV07XG4gICAgfVxuXG4gICAgdGhpcy5sZW5ndGggPSBiLmxlbmd0aDtcblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmlhbmQgPSBmdW5jdGlvbiBpYW5kIChudW0pIHtcbiAgICBhc3NlcnQoKHRoaXMubmVnYXRpdmUgfCBudW0ubmVnYXRpdmUpID09PSAwKTtcbiAgICByZXR1cm4gdGhpcy5pdWFuZChudW0pO1xuICB9O1xuXG4gIC8vIEFuZCBgbnVtYCB3aXRoIGB0aGlzYFxuICBCTi5wcm90b3R5cGUuYW5kID0gZnVuY3Rpb24gYW5kIChudW0pIHtcbiAgICBpZiAodGhpcy5sZW5ndGggPiBudW0ubGVuZ3RoKSByZXR1cm4gdGhpcy5jbG9uZSgpLmlhbmQobnVtKTtcbiAgICByZXR1cm4gbnVtLmNsb25lKCkuaWFuZCh0aGlzKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUudWFuZCA9IGZ1bmN0aW9uIHVhbmQgKG51bSkge1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHJldHVybiB0aGlzLmNsb25lKCkuaXVhbmQobnVtKTtcbiAgICByZXR1cm4gbnVtLmNsb25lKCkuaXVhbmQodGhpcyk7XG4gIH07XG5cbiAgLy8gWG9yIGBudW1gIHdpdGggYHRoaXNgIGluLXBsYWNlXG4gIEJOLnByb3RvdHlwZS5pdXhvciA9IGZ1bmN0aW9uIGl1eG9yIChudW0pIHtcbiAgICAvLyBhLmxlbmd0aCA+IGIubGVuZ3RoXG4gICAgdmFyIGE7XG4gICAgdmFyIGI7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkge1xuICAgICAgYSA9IHRoaXM7XG4gICAgICBiID0gbnVtO1xuICAgIH0gZWxzZSB7XG4gICAgICBhID0gbnVtO1xuICAgICAgYiA9IHRoaXM7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBiLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gYS53b3Jkc1tpXSBeIGIud29yZHNbaV07XG4gICAgfVxuXG4gICAgaWYgKHRoaXMgIT09IGEpIHtcbiAgICAgIGZvciAoOyBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgICAgICB0aGlzLndvcmRzW2ldID0gYS53b3Jkc1tpXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmxlbmd0aCA9IGEubGVuZ3RoO1xuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaXhvciA9IGZ1bmN0aW9uIGl4b3IgKG51bSkge1xuICAgIGFzc2VydCgodGhpcy5uZWdhdGl2ZSB8IG51bS5uZWdhdGl2ZSkgPT09IDApO1xuICAgIHJldHVybiB0aGlzLml1eG9yKG51bSk7XG4gIH07XG5cbiAgLy8gWG9yIGBudW1gIHdpdGggYHRoaXNgXG4gIEJOLnByb3RvdHlwZS54b3IgPSBmdW5jdGlvbiB4b3IgKG51bSkge1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHJldHVybiB0aGlzLmNsb25lKCkuaXhvcihudW0pO1xuICAgIHJldHVybiBudW0uY2xvbmUoKS5peG9yKHRoaXMpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS51eG9yID0gZnVuY3Rpb24gdXhvciAobnVtKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkgcmV0dXJuIHRoaXMuY2xvbmUoKS5pdXhvcihudW0pO1xuICAgIHJldHVybiBudW0uY2xvbmUoKS5pdXhvcih0aGlzKTtcbiAgfTtcblxuICAvLyBOb3QgYGB0aGlzYGAgd2l0aCBgYHdpZHRoYGAgYml0d2lkdGhcbiAgQk4ucHJvdG90eXBlLmlub3RuID0gZnVuY3Rpb24gaW5vdG4gKHdpZHRoKSB7XG4gICAgYXNzZXJ0KHR5cGVvZiB3aWR0aCA9PT0gJ251bWJlcicgJiYgd2lkdGggPj0gMCk7XG5cbiAgICB2YXIgYnl0ZXNOZWVkZWQgPSBNYXRoLmNlaWwod2lkdGggLyAyNikgfCAwO1xuICAgIHZhciBiaXRzTGVmdCA9IHdpZHRoICUgMjY7XG5cbiAgICAvLyBFeHRlbmQgdGhlIGJ1ZmZlciB3aXRoIGxlYWRpbmcgemVyb2VzXG4gICAgd2hpbGUgKHRoaXMubGVuZ3RoIDwgYnl0ZXNOZWVkZWQpIHtcbiAgICAgIHRoaXMud29yZHNbdGhpcy5sZW5ndGgrK10gPSAwO1xuICAgIH1cblxuICAgIGlmIChiaXRzTGVmdCA+IDApIHtcbiAgICAgIGJ5dGVzTmVlZGVkLS07XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIGNvbXBsZXRlIHdvcmRzXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlc05lZWRlZDsgaSsrKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gfnRoaXMud29yZHNbaV0gJiAweDNmZmZmZmY7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIHRoZSByZXNpZHVlXG4gICAgaWYgKGJpdHNMZWZ0ID4gMCkge1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IH50aGlzLndvcmRzW2ldICYgKDB4M2ZmZmZmZiA+PiAoMjYgLSBiaXRzTGVmdCkpO1xuICAgIH1cblxuICAgIC8vIEFuZCByZW1vdmUgbGVhZGluZyB6ZXJvZXNcbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5ub3RuID0gZnVuY3Rpb24gbm90biAod2lkdGgpIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmlub3RuKHdpZHRoKTtcbiAgfTtcblxuICAvLyBTZXQgYGJpdGAgb2YgYHRoaXNgXG4gIEJOLnByb3RvdHlwZS5zZXRuID0gZnVuY3Rpb24gc2V0biAoYml0LCB2YWwpIHtcbiAgICBhc3NlcnQodHlwZW9mIGJpdCA9PT0gJ251bWJlcicgJiYgYml0ID49IDApO1xuXG4gICAgdmFyIG9mZiA9IChiaXQgLyAyNikgfCAwO1xuICAgIHZhciB3Yml0ID0gYml0ICUgMjY7XG5cbiAgICB3aGlsZSAodGhpcy5sZW5ndGggPD0gb2ZmKSB7XG4gICAgICB0aGlzLndvcmRzW3RoaXMubGVuZ3RoKytdID0gMDtcbiAgICB9XG5cbiAgICBpZiAodmFsKSB7XG4gICAgICB0aGlzLndvcmRzW29mZl0gPSB0aGlzLndvcmRzW29mZl0gfCAoMSA8PCB3Yml0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy53b3Jkc1tvZmZdID0gdGhpcy53b3Jkc1tvZmZdICYgfigxIDw8IHdiaXQpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgLy8gQWRkIGBudW1gIHRvIGB0aGlzYCBpbi1wbGFjZVxuICBCTi5wcm90b3R5cGUuaWFkZCA9IGZ1bmN0aW9uIGlhZGQgKG51bSkge1xuICAgIHZhciByO1xuXG4gICAgLy8gbmVnYXRpdmUgKyBwb3NpdGl2ZVxuICAgIGlmICh0aGlzLm5lZ2F0aXZlICE9PSAwICYmIG51bS5uZWdhdGl2ZSA9PT0gMCkge1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDA7XG4gICAgICByID0gdGhpcy5pc3ViKG51bSk7XG4gICAgICB0aGlzLm5lZ2F0aXZlIF49IDE7XG4gICAgICByZXR1cm4gdGhpcy5fbm9ybVNpZ24oKTtcblxuICAgIC8vIHBvc2l0aXZlICsgbmVnYXRpdmVcbiAgICB9IGVsc2UgaWYgKHRoaXMubmVnYXRpdmUgPT09IDAgJiYgbnVtLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICBudW0ubmVnYXRpdmUgPSAwO1xuICAgICAgciA9IHRoaXMuaXN1YihudW0pO1xuICAgICAgbnVtLm5lZ2F0aXZlID0gMTtcbiAgICAgIHJldHVybiByLl9ub3JtU2lnbigpO1xuICAgIH1cblxuICAgIC8vIGEubGVuZ3RoID4gYi5sZW5ndGhcbiAgICB2YXIgYSwgYjtcbiAgICBpZiAodGhpcy5sZW5ndGggPiBudW0ubGVuZ3RoKSB7XG4gICAgICBhID0gdGhpcztcbiAgICAgIGIgPSBudW07XG4gICAgfSBlbHNlIHtcbiAgICAgIGEgPSBudW07XG4gICAgICBiID0gdGhpcztcbiAgICB9XG5cbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYi5sZW5ndGg7IGkrKykge1xuICAgICAgciA9IChhLndvcmRzW2ldIHwgMCkgKyAoYi53b3Jkc1tpXSB8IDApICsgY2Fycnk7XG4gICAgICB0aGlzLndvcmRzW2ldID0gciAmIDB4M2ZmZmZmZjtcbiAgICAgIGNhcnJ5ID0gciA+Pj4gMjY7XG4gICAgfVxuICAgIGZvciAoOyBjYXJyeSAhPT0gMCAmJiBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgICAgciA9IChhLndvcmRzW2ldIHwgMCkgKyBjYXJyeTtcbiAgICAgIHRoaXMud29yZHNbaV0gPSByICYgMHgzZmZmZmZmO1xuICAgICAgY2FycnkgPSByID4+PiAyNjtcbiAgICB9XG5cbiAgICB0aGlzLmxlbmd0aCA9IGEubGVuZ3RoO1xuICAgIGlmIChjYXJyeSAhPT0gMCkge1xuICAgICAgdGhpcy53b3Jkc1t0aGlzLmxlbmd0aF0gPSBjYXJyeTtcbiAgICAgIHRoaXMubGVuZ3RoKys7XG4gICAgLy8gQ29weSB0aGUgcmVzdCBvZiB0aGUgd29yZHNcbiAgICB9IGVsc2UgaWYgKGEgIT09IHRoaXMpIHtcbiAgICAgIGZvciAoOyBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgICAgICB0aGlzLndvcmRzW2ldID0gYS53b3Jkc1tpXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvLyBBZGQgYG51bWAgdG8gYHRoaXNgXG4gIEJOLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiBhZGQgKG51bSkge1xuICAgIHZhciByZXM7XG4gICAgaWYgKG51bS5uZWdhdGl2ZSAhPT0gMCAmJiB0aGlzLm5lZ2F0aXZlID09PSAwKSB7XG4gICAgICBudW0ubmVnYXRpdmUgPSAwO1xuICAgICAgcmVzID0gdGhpcy5zdWIobnVtKTtcbiAgICAgIG51bS5uZWdhdGl2ZSBePSAxO1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9IGVsc2UgaWYgKG51bS5uZWdhdGl2ZSA9PT0gMCAmJiB0aGlzLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMDtcbiAgICAgIHJlcyA9IG51bS5zdWIodGhpcyk7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMTtcbiAgICAgIHJldHVybiByZXM7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkgcmV0dXJuIHRoaXMuY2xvbmUoKS5pYWRkKG51bSk7XG5cbiAgICByZXR1cm4gbnVtLmNsb25lKCkuaWFkZCh0aGlzKTtcbiAgfTtcblxuICAvLyBTdWJ0cmFjdCBgbnVtYCBmcm9tIGB0aGlzYCBpbi1wbGFjZVxuICBCTi5wcm90b3R5cGUuaXN1YiA9IGZ1bmN0aW9uIGlzdWIgKG51bSkge1xuICAgIC8vIHRoaXMgLSAoLW51bSkgPSB0aGlzICsgbnVtXG4gICAgaWYgKG51bS5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgbnVtLm5lZ2F0aXZlID0gMDtcbiAgICAgIHZhciByID0gdGhpcy5pYWRkKG51bSk7XG4gICAgICBudW0ubmVnYXRpdmUgPSAxO1xuICAgICAgcmV0dXJuIHIuX25vcm1TaWduKCk7XG5cbiAgICAvLyAtdGhpcyAtIG51bSA9IC0odGhpcyArIG51bSlcbiAgICB9IGVsc2UgaWYgKHRoaXMubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgICAgdGhpcy5pYWRkKG51bSk7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMTtcbiAgICAgIHJldHVybiB0aGlzLl9ub3JtU2lnbigpO1xuICAgIH1cblxuICAgIC8vIEF0IHRoaXMgcG9pbnQgYm90aCBudW1iZXJzIGFyZSBwb3NpdGl2ZVxuICAgIHZhciBjbXAgPSB0aGlzLmNtcChudW0pO1xuXG4gICAgLy8gT3B0aW1pemF0aW9uIC0gemVyb2lmeVxuICAgIGlmIChjbXAgPT09IDApIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgICAgdGhpcy5sZW5ndGggPSAxO1xuICAgICAgdGhpcy53b3Jkc1swXSA9IDA7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvLyBhID4gYlxuICAgIHZhciBhLCBiO1xuICAgIGlmIChjbXAgPiAwKSB7XG4gICAgICBhID0gdGhpcztcbiAgICAgIGIgPSBudW07XG4gICAgfSBlbHNlIHtcbiAgICAgIGEgPSBudW07XG4gICAgICBiID0gdGhpcztcbiAgICB9XG5cbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYi5sZW5ndGg7IGkrKykge1xuICAgICAgciA9IChhLndvcmRzW2ldIHwgMCkgLSAoYi53b3Jkc1tpXSB8IDApICsgY2Fycnk7XG4gICAgICBjYXJyeSA9IHIgPj4gMjY7XG4gICAgICB0aGlzLndvcmRzW2ldID0gciAmIDB4M2ZmZmZmZjtcbiAgICB9XG4gICAgZm9yICg7IGNhcnJ5ICE9PSAwICYmIGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICByID0gKGEud29yZHNbaV0gfCAwKSArIGNhcnJ5O1xuICAgICAgY2FycnkgPSByID4+IDI2O1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IHIgJiAweDNmZmZmZmY7XG4gICAgfVxuXG4gICAgLy8gQ29weSByZXN0IG9mIHRoZSB3b3Jkc1xuICAgIGlmIChjYXJyeSA9PT0gMCAmJiBpIDwgYS5sZW5ndGggJiYgYSAhPT0gdGhpcykge1xuICAgICAgZm9yICg7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMud29yZHNbaV0gPSBhLndvcmRzW2ldO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMubGVuZ3RoID0gTWF0aC5tYXgodGhpcy5sZW5ndGgsIGkpO1xuXG4gICAgaWYgKGEgIT09IHRoaXMpIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAxO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgLy8gU3VidHJhY3QgYG51bWAgZnJvbSBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLnN1YiA9IGZ1bmN0aW9uIHN1YiAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pc3ViKG51bSk7XG4gIH07XG5cbiAgZnVuY3Rpb24gc21hbGxNdWxUbyAoc2VsZiwgbnVtLCBvdXQpIHtcbiAgICBvdXQubmVnYXRpdmUgPSBudW0ubmVnYXRpdmUgXiBzZWxmLm5lZ2F0aXZlO1xuICAgIHZhciBsZW4gPSAoc2VsZi5sZW5ndGggKyBudW0ubGVuZ3RoKSB8IDA7XG4gICAgb3V0Lmxlbmd0aCA9IGxlbjtcbiAgICBsZW4gPSAobGVuIC0gMSkgfCAwO1xuXG4gICAgLy8gUGVlbCBvbmUgaXRlcmF0aW9uIChjb21waWxlciBjYW4ndCBkbyBpdCwgYmVjYXVzZSBvZiBjb2RlIGNvbXBsZXhpdHkpXG4gICAgdmFyIGEgPSBzZWxmLndvcmRzWzBdIHwgMDtcbiAgICB2YXIgYiA9IG51bS53b3Jkc1swXSB8IDA7XG4gICAgdmFyIHIgPSBhICogYjtcblxuICAgIHZhciBsbyA9IHIgJiAweDNmZmZmZmY7XG4gICAgdmFyIGNhcnJ5ID0gKHIgLyAweDQwMDAwMDApIHwgMDtcbiAgICBvdXQud29yZHNbMF0gPSBsbztcblxuICAgIGZvciAodmFyIGsgPSAxOyBrIDwgbGVuOyBrKyspIHtcbiAgICAgIC8vIFN1bSBhbGwgd29yZHMgd2l0aCB0aGUgc2FtZSBgaSArIGogPSBrYCBhbmQgYWNjdW11bGF0ZSBgbmNhcnJ5YCxcbiAgICAgIC8vIG5vdGUgdGhhdCBuY2FycnkgY291bGQgYmUgPj0gMHgzZmZmZmZmXG4gICAgICB2YXIgbmNhcnJ5ID0gY2FycnkgPj4+IDI2O1xuICAgICAgdmFyIHJ3b3JkID0gY2FycnkgJiAweDNmZmZmZmY7XG4gICAgICB2YXIgbWF4SiA9IE1hdGgubWluKGssIG51bS5sZW5ndGggLSAxKTtcbiAgICAgIGZvciAodmFyIGogPSBNYXRoLm1heCgwLCBrIC0gc2VsZi5sZW5ndGggKyAxKTsgaiA8PSBtYXhKOyBqKyspIHtcbiAgICAgICAgdmFyIGkgPSAoayAtIGopIHwgMDtcbiAgICAgICAgYSA9IHNlbGYud29yZHNbaV0gfCAwO1xuICAgICAgICBiID0gbnVtLndvcmRzW2pdIHwgMDtcbiAgICAgICAgciA9IGEgKiBiICsgcndvcmQ7XG4gICAgICAgIG5jYXJyeSArPSAociAvIDB4NDAwMDAwMCkgfCAwO1xuICAgICAgICByd29yZCA9IHIgJiAweDNmZmZmZmY7XG4gICAgICB9XG4gICAgICBvdXQud29yZHNba10gPSByd29yZCB8IDA7XG4gICAgICBjYXJyeSA9IG5jYXJyeSB8IDA7XG4gICAgfVxuICAgIGlmIChjYXJyeSAhPT0gMCkge1xuICAgICAgb3V0LndvcmRzW2tdID0gY2FycnkgfCAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXQubGVuZ3RoLS07XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dC5zdHJpcCgpO1xuICB9XG5cbiAgLy8gVE9ETyhpbmR1dG55KTogaXQgbWF5IGJlIHJlYXNvbmFibGUgdG8gb21pdCBpdCBmb3IgdXNlcnMgd2hvIGRvbid0IG5lZWRcbiAgLy8gdG8gd29yayB3aXRoIDI1Ni1iaXQgbnVtYmVycywgb3RoZXJ3aXNlIGl0IGdpdmVzIDIwJSBpbXByb3ZlbWVudCBmb3IgMjU2LWJpdFxuICAvLyBtdWx0aXBsaWNhdGlvbiAobGlrZSBlbGxpcHRpYyBzZWNwMjU2azEpLlxuICB2YXIgY29tYjEwTXVsVG8gPSBmdW5jdGlvbiBjb21iMTBNdWxUbyAoc2VsZiwgbnVtLCBvdXQpIHtcbiAgICB2YXIgYSA9IHNlbGYud29yZHM7XG4gICAgdmFyIGIgPSBudW0ud29yZHM7XG4gICAgdmFyIG8gPSBvdXQud29yZHM7XG4gICAgdmFyIGMgPSAwO1xuICAgIHZhciBsbztcbiAgICB2YXIgbWlkO1xuICAgIHZhciBoaTtcbiAgICB2YXIgYTAgPSBhWzBdIHwgMDtcbiAgICB2YXIgYWwwID0gYTAgJiAweDFmZmY7XG4gICAgdmFyIGFoMCA9IGEwID4+PiAxMztcbiAgICB2YXIgYTEgPSBhWzFdIHwgMDtcbiAgICB2YXIgYWwxID0gYTEgJiAweDFmZmY7XG4gICAgdmFyIGFoMSA9IGExID4+PiAxMztcbiAgICB2YXIgYTIgPSBhWzJdIHwgMDtcbiAgICB2YXIgYWwyID0gYTIgJiAweDFmZmY7XG4gICAgdmFyIGFoMiA9IGEyID4+PiAxMztcbiAgICB2YXIgYTMgPSBhWzNdIHwgMDtcbiAgICB2YXIgYWwzID0gYTMgJiAweDFmZmY7XG4gICAgdmFyIGFoMyA9IGEzID4+PiAxMztcbiAgICB2YXIgYTQgPSBhWzRdIHwgMDtcbiAgICB2YXIgYWw0ID0gYTQgJiAweDFmZmY7XG4gICAgdmFyIGFoNCA9IGE0ID4+PiAxMztcbiAgICB2YXIgYTUgPSBhWzVdIHwgMDtcbiAgICB2YXIgYWw1ID0gYTUgJiAweDFmZmY7XG4gICAgdmFyIGFoNSA9IGE1ID4+PiAxMztcbiAgICB2YXIgYTYgPSBhWzZdIHwgMDtcbiAgICB2YXIgYWw2ID0gYTYgJiAweDFmZmY7XG4gICAgdmFyIGFoNiA9IGE2ID4+PiAxMztcbiAgICB2YXIgYTcgPSBhWzddIHwgMDtcbiAgICB2YXIgYWw3ID0gYTcgJiAweDFmZmY7XG4gICAgdmFyIGFoNyA9IGE3ID4+PiAxMztcbiAgICB2YXIgYTggPSBhWzhdIHwgMDtcbiAgICB2YXIgYWw4ID0gYTggJiAweDFmZmY7XG4gICAgdmFyIGFoOCA9IGE4ID4+PiAxMztcbiAgICB2YXIgYTkgPSBhWzldIHwgMDtcbiAgICB2YXIgYWw5ID0gYTkgJiAweDFmZmY7XG4gICAgdmFyIGFoOSA9IGE5ID4+PiAxMztcbiAgICB2YXIgYjAgPSBiWzBdIHwgMDtcbiAgICB2YXIgYmwwID0gYjAgJiAweDFmZmY7XG4gICAgdmFyIGJoMCA9IGIwID4+PiAxMztcbiAgICB2YXIgYjEgPSBiWzFdIHwgMDtcbiAgICB2YXIgYmwxID0gYjEgJiAweDFmZmY7XG4gICAgdmFyIGJoMSA9IGIxID4+PiAxMztcbiAgICB2YXIgYjIgPSBiWzJdIHwgMDtcbiAgICB2YXIgYmwyID0gYjIgJiAweDFmZmY7XG4gICAgdmFyIGJoMiA9IGIyID4+PiAxMztcbiAgICB2YXIgYjMgPSBiWzNdIHwgMDtcbiAgICB2YXIgYmwzID0gYjMgJiAweDFmZmY7XG4gICAgdmFyIGJoMyA9IGIzID4+PiAxMztcbiAgICB2YXIgYjQgPSBiWzRdIHwgMDtcbiAgICB2YXIgYmw0ID0gYjQgJiAweDFmZmY7XG4gICAgdmFyIGJoNCA9IGI0ID4+PiAxMztcbiAgICB2YXIgYjUgPSBiWzVdIHwgMDtcbiAgICB2YXIgYmw1ID0gYjUgJiAweDFmZmY7XG4gICAgdmFyIGJoNSA9IGI1ID4+PiAxMztcbiAgICB2YXIgYjYgPSBiWzZdIHwgMDtcbiAgICB2YXIgYmw2ID0gYjYgJiAweDFmZmY7XG4gICAgdmFyIGJoNiA9IGI2ID4+PiAxMztcbiAgICB2YXIgYjcgPSBiWzddIHwgMDtcbiAgICB2YXIgYmw3ID0gYjcgJiAweDFmZmY7XG4gICAgdmFyIGJoNyA9IGI3ID4+PiAxMztcbiAgICB2YXIgYjggPSBiWzhdIHwgMDtcbiAgICB2YXIgYmw4ID0gYjggJiAweDFmZmY7XG4gICAgdmFyIGJoOCA9IGI4ID4+PiAxMztcbiAgICB2YXIgYjkgPSBiWzldIHwgMDtcbiAgICB2YXIgYmw5ID0gYjkgJiAweDFmZmY7XG4gICAgdmFyIGJoOSA9IGI5ID4+PiAxMztcblxuICAgIG91dC5uZWdhdGl2ZSA9IHNlbGYubmVnYXRpdmUgXiBudW0ubmVnYXRpdmU7XG4gICAgb3V0Lmxlbmd0aCA9IDE5O1xuICAgIC8qIGsgPSAwICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWwwLCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDAsIGJoMCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDAsIGJsMCk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWgwLCBiaDApO1xuICAgIHZhciB3MCA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcwID4+PiAyNik7XG4gICAgdzAgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAxICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWwxLCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDEsIGJoMCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDEsIGJsMCk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWgxLCBiaDApO1xuICAgIGxvICs9IE1hdGguaW11bChhbDAsIGJsMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDAsIGJoMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDAsIGJsMSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMCwgYmgxKTtcbiAgICB2YXIgdzEgPSBjICsgbG8gKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpO1xuICAgIGMgPSBoaSArIChtaWQgPj4+IDEzKSArICh3MSA+Pj4gMjYpO1xuICAgIHcxICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gMiAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsMiwgYmwwKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWwyLCBiaDApO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgyLCBibDApO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoMiwgYmgwKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwxLCBibDEpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwxLCBiaDEpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgxLCBibDEpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDEsIGJoMSk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMCwgYmwyKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMCwgYmgyKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMCwgYmwyKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgwLCBiaDIpO1xuICAgIHZhciB3MiA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcyID4+PiAyNik7XG4gICAgdzIgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAzICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWwzLCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDMsIGJoMCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDMsIGJsMCk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWgzLCBiaDApO1xuICAgIGxvICs9IE1hdGguaW11bChhbDIsIGJsMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDIsIGJoMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDIsIGJsMSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMiwgYmgxKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwxLCBibDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwxLCBiaDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgxLCBibDIpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDEsIGJoMik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMCwgYmwzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMCwgYmgzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMCwgYmwzKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgwLCBiaDMpO1xuICAgIHZhciB3MyA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHczID4+PiAyNik7XG4gICAgdzMgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSA0ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw0LCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDQsIGJoMCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDQsIGJsMCk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg0LCBiaDApO1xuICAgIGxvICs9IE1hdGguaW11bChhbDMsIGJsMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDMsIGJoMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDMsIGJsMSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMywgYmgxKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwyLCBibDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwyLCBiaDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgyLCBibDIpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDIsIGJoMik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMSwgYmwzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMSwgYmgzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMSwgYmwzKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgxLCBiaDMpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDAsIGJsNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDAsIGJoNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDAsIGJsNCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMCwgYmg0KTtcbiAgICB2YXIgdzQgPSBjICsgbG8gKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpO1xuICAgIGMgPSBoaSArIChtaWQgPj4+IDEzKSArICh3NCA+Pj4gMjYpO1xuICAgIHc0ICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gNSAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsNSwgYmwwKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw1LCBiaDApO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg1LCBibDApO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoNSwgYmgwKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw0LCBibDEpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw0LCBiaDEpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg0LCBibDEpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDQsIGJoMSk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMywgYmwyKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMywgYmgyKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMywgYmwyKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgzLCBiaDIpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDIsIGJsMyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDIsIGJoMyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDIsIGJsMyk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMiwgYmgzKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwxLCBibDQpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwxLCBiaDQpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgxLCBibDQpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDEsIGJoNCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMCwgYmw1KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMCwgYmg1KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMCwgYmw1KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgwLCBiaDUpO1xuICAgIHZhciB3NSA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHc1ID4+PiAyNik7XG4gICAgdzUgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSA2ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw2LCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDYsIGJoMCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDYsIGJsMCk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg2LCBiaDApO1xuICAgIGxvICs9IE1hdGguaW11bChhbDUsIGJsMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDUsIGJoMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDUsIGJsMSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNSwgYmgxKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw0LCBibDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw0LCBiaDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg0LCBibDIpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDQsIGJoMik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMywgYmwzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMywgYmgzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMywgYmwzKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgzLCBiaDMpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDIsIGJsNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDIsIGJoNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDIsIGJsNCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMiwgYmg0KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwxLCBibDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwxLCBiaDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgxLCBibDUpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDEsIGJoNSk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMCwgYmw2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMCwgYmg2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMCwgYmw2KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgwLCBiaDYpO1xuICAgIHZhciB3NiA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHc2ID4+PiAyNik7XG4gICAgdzYgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSA3ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw3LCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDcsIGJoMCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDcsIGJsMCk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg3LCBiaDApO1xuICAgIGxvICs9IE1hdGguaW11bChhbDYsIGJsMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDYsIGJoMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDYsIGJsMSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNiwgYmgxKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw1LCBibDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw1LCBiaDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg1LCBibDIpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDUsIGJoMik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNCwgYmwzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNCwgYmgzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNCwgYmwzKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg0LCBiaDMpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDMsIGJsNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDMsIGJoNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDMsIGJsNCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMywgYmg0KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwyLCBibDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwyLCBiaDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgyLCBibDUpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDIsIGJoNSk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMSwgYmw2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMSwgYmg2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMSwgYmw2KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgxLCBiaDYpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDAsIGJsNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDAsIGJoNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDAsIGJsNyk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMCwgYmg3KTtcbiAgICB2YXIgdzcgPSBjICsgbG8gKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpO1xuICAgIGMgPSBoaSArIChtaWQgPj4+IDEzKSArICh3NyA+Pj4gMjYpO1xuICAgIHc3ICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gOCAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOCwgYmwwKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw4LCBiaDApO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg4LCBibDApO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoOCwgYmgwKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw3LCBibDEpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw3LCBiaDEpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg3LCBibDEpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDcsIGJoMSk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNiwgYmwyKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNiwgYmgyKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNiwgYmwyKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg2LCBiaDIpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDUsIGJsMyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDUsIGJoMyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDUsIGJsMyk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNSwgYmgzKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw0LCBibDQpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw0LCBiaDQpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg0LCBibDQpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDQsIGJoNCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMywgYmw1KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMywgYmg1KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMywgYmw1KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgzLCBiaDUpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDIsIGJsNik7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDIsIGJoNik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDIsIGJsNik7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMiwgYmg2KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwxLCBibDcpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwxLCBiaDcpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgxLCBibDcpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDEsIGJoNyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMCwgYmw4KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMCwgYmg4KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMCwgYmw4KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgwLCBiaDgpO1xuICAgIHZhciB3OCA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHc4ID4+PiAyNik7XG4gICAgdzggJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSA5ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoMCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDksIGJsMCk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDApO1xuICAgIGxvICs9IE1hdGguaW11bChhbDgsIGJsMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDgsIGJoMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDgsIGJsMSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoOCwgYmgxKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw3LCBibDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw3LCBiaDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg3LCBibDIpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDcsIGJoMik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNiwgYmwzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNiwgYmgzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNiwgYmwzKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg2LCBiaDMpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDUsIGJsNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDUsIGJoNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDUsIGJsNCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNSwgYmg0KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw0LCBibDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw0LCBiaDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg0LCBibDUpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDQsIGJoNSk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMywgYmw2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMywgYmg2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMywgYmw2KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgzLCBiaDYpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDIsIGJsNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDIsIGJoNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDIsIGJsNyk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMiwgYmg3KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwxLCBibDgpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwxLCBiaDgpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgxLCBibDgpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDEsIGJoOCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMCwgYmw5KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMCwgYmg5KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMCwgYmw5KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgwLCBiaDkpO1xuICAgIHZhciB3OSA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHc5ID4+PiAyNik7XG4gICAgdzkgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAxMCAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOSwgYmwxKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw5LCBiaDEpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg5LCBibDEpO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoOSwgYmgxKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw4LCBibDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw4LCBiaDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg4LCBibDIpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDgsIGJoMik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNywgYmwzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNywgYmgzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNywgYmwzKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg3LCBiaDMpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDYsIGJsNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDYsIGJoNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDYsIGJsNCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNiwgYmg0KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw1LCBibDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw1LCBiaDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg1LCBibDUpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDUsIGJoNSk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNCwgYmw2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNCwgYmg2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNCwgYmw2KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg0LCBiaDYpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDMsIGJsNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDMsIGJoNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDMsIGJsNyk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMywgYmg3KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwyLCBibDgpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwyLCBiaDgpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgyLCBibDgpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDIsIGJoOCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMSwgYmw5KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMSwgYmg5KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMSwgYmw5KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgxLCBiaDkpO1xuICAgIHZhciB3MTAgPSBjICsgbG8gKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpO1xuICAgIGMgPSBoaSArIChtaWQgPj4+IDEzKSArICh3MTAgPj4+IDI2KTtcbiAgICB3MTAgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAxMSAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOSwgYmwyKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw5LCBiaDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg5LCBibDIpO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoOSwgYmgyKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw4LCBibDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw4LCBiaDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg4LCBibDMpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDgsIGJoMyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNywgYmw0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNywgYmg0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNywgYmw0KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg3LCBiaDQpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDYsIGJsNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDYsIGJoNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDYsIGJsNSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNiwgYmg1KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw1LCBibDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw1LCBiaDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg1LCBibDYpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDUsIGJoNik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNCwgYmw3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNCwgYmg3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNCwgYmw3KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg0LCBiaDcpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDMsIGJsOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDMsIGJoOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDMsIGJsOCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMywgYmg4KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwyLCBibDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwyLCBiaDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgyLCBibDkpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDIsIGJoOSk7XG4gICAgdmFyIHcxMSA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcxMSA+Pj4gMjYpO1xuICAgIHcxMSAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDEyICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDMpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoMyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDksIGJsMyk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDMpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDgsIGJsNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDgsIGJoNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDgsIGJsNCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoOCwgYmg0KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw3LCBibDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw3LCBiaDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg3LCBibDUpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDcsIGJoNSk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNiwgYmw2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNiwgYmg2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNiwgYmw2KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg2LCBiaDYpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDUsIGJsNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDUsIGJoNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDUsIGJsNyk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNSwgYmg3KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw0LCBibDgpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw0LCBiaDgpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg0LCBibDgpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDQsIGJoOCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMywgYmw5KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMywgYmg5KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMywgYmw5KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgzLCBiaDkpO1xuICAgIHZhciB3MTIgPSBjICsgbG8gKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpO1xuICAgIGMgPSBoaSArIChtaWQgPj4+IDEzKSArICh3MTIgPj4+IDI2KTtcbiAgICB3MTIgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAxMyAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOSwgYmw0KTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw5LCBiaDQpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg5LCBibDQpO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoOSwgYmg0KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw4LCBibDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw4LCBiaDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg4LCBibDUpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDgsIGJoNSk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNywgYmw2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNywgYmg2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNywgYmw2KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg3LCBiaDYpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDYsIGJsNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDYsIGJoNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDYsIGJsNyk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNiwgYmg3KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw1LCBibDgpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw1LCBiaDgpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg1LCBibDgpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDUsIGJoOCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNCwgYmw5KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNCwgYmg5KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNCwgYmw5KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg0LCBiaDkpO1xuICAgIHZhciB3MTMgPSBjICsgbG8gKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpO1xuICAgIGMgPSBoaSArIChtaWQgPj4+IDEzKSArICh3MTMgPj4+IDI2KTtcbiAgICB3MTMgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAxNCAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOSwgYmw1KTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw5LCBiaDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg5LCBibDUpO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoOSwgYmg1KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw4LCBibDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw4LCBiaDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg4LCBibDYpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDgsIGJoNik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNywgYmw3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNywgYmg3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNywgYmw3KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg3LCBiaDcpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDYsIGJsOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDYsIGJoOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDYsIGJsOCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNiwgYmg4KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw1LCBibDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw1LCBiaDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg1LCBibDkpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDUsIGJoOSk7XG4gICAgdmFyIHcxNCA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcxNCA+Pj4gMjYpO1xuICAgIHcxNCAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDE1ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDYpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoNik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDksIGJsNik7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDYpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDgsIGJsNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDgsIGJoNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDgsIGJsNyk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoOCwgYmg3KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw3LCBibDgpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw3LCBiaDgpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg3LCBibDgpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDcsIGJoOCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNiwgYmw5KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNiwgYmg5KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNiwgYmw5KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg2LCBiaDkpO1xuICAgIHZhciB3MTUgPSBjICsgbG8gKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpO1xuICAgIGMgPSBoaSArIChtaWQgPj4+IDEzKSArICh3MTUgPj4+IDI2KTtcbiAgICB3MTUgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAxNiAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOSwgYmw3KTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw5LCBiaDcpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg5LCBibDcpO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoOSwgYmg3KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw4LCBibDgpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw4LCBiaDgpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg4LCBibDgpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDgsIGJoOCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNywgYmw5KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNywgYmg5KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNywgYmw5KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg3LCBiaDkpO1xuICAgIHZhciB3MTYgPSBjICsgbG8gKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpO1xuICAgIGMgPSBoaSArIChtaWQgPj4+IDEzKSArICh3MTYgPj4+IDI2KTtcbiAgICB3MTYgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAxNyAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOSwgYmw4KTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw5LCBiaDgpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg5LCBibDgpO1xuICAgIGhpID0gTWF0aC5pbXVsKGFoOSwgYmg4KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw4LCBibDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw4LCBiaDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg4LCBibDkpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDgsIGJoOSk7XG4gICAgdmFyIHcxNyA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcxNyA+Pj4gMjYpO1xuICAgIHcxNyAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDE4ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDkpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoOSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDksIGJsOSk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDkpO1xuICAgIHZhciB3MTggPSBjICsgbG8gKyAoKG1pZCAmIDB4MWZmZikgPDwgMTMpO1xuICAgIGMgPSBoaSArIChtaWQgPj4+IDEzKSArICh3MTggPj4+IDI2KTtcbiAgICB3MTggJj0gMHgzZmZmZmZmO1xuICAgIG9bMF0gPSB3MDtcbiAgICBvWzFdID0gdzE7XG4gICAgb1syXSA9IHcyO1xuICAgIG9bM10gPSB3MztcbiAgICBvWzRdID0gdzQ7XG4gICAgb1s1XSA9IHc1O1xuICAgIG9bNl0gPSB3NjtcbiAgICBvWzddID0gdzc7XG4gICAgb1s4XSA9IHc4O1xuICAgIG9bOV0gPSB3OTtcbiAgICBvWzEwXSA9IHcxMDtcbiAgICBvWzExXSA9IHcxMTtcbiAgICBvWzEyXSA9IHcxMjtcbiAgICBvWzEzXSA9IHcxMztcbiAgICBvWzE0XSA9IHcxNDtcbiAgICBvWzE1XSA9IHcxNTtcbiAgICBvWzE2XSA9IHcxNjtcbiAgICBvWzE3XSA9IHcxNztcbiAgICBvWzE4XSA9IHcxODtcbiAgICBpZiAoYyAhPT0gMCkge1xuICAgICAgb1sxOV0gPSBjO1xuICAgICAgb3V0Lmxlbmd0aCsrO1xuICAgIH1cbiAgICByZXR1cm4gb3V0O1xuICB9O1xuXG4gIC8vIFBvbHlmaWxsIGNvbWJcbiAgaWYgKCFNYXRoLmltdWwpIHtcbiAgICBjb21iMTBNdWxUbyA9IHNtYWxsTXVsVG87XG4gIH1cblxuICBmdW5jdGlvbiBiaWdNdWxUbyAoc2VsZiwgbnVtLCBvdXQpIHtcbiAgICBvdXQubmVnYXRpdmUgPSBudW0ubmVnYXRpdmUgXiBzZWxmLm5lZ2F0aXZlO1xuICAgIG91dC5sZW5ndGggPSBzZWxmLmxlbmd0aCArIG51bS5sZW5ndGg7XG5cbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIHZhciBobmNhcnJ5ID0gMDtcbiAgICBmb3IgKHZhciBrID0gMDsgayA8IG91dC5sZW5ndGggLSAxOyBrKyspIHtcbiAgICAgIC8vIFN1bSBhbGwgd29yZHMgd2l0aCB0aGUgc2FtZSBgaSArIGogPSBrYCBhbmQgYWNjdW11bGF0ZSBgbmNhcnJ5YCxcbiAgICAgIC8vIG5vdGUgdGhhdCBuY2FycnkgY291bGQgYmUgPj0gMHgzZmZmZmZmXG4gICAgICB2YXIgbmNhcnJ5ID0gaG5jYXJyeTtcbiAgICAgIGhuY2FycnkgPSAwO1xuICAgICAgdmFyIHJ3b3JkID0gY2FycnkgJiAweDNmZmZmZmY7XG4gICAgICB2YXIgbWF4SiA9IE1hdGgubWluKGssIG51bS5sZW5ndGggLSAxKTtcbiAgICAgIGZvciAodmFyIGogPSBNYXRoLm1heCgwLCBrIC0gc2VsZi5sZW5ndGggKyAxKTsgaiA8PSBtYXhKOyBqKyspIHtcbiAgICAgICAgdmFyIGkgPSBrIC0gajtcbiAgICAgICAgdmFyIGEgPSBzZWxmLndvcmRzW2ldIHwgMDtcbiAgICAgICAgdmFyIGIgPSBudW0ud29yZHNbal0gfCAwO1xuICAgICAgICB2YXIgciA9IGEgKiBiO1xuXG4gICAgICAgIHZhciBsbyA9IHIgJiAweDNmZmZmZmY7XG4gICAgICAgIG5jYXJyeSA9IChuY2FycnkgKyAoKHIgLyAweDQwMDAwMDApIHwgMCkpIHwgMDtcbiAgICAgICAgbG8gPSAobG8gKyByd29yZCkgfCAwO1xuICAgICAgICByd29yZCA9IGxvICYgMHgzZmZmZmZmO1xuICAgICAgICBuY2FycnkgPSAobmNhcnJ5ICsgKGxvID4+PiAyNikpIHwgMDtcblxuICAgICAgICBobmNhcnJ5ICs9IG5jYXJyeSA+Pj4gMjY7XG4gICAgICAgIG5jYXJyeSAmPSAweDNmZmZmZmY7XG4gICAgICB9XG4gICAgICBvdXQud29yZHNba10gPSByd29yZDtcbiAgICAgIGNhcnJ5ID0gbmNhcnJ5O1xuICAgICAgbmNhcnJ5ID0gaG5jYXJyeTtcbiAgICB9XG4gICAgaWYgKGNhcnJ5ICE9PSAwKSB7XG4gICAgICBvdXQud29yZHNba10gPSBjYXJyeTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0Lmxlbmd0aC0tO1xuICAgIH1cblxuICAgIHJldHVybiBvdXQuc3RyaXAoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGp1bWJvTXVsVG8gKHNlbGYsIG51bSwgb3V0KSB7XG4gICAgdmFyIGZmdG0gPSBuZXcgRkZUTSgpO1xuICAgIHJldHVybiBmZnRtLm11bHAoc2VsZiwgbnVtLCBvdXQpO1xuICB9XG5cbiAgQk4ucHJvdG90eXBlLm11bFRvID0gZnVuY3Rpb24gbXVsVG8gKG51bSwgb3V0KSB7XG4gICAgdmFyIHJlcztcbiAgICB2YXIgbGVuID0gdGhpcy5sZW5ndGggKyBudW0ubGVuZ3RoO1xuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMTAgJiYgbnVtLmxlbmd0aCA9PT0gMTApIHtcbiAgICAgIHJlcyA9IGNvbWIxME11bFRvKHRoaXMsIG51bSwgb3V0KTtcbiAgICB9IGVsc2UgaWYgKGxlbiA8IDYzKSB7XG4gICAgICByZXMgPSBzbWFsbE11bFRvKHRoaXMsIG51bSwgb3V0KTtcbiAgICB9IGVsc2UgaWYgKGxlbiA8IDEwMjQpIHtcbiAgICAgIHJlcyA9IGJpZ011bFRvKHRoaXMsIG51bSwgb3V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzID0ganVtYm9NdWxUbyh0aGlzLCBudW0sIG91dCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcztcbiAgfTtcblxuICAvLyBDb29sZXktVHVrZXkgYWxnb3JpdGhtIGZvciBGRlRcbiAgLy8gc2xpZ2h0bHkgcmV2aXNpdGVkIHRvIHJlbHkgb24gbG9vcGluZyBpbnN0ZWFkIG9mIHJlY3Vyc2lvblxuXG4gIGZ1bmN0aW9uIEZGVE0gKHgsIHkpIHtcbiAgICB0aGlzLnggPSB4O1xuICAgIHRoaXMueSA9IHk7XG4gIH1cblxuICBGRlRNLnByb3RvdHlwZS5tYWtlUkJUID0gZnVuY3Rpb24gbWFrZVJCVCAoTikge1xuICAgIHZhciB0ID0gbmV3IEFycmF5KE4pO1xuICAgIHZhciBsID0gQk4ucHJvdG90eXBlLl9jb3VudEJpdHMoTikgLSAxO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgTjsgaSsrKSB7XG4gICAgICB0W2ldID0gdGhpcy5yZXZCaW4oaSwgbCwgTik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHQ7XG4gIH07XG5cbiAgLy8gUmV0dXJucyBiaW5hcnktcmV2ZXJzZWQgcmVwcmVzZW50YXRpb24gb2YgYHhgXG4gIEZGVE0ucHJvdG90eXBlLnJldkJpbiA9IGZ1bmN0aW9uIHJldkJpbiAoeCwgbCwgTikge1xuICAgIGlmICh4ID09PSAwIHx8IHggPT09IE4gLSAxKSByZXR1cm4geDtcblxuICAgIHZhciByYiA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsOyBpKyspIHtcbiAgICAgIHJiIHw9ICh4ICYgMSkgPDwgKGwgLSBpIC0gMSk7XG4gICAgICB4ID4+PSAxO1xuICAgIH1cblxuICAgIHJldHVybiByYjtcbiAgfTtcblxuICAvLyBQZXJmb3JtcyBcInR3ZWVkbGluZ1wiIHBoYXNlLCB0aGVyZWZvcmUgJ2VtdWxhdGluZydcbiAgLy8gYmVoYXZpb3VyIG9mIHRoZSByZWN1cnNpdmUgYWxnb3JpdGhtXG4gIEZGVE0ucHJvdG90eXBlLnBlcm11dGUgPSBmdW5jdGlvbiBwZXJtdXRlIChyYnQsIHJ3cywgaXdzLCBydHdzLCBpdHdzLCBOKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBOOyBpKyspIHtcbiAgICAgIHJ0d3NbaV0gPSByd3NbcmJ0W2ldXTtcbiAgICAgIGl0d3NbaV0gPSBpd3NbcmJ0W2ldXTtcbiAgICB9XG4gIH07XG5cbiAgRkZUTS5wcm90b3R5cGUudHJhbnNmb3JtID0gZnVuY3Rpb24gdHJhbnNmb3JtIChyd3MsIGl3cywgcnR3cywgaXR3cywgTiwgcmJ0KSB7XG4gICAgdGhpcy5wZXJtdXRlKHJidCwgcndzLCBpd3MsIHJ0d3MsIGl0d3MsIE4pO1xuXG4gICAgZm9yICh2YXIgcyA9IDE7IHMgPCBOOyBzIDw8PSAxKSB7XG4gICAgICB2YXIgbCA9IHMgPDwgMTtcblxuICAgICAgdmFyIHJ0d2RmID0gTWF0aC5jb3MoMiAqIE1hdGguUEkgLyBsKTtcbiAgICAgIHZhciBpdHdkZiA9IE1hdGguc2luKDIgKiBNYXRoLlBJIC8gbCk7XG5cbiAgICAgIGZvciAodmFyIHAgPSAwOyBwIDwgTjsgcCArPSBsKSB7XG4gICAgICAgIHZhciBydHdkZl8gPSBydHdkZjtcbiAgICAgICAgdmFyIGl0d2RmXyA9IGl0d2RmO1xuXG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgczsgaisrKSB7XG4gICAgICAgICAgdmFyIHJlID0gcnR3c1twICsgal07XG4gICAgICAgICAgdmFyIGllID0gaXR3c1twICsgal07XG5cbiAgICAgICAgICB2YXIgcm8gPSBydHdzW3AgKyBqICsgc107XG4gICAgICAgICAgdmFyIGlvID0gaXR3c1twICsgaiArIHNdO1xuXG4gICAgICAgICAgdmFyIHJ4ID0gcnR3ZGZfICogcm8gLSBpdHdkZl8gKiBpbztcblxuICAgICAgICAgIGlvID0gcnR3ZGZfICogaW8gKyBpdHdkZl8gKiBybztcbiAgICAgICAgICBybyA9IHJ4O1xuXG4gICAgICAgICAgcnR3c1twICsgal0gPSByZSArIHJvO1xuICAgICAgICAgIGl0d3NbcCArIGpdID0gaWUgKyBpbztcblxuICAgICAgICAgIHJ0d3NbcCArIGogKyBzXSA9IHJlIC0gcm87XG4gICAgICAgICAgaXR3c1twICsgaiArIHNdID0gaWUgLSBpbztcblxuICAgICAgICAgIC8qIGpzaGludCBtYXhkZXB0aCA6IGZhbHNlICovXG4gICAgICAgICAgaWYgKGogIT09IGwpIHtcbiAgICAgICAgICAgIHJ4ID0gcnR3ZGYgKiBydHdkZl8gLSBpdHdkZiAqIGl0d2RmXztcblxuICAgICAgICAgICAgaXR3ZGZfID0gcnR3ZGYgKiBpdHdkZl8gKyBpdHdkZiAqIHJ0d2RmXztcbiAgICAgICAgICAgIHJ0d2RmXyA9IHJ4O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBGRlRNLnByb3RvdHlwZS5ndWVzc0xlbjEzYiA9IGZ1bmN0aW9uIGd1ZXNzTGVuMTNiIChuLCBtKSB7XG4gICAgdmFyIE4gPSBNYXRoLm1heChtLCBuKSB8IDE7XG4gICAgdmFyIG9kZCA9IE4gJiAxO1xuICAgIHZhciBpID0gMDtcbiAgICBmb3IgKE4gPSBOIC8gMiB8IDA7IE47IE4gPSBOID4+PiAxKSB7XG4gICAgICBpKys7XG4gICAgfVxuXG4gICAgcmV0dXJuIDEgPDwgaSArIDEgKyBvZGQ7XG4gIH07XG5cbiAgRkZUTS5wcm90b3R5cGUuY29uanVnYXRlID0gZnVuY3Rpb24gY29uanVnYXRlIChyd3MsIGl3cywgTikge1xuICAgIGlmIChOIDw9IDEpIHJldHVybjtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgTiAvIDI7IGkrKykge1xuICAgICAgdmFyIHQgPSByd3NbaV07XG5cbiAgICAgIHJ3c1tpXSA9IHJ3c1tOIC0gaSAtIDFdO1xuICAgICAgcndzW04gLSBpIC0gMV0gPSB0O1xuXG4gICAgICB0ID0gaXdzW2ldO1xuXG4gICAgICBpd3NbaV0gPSAtaXdzW04gLSBpIC0gMV07XG4gICAgICBpd3NbTiAtIGkgLSAxXSA9IC10O1xuICAgIH1cbiAgfTtcblxuICBGRlRNLnByb3RvdHlwZS5ub3JtYWxpemUxM2IgPSBmdW5jdGlvbiBub3JtYWxpemUxM2IgKHdzLCBOKSB7XG4gICAgdmFyIGNhcnJ5ID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IE4gLyAyOyBpKyspIHtcbiAgICAgIHZhciB3ID0gTWF0aC5yb3VuZCh3c1syICogaSArIDFdIC8gTikgKiAweDIwMDAgK1xuICAgICAgICBNYXRoLnJvdW5kKHdzWzIgKiBpXSAvIE4pICtcbiAgICAgICAgY2Fycnk7XG5cbiAgICAgIHdzW2ldID0gdyAmIDB4M2ZmZmZmZjtcblxuICAgICAgaWYgKHcgPCAweDQwMDAwMDApIHtcbiAgICAgICAgY2FycnkgPSAwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FycnkgPSB3IC8gMHg0MDAwMDAwIHwgMDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gd3M7XG4gIH07XG5cbiAgRkZUTS5wcm90b3R5cGUuY29udmVydDEzYiA9IGZ1bmN0aW9uIGNvbnZlcnQxM2IgKHdzLCBsZW4sIHJ3cywgTikge1xuICAgIHZhciBjYXJyeSA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgY2FycnkgPSBjYXJyeSArICh3c1tpXSB8IDApO1xuXG4gICAgICByd3NbMiAqIGldID0gY2FycnkgJiAweDFmZmY7IGNhcnJ5ID0gY2FycnkgPj4+IDEzO1xuICAgICAgcndzWzIgKiBpICsgMV0gPSBjYXJyeSAmIDB4MWZmZjsgY2FycnkgPSBjYXJyeSA+Pj4gMTM7XG4gICAgfVxuXG4gICAgLy8gUGFkIHdpdGggemVyb2VzXG4gICAgZm9yIChpID0gMiAqIGxlbjsgaSA8IE47ICsraSkge1xuICAgICAgcndzW2ldID0gMDtcbiAgICB9XG5cbiAgICBhc3NlcnQoY2FycnkgPT09IDApO1xuICAgIGFzc2VydCgoY2FycnkgJiB+MHgxZmZmKSA9PT0gMCk7XG4gIH07XG5cbiAgRkZUTS5wcm90b3R5cGUuc3R1YiA9IGZ1bmN0aW9uIHN0dWIgKE4pIHtcbiAgICB2YXIgcGggPSBuZXcgQXJyYXkoTik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBOOyBpKyspIHtcbiAgICAgIHBoW2ldID0gMDtcbiAgICB9XG5cbiAgICByZXR1cm4gcGg7XG4gIH07XG5cbiAgRkZUTS5wcm90b3R5cGUubXVscCA9IGZ1bmN0aW9uIG11bHAgKHgsIHksIG91dCkge1xuICAgIHZhciBOID0gMiAqIHRoaXMuZ3Vlc3NMZW4xM2IoeC5sZW5ndGgsIHkubGVuZ3RoKTtcblxuICAgIHZhciByYnQgPSB0aGlzLm1ha2VSQlQoTik7XG5cbiAgICB2YXIgXyA9IHRoaXMuc3R1YihOKTtcblxuICAgIHZhciByd3MgPSBuZXcgQXJyYXkoTik7XG4gICAgdmFyIHJ3c3QgPSBuZXcgQXJyYXkoTik7XG4gICAgdmFyIGl3c3QgPSBuZXcgQXJyYXkoTik7XG5cbiAgICB2YXIgbnJ3cyA9IG5ldyBBcnJheShOKTtcbiAgICB2YXIgbnJ3c3QgPSBuZXcgQXJyYXkoTik7XG4gICAgdmFyIG5pd3N0ID0gbmV3IEFycmF5KE4pO1xuXG4gICAgdmFyIHJtd3MgPSBvdXQud29yZHM7XG4gICAgcm13cy5sZW5ndGggPSBOO1xuXG4gICAgdGhpcy5jb252ZXJ0MTNiKHgud29yZHMsIHgubGVuZ3RoLCByd3MsIE4pO1xuICAgIHRoaXMuY29udmVydDEzYih5LndvcmRzLCB5Lmxlbmd0aCwgbnJ3cywgTik7XG5cbiAgICB0aGlzLnRyYW5zZm9ybShyd3MsIF8sIHJ3c3QsIGl3c3QsIE4sIHJidCk7XG4gICAgdGhpcy50cmFuc2Zvcm0obnJ3cywgXywgbnJ3c3QsIG5pd3N0LCBOLCByYnQpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBOOyBpKyspIHtcbiAgICAgIHZhciByeCA9IHJ3c3RbaV0gKiBucndzdFtpXSAtIGl3c3RbaV0gKiBuaXdzdFtpXTtcbiAgICAgIGl3c3RbaV0gPSByd3N0W2ldICogbml3c3RbaV0gKyBpd3N0W2ldICogbnJ3c3RbaV07XG4gICAgICByd3N0W2ldID0gcng7XG4gICAgfVxuXG4gICAgdGhpcy5jb25qdWdhdGUocndzdCwgaXdzdCwgTik7XG4gICAgdGhpcy50cmFuc2Zvcm0ocndzdCwgaXdzdCwgcm13cywgXywgTiwgcmJ0KTtcbiAgICB0aGlzLmNvbmp1Z2F0ZShybXdzLCBfLCBOKTtcbiAgICB0aGlzLm5vcm1hbGl6ZTEzYihybXdzLCBOKTtcblxuICAgIG91dC5uZWdhdGl2ZSA9IHgubmVnYXRpdmUgXiB5Lm5lZ2F0aXZlO1xuICAgIG91dC5sZW5ndGggPSB4Lmxlbmd0aCArIHkubGVuZ3RoO1xuICAgIHJldHVybiBvdXQuc3RyaXAoKTtcbiAgfTtcblxuICAvLyBNdWx0aXBseSBgdGhpc2AgYnkgYG51bWBcbiAgQk4ucHJvdG90eXBlLm11bCA9IGZ1bmN0aW9uIG11bCAobnVtKSB7XG4gICAgdmFyIG91dCA9IG5ldyBCTihudWxsKTtcbiAgICBvdXQud29yZHMgPSBuZXcgQXJyYXkodGhpcy5sZW5ndGggKyBudW0ubGVuZ3RoKTtcbiAgICByZXR1cm4gdGhpcy5tdWxUbyhudW0sIG91dCk7XG4gIH07XG5cbiAgLy8gTXVsdGlwbHkgZW1wbG95aW5nIEZGVFxuICBCTi5wcm90b3R5cGUubXVsZiA9IGZ1bmN0aW9uIG11bGYgKG51bSkge1xuICAgIHZhciBvdXQgPSBuZXcgQk4obnVsbCk7XG4gICAgb3V0LndvcmRzID0gbmV3IEFycmF5KHRoaXMubGVuZ3RoICsgbnVtLmxlbmd0aCk7XG4gICAgcmV0dXJuIGp1bWJvTXVsVG8odGhpcywgbnVtLCBvdXQpO1xuICB9O1xuXG4gIC8vIEluLXBsYWNlIE11bHRpcGxpY2F0aW9uXG4gIEJOLnByb3RvdHlwZS5pbXVsID0gZnVuY3Rpb24gaW11bCAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5tdWxUbyhudW0sIHRoaXMpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5pbXVsbiA9IGZ1bmN0aW9uIGltdWxuIChudW0pIHtcbiAgICBhc3NlcnQodHlwZW9mIG51bSA9PT0gJ251bWJlcicpO1xuXG4gICAgLy8gQ2FycnlcbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHcgPSAodGhpcy53b3Jkc1tpXSB8IDApICogbnVtO1xuICAgICAgdmFyIGxvID0gKHcgJiAweDNmZmZmZmYpICsgKGNhcnJ5ICYgMHgzZmZmZmZmKTtcbiAgICAgIGNhcnJ5ID4+PSAyNjtcbiAgICAgIGNhcnJ5ICs9ICh3IC8gMHg0MDAwMDAwKSB8IDA7XG4gICAgICAvLyBOT1RFOiBsbyBpcyAyN2JpdCBtYXhpbXVtXG4gICAgICBjYXJyeSArPSBsbyA+Pj4gMjY7XG4gICAgICB0aGlzLndvcmRzW2ldID0gbG8gJiAweDNmZmZmZmY7XG4gICAgfVxuXG4gICAgaWYgKGNhcnJ5ICE9PSAwKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gY2Fycnk7XG4gICAgICB0aGlzLmxlbmd0aCsrO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5tdWxuID0gZnVuY3Rpb24gbXVsbiAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pbXVsbihudW0pO1xuICB9O1xuXG4gIC8vIGB0aGlzYCAqIGB0aGlzYFxuICBCTi5wcm90b3R5cGUuc3FyID0gZnVuY3Rpb24gc3FyICgpIHtcbiAgICByZXR1cm4gdGhpcy5tdWwodGhpcyk7XG4gIH07XG5cbiAgLy8gYHRoaXNgICogYHRoaXNgIGluLXBsYWNlXG4gIEJOLnByb3RvdHlwZS5pc3FyID0gZnVuY3Rpb24gaXNxciAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW11bCh0aGlzLmNsb25lKCkpO1xuICB9O1xuXG4gIC8vIE1hdGgucG93KGB0aGlzYCwgYG51bWApXG4gIEJOLnByb3RvdHlwZS5wb3cgPSBmdW5jdGlvbiBwb3cgKG51bSkge1xuICAgIHZhciB3ID0gdG9CaXRBcnJheShudW0pO1xuICAgIGlmICh3Lmxlbmd0aCA9PT0gMCkgcmV0dXJuIG5ldyBCTigxKTtcblxuICAgIC8vIFNraXAgbGVhZGluZyB6ZXJvZXNcbiAgICB2YXIgcmVzID0gdGhpcztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHcubGVuZ3RoOyBpKyssIHJlcyA9IHJlcy5zcXIoKSkge1xuICAgICAgaWYgKHdbaV0gIT09IDApIGJyZWFrO1xuICAgIH1cblxuICAgIGlmICgrK2kgPCB3Lmxlbmd0aCkge1xuICAgICAgZm9yICh2YXIgcSA9IHJlcy5zcXIoKTsgaSA8IHcubGVuZ3RoOyBpKyssIHEgPSBxLnNxcigpKSB7XG4gICAgICAgIGlmICh3W2ldID09PSAwKSBjb250aW51ZTtcblxuICAgICAgICByZXMgPSByZXMubXVsKHEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgLy8gU2hpZnQtbGVmdCBpbi1wbGFjZVxuICBCTi5wcm90b3R5cGUuaXVzaGxuID0gZnVuY3Rpb24gaXVzaGxuIChiaXRzKSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBiaXRzID09PSAnbnVtYmVyJyAmJiBiaXRzID49IDApO1xuICAgIHZhciByID0gYml0cyAlIDI2O1xuICAgIHZhciBzID0gKGJpdHMgLSByKSAvIDI2O1xuICAgIHZhciBjYXJyeU1hc2sgPSAoMHgzZmZmZmZmID4+PiAoMjYgLSByKSkgPDwgKDI2IC0gcik7XG4gICAgdmFyIGk7XG5cbiAgICBpZiAociAhPT0gMCkge1xuICAgICAgdmFyIGNhcnJ5ID0gMDtcblxuICAgICAgZm9yIChpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIG5ld0NhcnJ5ID0gdGhpcy53b3Jkc1tpXSAmIGNhcnJ5TWFzaztcbiAgICAgICAgdmFyIGMgPSAoKHRoaXMud29yZHNbaV0gfCAwKSAtIG5ld0NhcnJ5KSA8PCByO1xuICAgICAgICB0aGlzLndvcmRzW2ldID0gYyB8IGNhcnJ5O1xuICAgICAgICBjYXJyeSA9IG5ld0NhcnJ5ID4+PiAoMjYgLSByKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNhcnJ5KSB7XG4gICAgICAgIHRoaXMud29yZHNbaV0gPSBjYXJyeTtcbiAgICAgICAgdGhpcy5sZW5ndGgrKztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocyAhPT0gMCkge1xuICAgICAgZm9yIChpID0gdGhpcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICB0aGlzLndvcmRzW2kgKyBzXSA9IHRoaXMud29yZHNbaV07XG4gICAgICB9XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBzOyBpKyspIHtcbiAgICAgICAgdGhpcy53b3Jkc1tpXSA9IDA7XG4gICAgICB9XG5cbiAgICAgIHRoaXMubGVuZ3RoICs9IHM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaXNobG4gPSBmdW5jdGlvbiBpc2hsbiAoYml0cykge1xuICAgIC8vIFRPRE8oaW5kdXRueSk6IGltcGxlbWVudCBtZVxuICAgIGFzc2VydCh0aGlzLm5lZ2F0aXZlID09PSAwKTtcbiAgICByZXR1cm4gdGhpcy5pdXNobG4oYml0cyk7XG4gIH07XG5cbiAgLy8gU2hpZnQtcmlnaHQgaW4tcGxhY2VcbiAgLy8gTk9URTogYGhpbnRgIGlzIGEgbG93ZXN0IGJpdCBiZWZvcmUgdHJhaWxpbmcgemVyb2VzXG4gIC8vIE5PVEU6IGlmIGBleHRlbmRlZGAgaXMgcHJlc2VudCAtIGl0IHdpbGwgYmUgZmlsbGVkIHdpdGggZGVzdHJveWVkIGJpdHNcbiAgQk4ucHJvdG90eXBlLml1c2hybiA9IGZ1bmN0aW9uIGl1c2hybiAoYml0cywgaGludCwgZXh0ZW5kZWQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGJpdHMgPT09ICdudW1iZXInICYmIGJpdHMgPj0gMCk7XG4gICAgdmFyIGg7XG4gICAgaWYgKGhpbnQpIHtcbiAgICAgIGggPSAoaGludCAtIChoaW50ICUgMjYpKSAvIDI2O1xuICAgIH0gZWxzZSB7XG4gICAgICBoID0gMDtcbiAgICB9XG5cbiAgICB2YXIgciA9IGJpdHMgJSAyNjtcbiAgICB2YXIgcyA9IE1hdGgubWluKChiaXRzIC0gcikgLyAyNiwgdGhpcy5sZW5ndGgpO1xuICAgIHZhciBtYXNrID0gMHgzZmZmZmZmIF4gKCgweDNmZmZmZmYgPj4+IHIpIDw8IHIpO1xuICAgIHZhciBtYXNrZWRXb3JkcyA9IGV4dGVuZGVkO1xuXG4gICAgaCAtPSBzO1xuICAgIGggPSBNYXRoLm1heCgwLCBoKTtcblxuICAgIC8vIEV4dGVuZGVkIG1vZGUsIGNvcHkgbWFza2VkIHBhcnRcbiAgICBpZiAobWFza2VkV29yZHMpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgczsgaSsrKSB7XG4gICAgICAgIG1hc2tlZFdvcmRzLndvcmRzW2ldID0gdGhpcy53b3Jkc1tpXTtcbiAgICAgIH1cbiAgICAgIG1hc2tlZFdvcmRzLmxlbmd0aCA9IHM7XG4gICAgfVxuXG4gICAgaWYgKHMgPT09IDApIHtcbiAgICAgIC8vIE5vLW9wLCB3ZSBzaG91bGQgbm90IG1vdmUgYW55dGhpbmcgYXQgYWxsXG4gICAgfSBlbHNlIGlmICh0aGlzLmxlbmd0aCA+IHMpIHtcbiAgICAgIHRoaXMubGVuZ3RoIC09IHM7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB0aGlzLndvcmRzW2ldID0gdGhpcy53b3Jkc1tpICsgc107XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMud29yZHNbMF0gPSAwO1xuICAgICAgdGhpcy5sZW5ndGggPSAxO1xuICAgIH1cblxuICAgIHZhciBjYXJyeSA9IDA7XG4gICAgZm9yIChpID0gdGhpcy5sZW5ndGggLSAxOyBpID49IDAgJiYgKGNhcnJ5ICE9PSAwIHx8IGkgPj0gaCk7IGktLSkge1xuICAgICAgdmFyIHdvcmQgPSB0aGlzLndvcmRzW2ldIHwgMDtcbiAgICAgIHRoaXMud29yZHNbaV0gPSAoY2FycnkgPDwgKDI2IC0gcikpIHwgKHdvcmQgPj4+IHIpO1xuICAgICAgY2FycnkgPSB3b3JkICYgbWFzaztcbiAgICB9XG5cbiAgICAvLyBQdXNoIGNhcnJpZWQgYml0cyBhcyBhIG1hc2tcbiAgICBpZiAobWFza2VkV29yZHMgJiYgY2FycnkgIT09IDApIHtcbiAgICAgIG1hc2tlZFdvcmRzLndvcmRzW21hc2tlZFdvcmRzLmxlbmd0aCsrXSA9IGNhcnJ5O1xuICAgIH1cblxuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy53b3Jkc1swXSA9IDA7XG4gICAgICB0aGlzLmxlbmd0aCA9IDE7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaXNocm4gPSBmdW5jdGlvbiBpc2hybiAoYml0cywgaGludCwgZXh0ZW5kZWQpIHtcbiAgICAvLyBUT0RPKGluZHV0bnkpOiBpbXBsZW1lbnQgbWVcbiAgICBhc3NlcnQodGhpcy5uZWdhdGl2ZSA9PT0gMCk7XG4gICAgcmV0dXJuIHRoaXMuaXVzaHJuKGJpdHMsIGhpbnQsIGV4dGVuZGVkKTtcbiAgfTtcblxuICAvLyBTaGlmdC1sZWZ0XG4gIEJOLnByb3RvdHlwZS5zaGxuID0gZnVuY3Rpb24gc2hsbiAoYml0cykge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaXNobG4oYml0cyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnVzaGxuID0gZnVuY3Rpb24gdXNobG4gKGJpdHMpIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLml1c2hsbihiaXRzKTtcbiAgfTtcblxuICAvLyBTaGlmdC1yaWdodFxuICBCTi5wcm90b3R5cGUuc2hybiA9IGZ1bmN0aW9uIHNocm4gKGJpdHMpIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmlzaHJuKGJpdHMpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS51c2hybiA9IGZ1bmN0aW9uIHVzaHJuIChiaXRzKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pdXNocm4oYml0cyk7XG4gIH07XG5cbiAgLy8gVGVzdCBpZiBuIGJpdCBpcyBzZXRcbiAgQk4ucHJvdG90eXBlLnRlc3RuID0gZnVuY3Rpb24gdGVzdG4gKGJpdCkge1xuICAgIGFzc2VydCh0eXBlb2YgYml0ID09PSAnbnVtYmVyJyAmJiBiaXQgPj0gMCk7XG4gICAgdmFyIHIgPSBiaXQgJSAyNjtcbiAgICB2YXIgcyA9IChiaXQgLSByKSAvIDI2O1xuICAgIHZhciBxID0gMSA8PCByO1xuXG4gICAgLy8gRmFzdCBjYXNlOiBiaXQgaXMgbXVjaCBoaWdoZXIgdGhhbiBhbGwgZXhpc3Rpbmcgd29yZHNcbiAgICBpZiAodGhpcy5sZW5ndGggPD0gcykgcmV0dXJuIGZhbHNlO1xuXG4gICAgLy8gQ2hlY2sgYml0IGFuZCByZXR1cm5cbiAgICB2YXIgdyA9IHRoaXMud29yZHNbc107XG5cbiAgICByZXR1cm4gISEodyAmIHEpO1xuICB9O1xuXG4gIC8vIFJldHVybiBvbmx5IGxvd2VycyBiaXRzIG9mIG51bWJlciAoaW4tcGxhY2UpXG4gIEJOLnByb3RvdHlwZS5pbWFza24gPSBmdW5jdGlvbiBpbWFza24gKGJpdHMpIHtcbiAgICBhc3NlcnQodHlwZW9mIGJpdHMgPT09ICdudW1iZXInICYmIGJpdHMgPj0gMCk7XG4gICAgdmFyIHIgPSBiaXRzICUgMjY7XG4gICAgdmFyIHMgPSAoYml0cyAtIHIpIC8gMjY7XG5cbiAgICBhc3NlcnQodGhpcy5uZWdhdGl2ZSA9PT0gMCwgJ2ltYXNrbiB3b3JrcyBvbmx5IHdpdGggcG9zaXRpdmUgbnVtYmVycycpO1xuXG4gICAgaWYgKHIgIT09IDApIHtcbiAgICAgIHMrKztcbiAgICB9XG4gICAgdGhpcy5sZW5ndGggPSBNYXRoLm1pbihzLCB0aGlzLmxlbmd0aCk7XG5cbiAgICBpZiAociAhPT0gMCkge1xuICAgICAgdmFyIG1hc2sgPSAweDNmZmZmZmYgXiAoKDB4M2ZmZmZmZiA+Pj4gcikgPDwgcik7XG4gICAgICB0aGlzLndvcmRzW3RoaXMubGVuZ3RoIC0gMV0gJj0gbWFzaztcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIC8vIFJldHVybiBvbmx5IGxvd2VycyBiaXRzIG9mIG51bWJlclxuICBCTi5wcm90b3R5cGUubWFza24gPSBmdW5jdGlvbiBtYXNrbiAoYml0cykge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaW1hc2tuKGJpdHMpO1xuICB9O1xuXG4gIC8vIEFkZCBwbGFpbiBudW1iZXIgYG51bWAgdG8gYHRoaXNgXG4gIEJOLnByb3RvdHlwZS5pYWRkbiA9IGZ1bmN0aW9uIGlhZGRuIChudW0pIHtcbiAgICBhc3NlcnQodHlwZW9mIG51bSA9PT0gJ251bWJlcicpO1xuICAgIGlmIChudW0gPCAwKSByZXR1cm4gdGhpcy5pc3VibigtbnVtKTtcblxuICAgIC8vIFBvc3NpYmxlIHNpZ24gY2hhbmdlXG4gICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMSAmJiAodGhpcy53b3Jkc1swXSB8IDApIDwgbnVtKSB7XG4gICAgICAgIHRoaXMud29yZHNbMF0gPSBudW0gLSAodGhpcy53b3Jkc1swXSB8IDApO1xuICAgICAgICB0aGlzLm5lZ2F0aXZlID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgICAgdGhpcy5pc3VibihudW0pO1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDE7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvLyBBZGQgd2l0aG91dCBjaGVja3NcbiAgICByZXR1cm4gdGhpcy5faWFkZG4obnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuX2lhZGRuID0gZnVuY3Rpb24gX2lhZGRuIChudW0pIHtcbiAgICB0aGlzLndvcmRzWzBdICs9IG51bTtcblxuICAgIC8vIENhcnJ5XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aCAmJiB0aGlzLndvcmRzW2ldID49IDB4NDAwMDAwMDsgaSsrKSB7XG4gICAgICB0aGlzLndvcmRzW2ldIC09IDB4NDAwMDAwMDtcbiAgICAgIGlmIChpID09PSB0aGlzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgdGhpcy53b3Jkc1tpICsgMV0gPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy53b3Jkc1tpICsgMV0rKztcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5sZW5ndGggPSBNYXRoLm1heCh0aGlzLmxlbmd0aCwgaSArIDEpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgLy8gU3VidHJhY3QgcGxhaW4gbnVtYmVyIGBudW1gIGZyb20gYHRoaXNgXG4gIEJOLnByb3RvdHlwZS5pc3VibiA9IGZ1bmN0aW9uIGlzdWJuIChudW0pIHtcbiAgICBhc3NlcnQodHlwZW9mIG51bSA9PT0gJ251bWJlcicpO1xuICAgIGlmIChudW0gPCAwKSByZXR1cm4gdGhpcy5pYWRkbigtbnVtKTtcblxuICAgIGlmICh0aGlzLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMDtcbiAgICAgIHRoaXMuaWFkZG4obnVtKTtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAxO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgdGhpcy53b3Jkc1swXSAtPSBudW07XG5cbiAgICBpZiAodGhpcy5sZW5ndGggPT09IDEgJiYgdGhpcy53b3Jkc1swXSA8IDApIHtcbiAgICAgIHRoaXMud29yZHNbMF0gPSAtdGhpcy53b3Jkc1swXTtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBDYXJyeVxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aCAmJiB0aGlzLndvcmRzW2ldIDwgMDsgaSsrKSB7XG4gICAgICAgIHRoaXMud29yZHNbaV0gKz0gMHg0MDAwMDAwO1xuICAgICAgICB0aGlzLndvcmRzW2kgKyAxXSAtPSAxO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmFkZG4gPSBmdW5jdGlvbiBhZGRuIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmlhZGRuKG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnN1Ym4gPSBmdW5jdGlvbiBzdWJuIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmlzdWJuKG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmlhYnMgPSBmdW5jdGlvbiBpYWJzICgpIHtcbiAgICB0aGlzLm5lZ2F0aXZlID0gMDtcblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5hYnMgPSBmdW5jdGlvbiBhYnMgKCkge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaWFicygpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5faXNobG5zdWJtdWwgPSBmdW5jdGlvbiBfaXNobG5zdWJtdWwgKG51bSwgbXVsLCBzaGlmdCkge1xuICAgIC8vIEJpZ2dlciBzdG9yYWdlIGlzIG5lZWRlZFxuICAgIHZhciBsZW4gPSBudW0ubGVuZ3RoICsgc2hpZnQ7XG4gICAgdmFyIGk7XG4gICAgaWYgKHRoaXMud29yZHMubGVuZ3RoIDwgbGVuKSB7XG4gICAgICB2YXIgdCA9IG5ldyBBcnJheShsZW4pO1xuICAgICAgZm9yIChpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdFtpXSA9IHRoaXMud29yZHNbaV07XG4gICAgICB9XG4gICAgICB0aGlzLndvcmRzID0gdDtcbiAgICB9IGVsc2Uge1xuICAgICAgaSA9IHRoaXMubGVuZ3RoO1xuICAgIH1cblxuICAgIC8vIFplcm9pZnkgcmVzdFxuICAgIHRoaXMubGVuZ3RoID0gTWF0aC5tYXgodGhpcy5sZW5ndGgsIGxlbik7XG4gICAgZm9yICg7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gMDtcbiAgICB9XG5cbiAgICB2YXIgdztcbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIGZvciAoaSA9IDA7IGkgPCBudW0ubGVuZ3RoOyBpKyspIHtcbiAgICAgIHcgPSAodGhpcy53b3Jkc1tpICsgc2hpZnRdIHwgMCkgKyBjYXJyeTtcbiAgICAgIHZhciByaWdodCA9IChudW0ud29yZHNbaV0gfCAwKSAqIG11bDtcbiAgICAgIHcgLT0gcmlnaHQgJiAweDNmZmZmZmY7XG4gICAgICBjYXJyeSA9ICh3ID4+IDI2KSAtICgocmlnaHQgLyAweDQwMDAwMDApIHwgMCk7XG4gICAgICB0aGlzLndvcmRzW2kgKyBzaGlmdF0gPSB3ICYgMHgzZmZmZmZmO1xuICAgIH1cbiAgICBmb3IgKDsgaSA8IHRoaXMubGVuZ3RoIC0gc2hpZnQ7IGkrKykge1xuICAgICAgdyA9ICh0aGlzLndvcmRzW2kgKyBzaGlmdF0gfCAwKSArIGNhcnJ5O1xuICAgICAgY2FycnkgPSB3ID4+IDI2O1xuICAgICAgdGhpcy53b3Jkc1tpICsgc2hpZnRdID0gdyAmIDB4M2ZmZmZmZjtcbiAgICB9XG5cbiAgICBpZiAoY2FycnkgPT09IDApIHJldHVybiB0aGlzLnN0cmlwKCk7XG5cbiAgICAvLyBTdWJ0cmFjdGlvbiBvdmVyZmxvd1xuICAgIGFzc2VydChjYXJyeSA9PT0gLTEpO1xuICAgIGNhcnJ5ID0gMDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgdyA9IC0odGhpcy53b3Jkc1tpXSB8IDApICsgY2Fycnk7XG4gICAgICBjYXJyeSA9IHcgPj4gMjY7XG4gICAgICB0aGlzLndvcmRzW2ldID0gdyAmIDB4M2ZmZmZmZjtcbiAgICB9XG4gICAgdGhpcy5uZWdhdGl2ZSA9IDE7XG5cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5fd29yZERpdiA9IGZ1bmN0aW9uIF93b3JkRGl2IChudW0sIG1vZGUpIHtcbiAgICB2YXIgc2hpZnQgPSB0aGlzLmxlbmd0aCAtIG51bS5sZW5ndGg7XG5cbiAgICB2YXIgYSA9IHRoaXMuY2xvbmUoKTtcbiAgICB2YXIgYiA9IG51bTtcblxuICAgIC8vIE5vcm1hbGl6ZVxuICAgIHZhciBiaGkgPSBiLndvcmRzW2IubGVuZ3RoIC0gMV0gfCAwO1xuICAgIHZhciBiaGlCaXRzID0gdGhpcy5fY291bnRCaXRzKGJoaSk7XG4gICAgc2hpZnQgPSAyNiAtIGJoaUJpdHM7XG4gICAgaWYgKHNoaWZ0ICE9PSAwKSB7XG4gICAgICBiID0gYi51c2hsbihzaGlmdCk7XG4gICAgICBhLml1c2hsbihzaGlmdCk7XG4gICAgICBiaGkgPSBiLndvcmRzW2IubGVuZ3RoIC0gMV0gfCAwO1xuICAgIH1cblxuICAgIC8vIEluaXRpYWxpemUgcXVvdGllbnRcbiAgICB2YXIgbSA9IGEubGVuZ3RoIC0gYi5sZW5ndGg7XG4gICAgdmFyIHE7XG5cbiAgICBpZiAobW9kZSAhPT0gJ21vZCcpIHtcbiAgICAgIHEgPSBuZXcgQk4obnVsbCk7XG4gICAgICBxLmxlbmd0aCA9IG0gKyAxO1xuICAgICAgcS53b3JkcyA9IG5ldyBBcnJheShxLmxlbmd0aCk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcS53b3Jkc1tpXSA9IDA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGRpZmYgPSBhLmNsb25lKCkuX2lzaGxuc3VibXVsKGIsIDEsIG0pO1xuICAgIGlmIChkaWZmLm5lZ2F0aXZlID09PSAwKSB7XG4gICAgICBhID0gZGlmZjtcbiAgICAgIGlmIChxKSB7XG4gICAgICAgIHEud29yZHNbbV0gPSAxO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGogPSBtIC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICAgIHZhciBxaiA9IChhLndvcmRzW2IubGVuZ3RoICsgal0gfCAwKSAqIDB4NDAwMDAwMCArXG4gICAgICAgIChhLndvcmRzW2IubGVuZ3RoICsgaiAtIDFdIHwgMCk7XG5cbiAgICAgIC8vIE5PVEU6IChxaiAvIGJoaSkgaXMgKDB4M2ZmZmZmZiAqIDB4NDAwMDAwMCArIDB4M2ZmZmZmZikgLyAweDIwMDAwMDAgbWF4XG4gICAgICAvLyAoMHg3ZmZmZmZmKVxuICAgICAgcWogPSBNYXRoLm1pbigocWogLyBiaGkpIHwgMCwgMHgzZmZmZmZmKTtcblxuICAgICAgYS5faXNobG5zdWJtdWwoYiwgcWosIGopO1xuICAgICAgd2hpbGUgKGEubmVnYXRpdmUgIT09IDApIHtcbiAgICAgICAgcWotLTtcbiAgICAgICAgYS5uZWdhdGl2ZSA9IDA7XG4gICAgICAgIGEuX2lzaGxuc3VibXVsKGIsIDEsIGopO1xuICAgICAgICBpZiAoIWEuaXNaZXJvKCkpIHtcbiAgICAgICAgICBhLm5lZ2F0aXZlIF49IDE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChxKSB7XG4gICAgICAgIHEud29yZHNbal0gPSBxajtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHEpIHtcbiAgICAgIHEuc3RyaXAoKTtcbiAgICB9XG4gICAgYS5zdHJpcCgpO1xuXG4gICAgLy8gRGVub3JtYWxpemVcbiAgICBpZiAobW9kZSAhPT0gJ2RpdicgJiYgc2hpZnQgIT09IDApIHtcbiAgICAgIGEuaXVzaHJuKHNoaWZ0KTtcbiAgICB9XG5cbiAgICByZXR1cm4geyBkaXY6IHEgfHwgbnVsbCwgbW9kOiBhIH07XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmRpdm1vZCA9IGZ1bmN0aW9uIGRpdm1vZCAobnVtLCBtb2RlLCBwb3NpdGl2ZSkge1xuICAgIGFzc2VydCghbnVtLmlzWmVybygpKTtcblxuICAgIHZhciBkaXYsIG1vZCwgcmVzO1xuICAgIGlmICh0aGlzLm5lZ2F0aXZlICE9PSAwICYmIG51bS5uZWdhdGl2ZSA9PT0gMCkge1xuICAgICAgcmVzID0gdGhpcy5uZWcoKS5kaXZtb2QobnVtLCBtb2RlKTtcblxuICAgICAgaWYgKG1vZGUgIT09ICdtb2QnKSB7XG4gICAgICAgIGRpdiA9IHJlcy5kaXYubmVnKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChtb2RlICE9PSAnZGl2Jykge1xuICAgICAgICBtb2QgPSByZXMubW9kLm5lZygpO1xuICAgICAgICBpZiAocG9zaXRpdmUgJiYgbW9kLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICAgICAgbW9kLmlhZGQobnVtKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkaXY6IGRpdixcbiAgICAgICAgbW9kOiBtb2RcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubmVnYXRpdmUgPT09IDAgJiYgbnVtLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICByZXMgPSB0aGlzLmRpdm1vZChudW0ubmVnKCksIG1vZGUpO1xuXG4gICAgICBpZiAobW9kZSAhPT0gJ21vZCcpIHtcbiAgICAgICAgZGl2ID0gcmVzLmRpdi5uZWcoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHsgZGl2OiBkaXYsIG1vZDogcmVzLm1vZCB9O1xuICAgIH1cblxuICAgIGlmICgodGhpcy5uZWdhdGl2ZSAmIG51bS5uZWdhdGl2ZSkgIT09IDApIHtcbiAgICAgIHJlcyA9IHRoaXMubmVnKCkuZGl2bW9kKG51bS5uZWcoKSwgbW9kZSk7XG5cbiAgICAgIGlmIChtb2RlICE9PSAnZGl2Jykge1xuICAgICAgICBtb2QgPSByZXMubW9kLm5lZygpO1xuICAgICAgICBpZiAocG9zaXRpdmUgJiYgbW9kLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICAgICAgbW9kLmlzdWIobnVtKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkaXY6IHJlcy5kaXYsXG4gICAgICAgIG1vZDogbW9kXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIEJvdGggbnVtYmVycyBhcmUgcG9zaXRpdmUgYXQgdGhpcyBwb2ludFxuXG4gICAgLy8gU3RyaXAgYm90aCBudW1iZXJzIHRvIGFwcHJveGltYXRlIHNoaWZ0IHZhbHVlXG4gICAgaWYgKG51bS5sZW5ndGggPiB0aGlzLmxlbmd0aCB8fCB0aGlzLmNtcChudW0pIDwgMCkge1xuICAgICAgcmV0dXJuIHsgZGl2OiBuZXcgQk4oMCksIG1vZDogdGhpcyB9O1xuICAgIH1cblxuICAgIC8vIFZlcnkgc2hvcnQgcmVkdWN0aW9uXG4gICAgaWYgKG51bS5sZW5ndGggPT09IDEpIHtcbiAgICAgIGlmIChtb2RlID09PSAnZGl2Jykge1xuICAgICAgICByZXR1cm4geyBkaXY6IHRoaXMuZGl2bihudW0ud29yZHNbMF0pLCBtb2Q6IG51bGwgfTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1vZGUgPT09ICdtb2QnKSB7XG4gICAgICAgIHJldHVybiB7IGRpdjogbnVsbCwgbW9kOiBuZXcgQk4odGhpcy5tb2RuKG51bS53b3Jkc1swXSkpIH07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRpdjogdGhpcy5kaXZuKG51bS53b3Jkc1swXSksXG4gICAgICAgIG1vZDogbmV3IEJOKHRoaXMubW9kbihudW0ud29yZHNbMF0pKVxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fd29yZERpdihudW0sIG1vZGUpO1xuICB9O1xuXG4gIC8vIEZpbmQgYHRoaXNgIC8gYG51bWBcbiAgQk4ucHJvdG90eXBlLmRpdiA9IGZ1bmN0aW9uIGRpdiAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuZGl2bW9kKG51bSwgJ2RpdicsIGZhbHNlKS5kaXY7XG4gIH07XG5cbiAgLy8gRmluZCBgdGhpc2AgJSBgbnVtYFxuICBCTi5wcm90b3R5cGUubW9kID0gZnVuY3Rpb24gbW9kIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5kaXZtb2QobnVtLCAnbW9kJywgZmFsc2UpLm1vZDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUudW1vZCA9IGZ1bmN0aW9uIHVtb2QgKG51bSkge1xuICAgIHJldHVybiB0aGlzLmRpdm1vZChudW0sICdtb2QnLCB0cnVlKS5tb2Q7XG4gIH07XG5cbiAgLy8gRmluZCBSb3VuZChgdGhpc2AgLyBgbnVtYClcbiAgQk4ucHJvdG90eXBlLmRpdlJvdW5kID0gZnVuY3Rpb24gZGl2Um91bmQgKG51bSkge1xuICAgIHZhciBkbSA9IHRoaXMuZGl2bW9kKG51bSk7XG5cbiAgICAvLyBGYXN0IGNhc2UgLSBleGFjdCBkaXZpc2lvblxuICAgIGlmIChkbS5tb2QuaXNaZXJvKCkpIHJldHVybiBkbS5kaXY7XG5cbiAgICB2YXIgbW9kID0gZG0uZGl2Lm5lZ2F0aXZlICE9PSAwID8gZG0ubW9kLmlzdWIobnVtKSA6IGRtLm1vZDtcblxuICAgIHZhciBoYWxmID0gbnVtLnVzaHJuKDEpO1xuICAgIHZhciByMiA9IG51bS5hbmRsbigxKTtcbiAgICB2YXIgY21wID0gbW9kLmNtcChoYWxmKTtcblxuICAgIC8vIFJvdW5kIGRvd25cbiAgICBpZiAoY21wIDwgMCB8fCByMiA9PT0gMSAmJiBjbXAgPT09IDApIHJldHVybiBkbS5kaXY7XG5cbiAgICAvLyBSb3VuZCB1cFxuICAgIHJldHVybiBkbS5kaXYubmVnYXRpdmUgIT09IDAgPyBkbS5kaXYuaXN1Ym4oMSkgOiBkbS5kaXYuaWFkZG4oMSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLm1vZG4gPSBmdW5jdGlvbiBtb2RuIChudW0pIHtcbiAgICBhc3NlcnQobnVtIDw9IDB4M2ZmZmZmZik7XG4gICAgdmFyIHAgPSAoMSA8PCAyNikgJSBudW07XG5cbiAgICB2YXIgYWNjID0gMDtcbiAgICBmb3IgKHZhciBpID0gdGhpcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYWNjID0gKHAgKiBhY2MgKyAodGhpcy53b3Jkc1tpXSB8IDApKSAlIG51bTtcbiAgICB9XG5cbiAgICByZXR1cm4gYWNjO1xuICB9O1xuXG4gIC8vIEluLXBsYWNlIGRpdmlzaW9uIGJ5IG51bWJlclxuICBCTi5wcm90b3R5cGUuaWRpdm4gPSBmdW5jdGlvbiBpZGl2biAobnVtKSB7XG4gICAgYXNzZXJ0KG51bSA8PSAweDNmZmZmZmYpO1xuXG4gICAgdmFyIGNhcnJ5ID0gMDtcbiAgICBmb3IgKHZhciBpID0gdGhpcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgdmFyIHcgPSAodGhpcy53b3Jkc1tpXSB8IDApICsgY2FycnkgKiAweDQwMDAwMDA7XG4gICAgICB0aGlzLndvcmRzW2ldID0gKHcgLyBudW0pIHwgMDtcbiAgICAgIGNhcnJ5ID0gdyAlIG51bTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5kaXZuID0gZnVuY3Rpb24gZGl2biAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pZGl2bihudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5lZ2NkID0gZnVuY3Rpb24gZWdjZCAocCkge1xuICAgIGFzc2VydChwLm5lZ2F0aXZlID09PSAwKTtcbiAgICBhc3NlcnQoIXAuaXNaZXJvKCkpO1xuXG4gICAgdmFyIHggPSB0aGlzO1xuICAgIHZhciB5ID0gcC5jbG9uZSgpO1xuXG4gICAgaWYgKHgubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIHggPSB4LnVtb2QocCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHggPSB4LmNsb25lKCk7XG4gICAgfVxuXG4gICAgLy8gQSAqIHggKyBCICogeSA9IHhcbiAgICB2YXIgQSA9IG5ldyBCTigxKTtcbiAgICB2YXIgQiA9IG5ldyBCTigwKTtcblxuICAgIC8vIEMgKiB4ICsgRCAqIHkgPSB5XG4gICAgdmFyIEMgPSBuZXcgQk4oMCk7XG4gICAgdmFyIEQgPSBuZXcgQk4oMSk7XG5cbiAgICB2YXIgZyA9IDA7XG5cbiAgICB3aGlsZSAoeC5pc0V2ZW4oKSAmJiB5LmlzRXZlbigpKSB7XG4gICAgICB4Lml1c2hybigxKTtcbiAgICAgIHkuaXVzaHJuKDEpO1xuICAgICAgKytnO1xuICAgIH1cblxuICAgIHZhciB5cCA9IHkuY2xvbmUoKTtcbiAgICB2YXIgeHAgPSB4LmNsb25lKCk7XG5cbiAgICB3aGlsZSAoIXguaXNaZXJvKCkpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBpbSA9IDE7ICh4LndvcmRzWzBdICYgaW0pID09PSAwICYmIGkgPCAyNjsgKytpLCBpbSA8PD0gMSk7XG4gICAgICBpZiAoaSA+IDApIHtcbiAgICAgICAgeC5pdXNocm4oaSk7XG4gICAgICAgIHdoaWxlIChpLS0gPiAwKSB7XG4gICAgICAgICAgaWYgKEEuaXNPZGQoKSB8fCBCLmlzT2RkKCkpIHtcbiAgICAgICAgICAgIEEuaWFkZCh5cCk7XG4gICAgICAgICAgICBCLmlzdWIoeHApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIEEuaXVzaHJuKDEpO1xuICAgICAgICAgIEIuaXVzaHJuKDEpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAodmFyIGogPSAwLCBqbSA9IDE7ICh5LndvcmRzWzBdICYgam0pID09PSAwICYmIGogPCAyNjsgKytqLCBqbSA8PD0gMSk7XG4gICAgICBpZiAoaiA+IDApIHtcbiAgICAgICAgeS5pdXNocm4oaik7XG4gICAgICAgIHdoaWxlIChqLS0gPiAwKSB7XG4gICAgICAgICAgaWYgKEMuaXNPZGQoKSB8fCBELmlzT2RkKCkpIHtcbiAgICAgICAgICAgIEMuaWFkZCh5cCk7XG4gICAgICAgICAgICBELmlzdWIoeHApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIEMuaXVzaHJuKDEpO1xuICAgICAgICAgIEQuaXVzaHJuKDEpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh4LmNtcCh5KSA+PSAwKSB7XG4gICAgICAgIHguaXN1Yih5KTtcbiAgICAgICAgQS5pc3ViKEMpO1xuICAgICAgICBCLmlzdWIoRCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB5LmlzdWIoeCk7XG4gICAgICAgIEMuaXN1YihBKTtcbiAgICAgICAgRC5pc3ViKEIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBhOiBDLFxuICAgICAgYjogRCxcbiAgICAgIGdjZDogeS5pdXNobG4oZylcbiAgICB9O1xuICB9O1xuXG4gIC8vIFRoaXMgaXMgcmVkdWNlZCBpbmNhcm5hdGlvbiBvZiB0aGUgYmluYXJ5IEVFQVxuICAvLyBhYm92ZSwgZGVzaWduYXRlZCB0byBpbnZlcnQgbWVtYmVycyBvZiB0aGVcbiAgLy8gX3ByaW1lXyBmaWVsZHMgRihwKSBhdCBhIG1heGltYWwgc3BlZWRcbiAgQk4ucHJvdG90eXBlLl9pbnZtcCA9IGZ1bmN0aW9uIF9pbnZtcCAocCkge1xuICAgIGFzc2VydChwLm5lZ2F0aXZlID09PSAwKTtcbiAgICBhc3NlcnQoIXAuaXNaZXJvKCkpO1xuXG4gICAgdmFyIGEgPSB0aGlzO1xuICAgIHZhciBiID0gcC5jbG9uZSgpO1xuXG4gICAgaWYgKGEubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIGEgPSBhLnVtb2QocCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGEgPSBhLmNsb25lKCk7XG4gICAgfVxuXG4gICAgdmFyIHgxID0gbmV3IEJOKDEpO1xuICAgIHZhciB4MiA9IG5ldyBCTigwKTtcblxuICAgIHZhciBkZWx0YSA9IGIuY2xvbmUoKTtcblxuICAgIHdoaWxlIChhLmNtcG4oMSkgPiAwICYmIGIuY21wbigxKSA+IDApIHtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBpbSA9IDE7IChhLndvcmRzWzBdICYgaW0pID09PSAwICYmIGkgPCAyNjsgKytpLCBpbSA8PD0gMSk7XG4gICAgICBpZiAoaSA+IDApIHtcbiAgICAgICAgYS5pdXNocm4oaSk7XG4gICAgICAgIHdoaWxlIChpLS0gPiAwKSB7XG4gICAgICAgICAgaWYgKHgxLmlzT2RkKCkpIHtcbiAgICAgICAgICAgIHgxLmlhZGQoZGVsdGEpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHgxLml1c2hybigxKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKHZhciBqID0gMCwgam0gPSAxOyAoYi53b3Jkc1swXSAmIGptKSA9PT0gMCAmJiBqIDwgMjY7ICsraiwgam0gPDw9IDEpO1xuICAgICAgaWYgKGogPiAwKSB7XG4gICAgICAgIGIuaXVzaHJuKGopO1xuICAgICAgICB3aGlsZSAoai0tID4gMCkge1xuICAgICAgICAgIGlmICh4Mi5pc09kZCgpKSB7XG4gICAgICAgICAgICB4Mi5pYWRkKGRlbHRhKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB4Mi5pdXNocm4oMSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGEuY21wKGIpID49IDApIHtcbiAgICAgICAgYS5pc3ViKGIpO1xuICAgICAgICB4MS5pc3ViKHgyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGIuaXN1YihhKTtcbiAgICAgICAgeDIuaXN1Yih4MSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHJlcztcbiAgICBpZiAoYS5jbXBuKDEpID09PSAwKSB7XG4gICAgICByZXMgPSB4MTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzID0geDI7XG4gICAgfVxuXG4gICAgaWYgKHJlcy5jbXBuKDApIDwgMCkge1xuICAgICAgcmVzLmlhZGQocCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcztcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZ2NkID0gZnVuY3Rpb24gZ2NkIChudW0pIHtcbiAgICBpZiAodGhpcy5pc1plcm8oKSkgcmV0dXJuIG51bS5jbG9uZSgpO1xuICAgIGlmIChudW0uaXNaZXJvKCkpIHJldHVybiB0aGlzLmNsb25lKCk7XG5cbiAgICB2YXIgYSA9IHRoaXMuY2xvbmUoKTtcbiAgICB2YXIgYiA9IG51bS5jbG9uZSgpO1xuICAgIGEubmVnYXRpdmUgPSAwO1xuICAgIGIubmVnYXRpdmUgPSAwO1xuXG4gICAgLy8gUmVtb3ZlIGNvbW1vbiBmYWN0b3Igb2YgdHdvXG4gICAgZm9yICh2YXIgc2hpZnQgPSAwOyBhLmlzRXZlbigpICYmIGIuaXNFdmVuKCk7IHNoaWZ0KyspIHtcbiAgICAgIGEuaXVzaHJuKDEpO1xuICAgICAgYi5pdXNocm4oMSk7XG4gICAgfVxuXG4gICAgZG8ge1xuICAgICAgd2hpbGUgKGEuaXNFdmVuKCkpIHtcbiAgICAgICAgYS5pdXNocm4oMSk7XG4gICAgICB9XG4gICAgICB3aGlsZSAoYi5pc0V2ZW4oKSkge1xuICAgICAgICBiLml1c2hybigxKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHIgPSBhLmNtcChiKTtcbiAgICAgIGlmIChyIDwgMCkge1xuICAgICAgICAvLyBTd2FwIGBhYCBhbmQgYGJgIHRvIG1ha2UgYGFgIGFsd2F5cyBiaWdnZXIgdGhhbiBgYmBcbiAgICAgICAgdmFyIHQgPSBhO1xuICAgICAgICBhID0gYjtcbiAgICAgICAgYiA9IHQ7XG4gICAgICB9IGVsc2UgaWYgKHIgPT09IDAgfHwgYi5jbXBuKDEpID09PSAwKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBhLmlzdWIoYik7XG4gICAgfSB3aGlsZSAodHJ1ZSk7XG5cbiAgICByZXR1cm4gYi5pdXNobG4oc2hpZnQpO1xuICB9O1xuXG4gIC8vIEludmVydCBudW1iZXIgaW4gdGhlIGZpZWxkIEYobnVtKVxuICBCTi5wcm90b3R5cGUuaW52bSA9IGZ1bmN0aW9uIGludm0gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmVnY2QobnVtKS5hLnVtb2QobnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaXNFdmVuID0gZnVuY3Rpb24gaXNFdmVuICgpIHtcbiAgICByZXR1cm4gKHRoaXMud29yZHNbMF0gJiAxKSA9PT0gMDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaXNPZGQgPSBmdW5jdGlvbiBpc09kZCAoKSB7XG4gICAgcmV0dXJuICh0aGlzLndvcmRzWzBdICYgMSkgPT09IDE7XG4gIH07XG5cbiAgLy8gQW5kIGZpcnN0IHdvcmQgYW5kIG51bVxuICBCTi5wcm90b3R5cGUuYW5kbG4gPSBmdW5jdGlvbiBhbmRsbiAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMud29yZHNbMF0gJiBudW07XG4gIH07XG5cbiAgLy8gSW5jcmVtZW50IGF0IHRoZSBiaXQgcG9zaXRpb24gaW4tbGluZVxuICBCTi5wcm90b3R5cGUuYmluY24gPSBmdW5jdGlvbiBiaW5jbiAoYml0KSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBiaXQgPT09ICdudW1iZXInKTtcbiAgICB2YXIgciA9IGJpdCAlIDI2O1xuICAgIHZhciBzID0gKGJpdCAtIHIpIC8gMjY7XG4gICAgdmFyIHEgPSAxIDw8IHI7XG5cbiAgICAvLyBGYXN0IGNhc2U6IGJpdCBpcyBtdWNoIGhpZ2hlciB0aGFuIGFsbCBleGlzdGluZyB3b3Jkc1xuICAgIGlmICh0aGlzLmxlbmd0aCA8PSBzKSB7XG4gICAgICBmb3IgKHZhciBpID0gdGhpcy5sZW5ndGg7IGkgPCBzICsgMTsgaSsrKSB7XG4gICAgICAgIHRoaXMud29yZHNbaV0gPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy53b3Jkc1tzXSB8PSBxO1xuICAgICAgdGhpcy5sZW5ndGggPSBzICsgMTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEFkZCBiaXQgYW5kIHByb3BhZ2F0ZSwgaWYgbmVlZGVkXG4gICAgdmFyIGNhcnJ5ID0gcTtcbiAgICBmb3IgKGkgPSBzOyBjYXJyeSAhPT0gMCAmJiBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHcgPSB0aGlzLndvcmRzW2ldIHwgMDtcbiAgICAgIHcgKz0gY2Fycnk7XG4gICAgICBjYXJyeSA9IHcgPj4+IDI2O1xuICAgICAgdyAmPSAweDNmZmZmZmY7XG4gICAgICB0aGlzLndvcmRzW2ldID0gdztcbiAgICB9XG4gICAgaWYgKGNhcnJ5ICE9PSAwKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gY2Fycnk7XG4gICAgICB0aGlzLmxlbmd0aCsrO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaXNaZXJvID0gZnVuY3Rpb24gaXNaZXJvICgpIHtcbiAgICByZXR1cm4gdGhpcy5sZW5ndGggPT09IDEgJiYgdGhpcy53b3Jkc1swXSA9PT0gMDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuY21wbiA9IGZ1bmN0aW9uIGNtcG4gKG51bSkge1xuICAgIHZhciBuZWdhdGl2ZSA9IG51bSA8IDA7XG5cbiAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCAmJiAhbmVnYXRpdmUpIHJldHVybiAtMTtcbiAgICBpZiAodGhpcy5uZWdhdGl2ZSA9PT0gMCAmJiBuZWdhdGl2ZSkgcmV0dXJuIDE7XG5cbiAgICB0aGlzLnN0cmlwKCk7XG5cbiAgICB2YXIgcmVzO1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IDEpIHtcbiAgICAgIHJlcyA9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChuZWdhdGl2ZSkge1xuICAgICAgICBudW0gPSAtbnVtO1xuICAgICAgfVxuXG4gICAgICBhc3NlcnQobnVtIDw9IDB4M2ZmZmZmZiwgJ051bWJlciBpcyB0b28gYmlnJyk7XG5cbiAgICAgIHZhciB3ID0gdGhpcy53b3Jkc1swXSB8IDA7XG4gICAgICByZXMgPSB3ID09PSBudW0gPyAwIDogdyA8IG51bSA/IC0xIDogMTtcbiAgICB9XG4gICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIHJlcyA9IC1yZXM7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgLy8gQ29tcGFyZSB0d28gbnVtYmVycyBhbmQgcmV0dXJuOlxuICAvLyAxIC0gaWYgYHRoaXNgID4gYG51bWBcbiAgLy8gMCAtIGlmIGB0aGlzYCA9PSBgbnVtYFxuICAvLyAtMSAtIGlmIGB0aGlzYCA8IGBudW1gXG4gIEJOLnByb3RvdHlwZS5jbXAgPSBmdW5jdGlvbiBjbXAgKG51bSkge1xuICAgIGlmICh0aGlzLm5lZ2F0aXZlICE9PSAwICYmIG51bS5uZWdhdGl2ZSA9PT0gMCkgcmV0dXJuIC0xO1xuICAgIGlmICh0aGlzLm5lZ2F0aXZlID09PSAwICYmIG51bS5uZWdhdGl2ZSAhPT0gMCkgcmV0dXJuIDE7XG5cbiAgICB2YXIgcmVzID0gdGhpcy51Y21wKG51bSk7XG4gICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDApIHJldHVybiAtcmVzO1xuXG4gICAgcmV0dXJuIHJlcztcbiAgfTtcblxuICAvLyBVbnNpZ25lZCBjb21wYXJpc29uXG4gIEJOLnByb3RvdHlwZS51Y21wID0gZnVuY3Rpb24gdWNtcCAobnVtKSB7XG4gICAgLy8gQXQgdGhpcyBwb2ludCBib3RoIG51bWJlcnMgaGF2ZSB0aGUgc2FtZSBzaWduXG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkgcmV0dXJuIDE7XG4gICAgaWYgKHRoaXMubGVuZ3RoIDwgbnVtLmxlbmd0aCkgcmV0dXJuIC0xO1xuXG4gICAgdmFyIHJlcyA9IDA7XG4gICAgZm9yICh2YXIgaSA9IHRoaXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHZhciBhID0gdGhpcy53b3Jkc1tpXSB8IDA7XG4gICAgICB2YXIgYiA9IG51bS53b3Jkc1tpXSB8IDA7XG5cbiAgICAgIGlmIChhID09PSBiKSBjb250aW51ZTtcbiAgICAgIGlmIChhIDwgYikge1xuICAgICAgICByZXMgPSAtMTtcbiAgICAgIH0gZWxzZSBpZiAoYSA+IGIpIHtcbiAgICAgICAgcmVzID0gMTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5ndG4gPSBmdW5jdGlvbiBndG4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNtcG4obnVtKSA9PT0gMTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZ3QgPSBmdW5jdGlvbiBndCAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY21wKG51bSkgPT09IDE7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmd0ZW4gPSBmdW5jdGlvbiBndGVuIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXBuKG51bSkgPj0gMDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZ3RlID0gZnVuY3Rpb24gZ3RlIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXAobnVtKSA+PSAwO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5sdG4gPSBmdW5jdGlvbiBsdG4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNtcG4obnVtKSA9PT0gLTE7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmx0ID0gZnVuY3Rpb24gbHQgKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNtcChudW0pID09PSAtMTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUubHRlbiA9IGZ1bmN0aW9uIGx0ZW4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNtcG4obnVtKSA8PSAwO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5sdGUgPSBmdW5jdGlvbiBsdGUgKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNtcChudW0pIDw9IDA7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmVxbiA9IGZ1bmN0aW9uIGVxbiAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY21wbihudW0pID09PSAwO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5lcSA9IGZ1bmN0aW9uIGVxIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXAobnVtKSA9PT0gMDtcbiAgfTtcblxuICAvL1xuICAvLyBBIHJlZHVjZSBjb250ZXh0LCBjb3VsZCBiZSB1c2luZyBtb250Z29tZXJ5IG9yIHNvbWV0aGluZyBiZXR0ZXIsIGRlcGVuZGluZ1xuICAvLyBvbiB0aGUgYG1gIGl0c2VsZi5cbiAgLy9cbiAgQk4ucmVkID0gZnVuY3Rpb24gcmVkIChudW0pIHtcbiAgICByZXR1cm4gbmV3IFJlZChudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS50b1JlZCA9IGZ1bmN0aW9uIHRvUmVkIChjdHgpIHtcbiAgICBhc3NlcnQoIXRoaXMucmVkLCAnQWxyZWFkeSBhIG51bWJlciBpbiByZWR1Y3Rpb24gY29udGV4dCcpO1xuICAgIGFzc2VydCh0aGlzLm5lZ2F0aXZlID09PSAwLCAncmVkIHdvcmtzIG9ubHkgd2l0aCBwb3NpdGl2ZXMnKTtcbiAgICByZXR1cm4gY3R4LmNvbnZlcnRUbyh0aGlzKS5fZm9yY2VSZWQoY3R4KTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZnJvbVJlZCA9IGZ1bmN0aW9uIGZyb21SZWQgKCkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ2Zyb21SZWQgd29ya3Mgb25seSB3aXRoIG51bWJlcnMgaW4gcmVkdWN0aW9uIGNvbnRleHQnKTtcbiAgICByZXR1cm4gdGhpcy5yZWQuY29udmVydEZyb20odGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLl9mb3JjZVJlZCA9IGZ1bmN0aW9uIF9mb3JjZVJlZCAoY3R4KSB7XG4gICAgdGhpcy5yZWQgPSBjdHg7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmZvcmNlUmVkID0gZnVuY3Rpb24gZm9yY2VSZWQgKGN0eCkge1xuICAgIGFzc2VydCghdGhpcy5yZWQsICdBbHJlYWR5IGEgbnVtYmVyIGluIHJlZHVjdGlvbiBjb250ZXh0Jyk7XG4gICAgcmV0dXJuIHRoaXMuX2ZvcmNlUmVkKGN0eCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZEFkZCA9IGZ1bmN0aW9uIHJlZEFkZCAobnVtKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkQWRkIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHJldHVybiB0aGlzLnJlZC5hZGQodGhpcywgbnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkSUFkZCA9IGZ1bmN0aW9uIHJlZElBZGQgKG51bSkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZElBZGQgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLmlhZGQodGhpcywgbnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkU3ViID0gZnVuY3Rpb24gcmVkU3ViIChudW0pIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWRTdWIgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLnN1Yih0aGlzLCBudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5yZWRJU3ViID0gZnVuY3Rpb24gcmVkSVN1YiAobnVtKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkSVN1YiB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgICByZXR1cm4gdGhpcy5yZWQuaXN1Yih0aGlzLCBudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5yZWRTaGwgPSBmdW5jdGlvbiByZWRTaGwgKG51bSkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZFNobCB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgICByZXR1cm4gdGhpcy5yZWQudXNobCh0aGlzLCBudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5yZWRNdWwgPSBmdW5jdGlvbiByZWRNdWwgKG51bSkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZE11bCB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgICB0aGlzLnJlZC5fdmVyaWZ5Mih0aGlzLCBudW0pO1xuICAgIHJldHVybiB0aGlzLnJlZC5tdWwodGhpcywgbnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkSU11bCA9IGZ1bmN0aW9uIHJlZElNdWwgKG51bSkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZE11bCB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgICB0aGlzLnJlZC5fdmVyaWZ5Mih0aGlzLCBudW0pO1xuICAgIHJldHVybiB0aGlzLnJlZC5pbXVsKHRoaXMsIG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZFNxciA9IGZ1bmN0aW9uIHJlZFNxciAoKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkU3FyIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkxKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnJlZC5zcXIodGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZElTcXIgPSBmdW5jdGlvbiByZWRJU3FyICgpIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWRJU3FyIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkxKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnJlZC5pc3FyKHRoaXMpO1xuICB9O1xuXG4gIC8vIFNxdWFyZSByb290IG92ZXIgcFxuICBCTi5wcm90b3R5cGUucmVkU3FydCA9IGZ1bmN0aW9uIHJlZFNxcnQgKCkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZFNxcnQgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgdGhpcy5yZWQuX3ZlcmlmeTEodGhpcyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLnNxcnQodGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZEludm0gPSBmdW5jdGlvbiByZWRJbnZtICgpIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWRJbnZtIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkxKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnJlZC5pbnZtKHRoaXMpO1xuICB9O1xuXG4gIC8vIFJldHVybiBuZWdhdGl2ZSBjbG9uZSBvZiBgdGhpc2AgJSBgcmVkIG1vZHVsb2BcbiAgQk4ucHJvdG90eXBlLnJlZE5lZyA9IGZ1bmN0aW9uIHJlZE5lZyAoKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkTmVnIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkxKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnJlZC5uZWcodGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZFBvdyA9IGZ1bmN0aW9uIHJlZFBvdyAobnVtKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkICYmICFudW0ucmVkLCAncmVkUG93KG5vcm1hbE51bSknKTtcbiAgICB0aGlzLnJlZC5fdmVyaWZ5MSh0aGlzKTtcbiAgICByZXR1cm4gdGhpcy5yZWQucG93KHRoaXMsIG51bSk7XG4gIH07XG5cbiAgLy8gUHJpbWUgbnVtYmVycyB3aXRoIGVmZmljaWVudCByZWR1Y3Rpb25cbiAgdmFyIHByaW1lcyA9IHtcbiAgICBrMjU2OiBudWxsLFxuICAgIHAyMjQ6IG51bGwsXG4gICAgcDE5MjogbnVsbCxcbiAgICBwMjU1MTk6IG51bGxcbiAgfTtcblxuICAvLyBQc2V1ZG8tTWVyc2VubmUgcHJpbWVcbiAgZnVuY3Rpb24gTVByaW1lIChuYW1lLCBwKSB7XG4gICAgLy8gUCA9IDIgXiBOIC0gS1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgdGhpcy5wID0gbmV3IEJOKHAsIDE2KTtcbiAgICB0aGlzLm4gPSB0aGlzLnAuYml0TGVuZ3RoKCk7XG4gICAgdGhpcy5rID0gbmV3IEJOKDEpLml1c2hsbih0aGlzLm4pLmlzdWIodGhpcy5wKTtcblxuICAgIHRoaXMudG1wID0gdGhpcy5fdG1wKCk7XG4gIH1cblxuICBNUHJpbWUucHJvdG90eXBlLl90bXAgPSBmdW5jdGlvbiBfdG1wICgpIHtcbiAgICB2YXIgdG1wID0gbmV3IEJOKG51bGwpO1xuICAgIHRtcC53b3JkcyA9IG5ldyBBcnJheShNYXRoLmNlaWwodGhpcy5uIC8gMTMpKTtcbiAgICByZXR1cm4gdG1wO1xuICB9O1xuXG4gIE1QcmltZS5wcm90b3R5cGUuaXJlZHVjZSA9IGZ1bmN0aW9uIGlyZWR1Y2UgKG51bSkge1xuICAgIC8vIEFzc3VtZXMgdGhhdCBgbnVtYCBpcyBsZXNzIHRoYW4gYFBeMmBcbiAgICAvLyBudW0gPSBISSAqICgyIF4gTiAtIEspICsgSEkgKiBLICsgTE8gPSBISSAqIEsgKyBMTyAobW9kIFApXG4gICAgdmFyIHIgPSBudW07XG4gICAgdmFyIHJsZW47XG5cbiAgICBkbyB7XG4gICAgICB0aGlzLnNwbGl0KHIsIHRoaXMudG1wKTtcbiAgICAgIHIgPSB0aGlzLmltdWxLKHIpO1xuICAgICAgciA9IHIuaWFkZCh0aGlzLnRtcCk7XG4gICAgICBybGVuID0gci5iaXRMZW5ndGgoKTtcbiAgICB9IHdoaWxlIChybGVuID4gdGhpcy5uKTtcblxuICAgIHZhciBjbXAgPSBybGVuIDwgdGhpcy5uID8gLTEgOiByLnVjbXAodGhpcy5wKTtcbiAgICBpZiAoY21wID09PSAwKSB7XG4gICAgICByLndvcmRzWzBdID0gMDtcbiAgICAgIHIubGVuZ3RoID0gMTtcbiAgICB9IGVsc2UgaWYgKGNtcCA+IDApIHtcbiAgICAgIHIuaXN1Yih0aGlzLnApO1xuICAgIH0gZWxzZSB7XG4gICAgICByLnN0cmlwKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHI7XG4gIH07XG5cbiAgTVByaW1lLnByb3RvdHlwZS5zcGxpdCA9IGZ1bmN0aW9uIHNwbGl0IChpbnB1dCwgb3V0KSB7XG4gICAgaW5wdXQuaXVzaHJuKHRoaXMubiwgMCwgb3V0KTtcbiAgfTtcblxuICBNUHJpbWUucHJvdG90eXBlLmltdWxLID0gZnVuY3Rpb24gaW11bEsgKG51bSkge1xuICAgIHJldHVybiBudW0uaW11bCh0aGlzLmspO1xuICB9O1xuXG4gIGZ1bmN0aW9uIEsyNTYgKCkge1xuICAgIE1QcmltZS5jYWxsKFxuICAgICAgdGhpcyxcbiAgICAgICdrMjU2JyxcbiAgICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZSBmZmZmZmMyZicpO1xuICB9XG4gIGluaGVyaXRzKEsyNTYsIE1QcmltZSk7XG5cbiAgSzI1Ni5wcm90b3R5cGUuc3BsaXQgPSBmdW5jdGlvbiBzcGxpdCAoaW5wdXQsIG91dHB1dCkge1xuICAgIC8vIDI1NiA9IDkgKiAyNiArIDIyXG4gICAgdmFyIG1hc2sgPSAweDNmZmZmZjtcblxuICAgIHZhciBvdXRMZW4gPSBNYXRoLm1pbihpbnB1dC5sZW5ndGgsIDkpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3V0TGVuOyBpKyspIHtcbiAgICAgIG91dHB1dC53b3Jkc1tpXSA9IGlucHV0LndvcmRzW2ldO1xuICAgIH1cbiAgICBvdXRwdXQubGVuZ3RoID0gb3V0TGVuO1xuXG4gICAgaWYgKGlucHV0Lmxlbmd0aCA8PSA5KSB7XG4gICAgICBpbnB1dC53b3Jkc1swXSA9IDA7XG4gICAgICBpbnB1dC5sZW5ndGggPSAxO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFNoaWZ0IGJ5IDkgbGltYnNcbiAgICB2YXIgcHJldiA9IGlucHV0LndvcmRzWzldO1xuICAgIG91dHB1dC53b3Jkc1tvdXRwdXQubGVuZ3RoKytdID0gcHJldiAmIG1hc2s7XG5cbiAgICBmb3IgKGkgPSAxMDsgaSA8IGlucHV0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgbmV4dCA9IGlucHV0LndvcmRzW2ldIHwgMDtcbiAgICAgIGlucHV0LndvcmRzW2kgLSAxMF0gPSAoKG5leHQgJiBtYXNrKSA8PCA0KSB8IChwcmV2ID4+PiAyMik7XG4gICAgICBwcmV2ID0gbmV4dDtcbiAgICB9XG4gICAgaW5wdXQud29yZHNbaSAtIDEwXSA9IHByZXYgPj4+IDIyO1xuICAgIGlucHV0Lmxlbmd0aCAtPSA5O1xuICB9O1xuXG4gIEsyNTYucHJvdG90eXBlLmltdWxLID0gZnVuY3Rpb24gaW11bEsgKG51bSkge1xuICAgIC8vIEsgPSAweDEwMDAwMDNkMSA9IFsgMHg0MCwgMHgzZDEgXVxuICAgIG51bS53b3Jkc1tudW0ubGVuZ3RoXSA9IDA7XG4gICAgbnVtLndvcmRzW251bS5sZW5ndGggKyAxXSA9IDA7XG4gICAgbnVtLmxlbmd0aCArPSAyO1xuXG4gICAgLy8gYm91bmRlZCBhdDogMHg0MCAqIDB4M2ZmZmZmZiArIDB4M2QwID0gMHgxMDAwMDAzOTBcbiAgICB2YXIgbG8gPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbnVtLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdyA9IG51bS53b3Jkc1tpXSB8IDA7XG4gICAgICBsbyArPSB3ICogMHgzZDE7XG4gICAgICBudW0ud29yZHNbaV0gPSBsbyAmIDB4M2ZmZmZmZjtcbiAgICAgIGxvID0gdyAqIDB4NDAgKyAoKGxvIC8gMHg0MDAwMDAwKSB8IDApO1xuICAgIH1cblxuICAgIC8vIEZhc3QgbGVuZ3RoIHJlZHVjdGlvblxuICAgIGlmIChudW0ud29yZHNbbnVtLmxlbmd0aCAtIDFdID09PSAwKSB7XG4gICAgICBudW0ubGVuZ3RoLS07XG4gICAgICBpZiAobnVtLndvcmRzW251bS5sZW5ndGggLSAxXSA9PT0gMCkge1xuICAgICAgICBudW0ubGVuZ3RoLS07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudW07XG4gIH07XG5cbiAgZnVuY3Rpb24gUDIyNCAoKSB7XG4gICAgTVByaW1lLmNhbGwoXG4gICAgICB0aGlzLFxuICAgICAgJ3AyMjQnLFxuICAgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIDAwMDAwMDAwIDAwMDAwMDAwIDAwMDAwMDAxJyk7XG4gIH1cbiAgaW5oZXJpdHMoUDIyNCwgTVByaW1lKTtcblxuICBmdW5jdGlvbiBQMTkyICgpIHtcbiAgICBNUHJpbWUuY2FsbChcbiAgICAgIHRoaXMsXG4gICAgICAncDE5MicsXG4gICAgICAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmUgZmZmZmZmZmYgZmZmZmZmZmYnKTtcbiAgfVxuICBpbmhlcml0cyhQMTkyLCBNUHJpbWUpO1xuXG4gIGZ1bmN0aW9uIFAyNTUxOSAoKSB7XG4gICAgLy8gMiBeIDI1NSAtIDE5XG4gICAgTVByaW1lLmNhbGwoXG4gICAgICB0aGlzLFxuICAgICAgJzI1NTE5JyxcbiAgICAgICc3ZmZmZmZmZmZmZmZmZmZmIGZmZmZmZmZmZmZmZmZmZmYgZmZmZmZmZmZmZmZmZmZmZiBmZmZmZmZmZmZmZmZmZmVkJyk7XG4gIH1cbiAgaW5oZXJpdHMoUDI1NTE5LCBNUHJpbWUpO1xuXG4gIFAyNTUxOS5wcm90b3R5cGUuaW11bEsgPSBmdW5jdGlvbiBpbXVsSyAobnVtKSB7XG4gICAgLy8gSyA9IDB4MTNcbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbnVtLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgaGkgPSAobnVtLndvcmRzW2ldIHwgMCkgKiAweDEzICsgY2Fycnk7XG4gICAgICB2YXIgbG8gPSBoaSAmIDB4M2ZmZmZmZjtcbiAgICAgIGhpID4+Pj0gMjY7XG5cbiAgICAgIG51bS53b3Jkc1tpXSA9IGxvO1xuICAgICAgY2FycnkgPSBoaTtcbiAgICB9XG4gICAgaWYgKGNhcnJ5ICE9PSAwKSB7XG4gICAgICBudW0ud29yZHNbbnVtLmxlbmd0aCsrXSA9IGNhcnJ5O1xuICAgIH1cbiAgICByZXR1cm4gbnVtO1xuICB9O1xuXG4gIC8vIEV4cG9ydGVkIG1vc3RseSBmb3IgdGVzdGluZyBwdXJwb3NlcywgdXNlIHBsYWluIG5hbWUgaW5zdGVhZFxuICBCTi5fcHJpbWUgPSBmdW5jdGlvbiBwcmltZSAobmFtZSkge1xuICAgIC8vIENhY2hlZCB2ZXJzaW9uIG9mIHByaW1lXG4gICAgaWYgKHByaW1lc1tuYW1lXSkgcmV0dXJuIHByaW1lc1tuYW1lXTtcblxuICAgIHZhciBwcmltZTtcbiAgICBpZiAobmFtZSA9PT0gJ2syNTYnKSB7XG4gICAgICBwcmltZSA9IG5ldyBLMjU2KCk7XG4gICAgfSBlbHNlIGlmIChuYW1lID09PSAncDIyNCcpIHtcbiAgICAgIHByaW1lID0gbmV3IFAyMjQoKTtcbiAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdwMTkyJykge1xuICAgICAgcHJpbWUgPSBuZXcgUDE5MigpO1xuICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ3AyNTUxOScpIHtcbiAgICAgIHByaW1lID0gbmV3IFAyNTUxOSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gcHJpbWUgJyArIG5hbWUpO1xuICAgIH1cbiAgICBwcmltZXNbbmFtZV0gPSBwcmltZTtcblxuICAgIHJldHVybiBwcmltZTtcbiAgfTtcblxuICAvL1xuICAvLyBCYXNlIHJlZHVjdGlvbiBlbmdpbmVcbiAgLy9cbiAgZnVuY3Rpb24gUmVkIChtKSB7XG4gICAgaWYgKHR5cGVvZiBtID09PSAnc3RyaW5nJykge1xuICAgICAgdmFyIHByaW1lID0gQk4uX3ByaW1lKG0pO1xuICAgICAgdGhpcy5tID0gcHJpbWUucDtcbiAgICAgIHRoaXMucHJpbWUgPSBwcmltZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5tID0gbTtcbiAgICAgIHRoaXMucHJpbWUgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIFJlZC5wcm90b3R5cGUuX3ZlcmlmeTEgPSBmdW5jdGlvbiBfdmVyaWZ5MSAoYSkge1xuICAgIGFzc2VydChhLm5lZ2F0aXZlID09PSAwLCAncmVkIHdvcmtzIG9ubHkgd2l0aCBwb3NpdGl2ZXMnKTtcbiAgICBhc3NlcnQoYS5yZWQsICdyZWQgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5fdmVyaWZ5MiA9IGZ1bmN0aW9uIF92ZXJpZnkyIChhLCBiKSB7XG4gICAgYXNzZXJ0KChhLm5lZ2F0aXZlIHwgYi5uZWdhdGl2ZSkgPT09IDAsICdyZWQgd29ya3Mgb25seSB3aXRoIHBvc2l0aXZlcycpO1xuICAgIGFzc2VydChhLnJlZCAmJiBhLnJlZCA9PT0gYi5yZWQsXG4gICAgICAncmVkIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuaW1vZCA9IGZ1bmN0aW9uIGltb2QgKGEpIHtcbiAgICBpZiAodGhpcy5wcmltZSkgcmV0dXJuIHRoaXMucHJpbWUuaXJlZHVjZShhKS5fZm9yY2VSZWQodGhpcyk7XG4gICAgcmV0dXJuIGEudW1vZCh0aGlzLm0pLl9mb3JjZVJlZCh0aGlzKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLm5lZyA9IGZ1bmN0aW9uIG5lZyAoYSkge1xuICAgIGlmIChhLmlzWmVybygpKSB7XG4gICAgICByZXR1cm4gYS5jbG9uZSgpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm0uc3ViKGEpLl9mb3JjZVJlZCh0aGlzKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZCAoYSwgYikge1xuICAgIHRoaXMuX3ZlcmlmeTIoYSwgYik7XG5cbiAgICB2YXIgcmVzID0gYS5hZGQoYik7XG4gICAgaWYgKHJlcy5jbXAodGhpcy5tKSA+PSAwKSB7XG4gICAgICByZXMuaXN1Yih0aGlzLm0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzLl9mb3JjZVJlZCh0aGlzKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmlhZGQgPSBmdW5jdGlvbiBpYWRkIChhLCBiKSB7XG4gICAgdGhpcy5fdmVyaWZ5MihhLCBiKTtcblxuICAgIHZhciByZXMgPSBhLmlhZGQoYik7XG4gICAgaWYgKHJlcy5jbXAodGhpcy5tKSA+PSAwKSB7XG4gICAgICByZXMuaXN1Yih0aGlzLm0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuc3ViID0gZnVuY3Rpb24gc3ViIChhLCBiKSB7XG4gICAgdGhpcy5fdmVyaWZ5MihhLCBiKTtcblxuICAgIHZhciByZXMgPSBhLnN1YihiKTtcbiAgICBpZiAocmVzLmNtcG4oMCkgPCAwKSB7XG4gICAgICByZXMuaWFkZCh0aGlzLm0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzLl9mb3JjZVJlZCh0aGlzKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmlzdWIgPSBmdW5jdGlvbiBpc3ViIChhLCBiKSB7XG4gICAgdGhpcy5fdmVyaWZ5MihhLCBiKTtcblxuICAgIHZhciByZXMgPSBhLmlzdWIoYik7XG4gICAgaWYgKHJlcy5jbXBuKDApIDwgMCkge1xuICAgICAgcmVzLmlhZGQodGhpcy5tKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLnNobCA9IGZ1bmN0aW9uIHNobCAoYSwgbnVtKSB7XG4gICAgdGhpcy5fdmVyaWZ5MShhKTtcbiAgICByZXR1cm4gdGhpcy5pbW9kKGEudXNobG4obnVtKSk7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5pbXVsID0gZnVuY3Rpb24gaW11bCAoYSwgYikge1xuICAgIHRoaXMuX3ZlcmlmeTIoYSwgYik7XG4gICAgcmV0dXJuIHRoaXMuaW1vZChhLmltdWwoYikpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUubXVsID0gZnVuY3Rpb24gbXVsIChhLCBiKSB7XG4gICAgdGhpcy5fdmVyaWZ5MihhLCBiKTtcbiAgICByZXR1cm4gdGhpcy5pbW9kKGEubXVsKGIpKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmlzcXIgPSBmdW5jdGlvbiBpc3FyIChhKSB7XG4gICAgcmV0dXJuIHRoaXMuaW11bChhLCBhLmNsb25lKCkpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuc3FyID0gZnVuY3Rpb24gc3FyIChhKSB7XG4gICAgcmV0dXJuIHRoaXMubXVsKGEsIGEpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuc3FydCA9IGZ1bmN0aW9uIHNxcnQgKGEpIHtcbiAgICBpZiAoYS5pc1plcm8oKSkgcmV0dXJuIGEuY2xvbmUoKTtcblxuICAgIHZhciBtb2QzID0gdGhpcy5tLmFuZGxuKDMpO1xuICAgIGFzc2VydChtb2QzICUgMiA9PT0gMSk7XG5cbiAgICAvLyBGYXN0IGNhc2VcbiAgICBpZiAobW9kMyA9PT0gMykge1xuICAgICAgdmFyIHBvdyA9IHRoaXMubS5hZGQobmV3IEJOKDEpKS5pdXNocm4oMik7XG4gICAgICByZXR1cm4gdGhpcy5wb3coYSwgcG93KTtcbiAgICB9XG5cbiAgICAvLyBUb25lbGxpLVNoYW5rcyBhbGdvcml0aG0gKFRvdGFsbHkgdW5vcHRpbWl6ZWQgYW5kIHNsb3cpXG4gICAgLy9cbiAgICAvLyBGaW5kIFEgYW5kIFMsIHRoYXQgUSAqIDIgXiBTID0gKFAgLSAxKVxuICAgIHZhciBxID0gdGhpcy5tLnN1Ym4oMSk7XG4gICAgdmFyIHMgPSAwO1xuICAgIHdoaWxlICghcS5pc1plcm8oKSAmJiBxLmFuZGxuKDEpID09PSAwKSB7XG4gICAgICBzKys7XG4gICAgICBxLml1c2hybigxKTtcbiAgICB9XG4gICAgYXNzZXJ0KCFxLmlzWmVybygpKTtcblxuICAgIHZhciBvbmUgPSBuZXcgQk4oMSkudG9SZWQodGhpcyk7XG4gICAgdmFyIG5PbmUgPSBvbmUucmVkTmVnKCk7XG5cbiAgICAvLyBGaW5kIHF1YWRyYXRpYyBub24tcmVzaWR1ZVxuICAgIC8vIE5PVEU6IE1heCBpcyBzdWNoIGJlY2F1c2Ugb2YgZ2VuZXJhbGl6ZWQgUmllbWFubiBoeXBvdGhlc2lzLlxuICAgIHZhciBscG93ID0gdGhpcy5tLnN1Ym4oMSkuaXVzaHJuKDEpO1xuICAgIHZhciB6ID0gdGhpcy5tLmJpdExlbmd0aCgpO1xuICAgIHogPSBuZXcgQk4oMiAqIHogKiB6KS50b1JlZCh0aGlzKTtcblxuICAgIHdoaWxlICh0aGlzLnBvdyh6LCBscG93KS5jbXAobk9uZSkgIT09IDApIHtcbiAgICAgIHoucmVkSUFkZChuT25lKTtcbiAgICB9XG5cbiAgICB2YXIgYyA9IHRoaXMucG93KHosIHEpO1xuICAgIHZhciByID0gdGhpcy5wb3coYSwgcS5hZGRuKDEpLml1c2hybigxKSk7XG4gICAgdmFyIHQgPSB0aGlzLnBvdyhhLCBxKTtcbiAgICB2YXIgbSA9IHM7XG4gICAgd2hpbGUgKHQuY21wKG9uZSkgIT09IDApIHtcbiAgICAgIHZhciB0bXAgPSB0O1xuICAgICAgZm9yICh2YXIgaSA9IDA7IHRtcC5jbXAob25lKSAhPT0gMDsgaSsrKSB7XG4gICAgICAgIHRtcCA9IHRtcC5yZWRTcXIoKTtcbiAgICAgIH1cbiAgICAgIGFzc2VydChpIDwgbSk7XG4gICAgICB2YXIgYiA9IHRoaXMucG93KGMsIG5ldyBCTigxKS5pdXNobG4obSAtIGkgLSAxKSk7XG5cbiAgICAgIHIgPSByLnJlZE11bChiKTtcbiAgICAgIGMgPSBiLnJlZFNxcigpO1xuICAgICAgdCA9IHQucmVkTXVsKGMpO1xuICAgICAgbSA9IGk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHI7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5pbnZtID0gZnVuY3Rpb24gaW52bSAoYSkge1xuICAgIHZhciBpbnYgPSBhLl9pbnZtcCh0aGlzLm0pO1xuICAgIGlmIChpbnYubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIGludi5uZWdhdGl2ZSA9IDA7XG4gICAgICByZXR1cm4gdGhpcy5pbW9kKGludikucmVkTmVnKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmltb2QoaW52KTtcbiAgICB9XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5wb3cgPSBmdW5jdGlvbiBwb3cgKGEsIG51bSkge1xuICAgIGlmIChudW0uaXNaZXJvKCkpIHJldHVybiBuZXcgQk4oMSk7XG4gICAgaWYgKG51bS5jbXBuKDEpID09PSAwKSByZXR1cm4gYS5jbG9uZSgpO1xuXG4gICAgdmFyIHdpbmRvd1NpemUgPSA0O1xuICAgIHZhciB3bmQgPSBuZXcgQXJyYXkoMSA8PCB3aW5kb3dTaXplKTtcbiAgICB3bmRbMF0gPSBuZXcgQk4oMSkudG9SZWQodGhpcyk7XG4gICAgd25kWzFdID0gYTtcbiAgICBmb3IgKHZhciBpID0gMjsgaSA8IHduZC5sZW5ndGg7IGkrKykge1xuICAgICAgd25kW2ldID0gdGhpcy5tdWwod25kW2kgLSAxXSwgYSk7XG4gICAgfVxuXG4gICAgdmFyIHJlcyA9IHduZFswXTtcbiAgICB2YXIgY3VycmVudCA9IDA7XG4gICAgdmFyIGN1cnJlbnRMZW4gPSAwO1xuICAgIHZhciBzdGFydCA9IG51bS5iaXRMZW5ndGgoKSAlIDI2O1xuICAgIGlmIChzdGFydCA9PT0gMCkge1xuICAgICAgc3RhcnQgPSAyNjtcbiAgICB9XG5cbiAgICBmb3IgKGkgPSBudW0ubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHZhciB3b3JkID0gbnVtLndvcmRzW2ldO1xuICAgICAgZm9yICh2YXIgaiA9IHN0YXJ0IC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICAgICAgdmFyIGJpdCA9ICh3b3JkID4+IGopICYgMTtcbiAgICAgICAgaWYgKHJlcyAhPT0gd25kWzBdKSB7XG4gICAgICAgICAgcmVzID0gdGhpcy5zcXIocmVzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChiaXQgPT09IDAgJiYgY3VycmVudCA9PT0gMCkge1xuICAgICAgICAgIGN1cnJlbnRMZW4gPSAwO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY3VycmVudCA8PD0gMTtcbiAgICAgICAgY3VycmVudCB8PSBiaXQ7XG4gICAgICAgIGN1cnJlbnRMZW4rKztcbiAgICAgICAgaWYgKGN1cnJlbnRMZW4gIT09IHdpbmRvd1NpemUgJiYgKGkgIT09IDAgfHwgaiAhPT0gMCkpIGNvbnRpbnVlO1xuXG4gICAgICAgIHJlcyA9IHRoaXMubXVsKHJlcywgd25kW2N1cnJlbnRdKTtcbiAgICAgICAgY3VycmVudExlbiA9IDA7XG4gICAgICAgIGN1cnJlbnQgPSAwO1xuICAgICAgfVxuICAgICAgc3RhcnQgPSAyNjtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuY29udmVydFRvID0gZnVuY3Rpb24gY29udmVydFRvIChudW0pIHtcbiAgICB2YXIgciA9IG51bS51bW9kKHRoaXMubSk7XG5cbiAgICByZXR1cm4gciA9PT0gbnVtID8gci5jbG9uZSgpIDogcjtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmNvbnZlcnRGcm9tID0gZnVuY3Rpb24gY29udmVydEZyb20gKG51bSkge1xuICAgIHZhciByZXMgPSBudW0uY2xvbmUoKTtcbiAgICByZXMucmVkID0gbnVsbDtcbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIC8vXG4gIC8vIE1vbnRnb21lcnkgbWV0aG9kIGVuZ2luZVxuICAvL1xuXG4gIEJOLm1vbnQgPSBmdW5jdGlvbiBtb250IChudW0pIHtcbiAgICByZXR1cm4gbmV3IE1vbnQobnVtKTtcbiAgfTtcblxuICBmdW5jdGlvbiBNb250IChtKSB7XG4gICAgUmVkLmNhbGwodGhpcywgbSk7XG5cbiAgICB0aGlzLnNoaWZ0ID0gdGhpcy5tLmJpdExlbmd0aCgpO1xuICAgIGlmICh0aGlzLnNoaWZ0ICUgMjYgIT09IDApIHtcbiAgICAgIHRoaXMuc2hpZnQgKz0gMjYgLSAodGhpcy5zaGlmdCAlIDI2KTtcbiAgICB9XG5cbiAgICB0aGlzLnIgPSBuZXcgQk4oMSkuaXVzaGxuKHRoaXMuc2hpZnQpO1xuICAgIHRoaXMucjIgPSB0aGlzLmltb2QodGhpcy5yLnNxcigpKTtcbiAgICB0aGlzLnJpbnYgPSB0aGlzLnIuX2ludm1wKHRoaXMubSk7XG5cbiAgICB0aGlzLm1pbnYgPSB0aGlzLnJpbnYubXVsKHRoaXMucikuaXN1Ym4oMSkuZGl2KHRoaXMubSk7XG4gICAgdGhpcy5taW52ID0gdGhpcy5taW52LnVtb2QodGhpcy5yKTtcbiAgICB0aGlzLm1pbnYgPSB0aGlzLnIuc3ViKHRoaXMubWludik7XG4gIH1cbiAgaW5oZXJpdHMoTW9udCwgUmVkKTtcblxuICBNb250LnByb3RvdHlwZS5jb252ZXJ0VG8gPSBmdW5jdGlvbiBjb252ZXJ0VG8gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmltb2QobnVtLnVzaGxuKHRoaXMuc2hpZnQpKTtcbiAgfTtcblxuICBNb250LnByb3RvdHlwZS5jb252ZXJ0RnJvbSA9IGZ1bmN0aW9uIGNvbnZlcnRGcm9tIChudW0pIHtcbiAgICB2YXIgciA9IHRoaXMuaW1vZChudW0ubXVsKHRoaXMucmludikpO1xuICAgIHIucmVkID0gbnVsbDtcbiAgICByZXR1cm4gcjtcbiAgfTtcblxuICBNb250LnByb3RvdHlwZS5pbXVsID0gZnVuY3Rpb24gaW11bCAoYSwgYikge1xuICAgIGlmIChhLmlzWmVybygpIHx8IGIuaXNaZXJvKCkpIHtcbiAgICAgIGEud29yZHNbMF0gPSAwO1xuICAgICAgYS5sZW5ndGggPSAxO1xuICAgICAgcmV0dXJuIGE7XG4gICAgfVxuXG4gICAgdmFyIHQgPSBhLmltdWwoYik7XG4gICAgdmFyIGMgPSB0Lm1hc2tuKHRoaXMuc2hpZnQpLm11bCh0aGlzLm1pbnYpLmltYXNrbih0aGlzLnNoaWZ0KS5tdWwodGhpcy5tKTtcbiAgICB2YXIgdSA9IHQuaXN1YihjKS5pdXNocm4odGhpcy5zaGlmdCk7XG4gICAgdmFyIHJlcyA9IHU7XG5cbiAgICBpZiAodS5jbXAodGhpcy5tKSA+PSAwKSB7XG4gICAgICByZXMgPSB1LmlzdWIodGhpcy5tKTtcbiAgICB9IGVsc2UgaWYgKHUuY21wbigwKSA8IDApIHtcbiAgICAgIHJlcyA9IHUuaWFkZCh0aGlzLm0pO1xuICAgIH1cblxuICAgIHJldHVybiByZXMuX2ZvcmNlUmVkKHRoaXMpO1xuICB9O1xuXG4gIE1vbnQucHJvdG90eXBlLm11bCA9IGZ1bmN0aW9uIG11bCAoYSwgYikge1xuICAgIGlmIChhLmlzWmVybygpIHx8IGIuaXNaZXJvKCkpIHJldHVybiBuZXcgQk4oMCkuX2ZvcmNlUmVkKHRoaXMpO1xuXG4gICAgdmFyIHQgPSBhLm11bChiKTtcbiAgICB2YXIgYyA9IHQubWFza24odGhpcy5zaGlmdCkubXVsKHRoaXMubWludikuaW1hc2tuKHRoaXMuc2hpZnQpLm11bCh0aGlzLm0pO1xuICAgIHZhciB1ID0gdC5pc3ViKGMpLml1c2hybih0aGlzLnNoaWZ0KTtcbiAgICB2YXIgcmVzID0gdTtcbiAgICBpZiAodS5jbXAodGhpcy5tKSA+PSAwKSB7XG4gICAgICByZXMgPSB1LmlzdWIodGhpcy5tKTtcbiAgICB9IGVsc2UgaWYgKHUuY21wbigwKSA8IDApIHtcbiAgICAgIHJlcyA9IHUuaWFkZCh0aGlzLm0pO1xuICAgIH1cblxuICAgIHJldHVybiByZXMuX2ZvcmNlUmVkKHRoaXMpO1xuICB9O1xuXG4gIE1vbnQucHJvdG90eXBlLmludm0gPSBmdW5jdGlvbiBpbnZtIChhKSB7XG4gICAgLy8gKEFSKV4tMSAqIFJeMiA9IChBXi0xICogUl4tMSkgKiBSXjIgPSBBXi0xICogUlxuICAgIHZhciByZXMgPSB0aGlzLmltb2QoYS5faW52bXAodGhpcy5tKS5tdWwodGhpcy5yMikpO1xuICAgIHJldHVybiByZXMuX2ZvcmNlUmVkKHRoaXMpO1xuICB9O1xufSkodHlwZW9mIG1vZHVsZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbW9kdWxlLCB0aGlzKTtcbiIsInZhciBibiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgcmFuZG9tQnl0ZXMgPSByZXF1aXJlKCdyYW5kb21ieXRlcycpO1xubW9kdWxlLmV4cG9ydHMgPSBjcnQ7XG5mdW5jdGlvbiBibGluZChwcml2KSB7XG4gIHZhciByID0gZ2V0cihwcml2KTtcbiAgdmFyIGJsaW5kZXIgPSByLnRvUmVkKGJuLm1vbnQocHJpdi5tb2R1bHVzKSlcbiAgLnJlZFBvdyhuZXcgYm4ocHJpdi5wdWJsaWNFeHBvbmVudCkpLmZyb21SZWQoKTtcbiAgcmV0dXJuIHtcbiAgICBibGluZGVyOiBibGluZGVyLFxuICAgIHVuYmxpbmRlcjpyLmludm0ocHJpdi5tb2R1bHVzKVxuICB9O1xufVxuZnVuY3Rpb24gY3J0KG1zZywgcHJpdikge1xuICB2YXIgYmxpbmRzID0gYmxpbmQocHJpdik7XG4gIHZhciBsZW4gPSBwcml2Lm1vZHVsdXMuYnl0ZUxlbmd0aCgpO1xuICB2YXIgbW9kID0gYm4ubW9udChwcml2Lm1vZHVsdXMpO1xuICB2YXIgYmxpbmRlZCA9IG5ldyBibihtc2cpLm11bChibGluZHMuYmxpbmRlcikudW1vZChwcml2Lm1vZHVsdXMpO1xuICB2YXIgYzEgPSBibGluZGVkLnRvUmVkKGJuLm1vbnQocHJpdi5wcmltZTEpKTtcbiAgdmFyIGMyID0gYmxpbmRlZC50b1JlZChibi5tb250KHByaXYucHJpbWUyKSk7XG4gIHZhciBxaW52ID0gcHJpdi5jb2VmZmljaWVudDtcbiAgdmFyIHAgPSBwcml2LnByaW1lMTtcbiAgdmFyIHEgPSBwcml2LnByaW1lMjtcbiAgdmFyIG0xID0gYzEucmVkUG93KHByaXYuZXhwb25lbnQxKTtcbiAgdmFyIG0yID0gYzIucmVkUG93KHByaXYuZXhwb25lbnQyKTtcbiAgbTEgPSBtMS5mcm9tUmVkKCk7XG4gIG0yID0gbTIuZnJvbVJlZCgpO1xuICB2YXIgaCA9IG0xLmlzdWIobTIpLmltdWwocWludikudW1vZChwKTtcbiAgaC5pbXVsKHEpO1xuICBtMi5pYWRkKGgpO1xuICByZXR1cm4gbmV3IEJ1ZmZlcihtMi5pbXVsKGJsaW5kcy51bmJsaW5kZXIpLnVtb2QocHJpdi5tb2R1bHVzKS50b0FycmF5KGZhbHNlLCBsZW4pKTtcbn1cbmNydC5nZXRyID0gZ2V0cjtcbmZ1bmN0aW9uIGdldHIocHJpdikge1xuICB2YXIgbGVuID0gcHJpdi5tb2R1bHVzLmJ5dGVMZW5ndGgoKTtcbiAgdmFyIHIgPSBuZXcgYm4ocmFuZG9tQnl0ZXMobGVuKSk7XG4gIHdoaWxlIChyLmNtcChwcml2Lm1vZHVsdXMpID49ICAwIHx8ICFyLnVtb2QocHJpdi5wcmltZTEpIHx8ICFyLnVtb2QocHJpdi5wcmltZTIpKSB7XG4gICAgciA9IG5ldyBibihyYW5kb21CeXRlcyhsZW4pKTtcbiAgfVxuICByZXR1cm4gcjtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGVsbGlwdGljID0gZXhwb3J0cztcblxuZWxsaXB0aWMudmVyc2lvbiA9IHJlcXVpcmUoJy4uL3BhY2thZ2UuanNvbicpLnZlcnNpb247XG5lbGxpcHRpYy51dGlscyA9IHJlcXVpcmUoJy4vZWxsaXB0aWMvdXRpbHMnKTtcbmVsbGlwdGljLnJhbmQgPSByZXF1aXJlKCdicm9yYW5kJyk7XG5lbGxpcHRpYy5obWFjRFJCRyA9IHJlcXVpcmUoJy4vZWxsaXB0aWMvaG1hYy1kcmJnJyk7XG5lbGxpcHRpYy5jdXJ2ZSA9IHJlcXVpcmUoJy4vZWxsaXB0aWMvY3VydmUnKTtcbmVsbGlwdGljLmN1cnZlcyA9IHJlcXVpcmUoJy4vZWxsaXB0aWMvY3VydmVzJyk7XG5cbi8vIFByb3RvY29sc1xuZWxsaXB0aWMuZWMgPSByZXF1aXJlKCcuL2VsbGlwdGljL2VjJyk7XG5lbGxpcHRpYy5lZGRzYSA9IHJlcXVpcmUoJy4vZWxsaXB0aWMvZWRkc2EnKTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciBlbGxpcHRpYyA9IHJlcXVpcmUoJy4uLy4uL2VsbGlwdGljJyk7XG52YXIgdXRpbHMgPSBlbGxpcHRpYy51dGlscztcbnZhciBnZXROQUYgPSB1dGlscy5nZXROQUY7XG52YXIgZ2V0SlNGID0gdXRpbHMuZ2V0SlNGO1xudmFyIGFzc2VydCA9IHV0aWxzLmFzc2VydDtcblxuZnVuY3Rpb24gQmFzZUN1cnZlKHR5cGUsIGNvbmYpIHtcbiAgdGhpcy50eXBlID0gdHlwZTtcbiAgdGhpcy5wID0gbmV3IEJOKGNvbmYucCwgMTYpO1xuXG4gIC8vIFVzZSBNb250Z29tZXJ5LCB3aGVuIHRoZXJlIGlzIG5vIGZhc3QgcmVkdWN0aW9uIGZvciB0aGUgcHJpbWVcbiAgdGhpcy5yZWQgPSBjb25mLnByaW1lID8gQk4ucmVkKGNvbmYucHJpbWUpIDogQk4ubW9udCh0aGlzLnApO1xuXG4gIC8vIFVzZWZ1bCBmb3IgbWFueSBjdXJ2ZXNcbiAgdGhpcy56ZXJvID0gbmV3IEJOKDApLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5vbmUgPSBuZXcgQk4oMSkudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLnR3byA9IG5ldyBCTigyKS50b1JlZCh0aGlzLnJlZCk7XG5cbiAgLy8gQ3VydmUgY29uZmlndXJhdGlvbiwgb3B0aW9uYWxcbiAgdGhpcy5uID0gY29uZi5uICYmIG5ldyBCTihjb25mLm4sIDE2KTtcbiAgdGhpcy5nID0gY29uZi5nICYmIHRoaXMucG9pbnRGcm9tSlNPTihjb25mLmcsIGNvbmYuZ1JlZCk7XG5cbiAgLy8gVGVtcG9yYXJ5IGFycmF5c1xuICB0aGlzLl93bmFmVDEgPSBuZXcgQXJyYXkoNCk7XG4gIHRoaXMuX3duYWZUMiA9IG5ldyBBcnJheSg0KTtcbiAgdGhpcy5fd25hZlQzID0gbmV3IEFycmF5KDQpO1xuICB0aGlzLl93bmFmVDQgPSBuZXcgQXJyYXkoNCk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEJhc2VDdXJ2ZTtcblxuQmFzZUN1cnZlLnByb3RvdHlwZS5wb2ludCA9IGZ1bmN0aW9uIHBvaW50KCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuQmFzZUN1cnZlLnByb3RvdHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uIHZhbGlkYXRlKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuQmFzZUN1cnZlLnByb3RvdHlwZS5fZml4ZWROYWZNdWwgPSBmdW5jdGlvbiBfZml4ZWROYWZNdWwocCwgaykge1xuICBhc3NlcnQocC5wcmVjb21wdXRlZCk7XG4gIHZhciBkb3VibGVzID0gcC5fZ2V0RG91YmxlcygpO1xuXG4gIHZhciBuYWYgPSBnZXROQUYoaywgMSk7XG4gIHZhciBJID0gKDEgPDwgKGRvdWJsZXMuc3RlcCArIDEpKSAtIChkb3VibGVzLnN0ZXAgJSAyID09PSAwID8gMiA6IDEpO1xuICBJIC89IDM7XG5cbiAgLy8gVHJhbnNsYXRlIGludG8gbW9yZSB3aW5kb3dlZCBmb3JtXG4gIHZhciByZXByID0gW107XG4gIGZvciAodmFyIGogPSAwOyBqIDwgbmFmLmxlbmd0aDsgaiArPSBkb3VibGVzLnN0ZXApIHtcbiAgICB2YXIgbmFmVyA9IDA7XG4gICAgZm9yICh2YXIgayA9IGogKyBkb3VibGVzLnN0ZXAgLSAxOyBrID49IGo7IGstLSlcbiAgICAgIG5hZlcgPSAobmFmVyA8PCAxKSArIG5hZltrXTtcbiAgICByZXByLnB1c2gobmFmVyk7XG4gIH1cblxuICB2YXIgYSA9IHRoaXMuanBvaW50KG51bGwsIG51bGwsIG51bGwpO1xuICB2YXIgYiA9IHRoaXMuanBvaW50KG51bGwsIG51bGwsIG51bGwpO1xuICBmb3IgKHZhciBpID0gSTsgaSA+IDA7IGktLSkge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgcmVwci5sZW5ndGg7IGorKykge1xuICAgICAgdmFyIG5hZlcgPSByZXByW2pdO1xuICAgICAgaWYgKG5hZlcgPT09IGkpXG4gICAgICAgIGIgPSBiLm1peGVkQWRkKGRvdWJsZXMucG9pbnRzW2pdKTtcbiAgICAgIGVsc2UgaWYgKG5hZlcgPT09IC1pKVxuICAgICAgICBiID0gYi5taXhlZEFkZChkb3VibGVzLnBvaW50c1tqXS5uZWcoKSk7XG4gICAgfVxuICAgIGEgPSBhLmFkZChiKTtcbiAgfVxuICByZXR1cm4gYS50b1AoKTtcbn07XG5cbkJhc2VDdXJ2ZS5wcm90b3R5cGUuX3duYWZNdWwgPSBmdW5jdGlvbiBfd25hZk11bChwLCBrKSB7XG4gIHZhciB3ID0gNDtcblxuICAvLyBQcmVjb21wdXRlIHdpbmRvd1xuICB2YXIgbmFmUG9pbnRzID0gcC5fZ2V0TkFGUG9pbnRzKHcpO1xuICB3ID0gbmFmUG9pbnRzLnduZDtcbiAgdmFyIHduZCA9IG5hZlBvaW50cy5wb2ludHM7XG5cbiAgLy8gR2V0IE5BRiBmb3JtXG4gIHZhciBuYWYgPSBnZXROQUYoaywgdyk7XG5cbiAgLy8gQWRkIGB0aGlzYCooTisxKSBmb3IgZXZlcnkgdy1OQUYgaW5kZXhcbiAgdmFyIGFjYyA9IHRoaXMuanBvaW50KG51bGwsIG51bGwsIG51bGwpO1xuICBmb3IgKHZhciBpID0gbmFmLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgLy8gQ291bnQgemVyb2VzXG4gICAgZm9yICh2YXIgayA9IDA7IGkgPj0gMCAmJiBuYWZbaV0gPT09IDA7IGktLSlcbiAgICAgIGsrKztcbiAgICBpZiAoaSA+PSAwKVxuICAgICAgaysrO1xuICAgIGFjYyA9IGFjYy5kYmxwKGspO1xuXG4gICAgaWYgKGkgPCAwKVxuICAgICAgYnJlYWs7XG4gICAgdmFyIHogPSBuYWZbaV07XG4gICAgYXNzZXJ0KHogIT09IDApO1xuICAgIGlmIChwLnR5cGUgPT09ICdhZmZpbmUnKSB7XG4gICAgICAvLyBKICstIFBcbiAgICAgIGlmICh6ID4gMClcbiAgICAgICAgYWNjID0gYWNjLm1peGVkQWRkKHduZFsoeiAtIDEpID4+IDFdKTtcbiAgICAgIGVsc2VcbiAgICAgICAgYWNjID0gYWNjLm1peGVkQWRkKHduZFsoLXogLSAxKSA+PiAxXS5uZWcoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEogKy0gSlxuICAgICAgaWYgKHogPiAwKVxuICAgICAgICBhY2MgPSBhY2MuYWRkKHduZFsoeiAtIDEpID4+IDFdKTtcbiAgICAgIGVsc2VcbiAgICAgICAgYWNjID0gYWNjLmFkZCh3bmRbKC16IC0gMSkgPj4gMV0ubmVnKCkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcC50eXBlID09PSAnYWZmaW5lJyA/IGFjYy50b1AoKSA6IGFjYztcbn07XG5cbkJhc2VDdXJ2ZS5wcm90b3R5cGUuX3duYWZNdWxBZGQgPSBmdW5jdGlvbiBfd25hZk11bEFkZChkZWZXLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50cyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2VmZnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuKSB7XG4gIHZhciB3bmRXaWR0aCA9IHRoaXMuX3duYWZUMTtcbiAgdmFyIHduZCA9IHRoaXMuX3duYWZUMjtcbiAgdmFyIG5hZiA9IHRoaXMuX3duYWZUMztcblxuICAvLyBGaWxsIGFsbCBhcnJheXNcbiAgdmFyIG1heCA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICB2YXIgcCA9IHBvaW50c1tpXTtcbiAgICB2YXIgbmFmUG9pbnRzID0gcC5fZ2V0TkFGUG9pbnRzKGRlZlcpO1xuICAgIHduZFdpZHRoW2ldID0gbmFmUG9pbnRzLnduZDtcbiAgICB3bmRbaV0gPSBuYWZQb2ludHMucG9pbnRzO1xuICB9XG5cbiAgLy8gQ29tYiBzbWFsbCB3aW5kb3cgTkFGc1xuICBmb3IgKHZhciBpID0gbGVuIC0gMTsgaSA+PSAxOyBpIC09IDIpIHtcbiAgICB2YXIgYSA9IGkgLSAxO1xuICAgIHZhciBiID0gaTtcbiAgICBpZiAod25kV2lkdGhbYV0gIT09IDEgfHwgd25kV2lkdGhbYl0gIT09IDEpIHtcbiAgICAgIG5hZlthXSA9IGdldE5BRihjb2VmZnNbYV0sIHduZFdpZHRoW2FdKTtcbiAgICAgIG5hZltiXSA9IGdldE5BRihjb2VmZnNbYl0sIHduZFdpZHRoW2JdKTtcbiAgICAgIG1heCA9IE1hdGgubWF4KG5hZlthXS5sZW5ndGgsIG1heCk7XG4gICAgICBtYXggPSBNYXRoLm1heChuYWZbYl0ubGVuZ3RoLCBtYXgpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdmFyIGNvbWIgPSBbXG4gICAgICBwb2ludHNbYV0sIC8qIDEgKi9cbiAgICAgIG51bGwsIC8qIDMgKi9cbiAgICAgIG51bGwsIC8qIDUgKi9cbiAgICAgIHBvaW50c1tiXSAvKiA3ICovXG4gICAgXTtcblxuICAgIC8vIFRyeSB0byBhdm9pZCBQcm9qZWN0aXZlIHBvaW50cywgaWYgcG9zc2libGVcbiAgICBpZiAocG9pbnRzW2FdLnkuY21wKHBvaW50c1tiXS55KSA9PT0gMCkge1xuICAgICAgY29tYlsxXSA9IHBvaW50c1thXS5hZGQocG9pbnRzW2JdKTtcbiAgICAgIGNvbWJbMl0gPSBwb2ludHNbYV0udG9KKCkubWl4ZWRBZGQocG9pbnRzW2JdLm5lZygpKTtcbiAgICB9IGVsc2UgaWYgKHBvaW50c1thXS55LmNtcChwb2ludHNbYl0ueS5yZWROZWcoKSkgPT09IDApIHtcbiAgICAgIGNvbWJbMV0gPSBwb2ludHNbYV0udG9KKCkubWl4ZWRBZGQocG9pbnRzW2JdKTtcbiAgICAgIGNvbWJbMl0gPSBwb2ludHNbYV0uYWRkKHBvaW50c1tiXS5uZWcoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbWJbMV0gPSBwb2ludHNbYV0udG9KKCkubWl4ZWRBZGQocG9pbnRzW2JdKTtcbiAgICAgIGNvbWJbMl0gPSBwb2ludHNbYV0udG9KKCkubWl4ZWRBZGQocG9pbnRzW2JdLm5lZygpKTtcbiAgICB9XG5cbiAgICB2YXIgaW5kZXggPSBbXG4gICAgICAtMywgLyogLTEgLTEgKi9cbiAgICAgIC0xLCAvKiAtMSAwICovXG4gICAgICAtNSwgLyogLTEgMSAqL1xuICAgICAgLTcsIC8qIDAgLTEgKi9cbiAgICAgIDAsIC8qIDAgMCAqL1xuICAgICAgNywgLyogMCAxICovXG4gICAgICA1LCAvKiAxIC0xICovXG4gICAgICAxLCAvKiAxIDAgKi9cbiAgICAgIDMgIC8qIDEgMSAqL1xuICAgIF07XG5cbiAgICB2YXIganNmID0gZ2V0SlNGKGNvZWZmc1thXSwgY29lZmZzW2JdKTtcbiAgICBtYXggPSBNYXRoLm1heChqc2ZbMF0ubGVuZ3RoLCBtYXgpO1xuICAgIG5hZlthXSA9IG5ldyBBcnJheShtYXgpO1xuICAgIG5hZltiXSA9IG5ldyBBcnJheShtYXgpO1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWF4OyBqKyspIHtcbiAgICAgIHZhciBqYSA9IGpzZlswXVtqXSB8IDA7XG4gICAgICB2YXIgamIgPSBqc2ZbMV1bal0gfCAwO1xuXG4gICAgICBuYWZbYV1bal0gPSBpbmRleFsoamEgKyAxKSAqIDMgKyAoamIgKyAxKV07XG4gICAgICBuYWZbYl1bal0gPSAwO1xuICAgICAgd25kW2FdID0gY29tYjtcbiAgICB9XG4gIH1cblxuICB2YXIgYWNjID0gdGhpcy5qcG9pbnQobnVsbCwgbnVsbCwgbnVsbCk7XG4gIHZhciB0bXAgPSB0aGlzLl93bmFmVDQ7XG4gIGZvciAodmFyIGkgPSBtYXg7IGkgPj0gMDsgaS0tKSB7XG4gICAgdmFyIGsgPSAwO1xuXG4gICAgd2hpbGUgKGkgPj0gMCkge1xuICAgICAgdmFyIHplcm8gPSB0cnVlO1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBsZW47IGorKykge1xuICAgICAgICB0bXBbal0gPSBuYWZbal1baV0gfCAwO1xuICAgICAgICBpZiAodG1wW2pdICE9PSAwKVxuICAgICAgICAgIHplcm8gPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmICghemVybylcbiAgICAgICAgYnJlYWs7XG4gICAgICBrKys7XG4gICAgICBpLS07XG4gICAgfVxuICAgIGlmIChpID49IDApXG4gICAgICBrKys7XG4gICAgYWNjID0gYWNjLmRibHAoayk7XG4gICAgaWYgKGkgPCAwKVxuICAgICAgYnJlYWs7XG5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IGxlbjsgaisrKSB7XG4gICAgICB2YXIgeiA9IHRtcFtqXTtcbiAgICAgIHZhciBwO1xuICAgICAgaWYgKHogPT09IDApXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgZWxzZSBpZiAoeiA+IDApXG4gICAgICAgIHAgPSB3bmRbal1bKHogLSAxKSA+PiAxXTtcbiAgICAgIGVsc2UgaWYgKHogPCAwKVxuICAgICAgICBwID0gd25kW2pdWygteiAtIDEpID4+IDFdLm5lZygpO1xuXG4gICAgICBpZiAocC50eXBlID09PSAnYWZmaW5lJylcbiAgICAgICAgYWNjID0gYWNjLm1peGVkQWRkKHApO1xuICAgICAgZWxzZVxuICAgICAgICBhY2MgPSBhY2MuYWRkKHApO1xuICAgIH1cbiAgfVxuICAvLyBaZXJvaWZ5IHJlZmVyZW5jZXNcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICB3bmRbaV0gPSBudWxsO1xuICByZXR1cm4gYWNjLnRvUCgpO1xufTtcblxuZnVuY3Rpb24gQmFzZVBvaW50KGN1cnZlLCB0eXBlKSB7XG4gIHRoaXMuY3VydmUgPSBjdXJ2ZTtcbiAgdGhpcy50eXBlID0gdHlwZTtcbiAgdGhpcy5wcmVjb21wdXRlZCA9IG51bGw7XG59XG5CYXNlQ3VydmUuQmFzZVBvaW50ID0gQmFzZVBvaW50O1xuXG5CYXNlUG9pbnQucHJvdG90eXBlLmVxID0gZnVuY3Rpb24gZXEoLypvdGhlciovKSB7XG4gIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG59O1xuXG5CYXNlUG9pbnQucHJvdG90eXBlLnZhbGlkYXRlID0gZnVuY3Rpb24gdmFsaWRhdGUoKSB7XG4gIHJldHVybiB0aGlzLmN1cnZlLnZhbGlkYXRlKHRoaXMpO1xufTtcblxuQmFzZUN1cnZlLnByb3RvdHlwZS5kZWNvZGVQb2ludCA9IGZ1bmN0aW9uIGRlY29kZVBvaW50KGJ5dGVzLCBlbmMpIHtcbiAgYnl0ZXMgPSB1dGlscy50b0FycmF5KGJ5dGVzLCBlbmMpO1xuXG4gIHZhciBsZW4gPSB0aGlzLnAuYnl0ZUxlbmd0aCgpO1xuICBpZiAoYnl0ZXNbMF0gPT09IDB4MDQgJiYgYnl0ZXMubGVuZ3RoIC0gMSA9PT0gMiAqIGxlbikge1xuICAgIHJldHVybiB0aGlzLnBvaW50KGJ5dGVzLnNsaWNlKDEsIDEgKyBsZW4pLFxuICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzLnNsaWNlKDEgKyBsZW4sIDEgKyAyICogbGVuKSk7XG4gIH0gZWxzZSBpZiAoKGJ5dGVzWzBdID09PSAweDAyIHx8IGJ5dGVzWzBdID09PSAweDAzKSAmJlxuICAgICAgICAgICAgICBieXRlcy5sZW5ndGggLSAxID09PSBsZW4pIHtcbiAgICByZXR1cm4gdGhpcy5wb2ludEZyb21YKGJ5dGVzLnNsaWNlKDEsIDEgKyBsZW4pLCBieXRlc1swXSA9PT0gMHgwMyk7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIHBvaW50IGZvcm1hdCcpO1xufTtcblxuQmFzZVBvaW50LnByb3RvdHlwZS5lbmNvZGVDb21wcmVzc2VkID0gZnVuY3Rpb24gZW5jb2RlQ29tcHJlc3NlZChlbmMpIHtcbiAgcmV0dXJuIHRoaXMuZW5jb2RlKGVuYywgdHJ1ZSk7XG59O1xuXG5CYXNlUG9pbnQucHJvdG90eXBlLl9lbmNvZGUgPSBmdW5jdGlvbiBfZW5jb2RlKGNvbXBhY3QpIHtcbiAgdmFyIGxlbiA9IHRoaXMuY3VydmUucC5ieXRlTGVuZ3RoKCk7XG4gIHZhciB4ID0gdGhpcy5nZXRYKCkudG9BcnJheSgnYmUnLCBsZW4pO1xuXG4gIGlmIChjb21wYWN0KVxuICAgIHJldHVybiBbIHRoaXMuZ2V0WSgpLmlzRXZlbigpID8gMHgwMiA6IDB4MDMgXS5jb25jYXQoeCk7XG5cbiAgcmV0dXJuIFsgMHgwNCBdLmNvbmNhdCh4LCB0aGlzLmdldFkoKS50b0FycmF5KCdiZScsIGxlbikpIDtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKGVuYywgY29tcGFjdCkge1xuICByZXR1cm4gdXRpbHMuZW5jb2RlKHRoaXMuX2VuY29kZShjb21wYWN0KSwgZW5jKTtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUucHJlY29tcHV0ZSA9IGZ1bmN0aW9uIHByZWNvbXB1dGUocG93ZXIpIHtcbiAgaWYgKHRoaXMucHJlY29tcHV0ZWQpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgdmFyIHByZWNvbXB1dGVkID0ge1xuICAgIGRvdWJsZXM6IG51bGwsXG4gICAgbmFmOiBudWxsLFxuICAgIGJldGE6IG51bGxcbiAgfTtcbiAgcHJlY29tcHV0ZWQubmFmID0gdGhpcy5fZ2V0TkFGUG9pbnRzKDgpO1xuICBwcmVjb21wdXRlZC5kb3VibGVzID0gdGhpcy5fZ2V0RG91Ymxlcyg0LCBwb3dlcik7XG4gIHByZWNvbXB1dGVkLmJldGEgPSB0aGlzLl9nZXRCZXRhKCk7XG4gIHRoaXMucHJlY29tcHV0ZWQgPSBwcmVjb21wdXRlZDtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuX2hhc0RvdWJsZXMgPSBmdW5jdGlvbiBfaGFzRG91YmxlcyhrKSB7XG4gIGlmICghdGhpcy5wcmVjb21wdXRlZClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGRvdWJsZXMgPSB0aGlzLnByZWNvbXB1dGVkLmRvdWJsZXM7XG4gIGlmICghZG91YmxlcylcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgcmV0dXJuIGRvdWJsZXMucG9pbnRzLmxlbmd0aCA+PSBNYXRoLmNlaWwoKGsuYml0TGVuZ3RoKCkgKyAxKSAvIGRvdWJsZXMuc3RlcCk7XG59O1xuXG5CYXNlUG9pbnQucHJvdG90eXBlLl9nZXREb3VibGVzID0gZnVuY3Rpb24gX2dldERvdWJsZXMoc3RlcCwgcG93ZXIpIHtcbiAgaWYgKHRoaXMucHJlY29tcHV0ZWQgJiYgdGhpcy5wcmVjb21wdXRlZC5kb3VibGVzKVxuICAgIHJldHVybiB0aGlzLnByZWNvbXB1dGVkLmRvdWJsZXM7XG5cbiAgdmFyIGRvdWJsZXMgPSBbIHRoaXMgXTtcbiAgdmFyIGFjYyA9IHRoaXM7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcG93ZXI7IGkgKz0gc3RlcCkge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgc3RlcDsgaisrKVxuICAgICAgYWNjID0gYWNjLmRibCgpO1xuICAgIGRvdWJsZXMucHVzaChhY2MpO1xuICB9XG4gIHJldHVybiB7XG4gICAgc3RlcDogc3RlcCxcbiAgICBwb2ludHM6IGRvdWJsZXNcbiAgfTtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuX2dldE5BRlBvaW50cyA9IGZ1bmN0aW9uIF9nZXROQUZQb2ludHMod25kKSB7XG4gIGlmICh0aGlzLnByZWNvbXB1dGVkICYmIHRoaXMucHJlY29tcHV0ZWQubmFmKVxuICAgIHJldHVybiB0aGlzLnByZWNvbXB1dGVkLm5hZjtcblxuICB2YXIgcmVzID0gWyB0aGlzIF07XG4gIHZhciBtYXggPSAoMSA8PCB3bmQpIC0gMTtcbiAgdmFyIGRibCA9IG1heCA9PT0gMSA/IG51bGwgOiB0aGlzLmRibCgpO1xuICBmb3IgKHZhciBpID0gMTsgaSA8IG1heDsgaSsrKVxuICAgIHJlc1tpXSA9IHJlc1tpIC0gMV0uYWRkKGRibCk7XG4gIHJldHVybiB7XG4gICAgd25kOiB3bmQsXG4gICAgcG9pbnRzOiByZXNcbiAgfTtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuX2dldEJldGEgPSBmdW5jdGlvbiBfZ2V0QmV0YSgpIHtcbiAgcmV0dXJuIG51bGw7XG59O1xuXG5CYXNlUG9pbnQucHJvdG90eXBlLmRibHAgPSBmdW5jdGlvbiBkYmxwKGspIHtcbiAgdmFyIHIgPSB0aGlzO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGs7IGkrKylcbiAgICByID0gci5kYmwoKTtcbiAgcmV0dXJuIHI7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3VydmUgPSByZXF1aXJlKCcuLi9jdXJ2ZScpO1xudmFyIGVsbGlwdGljID0gcmVxdWlyZSgnLi4vLi4vZWxsaXB0aWMnKTtcbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xudmFyIEJhc2UgPSBjdXJ2ZS5iYXNlO1xuXG52YXIgYXNzZXJ0ID0gZWxsaXB0aWMudXRpbHMuYXNzZXJ0O1xuXG5mdW5jdGlvbiBFZHdhcmRzQ3VydmUoY29uZikge1xuICAvLyBOT1RFOiBJbXBvcnRhbnQgYXMgd2UgYXJlIGNyZWF0aW5nIHBvaW50IGluIEJhc2UuY2FsbCgpXG4gIHRoaXMudHdpc3RlZCA9IChjb25mLmEgfCAwKSAhPT0gMTtcbiAgdGhpcy5tT25lQSA9IHRoaXMudHdpc3RlZCAmJiAoY29uZi5hIHwgMCkgPT09IC0xO1xuICB0aGlzLmV4dGVuZGVkID0gdGhpcy5tT25lQTtcblxuICBCYXNlLmNhbGwodGhpcywgJ2Vkd2FyZHMnLCBjb25mKTtcblxuICB0aGlzLmEgPSBuZXcgQk4oY29uZi5hLCAxNikudW1vZCh0aGlzLnJlZC5tKTtcbiAgdGhpcy5hID0gdGhpcy5hLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5jID0gbmV3IEJOKGNvbmYuYywgMTYpLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5jMiA9IHRoaXMuYy5yZWRTcXIoKTtcbiAgdGhpcy5kID0gbmV3IEJOKGNvbmYuZCwgMTYpLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5kZCA9IHRoaXMuZC5yZWRBZGQodGhpcy5kKTtcblxuICBhc3NlcnQoIXRoaXMudHdpc3RlZCB8fCB0aGlzLmMuZnJvbVJlZCgpLmNtcG4oMSkgPT09IDApO1xuICB0aGlzLm9uZUMgPSAoY29uZi5jIHwgMCkgPT09IDE7XG59XG5pbmhlcml0cyhFZHdhcmRzQ3VydmUsIEJhc2UpO1xubW9kdWxlLmV4cG9ydHMgPSBFZHdhcmRzQ3VydmU7XG5cbkVkd2FyZHNDdXJ2ZS5wcm90b3R5cGUuX211bEEgPSBmdW5jdGlvbiBfbXVsQShudW0pIHtcbiAgaWYgKHRoaXMubU9uZUEpXG4gICAgcmV0dXJuIG51bS5yZWROZWcoKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmEucmVkTXVsKG51bSk7XG59O1xuXG5FZHdhcmRzQ3VydmUucHJvdG90eXBlLl9tdWxDID0gZnVuY3Rpb24gX211bEMobnVtKSB7XG4gIGlmICh0aGlzLm9uZUMpXG4gICAgcmV0dXJuIG51bTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmMucmVkTXVsKG51bSk7XG59O1xuXG4vLyBKdXN0IGZvciBjb21wYXRpYmlsaXR5IHdpdGggU2hvcnQgY3VydmVcbkVkd2FyZHNDdXJ2ZS5wcm90b3R5cGUuanBvaW50ID0gZnVuY3Rpb24ganBvaW50KHgsIHksIHosIHQpIHtcbiAgcmV0dXJuIHRoaXMucG9pbnQoeCwgeSwgeiwgdCk7XG59O1xuXG5FZHdhcmRzQ3VydmUucHJvdG90eXBlLnBvaW50RnJvbVggPSBmdW5jdGlvbiBwb2ludEZyb21YKHgsIG9kZCkge1xuICB4ID0gbmV3IEJOKHgsIDE2KTtcbiAgaWYgKCF4LnJlZClcbiAgICB4ID0geC50b1JlZCh0aGlzLnJlZCk7XG5cbiAgdmFyIHgyID0geC5yZWRTcXIoKTtcbiAgdmFyIHJocyA9IHRoaXMuYzIucmVkU3ViKHRoaXMuYS5yZWRNdWwoeDIpKTtcbiAgdmFyIGxocyA9IHRoaXMub25lLnJlZFN1Yih0aGlzLmMyLnJlZE11bCh0aGlzLmQpLnJlZE11bCh4MikpO1xuXG4gIHZhciB5MiA9IHJocy5yZWRNdWwobGhzLnJlZEludm0oKSk7XG4gIHZhciB5ID0geTIucmVkU3FydCgpO1xuICBpZiAoeS5yZWRTcXIoKS5yZWRTdWIoeTIpLmNtcCh0aGlzLnplcm8pICE9PSAwKVxuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBwb2ludCcpO1xuXG4gIHZhciBpc09kZCA9IHkuZnJvbVJlZCgpLmlzT2RkKCk7XG4gIGlmIChvZGQgJiYgIWlzT2RkIHx8ICFvZGQgJiYgaXNPZGQpXG4gICAgeSA9IHkucmVkTmVnKCk7XG5cbiAgcmV0dXJuIHRoaXMucG9pbnQoeCwgeSk7XG59O1xuXG5FZHdhcmRzQ3VydmUucHJvdG90eXBlLnBvaW50RnJvbVkgPSBmdW5jdGlvbiBwb2ludEZyb21ZKHksIG9kZCkge1xuICB5ID0gbmV3IEJOKHksIDE2KTtcbiAgaWYgKCF5LnJlZClcbiAgICB5ID0geS50b1JlZCh0aGlzLnJlZCk7XG5cbiAgLy8geF4yID0gKHleMiAtIDEpIC8gKGQgeV4yICsgMSlcbiAgdmFyIHkyID0geS5yZWRTcXIoKTtcbiAgdmFyIGxocyA9IHkyLnJlZFN1Yih0aGlzLm9uZSk7XG4gIHZhciByaHMgPSB5Mi5yZWRNdWwodGhpcy5kKS5yZWRBZGQodGhpcy5vbmUpO1xuICB2YXIgeDIgPSBsaHMucmVkTXVsKHJocy5yZWRJbnZtKCkpO1xuXG4gIGlmICh4Mi5jbXAodGhpcy56ZXJvKSA9PT0gMCkge1xuICAgIGlmIChvZGQpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgcG9pbnQnKTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gdGhpcy5wb2ludCh0aGlzLnplcm8sIHkpO1xuICB9XG5cbiAgdmFyIHggPSB4Mi5yZWRTcXJ0KCk7XG4gIGlmICh4LnJlZFNxcigpLnJlZFN1Yih4MikuY21wKHRoaXMuemVybykgIT09IDApXG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHBvaW50Jyk7XG5cbiAgaWYgKHguaXNPZGQoKSAhPT0gb2RkKVxuICAgIHggPSB4LnJlZE5lZygpO1xuXG4gIHJldHVybiB0aGlzLnBvaW50KHgsIHkpO1xufTtcblxuRWR3YXJkc0N1cnZlLnByb3RvdHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uIHZhbGlkYXRlKHBvaW50KSB7XG4gIGlmIChwb2ludC5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgLy8gQ3VydmU6IEEgKiBYXjIgKyBZXjIgPSBDXjIgKiAoMSArIEQgKiBYXjIgKiBZXjIpXG4gIHBvaW50Lm5vcm1hbGl6ZSgpO1xuXG4gIHZhciB4MiA9IHBvaW50LngucmVkU3FyKCk7XG4gIHZhciB5MiA9IHBvaW50LnkucmVkU3FyKCk7XG4gIHZhciBsaHMgPSB4Mi5yZWRNdWwodGhpcy5hKS5yZWRBZGQoeTIpO1xuICB2YXIgcmhzID0gdGhpcy5jMi5yZWRNdWwodGhpcy5vbmUucmVkQWRkKHRoaXMuZC5yZWRNdWwoeDIpLnJlZE11bCh5MikpKTtcblxuICByZXR1cm4gbGhzLmNtcChyaHMpID09PSAwO1xufTtcblxuZnVuY3Rpb24gUG9pbnQoY3VydmUsIHgsIHksIHosIHQpIHtcbiAgQmFzZS5CYXNlUG9pbnQuY2FsbCh0aGlzLCBjdXJ2ZSwgJ3Byb2plY3RpdmUnKTtcbiAgaWYgKHggPT09IG51bGwgJiYgeSA9PT0gbnVsbCAmJiB6ID09PSBudWxsKSB7XG4gICAgdGhpcy54ID0gdGhpcy5jdXJ2ZS56ZXJvO1xuICAgIHRoaXMueSA9IHRoaXMuY3VydmUub25lO1xuICAgIHRoaXMueiA9IHRoaXMuY3VydmUub25lO1xuICAgIHRoaXMudCA9IHRoaXMuY3VydmUuemVybztcbiAgICB0aGlzLnpPbmUgPSB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHRoaXMueCA9IG5ldyBCTih4LCAxNik7XG4gICAgdGhpcy55ID0gbmV3IEJOKHksIDE2KTtcbiAgICB0aGlzLnogPSB6ID8gbmV3IEJOKHosIDE2KSA6IHRoaXMuY3VydmUub25lO1xuICAgIHRoaXMudCA9IHQgJiYgbmV3IEJOKHQsIDE2KTtcbiAgICBpZiAoIXRoaXMueC5yZWQpXG4gICAgICB0aGlzLnggPSB0aGlzLngudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICAgIGlmICghdGhpcy55LnJlZClcbiAgICAgIHRoaXMueSA9IHRoaXMueS50b1JlZCh0aGlzLmN1cnZlLnJlZCk7XG4gICAgaWYgKCF0aGlzLnoucmVkKVxuICAgICAgdGhpcy56ID0gdGhpcy56LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcbiAgICBpZiAodGhpcy50ICYmICF0aGlzLnQucmVkKVxuICAgICAgdGhpcy50ID0gdGhpcy50LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcbiAgICB0aGlzLnpPbmUgPSB0aGlzLnogPT09IHRoaXMuY3VydmUub25lO1xuXG4gICAgLy8gVXNlIGV4dGVuZGVkIGNvb3JkaW5hdGVzXG4gICAgaWYgKHRoaXMuY3VydmUuZXh0ZW5kZWQgJiYgIXRoaXMudCkge1xuICAgICAgdGhpcy50ID0gdGhpcy54LnJlZE11bCh0aGlzLnkpO1xuICAgICAgaWYgKCF0aGlzLnpPbmUpXG4gICAgICAgIHRoaXMudCA9IHRoaXMudC5yZWRNdWwodGhpcy56LnJlZEludm0oKSk7XG4gICAgfVxuICB9XG59XG5pbmhlcml0cyhQb2ludCwgQmFzZS5CYXNlUG9pbnQpO1xuXG5FZHdhcmRzQ3VydmUucHJvdG90eXBlLnBvaW50RnJvbUpTT04gPSBmdW5jdGlvbiBwb2ludEZyb21KU09OKG9iaikge1xuICByZXR1cm4gUG9pbnQuZnJvbUpTT04odGhpcywgb2JqKTtcbn07XG5cbkVkd2FyZHNDdXJ2ZS5wcm90b3R5cGUucG9pbnQgPSBmdW5jdGlvbiBwb2ludCh4LCB5LCB6LCB0KSB7XG4gIHJldHVybiBuZXcgUG9pbnQodGhpcywgeCwgeSwgeiwgdCk7XG59O1xuXG5Qb2ludC5mcm9tSlNPTiA9IGZ1bmN0aW9uIGZyb21KU09OKGN1cnZlLCBvYmopIHtcbiAgcmV0dXJuIG5ldyBQb2ludChjdXJ2ZSwgb2JqWzBdLCBvYmpbMV0sIG9ialsyXSk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QoKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gJzxFQyBQb2ludCBJbmZpbml0eT4nO1xuICByZXR1cm4gJzxFQyBQb2ludCB4OiAnICsgdGhpcy54LmZyb21SZWQoKS50b1N0cmluZygxNiwgMikgK1xuICAgICAgJyB5OiAnICsgdGhpcy55LmZyb21SZWQoKS50b1N0cmluZygxNiwgMikgK1xuICAgICAgJyB6OiAnICsgdGhpcy56LmZyb21SZWQoKS50b1N0cmluZygxNiwgMikgKyAnPic7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuaXNJbmZpbml0eSA9IGZ1bmN0aW9uIGlzSW5maW5pdHkoKSB7XG4gIC8vIFhYWCBUaGlzIGNvZGUgYXNzdW1lcyB0aGF0IHplcm8gaXMgYWx3YXlzIHplcm8gaW4gcmVkXG4gIHJldHVybiB0aGlzLnguY21wbigwKSA9PT0gMCAmJlxuICAgICAgICAgdGhpcy55LmNtcCh0aGlzLnopID09PSAwO1xufTtcblxuUG9pbnQucHJvdG90eXBlLl9leHREYmwgPSBmdW5jdGlvbiBfZXh0RGJsKCkge1xuICAvLyBoeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tdHdpc3RlZC1leHRlbmRlZC0xLmh0bWxcbiAgLy8gICAgICNkb3VibGluZy1kYmwtMjAwOC1od2NkXG4gIC8vIDRNICsgNFNcblxuICAvLyBBID0gWDFeMlxuICB2YXIgYSA9IHRoaXMueC5yZWRTcXIoKTtcbiAgLy8gQiA9IFkxXjJcbiAgdmFyIGIgPSB0aGlzLnkucmVkU3FyKCk7XG4gIC8vIEMgPSAyICogWjFeMlxuICB2YXIgYyA9IHRoaXMuei5yZWRTcXIoKTtcbiAgYyA9IGMucmVkSUFkZChjKTtcbiAgLy8gRCA9IGEgKiBBXG4gIHZhciBkID0gdGhpcy5jdXJ2ZS5fbXVsQShhKTtcbiAgLy8gRSA9IChYMSArIFkxKV4yIC0gQSAtIEJcbiAgdmFyIGUgPSB0aGlzLngucmVkQWRkKHRoaXMueSkucmVkU3FyKCkucmVkSVN1YihhKS5yZWRJU3ViKGIpO1xuICAvLyBHID0gRCArIEJcbiAgdmFyIGcgPSBkLnJlZEFkZChiKTtcbiAgLy8gRiA9IEcgLSBDXG4gIHZhciBmID0gZy5yZWRTdWIoYyk7XG4gIC8vIEggPSBEIC0gQlxuICB2YXIgaCA9IGQucmVkU3ViKGIpO1xuICAvLyBYMyA9IEUgKiBGXG4gIHZhciBueCA9IGUucmVkTXVsKGYpO1xuICAvLyBZMyA9IEcgKiBIXG4gIHZhciBueSA9IGcucmVkTXVsKGgpO1xuICAvLyBUMyA9IEUgKiBIXG4gIHZhciBudCA9IGUucmVkTXVsKGgpO1xuICAvLyBaMyA9IEYgKiBHXG4gIHZhciBueiA9IGYucmVkTXVsKGcpO1xuICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChueCwgbnksIG56LCBudCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuX3Byb2pEYmwgPSBmdW5jdGlvbiBfcHJvakRibCgpIHtcbiAgLy8gaHlwZXJlbGxpcHRpYy5vcmcvRUZEL2cxcC9hdXRvLXR3aXN0ZWQtcHJvamVjdGl2ZS5odG1sXG4gIC8vICAgICAjZG91YmxpbmctZGJsLTIwMDgtYmJqbHBcbiAgLy8gICAgICNkb3VibGluZy1kYmwtMjAwNy1ibFxuICAvLyBhbmQgb3RoZXJzXG4gIC8vIEdlbmVyYWxseSAzTSArIDRTIG9yIDJNICsgNFNcblxuICAvLyBCID0gKFgxICsgWTEpXjJcbiAgdmFyIGIgPSB0aGlzLngucmVkQWRkKHRoaXMueSkucmVkU3FyKCk7XG4gIC8vIEMgPSBYMV4yXG4gIHZhciBjID0gdGhpcy54LnJlZFNxcigpO1xuICAvLyBEID0gWTFeMlxuICB2YXIgZCA9IHRoaXMueS5yZWRTcXIoKTtcblxuICB2YXIgbng7XG4gIHZhciBueTtcbiAgdmFyIG56O1xuICBpZiAodGhpcy5jdXJ2ZS50d2lzdGVkKSB7XG4gICAgLy8gRSA9IGEgKiBDXG4gICAgdmFyIGUgPSB0aGlzLmN1cnZlLl9tdWxBKGMpO1xuICAgIC8vIEYgPSBFICsgRFxuICAgIHZhciBmID0gZS5yZWRBZGQoZCk7XG4gICAgaWYgKHRoaXMuek9uZSkge1xuICAgICAgLy8gWDMgPSAoQiAtIEMgLSBEKSAqIChGIC0gMilcbiAgICAgIG54ID0gYi5yZWRTdWIoYykucmVkU3ViKGQpLnJlZE11bChmLnJlZFN1Yih0aGlzLmN1cnZlLnR3bykpO1xuICAgICAgLy8gWTMgPSBGICogKEUgLSBEKVxuICAgICAgbnkgPSBmLnJlZE11bChlLnJlZFN1YihkKSk7XG4gICAgICAvLyBaMyA9IEZeMiAtIDIgKiBGXG4gICAgICBueiA9IGYucmVkU3FyKCkucmVkU3ViKGYpLnJlZFN1YihmKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSCA9IFoxXjJcbiAgICAgIHZhciBoID0gdGhpcy56LnJlZFNxcigpO1xuICAgICAgLy8gSiA9IEYgLSAyICogSFxuICAgICAgdmFyIGogPSBmLnJlZFN1YihoKS5yZWRJU3ViKGgpO1xuICAgICAgLy8gWDMgPSAoQi1DLUQpKkpcbiAgICAgIG54ID0gYi5yZWRTdWIoYykucmVkSVN1YihkKS5yZWRNdWwoaik7XG4gICAgICAvLyBZMyA9IEYgKiAoRSAtIEQpXG4gICAgICBueSA9IGYucmVkTXVsKGUucmVkU3ViKGQpKTtcbiAgICAgIC8vIFozID0gRiAqIEpcbiAgICAgIG56ID0gZi5yZWRNdWwoaik7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIEUgPSBDICsgRFxuICAgIHZhciBlID0gYy5yZWRBZGQoZCk7XG4gICAgLy8gSCA9IChjICogWjEpXjJcbiAgICB2YXIgaCA9IHRoaXMuY3VydmUuX211bEModGhpcy5jLnJlZE11bCh0aGlzLnopKS5yZWRTcXIoKTtcbiAgICAvLyBKID0gRSAtIDIgKiBIXG4gICAgdmFyIGogPSBlLnJlZFN1YihoKS5yZWRTdWIoaCk7XG4gICAgLy8gWDMgPSBjICogKEIgLSBFKSAqIEpcbiAgICBueCA9IHRoaXMuY3VydmUuX211bEMoYi5yZWRJU3ViKGUpKS5yZWRNdWwoaik7XG4gICAgLy8gWTMgPSBjICogRSAqIChDIC0gRClcbiAgICBueSA9IHRoaXMuY3VydmUuX211bEMoZSkucmVkTXVsKGMucmVkSVN1YihkKSk7XG4gICAgLy8gWjMgPSBFICogSlxuICAgIG56ID0gZS5yZWRNdWwoaik7XG4gIH1cbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobngsIG55LCBueik7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZGJsID0gZnVuY3Rpb24gZGJsKCkge1xuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gRG91YmxlIGluIGV4dGVuZGVkIGNvb3JkaW5hdGVzXG4gIGlmICh0aGlzLmN1cnZlLmV4dGVuZGVkKVxuICAgIHJldHVybiB0aGlzLl9leHREYmwoKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLl9wcm9qRGJsKCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuX2V4dEFkZCA9IGZ1bmN0aW9uIF9leHRBZGQocCkge1xuICAvLyBoeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tdHdpc3RlZC1leHRlbmRlZC0xLmh0bWxcbiAgLy8gICAgICNhZGRpdGlvbi1hZGQtMjAwOC1od2NkLTNcbiAgLy8gOE1cblxuICAvLyBBID0gKFkxIC0gWDEpICogKFkyIC0gWDIpXG4gIHZhciBhID0gdGhpcy55LnJlZFN1Yih0aGlzLngpLnJlZE11bChwLnkucmVkU3ViKHAueCkpO1xuICAvLyBCID0gKFkxICsgWDEpICogKFkyICsgWDIpXG4gIHZhciBiID0gdGhpcy55LnJlZEFkZCh0aGlzLngpLnJlZE11bChwLnkucmVkQWRkKHAueCkpO1xuICAvLyBDID0gVDEgKiBrICogVDJcbiAgdmFyIGMgPSB0aGlzLnQucmVkTXVsKHRoaXMuY3VydmUuZGQpLnJlZE11bChwLnQpO1xuICAvLyBEID0gWjEgKiAyICogWjJcbiAgdmFyIGQgPSB0aGlzLnoucmVkTXVsKHAuei5yZWRBZGQocC56KSk7XG4gIC8vIEUgPSBCIC0gQVxuICB2YXIgZSA9IGIucmVkU3ViKGEpO1xuICAvLyBGID0gRCAtIENcbiAgdmFyIGYgPSBkLnJlZFN1YihjKTtcbiAgLy8gRyA9IEQgKyBDXG4gIHZhciBnID0gZC5yZWRBZGQoYyk7XG4gIC8vIEggPSBCICsgQVxuICB2YXIgaCA9IGIucmVkQWRkKGEpO1xuICAvLyBYMyA9IEUgKiBGXG4gIHZhciBueCA9IGUucmVkTXVsKGYpO1xuICAvLyBZMyA9IEcgKiBIXG4gIHZhciBueSA9IGcucmVkTXVsKGgpO1xuICAvLyBUMyA9IEUgKiBIXG4gIHZhciBudCA9IGUucmVkTXVsKGgpO1xuICAvLyBaMyA9IEYgKiBHXG4gIHZhciBueiA9IGYucmVkTXVsKGcpO1xuICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChueCwgbnksIG56LCBudCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuX3Byb2pBZGQgPSBmdW5jdGlvbiBfcHJvakFkZChwKSB7XG4gIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by10d2lzdGVkLXByb2plY3RpdmUuaHRtbFxuICAvLyAgICAgI2FkZGl0aW9uLWFkZC0yMDA4LWJiamxwXG4gIC8vICAgICAjYWRkaXRpb24tYWRkLTIwMDctYmxcbiAgLy8gMTBNICsgMVNcblxuICAvLyBBID0gWjEgKiBaMlxuICB2YXIgYSA9IHRoaXMuei5yZWRNdWwocC56KTtcbiAgLy8gQiA9IEFeMlxuICB2YXIgYiA9IGEucmVkU3FyKCk7XG4gIC8vIEMgPSBYMSAqIFgyXG4gIHZhciBjID0gdGhpcy54LnJlZE11bChwLngpO1xuICAvLyBEID0gWTEgKiBZMlxuICB2YXIgZCA9IHRoaXMueS5yZWRNdWwocC55KTtcbiAgLy8gRSA9IGQgKiBDICogRFxuICB2YXIgZSA9IHRoaXMuY3VydmUuZC5yZWRNdWwoYykucmVkTXVsKGQpO1xuICAvLyBGID0gQiAtIEVcbiAgdmFyIGYgPSBiLnJlZFN1YihlKTtcbiAgLy8gRyA9IEIgKyBFXG4gIHZhciBnID0gYi5yZWRBZGQoZSk7XG4gIC8vIFgzID0gQSAqIEYgKiAoKFgxICsgWTEpICogKFgyICsgWTIpIC0gQyAtIEQpXG4gIHZhciB0bXAgPSB0aGlzLngucmVkQWRkKHRoaXMueSkucmVkTXVsKHAueC5yZWRBZGQocC55KSkucmVkSVN1YihjKS5yZWRJU3ViKGQpO1xuICB2YXIgbnggPSBhLnJlZE11bChmKS5yZWRNdWwodG1wKTtcbiAgdmFyIG55O1xuICB2YXIgbno7XG4gIGlmICh0aGlzLmN1cnZlLnR3aXN0ZWQpIHtcbiAgICAvLyBZMyA9IEEgKiBHICogKEQgLSBhICogQylcbiAgICBueSA9IGEucmVkTXVsKGcpLnJlZE11bChkLnJlZFN1Yih0aGlzLmN1cnZlLl9tdWxBKGMpKSk7XG4gICAgLy8gWjMgPSBGICogR1xuICAgIG56ID0gZi5yZWRNdWwoZyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gWTMgPSBBICogRyAqIChEIC0gQylcbiAgICBueSA9IGEucmVkTXVsKGcpLnJlZE11bChkLnJlZFN1YihjKSk7XG4gICAgLy8gWjMgPSBjICogRiAqIEdcbiAgICBueiA9IHRoaXMuY3VydmUuX211bEMoZikucmVkTXVsKGcpO1xuICB9XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG54LCBueSwgbnopO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZChwKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gcDtcbiAgaWYgKHAuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIGlmICh0aGlzLmN1cnZlLmV4dGVuZGVkKVxuICAgIHJldHVybiB0aGlzLl9leHRBZGQocCk7XG4gIGVsc2VcbiAgICByZXR1cm4gdGhpcy5fcHJvakFkZChwKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5tdWwgPSBmdW5jdGlvbiBtdWwoaykge1xuICBpZiAodGhpcy5faGFzRG91YmxlcyhrKSlcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5fZml4ZWROYWZNdWwodGhpcywgayk7XG4gIGVsc2VcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5fd25hZk11bCh0aGlzLCBrKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5tdWxBZGQgPSBmdW5jdGlvbiBtdWxBZGQoazEsIHAsIGsyKSB7XG4gIHJldHVybiB0aGlzLmN1cnZlLl93bmFmTXVsQWRkKDEsIFsgdGhpcywgcCBdLCBbIGsxLCBrMiBdLCAyKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5ub3JtYWxpemUgPSBmdW5jdGlvbiBub3JtYWxpemUoKSB7XG4gIGlmICh0aGlzLnpPbmUpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gTm9ybWFsaXplIGNvb3JkaW5hdGVzXG4gIHZhciB6aSA9IHRoaXMuei5yZWRJbnZtKCk7XG4gIHRoaXMueCA9IHRoaXMueC5yZWRNdWwoemkpO1xuICB0aGlzLnkgPSB0aGlzLnkucmVkTXVsKHppKTtcbiAgaWYgKHRoaXMudClcbiAgICB0aGlzLnQgPSB0aGlzLnQucmVkTXVsKHppKTtcbiAgdGhpcy56ID0gdGhpcy5jdXJ2ZS5vbmU7XG4gIHRoaXMuek9uZSA9IHRydWU7XG4gIHJldHVybiB0aGlzO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm5lZyA9IGZ1bmN0aW9uIG5lZygpIHtcbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQodGhpcy54LnJlZE5lZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMueixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50ICYmIHRoaXMudC5yZWROZWcoKSk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZ2V0WCA9IGZ1bmN0aW9uIGdldFgoKSB7XG4gIHRoaXMubm9ybWFsaXplKCk7XG4gIHJldHVybiB0aGlzLnguZnJvbVJlZCgpO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmdldFkgPSBmdW5jdGlvbiBnZXRZKCkge1xuICB0aGlzLm5vcm1hbGl6ZSgpO1xuICByZXR1cm4gdGhpcy55LmZyb21SZWQoKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5lcSA9IGZ1bmN0aW9uIGVxKG90aGVyKSB7XG4gIHJldHVybiB0aGlzID09PSBvdGhlciB8fFxuICAgICAgICAgdGhpcy5nZXRYKCkuY21wKG90aGVyLmdldFgoKSkgPT09IDAgJiZcbiAgICAgICAgIHRoaXMuZ2V0WSgpLmNtcChvdGhlci5nZXRZKCkpID09PSAwO1xufTtcblxuLy8gQ29tcGF0aWJpbGl0eSB3aXRoIEJhc2VDdXJ2ZVxuUG9pbnQucHJvdG90eXBlLnRvUCA9IFBvaW50LnByb3RvdHlwZS5ub3JtYWxpemU7XG5Qb2ludC5wcm90b3R5cGUubWl4ZWRBZGQgPSBQb2ludC5wcm90b3R5cGUuYWRkO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3VydmUgPSBleHBvcnRzO1xuXG5jdXJ2ZS5iYXNlID0gcmVxdWlyZSgnLi9iYXNlJyk7XG5jdXJ2ZS5zaG9ydCA9IHJlcXVpcmUoJy4vc2hvcnQnKTtcbmN1cnZlLm1vbnQgPSByZXF1aXJlKCcuL21vbnQnKTtcbmN1cnZlLmVkd2FyZHMgPSByZXF1aXJlKCcuL2Vkd2FyZHMnKTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGN1cnZlID0gcmVxdWlyZSgnLi4vY3VydmUnKTtcbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xudmFyIEJhc2UgPSBjdXJ2ZS5iYXNlO1xuXG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi8uLi9lbGxpcHRpYycpO1xudmFyIHV0aWxzID0gZWxsaXB0aWMudXRpbHM7XG5cbmZ1bmN0aW9uIE1vbnRDdXJ2ZShjb25mKSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnbW9udCcsIGNvbmYpO1xuXG4gIHRoaXMuYSA9IG5ldyBCTihjb25mLmEsIDE2KS50b1JlZCh0aGlzLnJlZCk7XG4gIHRoaXMuYiA9IG5ldyBCTihjb25mLmIsIDE2KS50b1JlZCh0aGlzLnJlZCk7XG4gIHRoaXMuaTQgPSBuZXcgQk4oNCkudG9SZWQodGhpcy5yZWQpLnJlZEludm0oKTtcbiAgdGhpcy50d28gPSBuZXcgQk4oMikudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLmEyNCA9IHRoaXMuaTQucmVkTXVsKHRoaXMuYS5yZWRBZGQodGhpcy50d28pKTtcbn1cbmluaGVyaXRzKE1vbnRDdXJ2ZSwgQmFzZSk7XG5tb2R1bGUuZXhwb3J0cyA9IE1vbnRDdXJ2ZTtcblxuTW9udEN1cnZlLnByb3RvdHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uIHZhbGlkYXRlKHBvaW50KSB7XG4gIHZhciB4ID0gcG9pbnQubm9ybWFsaXplKCkueDtcbiAgdmFyIHgyID0geC5yZWRTcXIoKTtcbiAgdmFyIHJocyA9IHgyLnJlZE11bCh4KS5yZWRBZGQoeDIucmVkTXVsKHRoaXMuYSkpLnJlZEFkZCh4KTtcbiAgdmFyIHkgPSByaHMucmVkU3FydCgpO1xuXG4gIHJldHVybiB5LnJlZFNxcigpLmNtcChyaHMpID09PSAwO1xufTtcblxuZnVuY3Rpb24gUG9pbnQoY3VydmUsIHgsIHopIHtcbiAgQmFzZS5CYXNlUG9pbnQuY2FsbCh0aGlzLCBjdXJ2ZSwgJ3Byb2plY3RpdmUnKTtcbiAgaWYgKHggPT09IG51bGwgJiYgeiA9PT0gbnVsbCkge1xuICAgIHRoaXMueCA9IHRoaXMuY3VydmUub25lO1xuICAgIHRoaXMueiA9IHRoaXMuY3VydmUuemVybztcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnggPSBuZXcgQk4oeCwgMTYpO1xuICAgIHRoaXMueiA9IG5ldyBCTih6LCAxNik7XG4gICAgaWYgKCF0aGlzLngucmVkKVxuICAgICAgdGhpcy54ID0gdGhpcy54LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcbiAgICBpZiAoIXRoaXMuei5yZWQpXG4gICAgICB0aGlzLnogPSB0aGlzLnoudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICB9XG59XG5pbmhlcml0cyhQb2ludCwgQmFzZS5CYXNlUG9pbnQpO1xuXG5Nb250Q3VydmUucHJvdG90eXBlLmRlY29kZVBvaW50ID0gZnVuY3Rpb24gZGVjb2RlUG9pbnQoYnl0ZXMsIGVuYykge1xuICByZXR1cm4gdGhpcy5wb2ludCh1dGlscy50b0FycmF5KGJ5dGVzLCBlbmMpLCAxKTtcbn07XG5cbk1vbnRDdXJ2ZS5wcm90b3R5cGUucG9pbnQgPSBmdW5jdGlvbiBwb2ludCh4LCB6KSB7XG4gIHJldHVybiBuZXcgUG9pbnQodGhpcywgeCwgeik7XG59O1xuXG5Nb250Q3VydmUucHJvdG90eXBlLnBvaW50RnJvbUpTT04gPSBmdW5jdGlvbiBwb2ludEZyb21KU09OKG9iaikge1xuICByZXR1cm4gUG9pbnQuZnJvbUpTT04odGhpcywgb2JqKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5wcmVjb21wdXRlID0gZnVuY3Rpb24gcHJlY29tcHV0ZSgpIHtcbiAgLy8gTm8tb3Bcbn07XG5cblBvaW50LnByb3RvdHlwZS5fZW5jb2RlID0gZnVuY3Rpb24gX2VuY29kZSgpIHtcbiAgcmV0dXJuIHRoaXMuZ2V0WCgpLnRvQXJyYXkoJ2JlJywgdGhpcy5jdXJ2ZS5wLmJ5dGVMZW5ndGgoKSk7XG59O1xuXG5Qb2ludC5mcm9tSlNPTiA9IGZ1bmN0aW9uIGZyb21KU09OKGN1cnZlLCBvYmopIHtcbiAgcmV0dXJuIG5ldyBQb2ludChjdXJ2ZSwgb2JqWzBdLCBvYmpbMV0gfHwgY3VydmUub25lKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiAnPEVDIFBvaW50IEluZmluaXR5Pic7XG4gIHJldHVybiAnPEVDIFBvaW50IHg6ICcgKyB0aGlzLnguZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArXG4gICAgICAnIHo6ICcgKyB0aGlzLnouZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArICc+Jztcbn07XG5cblBvaW50LnByb3RvdHlwZS5pc0luZmluaXR5ID0gZnVuY3Rpb24gaXNJbmZpbml0eSgpIHtcbiAgLy8gWFhYIFRoaXMgY29kZSBhc3N1bWVzIHRoYXQgemVybyBpcyBhbHdheXMgemVybyBpbiByZWRcbiAgcmV0dXJuIHRoaXMuei5jbXBuKDApID09PSAwO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmRibCA9IGZ1bmN0aW9uIGRibCgpIHtcbiAgLy8gaHR0cDovL2h5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by1tb250Z29tLXh6Lmh0bWwjZG91YmxpbmctZGJsLTE5ODctbS0zXG4gIC8vIDJNICsgMlMgKyA0QVxuXG4gIC8vIEEgPSBYMSArIFoxXG4gIHZhciBhID0gdGhpcy54LnJlZEFkZCh0aGlzLnopO1xuICAvLyBBQSA9IEFeMlxuICB2YXIgYWEgPSBhLnJlZFNxcigpO1xuICAvLyBCID0gWDEgLSBaMVxuICB2YXIgYiA9IHRoaXMueC5yZWRTdWIodGhpcy56KTtcbiAgLy8gQkIgPSBCXjJcbiAgdmFyIGJiID0gYi5yZWRTcXIoKTtcbiAgLy8gQyA9IEFBIC0gQkJcbiAgdmFyIGMgPSBhYS5yZWRTdWIoYmIpO1xuICAvLyBYMyA9IEFBICogQkJcbiAgdmFyIG54ID0gYWEucmVkTXVsKGJiKTtcbiAgLy8gWjMgPSBDICogKEJCICsgQTI0ICogQylcbiAgdmFyIG56ID0gYy5yZWRNdWwoYmIucmVkQWRkKHRoaXMuY3VydmUuYTI0LnJlZE11bChjKSkpO1xuICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChueCwgbnopO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZCgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdOb3Qgc3VwcG9ydGVkIG9uIE1vbnRnb21lcnkgY3VydmUnKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5kaWZmQWRkID0gZnVuY3Rpb24gZGlmZkFkZChwLCBkaWZmKSB7XG4gIC8vIGh0dHA6Ly9oeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tbW9udGdvbS14ei5odG1sI2RpZmZhZGQtZGFkZC0xOTg3LW0tM1xuICAvLyA0TSArIDJTICsgNkFcblxuICAvLyBBID0gWDIgKyBaMlxuICB2YXIgYSA9IHRoaXMueC5yZWRBZGQodGhpcy56KTtcbiAgLy8gQiA9IFgyIC0gWjJcbiAgdmFyIGIgPSB0aGlzLngucmVkU3ViKHRoaXMueik7XG4gIC8vIEMgPSBYMyArIFozXG4gIHZhciBjID0gcC54LnJlZEFkZChwLnopO1xuICAvLyBEID0gWDMgLSBaM1xuICB2YXIgZCA9IHAueC5yZWRTdWIocC56KTtcbiAgLy8gREEgPSBEICogQVxuICB2YXIgZGEgPSBkLnJlZE11bChhKTtcbiAgLy8gQ0IgPSBDICogQlxuICB2YXIgY2IgPSBjLnJlZE11bChiKTtcbiAgLy8gWDUgPSBaMSAqIChEQSArIENCKV4yXG4gIHZhciBueCA9IGRpZmYuei5yZWRNdWwoZGEucmVkQWRkKGNiKS5yZWRTcXIoKSk7XG4gIC8vIFo1ID0gWDEgKiAoREEgLSBDQileMlxuICB2YXIgbnogPSBkaWZmLngucmVkTXVsKGRhLnJlZElTdWIoY2IpLnJlZFNxcigpKTtcbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobngsIG56KTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5tdWwgPSBmdW5jdGlvbiBtdWwoaykge1xuICB2YXIgdCA9IGsuY2xvbmUoKTtcbiAgdmFyIGEgPSB0aGlzOyAvLyAoTiAvIDIpICogUSArIFFcbiAgdmFyIGIgPSB0aGlzLmN1cnZlLnBvaW50KG51bGwsIG51bGwpOyAvLyAoTiAvIDIpICogUVxuICB2YXIgYyA9IHRoaXM7IC8vIFFcblxuICBmb3IgKHZhciBiaXRzID0gW107IHQuY21wbigwKSAhPT0gMDsgdC5pdXNocm4oMSkpXG4gICAgYml0cy5wdXNoKHQuYW5kbG4oMSkpO1xuXG4gIGZvciAodmFyIGkgPSBiaXRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgaWYgKGJpdHNbaV0gPT09IDApIHtcbiAgICAgIC8vIE4gKiBRICsgUSA9ICgoTiAvIDIpICogUSArIFEpKSArIChOIC8gMikgKiBRXG4gICAgICBhID0gYS5kaWZmQWRkKGIsIGMpO1xuICAgICAgLy8gTiAqIFEgPSAyICogKChOIC8gMikgKiBRICsgUSkpXG4gICAgICBiID0gYi5kYmwoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTiAqIFEgPSAoKE4gLyAyKSAqIFEgKyBRKSArICgoTiAvIDIpICogUSlcbiAgICAgIGIgPSBhLmRpZmZBZGQoYiwgYyk7XG4gICAgICAvLyBOICogUSArIFEgPSAyICogKChOIC8gMikgKiBRICsgUSlcbiAgICAgIGEgPSBhLmRibCgpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYjtcbn07XG5cblBvaW50LnByb3RvdHlwZS5tdWxBZGQgPSBmdW5jdGlvbiBtdWxBZGQoKSB7XG4gIHRocm93IG5ldyBFcnJvcignTm90IHN1cHBvcnRlZCBvbiBNb250Z29tZXJ5IGN1cnZlJyk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZXEgPSBmdW5jdGlvbiBlcShvdGhlcikge1xuICByZXR1cm4gdGhpcy5nZXRYKCkuY21wKG90aGVyLmdldFgoKSkgPT09IDA7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUubm9ybWFsaXplID0gZnVuY3Rpb24gbm9ybWFsaXplKCkge1xuICB0aGlzLnggPSB0aGlzLngucmVkTXVsKHRoaXMuei5yZWRJbnZtKCkpO1xuICB0aGlzLnogPSB0aGlzLmN1cnZlLm9uZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZ2V0WCA9IGZ1bmN0aW9uIGdldFgoKSB7XG4gIC8vIE5vcm1hbGl6ZSBjb29yZGluYXRlc1xuICB0aGlzLm5vcm1hbGl6ZSgpO1xuXG4gIHJldHVybiB0aGlzLnguZnJvbVJlZCgpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGN1cnZlID0gcmVxdWlyZSgnLi4vY3VydmUnKTtcbnZhciBlbGxpcHRpYyA9IHJlcXVpcmUoJy4uLy4uL2VsbGlwdGljJyk7XG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbnZhciBCYXNlID0gY3VydmUuYmFzZTtcblxudmFyIGFzc2VydCA9IGVsbGlwdGljLnV0aWxzLmFzc2VydDtcblxuZnVuY3Rpb24gU2hvcnRDdXJ2ZShjb25mKSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnc2hvcnQnLCBjb25mKTtcblxuICB0aGlzLmEgPSBuZXcgQk4oY29uZi5hLCAxNikudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLmIgPSBuZXcgQk4oY29uZi5iLCAxNikudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLnRpbnYgPSB0aGlzLnR3by5yZWRJbnZtKCk7XG5cbiAgdGhpcy56ZXJvQSA9IHRoaXMuYS5mcm9tUmVkKCkuY21wbigwKSA9PT0gMDtcbiAgdGhpcy50aHJlZUEgPSB0aGlzLmEuZnJvbVJlZCgpLnN1Yih0aGlzLnApLmNtcG4oLTMpID09PSAwO1xuXG4gIC8vIElmIHRoZSBjdXJ2ZSBpcyBlbmRvbW9ycGhpYywgcHJlY2FsY3VsYXRlIGJldGEgYW5kIGxhbWJkYVxuICB0aGlzLmVuZG8gPSB0aGlzLl9nZXRFbmRvbW9ycGhpc20oY29uZik7XG4gIHRoaXMuX2VuZG9XbmFmVDEgPSBuZXcgQXJyYXkoNCk7XG4gIHRoaXMuX2VuZG9XbmFmVDIgPSBuZXcgQXJyYXkoNCk7XG59XG5pbmhlcml0cyhTaG9ydEN1cnZlLCBCYXNlKTtcbm1vZHVsZS5leHBvcnRzID0gU2hvcnRDdXJ2ZTtcblxuU2hvcnRDdXJ2ZS5wcm90b3R5cGUuX2dldEVuZG9tb3JwaGlzbSA9IGZ1bmN0aW9uIF9nZXRFbmRvbW9ycGhpc20oY29uZikge1xuICAvLyBObyBlZmZpY2llbnQgZW5kb21vcnBoaXNtXG4gIGlmICghdGhpcy56ZXJvQSB8fCAhdGhpcy5nIHx8ICF0aGlzLm4gfHwgdGhpcy5wLm1vZG4oMykgIT09IDEpXG4gICAgcmV0dXJuO1xuXG4gIC8vIENvbXB1dGUgYmV0YSBhbmQgbGFtYmRhLCB0aGF0IGxhbWJkYSAqIFAgPSAoYmV0YSAqIFB4OyBQeSlcbiAgdmFyIGJldGE7XG4gIHZhciBsYW1iZGE7XG4gIGlmIChjb25mLmJldGEpIHtcbiAgICBiZXRhID0gbmV3IEJOKGNvbmYuYmV0YSwgMTYpLnRvUmVkKHRoaXMucmVkKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgYmV0YXMgPSB0aGlzLl9nZXRFbmRvUm9vdHModGhpcy5wKTtcbiAgICAvLyBDaG9vc2UgdGhlIHNtYWxsZXN0IGJldGFcbiAgICBiZXRhID0gYmV0YXNbMF0uY21wKGJldGFzWzFdKSA8IDAgPyBiZXRhc1swXSA6IGJldGFzWzFdO1xuICAgIGJldGEgPSBiZXRhLnRvUmVkKHRoaXMucmVkKTtcbiAgfVxuICBpZiAoY29uZi5sYW1iZGEpIHtcbiAgICBsYW1iZGEgPSBuZXcgQk4oY29uZi5sYW1iZGEsIDE2KTtcbiAgfSBlbHNlIHtcbiAgICAvLyBDaG9vc2UgdGhlIGxhbWJkYSB0aGF0IGlzIG1hdGNoaW5nIHNlbGVjdGVkIGJldGFcbiAgICB2YXIgbGFtYmRhcyA9IHRoaXMuX2dldEVuZG9Sb290cyh0aGlzLm4pO1xuICAgIGlmICh0aGlzLmcubXVsKGxhbWJkYXNbMF0pLnguY21wKHRoaXMuZy54LnJlZE11bChiZXRhKSkgPT09IDApIHtcbiAgICAgIGxhbWJkYSA9IGxhbWJkYXNbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGxhbWJkYSA9IGxhbWJkYXNbMV07XG4gICAgICBhc3NlcnQodGhpcy5nLm11bChsYW1iZGEpLnguY21wKHRoaXMuZy54LnJlZE11bChiZXRhKSkgPT09IDApO1xuICAgIH1cbiAgfVxuXG4gIC8vIEdldCBiYXNpcyB2ZWN0b3JzLCB1c2VkIGZvciBiYWxhbmNlZCBsZW5ndGgtdHdvIHJlcHJlc2VudGF0aW9uXG4gIHZhciBiYXNpcztcbiAgaWYgKGNvbmYuYmFzaXMpIHtcbiAgICBiYXNpcyA9IGNvbmYuYmFzaXMubWFwKGZ1bmN0aW9uKHZlYykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYTogbmV3IEJOKHZlYy5hLCAxNiksXG4gICAgICAgIGI6IG5ldyBCTih2ZWMuYiwgMTYpXG4gICAgICB9O1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGJhc2lzID0gdGhpcy5fZ2V0RW5kb0Jhc2lzKGxhbWJkYSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGJldGE6IGJldGEsXG4gICAgbGFtYmRhOiBsYW1iZGEsXG4gICAgYmFzaXM6IGJhc2lzXG4gIH07XG59O1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS5fZ2V0RW5kb1Jvb3RzID0gZnVuY3Rpb24gX2dldEVuZG9Sb290cyhudW0pIHtcbiAgLy8gRmluZCByb290cyBvZiBmb3IgeF4yICsgeCArIDEgaW4gRlxuICAvLyBSb290ID0gKC0xICstIFNxcnQoLTMpKSAvIDJcbiAgLy9cbiAgdmFyIHJlZCA9IG51bSA9PT0gdGhpcy5wID8gdGhpcy5yZWQgOiBCTi5tb250KG51bSk7XG4gIHZhciB0aW52ID0gbmV3IEJOKDIpLnRvUmVkKHJlZCkucmVkSW52bSgpO1xuICB2YXIgbnRpbnYgPSB0aW52LnJlZE5lZygpO1xuXG4gIHZhciBzID0gbmV3IEJOKDMpLnRvUmVkKHJlZCkucmVkTmVnKCkucmVkU3FydCgpLnJlZE11bCh0aW52KTtcblxuICB2YXIgbDEgPSBudGludi5yZWRBZGQocykuZnJvbVJlZCgpO1xuICB2YXIgbDIgPSBudGludi5yZWRTdWIocykuZnJvbVJlZCgpO1xuICByZXR1cm4gWyBsMSwgbDIgXTtcbn07XG5cblNob3J0Q3VydmUucHJvdG90eXBlLl9nZXRFbmRvQmFzaXMgPSBmdW5jdGlvbiBfZ2V0RW5kb0Jhc2lzKGxhbWJkYSkge1xuICAvLyBhcHJ4U3FydCA+PSBzcXJ0KHRoaXMubilcbiAgdmFyIGFwcnhTcXJ0ID0gdGhpcy5uLnVzaHJuKE1hdGguZmxvb3IodGhpcy5uLmJpdExlbmd0aCgpIC8gMikpO1xuXG4gIC8vIDMuNzRcbiAgLy8gUnVuIEVHQ0QsIHVudGlsIHIoTCArIDEpIDwgYXByeFNxcnRcbiAgdmFyIHUgPSBsYW1iZGE7XG4gIHZhciB2ID0gdGhpcy5uLmNsb25lKCk7XG4gIHZhciB4MSA9IG5ldyBCTigxKTtcbiAgdmFyIHkxID0gbmV3IEJOKDApO1xuICB2YXIgeDIgPSBuZXcgQk4oMCk7XG4gIHZhciB5MiA9IG5ldyBCTigxKTtcblxuICAvLyBOT1RFOiBhbGwgdmVjdG9ycyBhcmUgcm9vdHMgb2Y6IGEgKyBiICogbGFtYmRhID0gMCAobW9kIG4pXG4gIHZhciBhMDtcbiAgdmFyIGIwO1xuICAvLyBGaXJzdCB2ZWN0b3JcbiAgdmFyIGExO1xuICB2YXIgYjE7XG4gIC8vIFNlY29uZCB2ZWN0b3JcbiAgdmFyIGEyO1xuICB2YXIgYjI7XG5cbiAgdmFyIHByZXZSO1xuICB2YXIgaSA9IDA7XG4gIHZhciByO1xuICB2YXIgeDtcbiAgd2hpbGUgKHUuY21wbigwKSAhPT0gMCkge1xuICAgIHZhciBxID0gdi5kaXYodSk7XG4gICAgciA9IHYuc3ViKHEubXVsKHUpKTtcbiAgICB4ID0geDIuc3ViKHEubXVsKHgxKSk7XG4gICAgdmFyIHkgPSB5Mi5zdWIocS5tdWwoeTEpKTtcblxuICAgIGlmICghYTEgJiYgci5jbXAoYXByeFNxcnQpIDwgMCkge1xuICAgICAgYTAgPSBwcmV2Ui5uZWcoKTtcbiAgICAgIGIwID0geDE7XG4gICAgICBhMSA9IHIubmVnKCk7XG4gICAgICBiMSA9IHg7XG4gICAgfSBlbHNlIGlmIChhMSAmJiArK2kgPT09IDIpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBwcmV2UiA9IHI7XG5cbiAgICB2ID0gdTtcbiAgICB1ID0gcjtcbiAgICB4MiA9IHgxO1xuICAgIHgxID0geDtcbiAgICB5MiA9IHkxO1xuICAgIHkxID0geTtcbiAgfVxuICBhMiA9IHIubmVnKCk7XG4gIGIyID0geDtcblxuICB2YXIgbGVuMSA9IGExLnNxcigpLmFkZChiMS5zcXIoKSk7XG4gIHZhciBsZW4yID0gYTIuc3FyKCkuYWRkKGIyLnNxcigpKTtcbiAgaWYgKGxlbjIuY21wKGxlbjEpID49IDApIHtcbiAgICBhMiA9IGEwO1xuICAgIGIyID0gYjA7XG4gIH1cblxuICAvLyBOb3JtYWxpemUgc2lnbnNcbiAgaWYgKGExLm5lZ2F0aXZlKSB7XG4gICAgYTEgPSBhMS5uZWcoKTtcbiAgICBiMSA9IGIxLm5lZygpO1xuICB9XG4gIGlmIChhMi5uZWdhdGl2ZSkge1xuICAgIGEyID0gYTIubmVnKCk7XG4gICAgYjIgPSBiMi5uZWcoKTtcbiAgfVxuXG4gIHJldHVybiBbXG4gICAgeyBhOiBhMSwgYjogYjEgfSxcbiAgICB7IGE6IGEyLCBiOiBiMiB9XG4gIF07XG59O1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS5fZW5kb1NwbGl0ID0gZnVuY3Rpb24gX2VuZG9TcGxpdChrKSB7XG4gIHZhciBiYXNpcyA9IHRoaXMuZW5kby5iYXNpcztcbiAgdmFyIHYxID0gYmFzaXNbMF07XG4gIHZhciB2MiA9IGJhc2lzWzFdO1xuXG4gIHZhciBjMSA9IHYyLmIubXVsKGspLmRpdlJvdW5kKHRoaXMubik7XG4gIHZhciBjMiA9IHYxLmIubmVnKCkubXVsKGspLmRpdlJvdW5kKHRoaXMubik7XG5cbiAgdmFyIHAxID0gYzEubXVsKHYxLmEpO1xuICB2YXIgcDIgPSBjMi5tdWwodjIuYSk7XG4gIHZhciBxMSA9IGMxLm11bCh2MS5iKTtcbiAgdmFyIHEyID0gYzIubXVsKHYyLmIpO1xuXG4gIC8vIENhbGN1bGF0ZSBhbnN3ZXJcbiAgdmFyIGsxID0gay5zdWIocDEpLnN1YihwMik7XG4gIHZhciBrMiA9IHExLmFkZChxMikubmVnKCk7XG4gIHJldHVybiB7IGsxOiBrMSwgazI6IGsyIH07XG59O1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS5wb2ludEZyb21YID0gZnVuY3Rpb24gcG9pbnRGcm9tWCh4LCBvZGQpIHtcbiAgeCA9IG5ldyBCTih4LCAxNik7XG4gIGlmICgheC5yZWQpXG4gICAgeCA9IHgudG9SZWQodGhpcy5yZWQpO1xuXG4gIHZhciB5MiA9IHgucmVkU3FyKCkucmVkTXVsKHgpLnJlZElBZGQoeC5yZWRNdWwodGhpcy5hKSkucmVkSUFkZCh0aGlzLmIpO1xuICB2YXIgeSA9IHkyLnJlZFNxcnQoKTtcbiAgaWYgKHkucmVkU3FyKCkucmVkU3ViKHkyKS5jbXAodGhpcy56ZXJvKSAhPT0gMClcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgcG9pbnQnKTtcblxuICAvLyBYWFggSXMgdGhlcmUgYW55IHdheSB0byB0ZWxsIGlmIHRoZSBudW1iZXIgaXMgb2RkIHdpdGhvdXQgY29udmVydGluZyBpdFxuICAvLyB0byBub24tcmVkIGZvcm0/XG4gIHZhciBpc09kZCA9IHkuZnJvbVJlZCgpLmlzT2RkKCk7XG4gIGlmIChvZGQgJiYgIWlzT2RkIHx8ICFvZGQgJiYgaXNPZGQpXG4gICAgeSA9IHkucmVkTmVnKCk7XG5cbiAgcmV0dXJuIHRoaXMucG9pbnQoeCwgeSk7XG59O1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uIHZhbGlkYXRlKHBvaW50KSB7XG4gIGlmIChwb2ludC5pbmYpXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgdmFyIHggPSBwb2ludC54O1xuICB2YXIgeSA9IHBvaW50Lnk7XG5cbiAgdmFyIGF4ID0gdGhpcy5hLnJlZE11bCh4KTtcbiAgdmFyIHJocyA9IHgucmVkU3FyKCkucmVkTXVsKHgpLnJlZElBZGQoYXgpLnJlZElBZGQodGhpcy5iKTtcbiAgcmV0dXJuIHkucmVkU3FyKCkucmVkSVN1YihyaHMpLmNtcG4oMCkgPT09IDA7XG59O1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS5fZW5kb1duYWZNdWxBZGQgPVxuICAgIGZ1bmN0aW9uIF9lbmRvV25hZk11bEFkZChwb2ludHMsIGNvZWZmcykge1xuICB2YXIgbnBvaW50cyA9IHRoaXMuX2VuZG9XbmFmVDE7XG4gIHZhciBuY29lZmZzID0gdGhpcy5fZW5kb1duYWZUMjtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgc3BsaXQgPSB0aGlzLl9lbmRvU3BsaXQoY29lZmZzW2ldKTtcbiAgICB2YXIgcCA9IHBvaW50c1tpXTtcbiAgICB2YXIgYmV0YSA9IHAuX2dldEJldGEoKTtcblxuICAgIGlmIChzcGxpdC5rMS5uZWdhdGl2ZSkge1xuICAgICAgc3BsaXQuazEuaW5lZygpO1xuICAgICAgcCA9IHAubmVnKHRydWUpO1xuICAgIH1cbiAgICBpZiAoc3BsaXQuazIubmVnYXRpdmUpIHtcbiAgICAgIHNwbGl0LmsyLmluZWcoKTtcbiAgICAgIGJldGEgPSBiZXRhLm5lZyh0cnVlKTtcbiAgICB9XG5cbiAgICBucG9pbnRzW2kgKiAyXSA9IHA7XG4gICAgbnBvaW50c1tpICogMiArIDFdID0gYmV0YTtcbiAgICBuY29lZmZzW2kgKiAyXSA9IHNwbGl0LmsxO1xuICAgIG5jb2VmZnNbaSAqIDIgKyAxXSA9IHNwbGl0LmsyO1xuICB9XG4gIHZhciByZXMgPSB0aGlzLl93bmFmTXVsQWRkKDEsIG5wb2ludHMsIG5jb2VmZnMsIGkgKiAyKTtcblxuICAvLyBDbGVhbi11cCByZWZlcmVuY2VzIHRvIHBvaW50cyBhbmQgY29lZmZpY2llbnRzXG4gIGZvciAodmFyIGogPSAwOyBqIDwgaSAqIDI7IGorKykge1xuICAgIG5wb2ludHNbal0gPSBudWxsO1xuICAgIG5jb2VmZnNbal0gPSBudWxsO1xuICB9XG4gIHJldHVybiByZXM7XG59O1xuXG5mdW5jdGlvbiBQb2ludChjdXJ2ZSwgeCwgeSwgaXNSZWQpIHtcbiAgQmFzZS5CYXNlUG9pbnQuY2FsbCh0aGlzLCBjdXJ2ZSwgJ2FmZmluZScpO1xuICBpZiAoeCA9PT0gbnVsbCAmJiB5ID09PSBudWxsKSB7XG4gICAgdGhpcy54ID0gbnVsbDtcbiAgICB0aGlzLnkgPSBudWxsO1xuICAgIHRoaXMuaW5mID0gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnggPSBuZXcgQk4oeCwgMTYpO1xuICAgIHRoaXMueSA9IG5ldyBCTih5LCAxNik7XG4gICAgLy8gRm9yY2UgcmVkZ29tZXJ5IHJlcHJlc2VudGF0aW9uIHdoZW4gbG9hZGluZyBmcm9tIEpTT05cbiAgICBpZiAoaXNSZWQpIHtcbiAgICAgIHRoaXMueC5mb3JjZVJlZCh0aGlzLmN1cnZlLnJlZCk7XG4gICAgICB0aGlzLnkuZm9yY2VSZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMueC5yZWQpXG4gICAgICB0aGlzLnggPSB0aGlzLngudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICAgIGlmICghdGhpcy55LnJlZClcbiAgICAgIHRoaXMueSA9IHRoaXMueS50b1JlZCh0aGlzLmN1cnZlLnJlZCk7XG4gICAgdGhpcy5pbmYgPSBmYWxzZTtcbiAgfVxufVxuaW5oZXJpdHMoUG9pbnQsIEJhc2UuQmFzZVBvaW50KTtcblxuU2hvcnRDdXJ2ZS5wcm90b3R5cGUucG9pbnQgPSBmdW5jdGlvbiBwb2ludCh4LCB5LCBpc1JlZCkge1xuICByZXR1cm4gbmV3IFBvaW50KHRoaXMsIHgsIHksIGlzUmVkKTtcbn07XG5cblNob3J0Q3VydmUucHJvdG90eXBlLnBvaW50RnJvbUpTT04gPSBmdW5jdGlvbiBwb2ludEZyb21KU09OKG9iaiwgcmVkKSB7XG4gIHJldHVybiBQb2ludC5mcm9tSlNPTih0aGlzLCBvYmosIHJlZCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuX2dldEJldGEgPSBmdW5jdGlvbiBfZ2V0QmV0YSgpIHtcbiAgaWYgKCF0aGlzLmN1cnZlLmVuZG8pXG4gICAgcmV0dXJuO1xuXG4gIHZhciBwcmUgPSB0aGlzLnByZWNvbXB1dGVkO1xuICBpZiAocHJlICYmIHByZS5iZXRhKVxuICAgIHJldHVybiBwcmUuYmV0YTtcblxuICB2YXIgYmV0YSA9IHRoaXMuY3VydmUucG9pbnQodGhpcy54LnJlZE11bCh0aGlzLmN1cnZlLmVuZG8uYmV0YSksIHRoaXMueSk7XG4gIGlmIChwcmUpIHtcbiAgICB2YXIgY3VydmUgPSB0aGlzLmN1cnZlO1xuICAgIHZhciBlbmRvTXVsID0gZnVuY3Rpb24ocCkge1xuICAgICAgcmV0dXJuIGN1cnZlLnBvaW50KHAueC5yZWRNdWwoY3VydmUuZW5kby5iZXRhKSwgcC55KTtcbiAgICB9O1xuICAgIHByZS5iZXRhID0gYmV0YTtcbiAgICBiZXRhLnByZWNvbXB1dGVkID0ge1xuICAgICAgYmV0YTogbnVsbCxcbiAgICAgIG5hZjogcHJlLm5hZiAmJiB7XG4gICAgICAgIHduZDogcHJlLm5hZi53bmQsXG4gICAgICAgIHBvaW50czogcHJlLm5hZi5wb2ludHMubWFwKGVuZG9NdWwpXG4gICAgICB9LFxuICAgICAgZG91YmxlczogcHJlLmRvdWJsZXMgJiYge1xuICAgICAgICBzdGVwOiBwcmUuZG91Ymxlcy5zdGVwLFxuICAgICAgICBwb2ludHM6IHByZS5kb3VibGVzLnBvaW50cy5tYXAoZW5kb011bClcbiAgICAgIH1cbiAgICB9O1xuICB9XG4gIHJldHVybiBiZXRhO1xufTtcblxuUG9pbnQucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgaWYgKCF0aGlzLnByZWNvbXB1dGVkKVxuICAgIHJldHVybiBbIHRoaXMueCwgdGhpcy55IF07XG5cbiAgcmV0dXJuIFsgdGhpcy54LCB0aGlzLnksIHRoaXMucHJlY29tcHV0ZWQgJiYge1xuICAgIGRvdWJsZXM6IHRoaXMucHJlY29tcHV0ZWQuZG91YmxlcyAmJiB7XG4gICAgICBzdGVwOiB0aGlzLnByZWNvbXB1dGVkLmRvdWJsZXMuc3RlcCxcbiAgICAgIHBvaW50czogdGhpcy5wcmVjb21wdXRlZC5kb3VibGVzLnBvaW50cy5zbGljZSgxKVxuICAgIH0sXG4gICAgbmFmOiB0aGlzLnByZWNvbXB1dGVkLm5hZiAmJiB7XG4gICAgICB3bmQ6IHRoaXMucHJlY29tcHV0ZWQubmFmLnduZCxcbiAgICAgIHBvaW50czogdGhpcy5wcmVjb21wdXRlZC5uYWYucG9pbnRzLnNsaWNlKDEpXG4gICAgfVxuICB9IF07XG59O1xuXG5Qb2ludC5mcm9tSlNPTiA9IGZ1bmN0aW9uIGZyb21KU09OKGN1cnZlLCBvYmosIHJlZCkge1xuICBpZiAodHlwZW9mIG9iaiA9PT0gJ3N0cmluZycpXG4gICAgb2JqID0gSlNPTi5wYXJzZShvYmopO1xuICB2YXIgcmVzID0gY3VydmUucG9pbnQob2JqWzBdLCBvYmpbMV0sIHJlZCk7XG4gIGlmICghb2JqWzJdKVxuICAgIHJldHVybiByZXM7XG5cbiAgZnVuY3Rpb24gb2JqMnBvaW50KG9iaikge1xuICAgIHJldHVybiBjdXJ2ZS5wb2ludChvYmpbMF0sIG9ialsxXSwgcmVkKTtcbiAgfVxuXG4gIHZhciBwcmUgPSBvYmpbMl07XG4gIHJlcy5wcmVjb21wdXRlZCA9IHtcbiAgICBiZXRhOiBudWxsLFxuICAgIGRvdWJsZXM6IHByZS5kb3VibGVzICYmIHtcbiAgICAgIHN0ZXA6IHByZS5kb3VibGVzLnN0ZXAsXG4gICAgICBwb2ludHM6IFsgcmVzIF0uY29uY2F0KHByZS5kb3VibGVzLnBvaW50cy5tYXAob2JqMnBvaW50KSlcbiAgICB9LFxuICAgIG5hZjogcHJlLm5hZiAmJiB7XG4gICAgICB3bmQ6IHByZS5uYWYud25kLFxuICAgICAgcG9pbnRzOiBbIHJlcyBdLmNvbmNhdChwcmUubmFmLnBvaW50cy5tYXAob2JqMnBvaW50KSlcbiAgICB9XG4gIH07XG4gIHJldHVybiByZXM7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QoKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gJzxFQyBQb2ludCBJbmZpbml0eT4nO1xuICByZXR1cm4gJzxFQyBQb2ludCB4OiAnICsgdGhpcy54LmZyb21SZWQoKS50b1N0cmluZygxNiwgMikgK1xuICAgICAgJyB5OiAnICsgdGhpcy55LmZyb21SZWQoKS50b1N0cmluZygxNiwgMikgKyAnPic7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuaXNJbmZpbml0eSA9IGZ1bmN0aW9uIGlzSW5maW5pdHkoKSB7XG4gIHJldHVybiB0aGlzLmluZjtcbn07XG5cblBvaW50LnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiBhZGQocCkge1xuICAvLyBPICsgUCA9IFBcbiAgaWYgKHRoaXMuaW5mKVxuICAgIHJldHVybiBwO1xuXG4gIC8vIFAgKyBPID0gUFxuICBpZiAocC5pbmYpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gUCArIFAgPSAyUFxuICBpZiAodGhpcy5lcShwKSlcbiAgICByZXR1cm4gdGhpcy5kYmwoKTtcblxuICAvLyBQICsgKC1QKSA9IE9cbiAgaWYgKHRoaXMubmVnKCkuZXEocCkpXG4gICAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobnVsbCwgbnVsbCk7XG5cbiAgLy8gUCArIFEgPSBPXG4gIGlmICh0aGlzLnguY21wKHAueCkgPT09IDApXG4gICAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobnVsbCwgbnVsbCk7XG5cbiAgdmFyIGMgPSB0aGlzLnkucmVkU3ViKHAueSk7XG4gIGlmIChjLmNtcG4oMCkgIT09IDApXG4gICAgYyA9IGMucmVkTXVsKHRoaXMueC5yZWRTdWIocC54KS5yZWRJbnZtKCkpO1xuICB2YXIgbnggPSBjLnJlZFNxcigpLnJlZElTdWIodGhpcy54KS5yZWRJU3ViKHAueCk7XG4gIHZhciBueSA9IGMucmVkTXVsKHRoaXMueC5yZWRTdWIobngpKS5yZWRJU3ViKHRoaXMueSk7XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG54LCBueSk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZGJsID0gZnVuY3Rpb24gZGJsKCkge1xuICBpZiAodGhpcy5pbmYpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gMlAgPSBPXG4gIHZhciB5czEgPSB0aGlzLnkucmVkQWRkKHRoaXMueSk7XG4gIGlmICh5czEuY21wbigwKSA9PT0gMClcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChudWxsLCBudWxsKTtcblxuICB2YXIgYSA9IHRoaXMuY3VydmUuYTtcblxuICB2YXIgeDIgPSB0aGlzLngucmVkU3FyKCk7XG4gIHZhciBkeWludiA9IHlzMS5yZWRJbnZtKCk7XG4gIHZhciBjID0geDIucmVkQWRkKHgyKS5yZWRJQWRkKHgyKS5yZWRJQWRkKGEpLnJlZE11bChkeWludik7XG5cbiAgdmFyIG54ID0gYy5yZWRTcXIoKS5yZWRJU3ViKHRoaXMueC5yZWRBZGQodGhpcy54KSk7XG4gIHZhciBueSA9IGMucmVkTXVsKHRoaXMueC5yZWRTdWIobngpKS5yZWRJU3ViKHRoaXMueSk7XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG54LCBueSk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZ2V0WCA9IGZ1bmN0aW9uIGdldFgoKSB7XG4gIHJldHVybiB0aGlzLnguZnJvbVJlZCgpO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmdldFkgPSBmdW5jdGlvbiBnZXRZKCkge1xuICByZXR1cm4gdGhpcy55LmZyb21SZWQoKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5tdWwgPSBmdW5jdGlvbiBtdWwoaykge1xuICBrID0gbmV3IEJOKGssIDE2KTtcblxuICBpZiAodGhpcy5faGFzRG91YmxlcyhrKSlcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5fZml4ZWROYWZNdWwodGhpcywgayk7XG4gIGVsc2UgaWYgKHRoaXMuY3VydmUuZW5kbylcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5fZW5kb1duYWZNdWxBZGQoWyB0aGlzIF0sIFsgayBdKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl93bmFmTXVsKHRoaXMsIGspO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm11bEFkZCA9IGZ1bmN0aW9uIG11bEFkZChrMSwgcDIsIGsyKSB7XG4gIHZhciBwb2ludHMgPSBbIHRoaXMsIHAyIF07XG4gIHZhciBjb2VmZnMgPSBbIGsxLCBrMiBdO1xuICBpZiAodGhpcy5jdXJ2ZS5lbmRvKVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl9lbmRvV25hZk11bEFkZChwb2ludHMsIGNvZWZmcyk7XG4gIGVsc2VcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5fd25hZk11bEFkZCgxLCBwb2ludHMsIGNvZWZmcywgMik7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZXEgPSBmdW5jdGlvbiBlcShwKSB7XG4gIHJldHVybiB0aGlzID09PSBwIHx8XG4gICAgICAgICB0aGlzLmluZiA9PT0gcC5pbmYgJiZcbiAgICAgICAgICAgICAodGhpcy5pbmYgfHwgdGhpcy54LmNtcChwLngpID09PSAwICYmIHRoaXMueS5jbXAocC55KSA9PT0gMCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUubmVnID0gZnVuY3Rpb24gbmVnKF9wcmVjb21wdXRlKSB7XG4gIGlmICh0aGlzLmluZilcbiAgICByZXR1cm4gdGhpcztcblxuICB2YXIgcmVzID0gdGhpcy5jdXJ2ZS5wb2ludCh0aGlzLngsIHRoaXMueS5yZWROZWcoKSk7XG4gIGlmIChfcHJlY29tcHV0ZSAmJiB0aGlzLnByZWNvbXB1dGVkKSB7XG4gICAgdmFyIHByZSA9IHRoaXMucHJlY29tcHV0ZWQ7XG4gICAgdmFyIG5lZ2F0ZSA9IGZ1bmN0aW9uKHApIHtcbiAgICAgIHJldHVybiBwLm5lZygpO1xuICAgIH07XG4gICAgcmVzLnByZWNvbXB1dGVkID0ge1xuICAgICAgbmFmOiBwcmUubmFmICYmIHtcbiAgICAgICAgd25kOiBwcmUubmFmLnduZCxcbiAgICAgICAgcG9pbnRzOiBwcmUubmFmLnBvaW50cy5tYXAobmVnYXRlKVxuICAgICAgfSxcbiAgICAgIGRvdWJsZXM6IHByZS5kb3VibGVzICYmIHtcbiAgICAgICAgc3RlcDogcHJlLmRvdWJsZXMuc3RlcCxcbiAgICAgICAgcG9pbnRzOiBwcmUuZG91Ymxlcy5wb2ludHMubWFwKG5lZ2F0ZSlcbiAgICAgIH1cbiAgICB9O1xuICB9XG4gIHJldHVybiByZXM7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUudG9KID0gZnVuY3Rpb24gdG9KKCkge1xuICBpZiAodGhpcy5pbmYpXG4gICAgcmV0dXJuIHRoaXMuY3VydmUuanBvaW50KG51bGwsIG51bGwsIG51bGwpO1xuXG4gIHZhciByZXMgPSB0aGlzLmN1cnZlLmpwb2ludCh0aGlzLngsIHRoaXMueSwgdGhpcy5jdXJ2ZS5vbmUpO1xuICByZXR1cm4gcmVzO1xufTtcblxuZnVuY3Rpb24gSlBvaW50KGN1cnZlLCB4LCB5LCB6KSB7XG4gIEJhc2UuQmFzZVBvaW50LmNhbGwodGhpcywgY3VydmUsICdqYWNvYmlhbicpO1xuICBpZiAoeCA9PT0gbnVsbCAmJiB5ID09PSBudWxsICYmIHogPT09IG51bGwpIHtcbiAgICB0aGlzLnggPSB0aGlzLmN1cnZlLm9uZTtcbiAgICB0aGlzLnkgPSB0aGlzLmN1cnZlLm9uZTtcbiAgICB0aGlzLnogPSBuZXcgQk4oMCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy54ID0gbmV3IEJOKHgsIDE2KTtcbiAgICB0aGlzLnkgPSBuZXcgQk4oeSwgMTYpO1xuICAgIHRoaXMueiA9IG5ldyBCTih6LCAxNik7XG4gIH1cbiAgaWYgKCF0aGlzLngucmVkKVxuICAgIHRoaXMueCA9IHRoaXMueC50b1JlZCh0aGlzLmN1cnZlLnJlZCk7XG4gIGlmICghdGhpcy55LnJlZClcbiAgICB0aGlzLnkgPSB0aGlzLnkudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICBpZiAoIXRoaXMuei5yZWQpXG4gICAgdGhpcy56ID0gdGhpcy56LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcblxuICB0aGlzLnpPbmUgPSB0aGlzLnogPT09IHRoaXMuY3VydmUub25lO1xufVxuaW5oZXJpdHMoSlBvaW50LCBCYXNlLkJhc2VQb2ludCk7XG5cblNob3J0Q3VydmUucHJvdG90eXBlLmpwb2ludCA9IGZ1bmN0aW9uIGpwb2ludCh4LCB5LCB6KSB7XG4gIHJldHVybiBuZXcgSlBvaW50KHRoaXMsIHgsIHksIHopO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS50b1AgPSBmdW5jdGlvbiB0b1AoKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChudWxsLCBudWxsKTtcblxuICB2YXIgemludiA9IHRoaXMuei5yZWRJbnZtKCk7XG4gIHZhciB6aW52MiA9IHppbnYucmVkU3FyKCk7XG4gIHZhciBheCA9IHRoaXMueC5yZWRNdWwoemludjIpO1xuICB2YXIgYXkgPSB0aGlzLnkucmVkTXVsKHppbnYyKS5yZWRNdWwoemludik7XG5cbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQoYXgsIGF5KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUubmVnID0gZnVuY3Rpb24gbmVnKCkge1xuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQodGhpcy54LCB0aGlzLnkucmVkTmVnKCksIHRoaXMueik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZChwKSB7XG4gIC8vIE8gKyBQID0gUFxuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHA7XG5cbiAgLy8gUCArIE8gPSBQXG4gIGlmIChwLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyAxMk0gKyA0UyArIDdBXG4gIHZhciBwejIgPSBwLnoucmVkU3FyKCk7XG4gIHZhciB6MiA9IHRoaXMuei5yZWRTcXIoKTtcbiAgdmFyIHUxID0gdGhpcy54LnJlZE11bChwejIpO1xuICB2YXIgdTIgPSBwLngucmVkTXVsKHoyKTtcbiAgdmFyIHMxID0gdGhpcy55LnJlZE11bChwejIucmVkTXVsKHAueikpO1xuICB2YXIgczIgPSBwLnkucmVkTXVsKHoyLnJlZE11bCh0aGlzLnopKTtcblxuICB2YXIgaCA9IHUxLnJlZFN1Yih1Mik7XG4gIHZhciByID0gczEucmVkU3ViKHMyKTtcbiAgaWYgKGguY21wbigwKSA9PT0gMCkge1xuICAgIGlmIChyLmNtcG4oMCkgIT09IDApXG4gICAgICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobnVsbCwgbnVsbCwgbnVsbCk7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIHRoaXMuZGJsKCk7XG4gIH1cblxuICB2YXIgaDIgPSBoLnJlZFNxcigpO1xuICB2YXIgaDMgPSBoMi5yZWRNdWwoaCk7XG4gIHZhciB2ID0gdTEucmVkTXVsKGgyKTtcblxuICB2YXIgbnggPSByLnJlZFNxcigpLnJlZElBZGQoaDMpLnJlZElTdWIodikucmVkSVN1Yih2KTtcbiAgdmFyIG55ID0gci5yZWRNdWwodi5yZWRJU3ViKG54KSkucmVkSVN1YihzMS5yZWRNdWwoaDMpKTtcbiAgdmFyIG56ID0gdGhpcy56LnJlZE11bChwLnopLnJlZE11bChoKTtcblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobngsIG55LCBueik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLm1peGVkQWRkID0gZnVuY3Rpb24gbWl4ZWRBZGQocCkge1xuICAvLyBPICsgUCA9IFBcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiBwLnRvSigpO1xuXG4gIC8vIFAgKyBPID0gUFxuICBpZiAocC5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gOE0gKyAzUyArIDdBXG4gIHZhciB6MiA9IHRoaXMuei5yZWRTcXIoKTtcbiAgdmFyIHUxID0gdGhpcy54O1xuICB2YXIgdTIgPSBwLngucmVkTXVsKHoyKTtcbiAgdmFyIHMxID0gdGhpcy55O1xuICB2YXIgczIgPSBwLnkucmVkTXVsKHoyKS5yZWRNdWwodGhpcy56KTtcblxuICB2YXIgaCA9IHUxLnJlZFN1Yih1Mik7XG4gIHZhciByID0gczEucmVkU3ViKHMyKTtcbiAgaWYgKGguY21wbigwKSA9PT0gMCkge1xuICAgIGlmIChyLmNtcG4oMCkgIT09IDApXG4gICAgICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobnVsbCwgbnVsbCwgbnVsbCk7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIHRoaXMuZGJsKCk7XG4gIH1cblxuICB2YXIgaDIgPSBoLnJlZFNxcigpO1xuICB2YXIgaDMgPSBoMi5yZWRNdWwoaCk7XG4gIHZhciB2ID0gdTEucmVkTXVsKGgyKTtcblxuICB2YXIgbnggPSByLnJlZFNxcigpLnJlZElBZGQoaDMpLnJlZElTdWIodikucmVkSVN1Yih2KTtcbiAgdmFyIG55ID0gci5yZWRNdWwodi5yZWRJU3ViKG54KSkucmVkSVN1YihzMS5yZWRNdWwoaDMpKTtcbiAgdmFyIG56ID0gdGhpcy56LnJlZE11bChoKTtcblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobngsIG55LCBueik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLmRibHAgPSBmdW5jdGlvbiBkYmxwKHBvdykge1xuICBpZiAocG93ID09PSAwKVxuICAgIHJldHVybiB0aGlzO1xuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRoaXM7XG4gIGlmICghcG93KVxuICAgIHJldHVybiB0aGlzLmRibCgpO1xuXG4gIGlmICh0aGlzLmN1cnZlLnplcm9BIHx8IHRoaXMuY3VydmUudGhyZWVBKSB7XG4gICAgdmFyIHIgPSB0aGlzO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG93OyBpKyspXG4gICAgICByID0gci5kYmwoKTtcbiAgICByZXR1cm4gcjtcbiAgfVxuXG4gIC8vIDFNICsgMlMgKyAxQSArIE4gKiAoNFMgKyA1TSArIDhBKVxuICAvLyBOID0gMSA9PiA2TSArIDZTICsgOUFcbiAgdmFyIGEgPSB0aGlzLmN1cnZlLmE7XG4gIHZhciB0aW52ID0gdGhpcy5jdXJ2ZS50aW52O1xuXG4gIHZhciBqeCA9IHRoaXMueDtcbiAgdmFyIGp5ID0gdGhpcy55O1xuICB2YXIganogPSB0aGlzLno7XG4gIHZhciBqejQgPSBqei5yZWRTcXIoKS5yZWRTcXIoKTtcblxuICAvLyBSZXVzZSByZXN1bHRzXG4gIHZhciBqeWQgPSBqeS5yZWRBZGQoankpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHBvdzsgaSsrKSB7XG4gICAgdmFyIGp4MiA9IGp4LnJlZFNxcigpO1xuICAgIHZhciBqeWQyID0ganlkLnJlZFNxcigpO1xuICAgIHZhciBqeWQ0ID0ganlkMi5yZWRTcXIoKTtcbiAgICB2YXIgYyA9IGp4Mi5yZWRBZGQoangyKS5yZWRJQWRkKGp4MikucmVkSUFkZChhLnJlZE11bChqejQpKTtcblxuICAgIHZhciB0MSA9IGp4LnJlZE11bChqeWQyKTtcbiAgICB2YXIgbnggPSBjLnJlZFNxcigpLnJlZElTdWIodDEucmVkQWRkKHQxKSk7XG4gICAgdmFyIHQyID0gdDEucmVkSVN1YihueCk7XG4gICAgdmFyIGRueSA9IGMucmVkTXVsKHQyKTtcbiAgICBkbnkgPSBkbnkucmVkSUFkZChkbnkpLnJlZElTdWIoanlkNCk7XG4gICAgdmFyIG56ID0ganlkLnJlZE11bChqeik7XG4gICAgaWYgKGkgKyAxIDwgcG93KVxuICAgICAgano0ID0gano0LnJlZE11bChqeWQ0KTtcblxuICAgIGp4ID0gbng7XG4gICAganogPSBuejtcbiAgICBqeWQgPSBkbnk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQoangsIGp5ZC5yZWRNdWwodGludiksIGp6KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUuZGJsID0gZnVuY3Rpb24gZGJsKCkge1xuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgaWYgKHRoaXMuY3VydmUuemVyb0EpXG4gICAgcmV0dXJuIHRoaXMuX3plcm9EYmwoKTtcbiAgZWxzZSBpZiAodGhpcy5jdXJ2ZS50aHJlZUEpXG4gICAgcmV0dXJuIHRoaXMuX3RocmVlRGJsKCk7XG4gIGVsc2VcbiAgICByZXR1cm4gdGhpcy5fZGJsKCk7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLl96ZXJvRGJsID0gZnVuY3Rpb24gX3plcm9EYmwoKSB7XG4gIHZhciBueDtcbiAgdmFyIG55O1xuICB2YXIgbno7XG4gIC8vIFogPSAxXG4gIGlmICh0aGlzLnpPbmUpIHtcbiAgICAvLyBoeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tc2hvcnR3LWphY29iaWFuLTAuaHRtbFxuICAgIC8vICAgICAjZG91YmxpbmctbWRibC0yMDA3LWJsXG4gICAgLy8gMU0gKyA1UyArIDE0QVxuXG4gICAgLy8gWFggPSBYMV4yXG4gICAgdmFyIHh4ID0gdGhpcy54LnJlZFNxcigpO1xuICAgIC8vIFlZID0gWTFeMlxuICAgIHZhciB5eSA9IHRoaXMueS5yZWRTcXIoKTtcbiAgICAvLyBZWVlZID0gWVleMlxuICAgIHZhciB5eXl5ID0geXkucmVkU3FyKCk7XG4gICAgLy8gUyA9IDIgKiAoKFgxICsgWVkpXjIgLSBYWCAtIFlZWVkpXG4gICAgdmFyIHMgPSB0aGlzLngucmVkQWRkKHl5KS5yZWRTcXIoKS5yZWRJU3ViKHh4KS5yZWRJU3ViKHl5eXkpO1xuICAgIHMgPSBzLnJlZElBZGQocyk7XG4gICAgLy8gTSA9IDMgKiBYWCArIGE7IGEgPSAwXG4gICAgdmFyIG0gPSB4eC5yZWRBZGQoeHgpLnJlZElBZGQoeHgpO1xuICAgIC8vIFQgPSBNIF4gMiAtIDIqU1xuICAgIHZhciB0ID0gbS5yZWRTcXIoKS5yZWRJU3ViKHMpLnJlZElTdWIocyk7XG5cbiAgICAvLyA4ICogWVlZWVxuICAgIHZhciB5eXl5OCA9IHl5eXkucmVkSUFkZCh5eXl5KTtcbiAgICB5eXl5OCA9IHl5eXk4LnJlZElBZGQoeXl5eTgpO1xuICAgIHl5eXk4ID0geXl5eTgucmVkSUFkZCh5eXl5OCk7XG5cbiAgICAvLyBYMyA9IFRcbiAgICBueCA9IHQ7XG4gICAgLy8gWTMgPSBNICogKFMgLSBUKSAtIDggKiBZWVlZXG4gICAgbnkgPSBtLnJlZE11bChzLnJlZElTdWIodCkpLnJlZElTdWIoeXl5eTgpO1xuICAgIC8vIFozID0gMipZMVxuICAgIG56ID0gdGhpcy55LnJlZEFkZCh0aGlzLnkpO1xuICB9IGVsc2Uge1xuICAgIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by1zaG9ydHctamFjb2JpYW4tMC5odG1sXG4gICAgLy8gICAgICNkb3VibGluZy1kYmwtMjAwOS1sXG4gICAgLy8gMk0gKyA1UyArIDEzQVxuXG4gICAgLy8gQSA9IFgxXjJcbiAgICB2YXIgYSA9IHRoaXMueC5yZWRTcXIoKTtcbiAgICAvLyBCID0gWTFeMlxuICAgIHZhciBiID0gdGhpcy55LnJlZFNxcigpO1xuICAgIC8vIEMgPSBCXjJcbiAgICB2YXIgYyA9IGIucmVkU3FyKCk7XG4gICAgLy8gRCA9IDIgKiAoKFgxICsgQileMiAtIEEgLSBDKVxuICAgIHZhciBkID0gdGhpcy54LnJlZEFkZChiKS5yZWRTcXIoKS5yZWRJU3ViKGEpLnJlZElTdWIoYyk7XG4gICAgZCA9IGQucmVkSUFkZChkKTtcbiAgICAvLyBFID0gMyAqIEFcbiAgICB2YXIgZSA9IGEucmVkQWRkKGEpLnJlZElBZGQoYSk7XG4gICAgLy8gRiA9IEVeMlxuICAgIHZhciBmID0gZS5yZWRTcXIoKTtcblxuICAgIC8vIDggKiBDXG4gICAgdmFyIGM4ID0gYy5yZWRJQWRkKGMpO1xuICAgIGM4ID0gYzgucmVkSUFkZChjOCk7XG4gICAgYzggPSBjOC5yZWRJQWRkKGM4KTtcblxuICAgIC8vIFgzID0gRiAtIDIgKiBEXG4gICAgbnggPSBmLnJlZElTdWIoZCkucmVkSVN1YihkKTtcbiAgICAvLyBZMyA9IEUgKiAoRCAtIFgzKSAtIDggKiBDXG4gICAgbnkgPSBlLnJlZE11bChkLnJlZElTdWIobngpKS5yZWRJU3ViKGM4KTtcbiAgICAvLyBaMyA9IDIgKiBZMSAqIFoxXG4gICAgbnogPSB0aGlzLnkucmVkTXVsKHRoaXMueik7XG4gICAgbnogPSBuei5yZWRJQWRkKG56KTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmN1cnZlLmpwb2ludChueCwgbnksIG56KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUuX3RocmVlRGJsID0gZnVuY3Rpb24gX3RocmVlRGJsKCkge1xuICB2YXIgbng7XG4gIHZhciBueTtcbiAgdmFyIG56O1xuICAvLyBaID0gMVxuICBpZiAodGhpcy56T25lKSB7XG4gICAgLy8gaHlwZXJlbGxpcHRpYy5vcmcvRUZEL2cxcC9hdXRvLXNob3J0dy1qYWNvYmlhbi0zLmh0bWxcbiAgICAvLyAgICAgI2RvdWJsaW5nLW1kYmwtMjAwNy1ibFxuICAgIC8vIDFNICsgNVMgKyAxNUFcblxuICAgIC8vIFhYID0gWDFeMlxuICAgIHZhciB4eCA9IHRoaXMueC5yZWRTcXIoKTtcbiAgICAvLyBZWSA9IFkxXjJcbiAgICB2YXIgeXkgPSB0aGlzLnkucmVkU3FyKCk7XG4gICAgLy8gWVlZWSA9IFlZXjJcbiAgICB2YXIgeXl5eSA9IHl5LnJlZFNxcigpO1xuICAgIC8vIFMgPSAyICogKChYMSArIFlZKV4yIC0gWFggLSBZWVlZKVxuICAgIHZhciBzID0gdGhpcy54LnJlZEFkZCh5eSkucmVkU3FyKCkucmVkSVN1Yih4eCkucmVkSVN1Yih5eXl5KTtcbiAgICBzID0gcy5yZWRJQWRkKHMpO1xuICAgIC8vIE0gPSAzICogWFggKyBhXG4gICAgdmFyIG0gPSB4eC5yZWRBZGQoeHgpLnJlZElBZGQoeHgpLnJlZElBZGQodGhpcy5jdXJ2ZS5hKTtcbiAgICAvLyBUID0gTV4yIC0gMiAqIFNcbiAgICB2YXIgdCA9IG0ucmVkU3FyKCkucmVkSVN1YihzKS5yZWRJU3ViKHMpO1xuICAgIC8vIFgzID0gVFxuICAgIG54ID0gdDtcbiAgICAvLyBZMyA9IE0gKiAoUyAtIFQpIC0gOCAqIFlZWVlcbiAgICB2YXIgeXl5eTggPSB5eXl5LnJlZElBZGQoeXl5eSk7XG4gICAgeXl5eTggPSB5eXl5OC5yZWRJQWRkKHl5eXk4KTtcbiAgICB5eXl5OCA9IHl5eXk4LnJlZElBZGQoeXl5eTgpO1xuICAgIG55ID0gbS5yZWRNdWwocy5yZWRJU3ViKHQpKS5yZWRJU3ViKHl5eXk4KTtcbiAgICAvLyBaMyA9IDIgKiBZMVxuICAgIG56ID0gdGhpcy55LnJlZEFkZCh0aGlzLnkpO1xuICB9IGVsc2Uge1xuICAgIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by1zaG9ydHctamFjb2JpYW4tMy5odG1sI2RvdWJsaW5nLWRibC0yMDAxLWJcbiAgICAvLyAzTSArIDVTXG5cbiAgICAvLyBkZWx0YSA9IFoxXjJcbiAgICB2YXIgZGVsdGEgPSB0aGlzLnoucmVkU3FyKCk7XG4gICAgLy8gZ2FtbWEgPSBZMV4yXG4gICAgdmFyIGdhbW1hID0gdGhpcy55LnJlZFNxcigpO1xuICAgIC8vIGJldGEgPSBYMSAqIGdhbW1hXG4gICAgdmFyIGJldGEgPSB0aGlzLngucmVkTXVsKGdhbW1hKTtcbiAgICAvLyBhbHBoYSA9IDMgKiAoWDEgLSBkZWx0YSkgKiAoWDEgKyBkZWx0YSlcbiAgICB2YXIgYWxwaGEgPSB0aGlzLngucmVkU3ViKGRlbHRhKS5yZWRNdWwodGhpcy54LnJlZEFkZChkZWx0YSkpO1xuICAgIGFscGhhID0gYWxwaGEucmVkQWRkKGFscGhhKS5yZWRJQWRkKGFscGhhKTtcbiAgICAvLyBYMyA9IGFscGhhXjIgLSA4ICogYmV0YVxuICAgIHZhciBiZXRhNCA9IGJldGEucmVkSUFkZChiZXRhKTtcbiAgICBiZXRhNCA9IGJldGE0LnJlZElBZGQoYmV0YTQpO1xuICAgIHZhciBiZXRhOCA9IGJldGE0LnJlZEFkZChiZXRhNCk7XG4gICAgbnggPSBhbHBoYS5yZWRTcXIoKS5yZWRJU3ViKGJldGE4KTtcbiAgICAvLyBaMyA9IChZMSArIFoxKV4yIC0gZ2FtbWEgLSBkZWx0YVxuICAgIG56ID0gdGhpcy55LnJlZEFkZCh0aGlzLnopLnJlZFNxcigpLnJlZElTdWIoZ2FtbWEpLnJlZElTdWIoZGVsdGEpO1xuICAgIC8vIFkzID0gYWxwaGEgKiAoNCAqIGJldGEgLSBYMykgLSA4ICogZ2FtbWFeMlxuICAgIHZhciBnZ2FtbWE4ID0gZ2FtbWEucmVkU3FyKCk7XG4gICAgZ2dhbW1hOCA9IGdnYW1tYTgucmVkSUFkZChnZ2FtbWE4KTtcbiAgICBnZ2FtbWE4ID0gZ2dhbW1hOC5yZWRJQWRkKGdnYW1tYTgpO1xuICAgIGdnYW1tYTggPSBnZ2FtbWE4LnJlZElBZGQoZ2dhbW1hOCk7XG4gICAgbnkgPSBhbHBoYS5yZWRNdWwoYmV0YTQucmVkSVN1YihueCkpLnJlZElTdWIoZ2dhbW1hOCk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobngsIG55LCBueik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLl9kYmwgPSBmdW5jdGlvbiBfZGJsKCkge1xuICB2YXIgYSA9IHRoaXMuY3VydmUuYTtcblxuICAvLyA0TSArIDZTICsgMTBBXG4gIHZhciBqeCA9IHRoaXMueDtcbiAgdmFyIGp5ID0gdGhpcy55O1xuICB2YXIganogPSB0aGlzLno7XG4gIHZhciBqejQgPSBqei5yZWRTcXIoKS5yZWRTcXIoKTtcblxuICB2YXIgangyID0gangucmVkU3FyKCk7XG4gIHZhciBqeTIgPSBqeS5yZWRTcXIoKTtcblxuICB2YXIgYyA9IGp4Mi5yZWRBZGQoangyKS5yZWRJQWRkKGp4MikucmVkSUFkZChhLnJlZE11bChqejQpKTtcblxuICB2YXIganhkNCA9IGp4LnJlZEFkZChqeCk7XG4gIGp4ZDQgPSBqeGQ0LnJlZElBZGQoanhkNCk7XG4gIHZhciB0MSA9IGp4ZDQucmVkTXVsKGp5Mik7XG4gIHZhciBueCA9IGMucmVkU3FyKCkucmVkSVN1Yih0MS5yZWRBZGQodDEpKTtcbiAgdmFyIHQyID0gdDEucmVkSVN1YihueCk7XG5cbiAgdmFyIGp5ZDggPSBqeTIucmVkU3FyKCk7XG4gIGp5ZDggPSBqeWQ4LnJlZElBZGQoanlkOCk7XG4gIGp5ZDggPSBqeWQ4LnJlZElBZGQoanlkOCk7XG4gIGp5ZDggPSBqeWQ4LnJlZElBZGQoanlkOCk7XG4gIHZhciBueSA9IGMucmVkTXVsKHQyKS5yZWRJU3ViKGp5ZDgpO1xuICB2YXIgbnogPSBqeS5yZWRBZGQoankpLnJlZE11bChqeik7XG5cbiAgcmV0dXJuIHRoaXMuY3VydmUuanBvaW50KG54LCBueSwgbnopO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS50cnBsID0gZnVuY3Rpb24gdHJwbCgpIHtcbiAgaWYgKCF0aGlzLmN1cnZlLnplcm9BKVxuICAgIHJldHVybiB0aGlzLmRibCgpLmFkZCh0aGlzKTtcblxuICAvLyBoeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tc2hvcnR3LWphY29iaWFuLTAuaHRtbCN0cmlwbGluZy10cGwtMjAwNy1ibFxuICAvLyA1TSArIDEwUyArIC4uLlxuXG4gIC8vIFhYID0gWDFeMlxuICB2YXIgeHggPSB0aGlzLngucmVkU3FyKCk7XG4gIC8vIFlZID0gWTFeMlxuICB2YXIgeXkgPSB0aGlzLnkucmVkU3FyKCk7XG4gIC8vIFpaID0gWjFeMlxuICB2YXIgenogPSB0aGlzLnoucmVkU3FyKCk7XG4gIC8vIFlZWVkgPSBZWV4yXG4gIHZhciB5eXl5ID0geXkucmVkU3FyKCk7XG4gIC8vIE0gPSAzICogWFggKyBhICogWloyOyBhID0gMFxuICB2YXIgbSA9IHh4LnJlZEFkZCh4eCkucmVkSUFkZCh4eCk7XG4gIC8vIE1NID0gTV4yXG4gIHZhciBtbSA9IG0ucmVkU3FyKCk7XG4gIC8vIEUgPSA2ICogKChYMSArIFlZKV4yIC0gWFggLSBZWVlZKSAtIE1NXG4gIHZhciBlID0gdGhpcy54LnJlZEFkZCh5eSkucmVkU3FyKCkucmVkSVN1Yih4eCkucmVkSVN1Yih5eXl5KTtcbiAgZSA9IGUucmVkSUFkZChlKTtcbiAgZSA9IGUucmVkQWRkKGUpLnJlZElBZGQoZSk7XG4gIGUgPSBlLnJlZElTdWIobW0pO1xuICAvLyBFRSA9IEVeMlxuICB2YXIgZWUgPSBlLnJlZFNxcigpO1xuICAvLyBUID0gMTYqWVlZWVxuICB2YXIgdCA9IHl5eXkucmVkSUFkZCh5eXl5KTtcbiAgdCA9IHQucmVkSUFkZCh0KTtcbiAgdCA9IHQucmVkSUFkZCh0KTtcbiAgdCA9IHQucmVkSUFkZCh0KTtcbiAgLy8gVSA9IChNICsgRSleMiAtIE1NIC0gRUUgLSBUXG4gIHZhciB1ID0gbS5yZWRJQWRkKGUpLnJlZFNxcigpLnJlZElTdWIobW0pLnJlZElTdWIoZWUpLnJlZElTdWIodCk7XG4gIC8vIFgzID0gNCAqIChYMSAqIEVFIC0gNCAqIFlZICogVSlcbiAgdmFyIHl5dTQgPSB5eS5yZWRNdWwodSk7XG4gIHl5dTQgPSB5eXU0LnJlZElBZGQoeXl1NCk7XG4gIHl5dTQgPSB5eXU0LnJlZElBZGQoeXl1NCk7XG4gIHZhciBueCA9IHRoaXMueC5yZWRNdWwoZWUpLnJlZElTdWIoeXl1NCk7XG4gIG54ID0gbngucmVkSUFkZChueCk7XG4gIG54ID0gbngucmVkSUFkZChueCk7XG4gIC8vIFkzID0gOCAqIFkxICogKFUgKiAoVCAtIFUpIC0gRSAqIEVFKVxuICB2YXIgbnkgPSB0aGlzLnkucmVkTXVsKHUucmVkTXVsKHQucmVkSVN1Yih1KSkucmVkSVN1YihlLnJlZE11bChlZSkpKTtcbiAgbnkgPSBueS5yZWRJQWRkKG55KTtcbiAgbnkgPSBueS5yZWRJQWRkKG55KTtcbiAgbnkgPSBueS5yZWRJQWRkKG55KTtcbiAgLy8gWjMgPSAoWjEgKyBFKV4yIC0gWlogLSBFRVxuICB2YXIgbnogPSB0aGlzLnoucmVkQWRkKGUpLnJlZFNxcigpLnJlZElTdWIoenopLnJlZElTdWIoZWUpO1xuXG4gIHJldHVybiB0aGlzLmN1cnZlLmpwb2ludChueCwgbnksIG56KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUubXVsID0gZnVuY3Rpb24gbXVsKGssIGtiYXNlKSB7XG4gIGsgPSBuZXcgQk4oaywga2Jhc2UpO1xuXG4gIHJldHVybiB0aGlzLmN1cnZlLl93bmFmTXVsKHRoaXMsIGspO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS5lcSA9IGZ1bmN0aW9uIGVxKHApIHtcbiAgaWYgKHAudHlwZSA9PT0gJ2FmZmluZScpXG4gICAgcmV0dXJuIHRoaXMuZXEocC50b0ooKSk7XG5cbiAgaWYgKHRoaXMgPT09IHApXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgLy8geDEgKiB6Ml4yID09IHgyICogejFeMlxuICB2YXIgejIgPSB0aGlzLnoucmVkU3FyKCk7XG4gIHZhciBwejIgPSBwLnoucmVkU3FyKCk7XG4gIGlmICh0aGlzLngucmVkTXVsKHB6MikucmVkSVN1YihwLngucmVkTXVsKHoyKSkuY21wbigwKSAhPT0gMClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgLy8geTEgKiB6Ml4zID09IHkyICogejFeM1xuICB2YXIgejMgPSB6Mi5yZWRNdWwodGhpcy56KTtcbiAgdmFyIHB6MyA9IHB6Mi5yZWRNdWwocC56KTtcbiAgcmV0dXJuIHRoaXMueS5yZWRNdWwocHozKS5yZWRJU3ViKHAueS5yZWRNdWwoejMpKS5jbXBuKDApID09PSAwO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiAnPEVDIEpQb2ludCBJbmZpbml0eT4nO1xuICByZXR1cm4gJzxFQyBKUG9pbnQgeDogJyArIHRoaXMueC50b1N0cmluZygxNiwgMikgK1xuICAgICAgJyB5OiAnICsgdGhpcy55LnRvU3RyaW5nKDE2LCAyKSArXG4gICAgICAnIHo6ICcgKyB0aGlzLnoudG9TdHJpbmcoMTYsIDIpICsgJz4nO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS5pc0luZmluaXR5ID0gZnVuY3Rpb24gaXNJbmZpbml0eSgpIHtcbiAgLy8gWFhYIFRoaXMgY29kZSBhc3N1bWVzIHRoYXQgemVybyBpcyBhbHdheXMgemVybyBpbiByZWRcbiAgcmV0dXJuIHRoaXMuei5jbXBuKDApID09PSAwO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGN1cnZlcyA9IGV4cG9ydHM7XG5cbnZhciBoYXNoID0gcmVxdWlyZSgnaGFzaC5qcycpO1xudmFyIGVsbGlwdGljID0gcmVxdWlyZSgnLi4vZWxsaXB0aWMnKTtcblxudmFyIGFzc2VydCA9IGVsbGlwdGljLnV0aWxzLmFzc2VydDtcblxuZnVuY3Rpb24gUHJlc2V0Q3VydmUob3B0aW9ucykge1xuICBpZiAob3B0aW9ucy50eXBlID09PSAnc2hvcnQnKVxuICAgIHRoaXMuY3VydmUgPSBuZXcgZWxsaXB0aWMuY3VydmUuc2hvcnQob3B0aW9ucyk7XG4gIGVsc2UgaWYgKG9wdGlvbnMudHlwZSA9PT0gJ2Vkd2FyZHMnKVxuICAgIHRoaXMuY3VydmUgPSBuZXcgZWxsaXB0aWMuY3VydmUuZWR3YXJkcyhvcHRpb25zKTtcbiAgZWxzZVxuICAgIHRoaXMuY3VydmUgPSBuZXcgZWxsaXB0aWMuY3VydmUubW9udChvcHRpb25zKTtcbiAgdGhpcy5nID0gdGhpcy5jdXJ2ZS5nO1xuICB0aGlzLm4gPSB0aGlzLmN1cnZlLm47XG4gIHRoaXMuaGFzaCA9IG9wdGlvbnMuaGFzaDtcblxuICBhc3NlcnQodGhpcy5nLnZhbGlkYXRlKCksICdJbnZhbGlkIGN1cnZlJyk7XG4gIGFzc2VydCh0aGlzLmcubXVsKHRoaXMubikuaXNJbmZpbml0eSgpLCAnSW52YWxpZCBjdXJ2ZSwgRypOICE9IE8nKTtcbn1cbmN1cnZlcy5QcmVzZXRDdXJ2ZSA9IFByZXNldEN1cnZlO1xuXG5mdW5jdGlvbiBkZWZpbmVDdXJ2ZShuYW1lLCBvcHRpb25zKSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdXJ2ZXMsIG5hbWUsIHtcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGN1cnZlID0gbmV3IFByZXNldEN1cnZlKG9wdGlvbnMpO1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN1cnZlcywgbmFtZSwge1xuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIHZhbHVlOiBjdXJ2ZVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gY3VydmU7XG4gICAgfVxuICB9KTtcbn1cblxuZGVmaW5lQ3VydmUoJ3AxOTInLCB7XG4gIHR5cGU6ICdzaG9ydCcsXG4gIHByaW1lOiAncDE5MicsXG4gIHA6ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZSBmZmZmZmZmZiBmZmZmZmZmZicsXG4gIGE6ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZSBmZmZmZmZmZiBmZmZmZmZmYycsXG4gIGI6ICc2NDIxMDUxOSBlNTljODBlNyAwZmE3ZTlhYiA3MjI0MzA0OSBmZWI4ZGVlYyBjMTQ2YjliMScsXG4gIG46ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiA5OWRlZjgzNiAxNDZiYzliMSBiNGQyMjgzMScsXG4gIGhhc2g6IGhhc2guc2hhMjU2LFxuICBnUmVkOiBmYWxzZSxcbiAgZzogW1xuICAgICcxODhkYTgwZSBiMDMwOTBmNiA3Y2JmMjBlYiA0M2ExODgwMCBmNGZmMGFmZCA4MmZmMTAxMicsXG4gICAgJzA3MTkyYjk1IGZmYzhkYTc4IDYzMTAxMWVkIDZiMjRjZGQ1IDczZjk3N2ExIDFlNzk0ODExJ1xuICBdXG59KTtcblxuZGVmaW5lQ3VydmUoJ3AyMjQnLCB7XG4gIHR5cGU6ICdzaG9ydCcsXG4gIHByaW1lOiAncDIyNCcsXG4gIHA6ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiAwMDAwMDAwMCAwMDAwMDAwMCAwMDAwMDAwMScsXG4gIGE6ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZSBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZScsXG4gIGI6ICdiNDA1MGE4NSAwYzA0YjNhYiBmNTQxMzI1NiA1MDQ0YjBiNyBkN2JmZDhiYSAyNzBiMzk0MyAyMzU1ZmZiNCcsXG4gIG46ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmMTZhMiBlMGI4ZjAzZSAxM2RkMjk0NSA1YzVjMmEzZCcsXG4gIGhhc2g6IGhhc2guc2hhMjU2LFxuICBnUmVkOiBmYWxzZSxcbiAgZzogW1xuICAgICdiNzBlMGNiZCA2YmI0YmY3ZiAzMjEzOTBiOSA0YTAzYzFkMyA1NmMyMTEyMiAzNDMyODBkNiAxMTVjMWQyMScsXG4gICAgJ2JkMzc2Mzg4IGI1ZjcyM2ZiIDRjMjJkZmU2IGNkNDM3NWEwIDVhMDc0NzY0IDQ0ZDU4MTk5IDg1MDA3ZTM0J1xuICBdXG59KTtcblxuZGVmaW5lQ3VydmUoJ3AyNTYnLCB7XG4gIHR5cGU6ICdzaG9ydCcsXG4gIHByaW1lOiBudWxsLFxuICBwOiAnZmZmZmZmZmYgMDAwMDAwMDEgMDAwMDAwMDAgMDAwMDAwMDAgMDAwMDAwMDAgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYnLFxuICBhOiAnZmZmZmZmZmYgMDAwMDAwMDEgMDAwMDAwMDAgMDAwMDAwMDAgMDAwMDAwMDAgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmMnLFxuICBiOiAnNWFjNjM1ZDggYWEzYTkzZTcgYjNlYmJkNTUgNzY5ODg2YmMgNjUxZDA2YjAgY2M1M2IwZjYgM2JjZTNjM2UgMjdkMjYwNGInLFxuICBuOiAnZmZmZmZmZmYgMDAwMDAwMDAgZmZmZmZmZmYgZmZmZmZmZmYgYmNlNmZhYWQgYTcxNzllODQgZjNiOWNhYzIgZmM2MzI1NTEnLFxuICBoYXNoOiBoYXNoLnNoYTI1NixcbiAgZ1JlZDogZmFsc2UsXG4gIGc6IFtcbiAgICAnNmIxN2QxZjIgZTEyYzQyNDcgZjhiY2U2ZTUgNjNhNDQwZjIgNzcwMzdkODEgMmRlYjMzYTAgZjRhMTM5NDUgZDg5OGMyOTYnLFxuICAgICc0ZmUzNDJlMiBmZTFhN2Y5YiA4ZWU3ZWI0YSA3YzBmOWUxNiAyYmNlMzM1NyA2YjMxNWVjZSBjYmI2NDA2OCAzN2JmNTFmNSdcbiAgXVxufSk7XG5cbmRlZmluZUN1cnZlKCdwMzg0Jywge1xuICB0eXBlOiAnc2hvcnQnLFxuICBwcmltZTogbnVsbCxcbiAgcDogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmICcgK1xuICAgICAnZmZmZmZmZmUgZmZmZmZmZmYgMDAwMDAwMDAgMDAwMDAwMDAgZmZmZmZmZmYnLFxuICBhOiAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgJyArXG4gICAgICdmZmZmZmZmZSBmZmZmZmZmZiAwMDAwMDAwMCAwMDAwMDAwMCBmZmZmZmZmYycsXG4gIGI6ICdiMzMxMmZhNyBlMjNlZTdlNCA5ODhlMDU2YiBlM2Y4MmQxOSAxODFkOWM2ZSBmZTgxNDExMiAwMzE0MDg4ZiAnICtcbiAgICAgJzUwMTM4NzVhIGM2NTYzOThkIDhhMmVkMTlkIDJhODVjOGVkIGQzZWMyYWVmJyxcbiAgbjogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGM3NjM0ZDgxICcgK1xuICAgICAnZjQzNzJkZGYgNTgxYTBkYjIgNDhiMGE3N2EgZWNlYzE5NmEgY2NjNTI5NzMnLFxuICBoYXNoOiBoYXNoLnNoYTM4NCxcbiAgZ1JlZDogZmFsc2UsXG4gIGc6IFtcbiAgICAnYWE4N2NhMjIgYmU4YjA1MzcgOGViMWM3MWUgZjMyMGFkNzQgNmUxZDNiNjIgOGJhNzliOTggNTlmNzQxZTAgODI1NDJhMzggJyArXG4gICAgJzU1MDJmMjVkIGJmNTUyOTZjIDNhNTQ1ZTM4IDcyNzYwYWI3JyxcbiAgICAnMzYxN2RlNGEgOTYyNjJjNmYgNWQ5ZTk4YmYgOTI5MmRjMjkgZjhmNDFkYmQgMjg5YTE0N2MgZTlkYTMxMTMgYjVmMGI4YzAgJyArXG4gICAgJzBhNjBiMWNlIDFkN2U4MTlkIDdhNDMxZDdjIDkwZWEwZTVmJ1xuICBdXG59KTtcblxuZGVmaW5lQ3VydmUoJ3A1MjEnLCB7XG4gIHR5cGU6ICdzaG9ydCcsXG4gIHByaW1lOiBudWxsLFxuICBwOiAnMDAwMDAxZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgJyArXG4gICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiAnICtcbiAgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmJyxcbiAgYTogJzAwMDAwMWZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmICcgK1xuICAgICAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgJyArXG4gICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmYycsXG4gIGI6ICcwMDAwMDA1MSA5NTNlYjk2MSA4ZTFjOWExZiA5MjlhMjFhMCBiNjg1NDBlZSBhMmRhNzI1YiAnICtcbiAgICAgJzk5YjMxNWYzIGI4YjQ4OTkxIDhlZjEwOWUxIDU2MTkzOTUxIGVjN2U5MzdiIDE2NTJjMGJkICcgK1xuICAgICAnM2JiMWJmMDcgMzU3M2RmODggM2QyYzM0ZjEgZWY0NTFmZDQgNmI1MDNmMDAnLFxuICBuOiAnMDAwMDAxZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgJyArXG4gICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmYSA1MTg2ODc4MyBiZjJmOTY2YiA3ZmNjMDE0OCAnICtcbiAgICAgJ2Y3MDlhNWQwIDNiYjVjOWI4IDg5OWM0N2FlIGJiNmZiNzFlIDkxMzg2NDA5JyxcbiAgaGFzaDogaGFzaC5zaGE1MTIsXG4gIGdSZWQ6IGZhbHNlLFxuICBnOiBbXG4gICAgJzAwMDAwMGM2IDg1OGUwNmI3IDA0MDRlOWNkIDllM2VjYjY2IDIzOTViNDQyIDljNjQ4MTM5ICcgK1xuICAgICcwNTNmYjUyMSBmODI4YWY2MCA2YjRkM2RiYSBhMTRiNWU3NyBlZmU3NTkyOCBmZTFkYzEyNyAnICtcbiAgICAnYTJmZmE4ZGUgMzM0OGIzYzEgODU2YTQyOWIgZjk3ZTdlMzEgYzJlNWJkNjYnLFxuICAgICcwMDAwMDExOCAzOTI5NmE3OCA5YTNiYzAwNCA1YzhhNWZiNCAyYzdkMWJkOSA5OGY1NDQ0OSAnICtcbiAgICAnNTc5YjQ0NjggMTdhZmJkMTcgMjczZTY2MmMgOTdlZTcyOTkgNWVmNDI2NDAgYzU1MGI5MDEgJyArXG4gICAgJzNmYWQwNzYxIDM1M2M3MDg2IGEyNzJjMjQwIDg4YmU5NDc2IDlmZDE2NjUwJ1xuICBdXG59KTtcblxuZGVmaW5lQ3VydmUoJ2N1cnZlMjU1MTknLCB7XG4gIHR5cGU6ICdtb250JyxcbiAgcHJpbWU6ICdwMjU1MTknLFxuICBwOiAnN2ZmZmZmZmZmZmZmZmZmZiBmZmZmZmZmZmZmZmZmZmZmIGZmZmZmZmZmZmZmZmZmZmYgZmZmZmZmZmZmZmZmZmZlZCcsXG4gIGE6ICc3NmQwNicsXG4gIGI6ICcwJyxcbiAgbjogJzEwMDAwMDAwMDAwMDAwMDAgMDAwMDAwMDAwMDAwMDAwMCAxNGRlZjlkZWEyZjc5Y2Q2IDU4MTI2MzFhNWNmNWQzZWQnLFxuICBoYXNoOiBoYXNoLnNoYTI1NixcbiAgZ1JlZDogZmFsc2UsXG4gIGc6IFtcbiAgICAnOSdcbiAgXVxufSk7XG5cbmRlZmluZUN1cnZlKCdlZDI1NTE5Jywge1xuICB0eXBlOiAnZWR3YXJkcycsXG4gIHByaW1lOiAncDI1NTE5JyxcbiAgcDogJzdmZmZmZmZmZmZmZmZmZmYgZmZmZmZmZmZmZmZmZmZmZiBmZmZmZmZmZmZmZmZmZmZmIGZmZmZmZmZmZmZmZmZmZWQnLFxuICBhOiAnLTEnLFxuICBjOiAnMScsXG4gIC8vIC0xMjE2NjUgKiAoMTIxNjY2XigtMSkpIChtb2QgUClcbiAgZDogJzUyMDM2Y2VlMmI2ZmZlNzMgOGNjNzQwNzk3Nzc5ZTg5OCAwMDcwMGE0ZDQxNDFkOGFiIDc1ZWI0ZGNhMTM1OTc4YTMnLFxuICBuOiAnMTAwMDAwMDAwMDAwMDAwMCAwMDAwMDAwMDAwMDAwMDAwIDE0ZGVmOWRlYTJmNzljZDYgNTgxMjYzMWE1Y2Y1ZDNlZCcsXG4gIGhhc2g6IGhhc2guc2hhMjU2LFxuICBnUmVkOiBmYWxzZSxcbiAgZzogW1xuICAgICcyMTY5MzZkM2NkNmU1M2ZlYzBhNGUyMzFmZGQ2ZGM1YzY5MmNjNzYwOTUyNWE3YjJjOTU2MmQ2MDhmMjVkNTFhJyxcblxuICAgIC8vIDQvNVxuICAgICc2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjU4J1xuICBdXG59KTtcblxudmFyIHByZTtcbnRyeSB7XG4gIHByZSA9IHJlcXVpcmUoJy4vcHJlY29tcHV0ZWQvc2VjcDI1NmsxJyk7XG59IGNhdGNoIChlKSB7XG4gIHByZSA9IHVuZGVmaW5lZDtcbn1cblxuZGVmaW5lQ3VydmUoJ3NlY3AyNTZrMScsIHtcbiAgdHlwZTogJ3Nob3J0JyxcbiAgcHJpbWU6ICdrMjU2JyxcbiAgcDogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZlIGZmZmZmYzJmJyxcbiAgYTogJzAnLFxuICBiOiAnNycsXG4gIG46ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZSBiYWFlZGNlNiBhZjQ4YTAzYiBiZmQyNWU4YyBkMDM2NDE0MScsXG4gIGg6ICcxJyxcbiAgaGFzaDogaGFzaC5zaGEyNTYsXG5cbiAgLy8gUHJlY29tcHV0ZWQgZW5kb21vcnBoaXNtXG4gIGJldGE6ICc3YWU5NmEyYjY1N2MwNzEwNmU2NDQ3OWVhYzM0MzRlOTljZjA0OTc1MTJmNTg5OTVjMTM5NmMyODcxOTUwMWVlJyxcbiAgbGFtYmRhOiAnNTM2M2FkNGNjMDVjMzBlMGE1MjYxYzAyODgxMjY0NWExMjJlMjJlYTIwODE2Njc4ZGYwMjk2N2MxYjIzYmQ3MicsXG4gIGJhc2lzOiBbXG4gICAge1xuICAgICAgYTogJzMwODZkMjIxYTdkNDZiY2RlODZjOTBlNDkyODRlYjE1JyxcbiAgICAgIGI6ICctZTQ0MzdlZDYwMTBlODgyODZmNTQ3ZmE5MGFiZmU0YzMnXG4gICAgfSxcbiAgICB7XG4gICAgICBhOiAnMTE0Y2E1MGY3YThlMmYzZjY1N2MxMTA4ZDlkNDRjZmQ4JyxcbiAgICAgIGI6ICczMDg2ZDIyMWE3ZDQ2YmNkZTg2YzkwZTQ5Mjg0ZWIxNSdcbiAgICB9XG4gIF0sXG5cbiAgZ1JlZDogZmFsc2UsXG4gIGc6IFtcbiAgICAnNzliZTY2N2VmOWRjYmJhYzU1YTA2Mjk1Y2U4NzBiMDcwMjliZmNkYjJkY2UyOGQ5NTlmMjgxNWIxNmY4MTc5OCcsXG4gICAgJzQ4M2FkYTc3MjZhM2M0NjU1ZGE0ZmJmYzBlMTEwOGE4ZmQxN2I0NDhhNjg1NTQxOTljNDdkMDhmZmIxMGQ0YjgnLFxuICAgIHByZVxuICBdXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciBlbGxpcHRpYyA9IHJlcXVpcmUoJy4uLy4uL2VsbGlwdGljJyk7XG52YXIgdXRpbHMgPSBlbGxpcHRpYy51dGlscztcbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG5cbnZhciBLZXlQYWlyID0gcmVxdWlyZSgnLi9rZXknKTtcbnZhciBTaWduYXR1cmUgPSByZXF1aXJlKCcuL3NpZ25hdHVyZScpO1xuXG5mdW5jdGlvbiBFQyhvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBFQykpXG4gICAgcmV0dXJuIG5ldyBFQyhvcHRpb25zKTtcblxuICAvLyBTaG9ydGN1dCBgZWxsaXB0aWMuZWMoY3VydmUtbmFtZSlgXG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycpIHtcbiAgICBhc3NlcnQoZWxsaXB0aWMuY3VydmVzLmhhc093blByb3BlcnR5KG9wdGlvbnMpLCAnVW5rbm93biBjdXJ2ZSAnICsgb3B0aW9ucyk7XG5cbiAgICBvcHRpb25zID0gZWxsaXB0aWMuY3VydmVzW29wdGlvbnNdO1xuICB9XG5cbiAgLy8gU2hvcnRjdXQgZm9yIGBlbGxpcHRpYy5lYyhlbGxpcHRpYy5jdXJ2ZXMuY3VydmVOYW1lKWBcbiAgaWYgKG9wdGlvbnMgaW5zdGFuY2VvZiBlbGxpcHRpYy5jdXJ2ZXMuUHJlc2V0Q3VydmUpXG4gICAgb3B0aW9ucyA9IHsgY3VydmU6IG9wdGlvbnMgfTtcblxuICB0aGlzLmN1cnZlID0gb3B0aW9ucy5jdXJ2ZS5jdXJ2ZTtcbiAgdGhpcy5uID0gdGhpcy5jdXJ2ZS5uO1xuICB0aGlzLm5oID0gdGhpcy5uLnVzaHJuKDEpO1xuICB0aGlzLmcgPSB0aGlzLmN1cnZlLmc7XG5cbiAgLy8gUG9pbnQgb24gY3VydmVcbiAgdGhpcy5nID0gb3B0aW9ucy5jdXJ2ZS5nO1xuICB0aGlzLmcucHJlY29tcHV0ZShvcHRpb25zLmN1cnZlLm4uYml0TGVuZ3RoKCkgKyAxKTtcblxuICAvLyBIYXNoIGZvciBmdW5jdGlvbiBmb3IgRFJCR1xuICB0aGlzLmhhc2ggPSBvcHRpb25zLmhhc2ggfHwgb3B0aW9ucy5jdXJ2ZS5oYXNoO1xufVxubW9kdWxlLmV4cG9ydHMgPSBFQztcblxuRUMucHJvdG90eXBlLmtleVBhaXIgPSBmdW5jdGlvbiBrZXlQYWlyKG9wdGlvbnMpIHtcbiAgcmV0dXJuIG5ldyBLZXlQYWlyKHRoaXMsIG9wdGlvbnMpO1xufTtcblxuRUMucHJvdG90eXBlLmtleUZyb21Qcml2YXRlID0gZnVuY3Rpb24ga2V5RnJvbVByaXZhdGUocHJpdiwgZW5jKSB7XG4gIHJldHVybiBLZXlQYWlyLmZyb21Qcml2YXRlKHRoaXMsIHByaXYsIGVuYyk7XG59O1xuXG5FQy5wcm90b3R5cGUua2V5RnJvbVB1YmxpYyA9IGZ1bmN0aW9uIGtleUZyb21QdWJsaWMocHViLCBlbmMpIHtcbiAgcmV0dXJuIEtleVBhaXIuZnJvbVB1YmxpYyh0aGlzLCBwdWIsIGVuYyk7XG59O1xuXG5FQy5wcm90b3R5cGUuZ2VuS2V5UGFpciA9IGZ1bmN0aW9uIGdlbktleVBhaXIob3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMpXG4gICAgb3B0aW9ucyA9IHt9O1xuXG4gIC8vIEluc3RhbnRpYXRlIEhtYWNfRFJCR1xuICB2YXIgZHJiZyA9IG5ldyBlbGxpcHRpYy5obWFjRFJCRyh7XG4gICAgaGFzaDogdGhpcy5oYXNoLFxuICAgIHBlcnM6IG9wdGlvbnMucGVycyxcbiAgICBlbnRyb3B5OiBvcHRpb25zLmVudHJvcHkgfHwgZWxsaXB0aWMucmFuZCh0aGlzLmhhc2guaG1hY1N0cmVuZ3RoKSxcbiAgICBub25jZTogdGhpcy5uLnRvQXJyYXkoKVxuICB9KTtcblxuICB2YXIgYnl0ZXMgPSB0aGlzLm4uYnl0ZUxlbmd0aCgpO1xuICB2YXIgbnMyID0gdGhpcy5uLnN1YihuZXcgQk4oMikpO1xuICBkbyB7XG4gICAgdmFyIHByaXYgPSBuZXcgQk4oZHJiZy5nZW5lcmF0ZShieXRlcykpO1xuICAgIGlmIChwcml2LmNtcChuczIpID4gMClcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgcHJpdi5pYWRkbigxKTtcbiAgICByZXR1cm4gdGhpcy5rZXlGcm9tUHJpdmF0ZShwcml2KTtcbiAgfSB3aGlsZSAodHJ1ZSk7XG59O1xuXG5FQy5wcm90b3R5cGUuX3RydW5jYXRlVG9OID0gZnVuY3Rpb24gdHJ1bmNhdGVUb04obXNnLCB0cnVuY09ubHkpIHtcbiAgdmFyIGRlbHRhID0gbXNnLmJ5dGVMZW5ndGgoKSAqIDggLSB0aGlzLm4uYml0TGVuZ3RoKCk7XG4gIGlmIChkZWx0YSA+IDApXG4gICAgbXNnID0gbXNnLnVzaHJuKGRlbHRhKTtcbiAgaWYgKCF0cnVuY09ubHkgJiYgbXNnLmNtcCh0aGlzLm4pID49IDApXG4gICAgcmV0dXJuIG1zZy5zdWIodGhpcy5uKTtcbiAgZWxzZVxuICAgIHJldHVybiBtc2c7XG59O1xuXG5FQy5wcm90b3R5cGUuc2lnbiA9IGZ1bmN0aW9uIHNpZ24obXNnLCBrZXksIGVuYywgb3B0aW9ucykge1xuICBpZiAodHlwZW9mIGVuYyA9PT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zID0gZW5jO1xuICAgIGVuYyA9IG51bGw7XG4gIH1cbiAgaWYgKCFvcHRpb25zKVxuICAgIG9wdGlvbnMgPSB7fTtcblxuICBrZXkgPSB0aGlzLmtleUZyb21Qcml2YXRlKGtleSwgZW5jKTtcbiAgbXNnID0gdGhpcy5fdHJ1bmNhdGVUb04obmV3IEJOKG1zZywgMTYpKTtcblxuICAvLyBaZXJvLWV4dGVuZCBrZXkgdG8gcHJvdmlkZSBlbm91Z2ggZW50cm9weVxuICB2YXIgYnl0ZXMgPSB0aGlzLm4uYnl0ZUxlbmd0aCgpO1xuICB2YXIgYmtleSA9IGtleS5nZXRQcml2YXRlKCkudG9BcnJheSgnYmUnLCBieXRlcyk7XG5cbiAgLy8gWmVyby1leHRlbmQgbm9uY2UgdG8gaGF2ZSB0aGUgc2FtZSBieXRlIHNpemUgYXMgTlxuICB2YXIgbm9uY2UgPSBtc2cudG9BcnJheSgnYmUnLCBieXRlcyk7XG5cbiAgLy8gSW5zdGFudGlhdGUgSG1hY19EUkJHXG4gIHZhciBkcmJnID0gbmV3IGVsbGlwdGljLmhtYWNEUkJHKHtcbiAgICBoYXNoOiB0aGlzLmhhc2gsXG4gICAgZW50cm9weTogYmtleSxcbiAgICBub25jZTogbm9uY2UsXG4gICAgcGVyczogb3B0aW9ucy5wZXJzLFxuICAgIHBlcnNFbmM6IG9wdGlvbnMucGVyc0VuY1xuICB9KTtcblxuICAvLyBOdW1iZXIgb2YgYnl0ZXMgdG8gZ2VuZXJhdGVcbiAgdmFyIG5zMSA9IHRoaXMubi5zdWIobmV3IEJOKDEpKTtcblxuICBmb3IgKHZhciBpdGVyID0gMDsgdHJ1ZTsgaXRlcisrKSB7XG4gICAgdmFyIGsgPSBvcHRpb25zLmsgP1xuICAgICAgICBvcHRpb25zLmsoaXRlcikgOlxuICAgICAgICBuZXcgQk4oZHJiZy5nZW5lcmF0ZSh0aGlzLm4uYnl0ZUxlbmd0aCgpKSk7XG4gICAgayA9IHRoaXMuX3RydW5jYXRlVG9OKGssIHRydWUpO1xuICAgIGlmIChrLmNtcG4oMSkgPD0gMCB8fCBrLmNtcChuczEpID49IDApXG4gICAgICBjb250aW51ZTtcblxuICAgIHZhciBrcCA9IHRoaXMuZy5tdWwoayk7XG4gICAgaWYgKGtwLmlzSW5maW5pdHkoKSlcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgdmFyIGtwWCA9IGtwLmdldFgoKTtcbiAgICB2YXIgciA9IGtwWC51bW9kKHRoaXMubik7XG4gICAgaWYgKHIuY21wbigwKSA9PT0gMClcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgdmFyIHMgPSBrLmludm0odGhpcy5uKS5tdWwoci5tdWwoa2V5LmdldFByaXZhdGUoKSkuaWFkZChtc2cpKTtcbiAgICBzID0gcy51bW9kKHRoaXMubik7XG4gICAgaWYgKHMuY21wbigwKSA9PT0gMClcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgdmFyIHJlY292ZXJ5UGFyYW0gPSAoa3AuZ2V0WSgpLmlzT2RkKCkgPyAxIDogMCkgfFxuICAgICAgICAgICAgICAgICAgICAgICAgKGtwWC5jbXAocikgIT09IDAgPyAyIDogMCk7XG5cbiAgICAvLyBVc2UgY29tcGxlbWVudCBvZiBgc2AsIGlmIGl0IGlzID4gYG4gLyAyYFxuICAgIGlmIChvcHRpb25zLmNhbm9uaWNhbCAmJiBzLmNtcCh0aGlzLm5oKSA+IDApIHtcbiAgICAgIHMgPSB0aGlzLm4uc3ViKHMpO1xuICAgICAgcmVjb3ZlcnlQYXJhbSBePSAxO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgU2lnbmF0dXJlKHsgcjogciwgczogcywgcmVjb3ZlcnlQYXJhbTogcmVjb3ZlcnlQYXJhbSB9KTtcbiAgfVxufTtcblxuRUMucHJvdG90eXBlLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtc2csIHNpZ25hdHVyZSwga2V5LCBlbmMpIHtcbiAgbXNnID0gdGhpcy5fdHJ1bmNhdGVUb04obmV3IEJOKG1zZywgMTYpKTtcbiAga2V5ID0gdGhpcy5rZXlGcm9tUHVibGljKGtleSwgZW5jKTtcbiAgc2lnbmF0dXJlID0gbmV3IFNpZ25hdHVyZShzaWduYXR1cmUsICdoZXgnKTtcblxuICAvLyBQZXJmb3JtIHByaW1pdGl2ZSB2YWx1ZXMgdmFsaWRhdGlvblxuICB2YXIgciA9IHNpZ25hdHVyZS5yO1xuICB2YXIgcyA9IHNpZ25hdHVyZS5zO1xuICBpZiAoci5jbXBuKDEpIDwgMCB8fCByLmNtcCh0aGlzLm4pID49IDApXG4gICAgcmV0dXJuIGZhbHNlO1xuICBpZiAocy5jbXBuKDEpIDwgMCB8fCBzLmNtcCh0aGlzLm4pID49IDApXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIFZhbGlkYXRlIHNpZ25hdHVyZVxuICB2YXIgc2ludiA9IHMuaW52bSh0aGlzLm4pO1xuICB2YXIgdTEgPSBzaW52Lm11bChtc2cpLnVtb2QodGhpcy5uKTtcbiAgdmFyIHUyID0gc2ludi5tdWwocikudW1vZCh0aGlzLm4pO1xuXG4gIHZhciBwID0gdGhpcy5nLm11bEFkZCh1MSwga2V5LmdldFB1YmxpYygpLCB1Mik7XG4gIGlmIChwLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgcmV0dXJuIHAuZ2V0WCgpLnVtb2QodGhpcy5uKS5jbXAocikgPT09IDA7XG59O1xuXG5FQy5wcm90b3R5cGUucmVjb3ZlclB1YktleSA9IGZ1bmN0aW9uKG1zZywgc2lnbmF0dXJlLCBqLCBlbmMpIHtcbiAgYXNzZXJ0KCgzICYgaikgPT09IGosICdUaGUgcmVjb3ZlcnkgcGFyYW0gaXMgbW9yZSB0aGFuIHR3byBiaXRzJyk7XG4gIHNpZ25hdHVyZSA9IG5ldyBTaWduYXR1cmUoc2lnbmF0dXJlLCBlbmMpO1xuXG4gIHZhciBuID0gdGhpcy5uO1xuICB2YXIgZSA9IG5ldyBCTihtc2cpO1xuICB2YXIgciA9IHNpZ25hdHVyZS5yO1xuICB2YXIgcyA9IHNpZ25hdHVyZS5zO1xuXG4gIC8vIEEgc2V0IExTQiBzaWduaWZpZXMgdGhhdCB0aGUgeS1jb29yZGluYXRlIGlzIG9kZFxuICB2YXIgaXNZT2RkID0gaiAmIDE7XG4gIHZhciBpc1NlY29uZEtleSA9IGogPj4gMTtcbiAgaWYgKHIuY21wKHRoaXMuY3VydmUucC51bW9kKHRoaXMuY3VydmUubikpID49IDAgJiYgaXNTZWNvbmRLZXkpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZmluZCBzZW5jb25kIGtleSBjYW5kaW5hdGUnKTtcblxuICAvLyAxLjEuIExldCB4ID0gciArIGpuLlxuICBpZiAoaXNTZWNvbmRLZXkpXG4gICAgciA9IHRoaXMuY3VydmUucG9pbnRGcm9tWChyLmFkZCh0aGlzLmN1cnZlLm4pLCBpc1lPZGQpO1xuICBlbHNlXG4gICAgciA9IHRoaXMuY3VydmUucG9pbnRGcm9tWChyLCBpc1lPZGQpO1xuXG4gIHZhciBlTmVnID0gbi5zdWIoZSk7XG5cbiAgLy8gMS42LjEgQ29tcHV0ZSBRID0gcl4tMSAoc1IgLSAgZUcpXG4gIC8vICAgICAgICAgICAgICAgUSA9IHJeLTEgKHNSICsgLWVHKVxuICB2YXIgckludiA9IHNpZ25hdHVyZS5yLmludm0obik7XG4gIHJldHVybiB0aGlzLmcubXVsQWRkKGVOZWcsIHIsIHMpLm11bChySW52KTtcbn07XG5cbkVDLnByb3RvdHlwZS5nZXRLZXlSZWNvdmVyeVBhcmFtID0gZnVuY3Rpb24oZSwgc2lnbmF0dXJlLCBRLCBlbmMpIHtcbiAgc2lnbmF0dXJlID0gbmV3IFNpZ25hdHVyZShzaWduYXR1cmUsIGVuYyk7XG4gIGlmIChzaWduYXR1cmUucmVjb3ZlcnlQYXJhbSAhPT0gbnVsbClcbiAgICByZXR1cm4gc2lnbmF0dXJlLnJlY292ZXJ5UGFyYW07XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICB2YXIgUXByaW1lO1xuICAgIHRyeSB7XG4gICAgICBRcHJpbWUgPSB0aGlzLnJlY292ZXJQdWJLZXkoZSwgc2lnbmF0dXJlLCBpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoUXByaW1lLmVxKFEpKVxuICAgICAgcmV0dXJuIGk7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZmluZCB2YWxpZCByZWNvdmVyeSBmYWN0b3InKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG5cbmZ1bmN0aW9uIEtleVBhaXIoZWMsIG9wdGlvbnMpIHtcbiAgdGhpcy5lYyA9IGVjO1xuICB0aGlzLnByaXYgPSBudWxsO1xuICB0aGlzLnB1YiA9IG51bGw7XG5cbiAgLy8gS2V5UGFpcihlYywgeyBwcml2OiAuLi4sIHB1YjogLi4uIH0pXG4gIGlmIChvcHRpb25zLnByaXYpXG4gICAgdGhpcy5faW1wb3J0UHJpdmF0ZShvcHRpb25zLnByaXYsIG9wdGlvbnMucHJpdkVuYyk7XG4gIGlmIChvcHRpb25zLnB1YilcbiAgICB0aGlzLl9pbXBvcnRQdWJsaWMob3B0aW9ucy5wdWIsIG9wdGlvbnMucHViRW5jKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gS2V5UGFpcjtcblxuS2V5UGFpci5mcm9tUHVibGljID0gZnVuY3Rpb24gZnJvbVB1YmxpYyhlYywgcHViLCBlbmMpIHtcbiAgaWYgKHB1YiBpbnN0YW5jZW9mIEtleVBhaXIpXG4gICAgcmV0dXJuIHB1YjtcblxuICByZXR1cm4gbmV3IEtleVBhaXIoZWMsIHtcbiAgICBwdWI6IHB1YixcbiAgICBwdWJFbmM6IGVuY1xuICB9KTtcbn07XG5cbktleVBhaXIuZnJvbVByaXZhdGUgPSBmdW5jdGlvbiBmcm9tUHJpdmF0ZShlYywgcHJpdiwgZW5jKSB7XG4gIGlmIChwcml2IGluc3RhbmNlb2YgS2V5UGFpcilcbiAgICByZXR1cm4gcHJpdjtcblxuICByZXR1cm4gbmV3IEtleVBhaXIoZWMsIHtcbiAgICBwcml2OiBwcml2LFxuICAgIHByaXZFbmM6IGVuY1xuICB9KTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLnZhbGlkYXRlID0gZnVuY3Rpb24gdmFsaWRhdGUoKSB7XG4gIHZhciBwdWIgPSB0aGlzLmdldFB1YmxpYygpO1xuXG4gIGlmIChwdWIuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiB7IHJlc3VsdDogZmFsc2UsIHJlYXNvbjogJ0ludmFsaWQgcHVibGljIGtleScgfTtcbiAgaWYgKCFwdWIudmFsaWRhdGUoKSlcbiAgICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCByZWFzb246ICdQdWJsaWMga2V5IGlzIG5vdCBhIHBvaW50JyB9O1xuICBpZiAoIXB1Yi5tdWwodGhpcy5lYy5jdXJ2ZS5uKS5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHsgcmVzdWx0OiBmYWxzZSwgcmVhc29uOiAnUHVibGljIGtleSAqIE4gIT0gTycgfTtcblxuICByZXR1cm4geyByZXN1bHQ6IHRydWUsIHJlYXNvbjogbnVsbCB9O1xufTtcblxuS2V5UGFpci5wcm90b3R5cGUuZ2V0UHVibGljID0gZnVuY3Rpb24gZ2V0UHVibGljKGNvbXBhY3QsIGVuYykge1xuICAvLyBjb21wYWN0IGlzIG9wdGlvbmFsIGFyZ3VtZW50XG4gIGlmICh0eXBlb2YgY29tcGFjdCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmMgPSBjb21wYWN0O1xuICAgIGNvbXBhY3QgPSBudWxsO1xuICB9XG5cbiAgaWYgKCF0aGlzLnB1YilcbiAgICB0aGlzLnB1YiA9IHRoaXMuZWMuZy5tdWwodGhpcy5wcml2KTtcblxuICBpZiAoIWVuYylcbiAgICByZXR1cm4gdGhpcy5wdWI7XG5cbiAgcmV0dXJuIHRoaXMucHViLmVuY29kZShlbmMsIGNvbXBhY3QpO1xufTtcblxuS2V5UGFpci5wcm90b3R5cGUuZ2V0UHJpdmF0ZSA9IGZ1bmN0aW9uIGdldFByaXZhdGUoZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB0aGlzLnByaXYudG9TdHJpbmcoMTYsIDIpO1xuICBlbHNlXG4gICAgcmV0dXJuIHRoaXMucHJpdjtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLl9pbXBvcnRQcml2YXRlID0gZnVuY3Rpb24gX2ltcG9ydFByaXZhdGUoa2V5LCBlbmMpIHtcbiAgdGhpcy5wcml2ID0gbmV3IEJOKGtleSwgZW5jIHx8IDE2KTtcblxuICAvLyBFbnN1cmUgdGhhdCB0aGUgcHJpdiB3b24ndCBiZSBiaWdnZXIgdGhhbiBuLCBvdGhlcndpc2Ugd2UgbWF5IGZhaWxcbiAgLy8gaW4gZml4ZWQgbXVsdGlwbGljYXRpb24gbWV0aG9kXG4gIHRoaXMucHJpdiA9IHRoaXMucHJpdi51bW9kKHRoaXMuZWMuY3VydmUubik7XG59O1xuXG5LZXlQYWlyLnByb3RvdHlwZS5faW1wb3J0UHVibGljID0gZnVuY3Rpb24gX2ltcG9ydFB1YmxpYyhrZXksIGVuYykge1xuICBpZiAoa2V5LnggfHwga2V5LnkpIHtcbiAgICB0aGlzLnB1YiA9IHRoaXMuZWMuY3VydmUucG9pbnQoa2V5LngsIGtleS55KTtcbiAgICByZXR1cm47XG4gIH1cbiAgdGhpcy5wdWIgPSB0aGlzLmVjLmN1cnZlLmRlY29kZVBvaW50KGtleSwgZW5jKTtcbn07XG5cbi8vIEVDREhcbktleVBhaXIucHJvdG90eXBlLmRlcml2ZSA9IGZ1bmN0aW9uIGRlcml2ZShwdWIpIHtcbiAgcmV0dXJuIHB1Yi5tdWwodGhpcy5wcml2KS5nZXRYKCk7XG59O1xuXG4vLyBFQ0RTQVxuS2V5UGFpci5wcm90b3R5cGUuc2lnbiA9IGZ1bmN0aW9uIHNpZ24obXNnLCBlbmMsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIHRoaXMuZWMuc2lnbihtc2csIHRoaXMsIGVuYywgb3B0aW9ucyk7XG59O1xuXG5LZXlQYWlyLnByb3RvdHlwZS52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobXNnLCBzaWduYXR1cmUpIHtcbiAgcmV0dXJuIHRoaXMuZWMudmVyaWZ5KG1zZywgc2lnbmF0dXJlLCB0aGlzKTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0KCkge1xuICByZXR1cm4gJzxLZXkgcHJpdjogJyArICh0aGlzLnByaXYgJiYgdGhpcy5wcml2LnRvU3RyaW5nKDE2LCAyKSkgK1xuICAgICAgICAgJyBwdWI6ICcgKyAodGhpcy5wdWIgJiYgdGhpcy5wdWIuaW5zcGVjdCgpKSArICcgPic7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpO1xuXG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi8uLi9lbGxpcHRpYycpO1xudmFyIHV0aWxzID0gZWxsaXB0aWMudXRpbHM7XG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xuXG5mdW5jdGlvbiBTaWduYXR1cmUob3B0aW9ucywgZW5jKSB7XG4gIGlmIChvcHRpb25zIGluc3RhbmNlb2YgU2lnbmF0dXJlKVxuICAgIHJldHVybiBvcHRpb25zO1xuXG4gIGlmICh0aGlzLl9pbXBvcnRERVIob3B0aW9ucywgZW5jKSlcbiAgICByZXR1cm47XG5cbiAgYXNzZXJ0KG9wdGlvbnMuciAmJiBvcHRpb25zLnMsICdTaWduYXR1cmUgd2l0aG91dCByIG9yIHMnKTtcbiAgdGhpcy5yID0gbmV3IEJOKG9wdGlvbnMuciwgMTYpO1xuICB0aGlzLnMgPSBuZXcgQk4ob3B0aW9ucy5zLCAxNik7XG4gIGlmIChvcHRpb25zLnJlY292ZXJ5UGFyYW0gPT09IHVuZGVmaW5lZClcbiAgICB0aGlzLnJlY292ZXJ5UGFyYW0gPSBudWxsO1xuICBlbHNlXG4gICAgdGhpcy5yZWNvdmVyeVBhcmFtID0gb3B0aW9ucy5yZWNvdmVyeVBhcmFtO1xufVxubW9kdWxlLmV4cG9ydHMgPSBTaWduYXR1cmU7XG5cbmZ1bmN0aW9uIFBvc2l0aW9uKCkge1xuICB0aGlzLnBsYWNlID0gMDtcbn1cblxuZnVuY3Rpb24gZ2V0TGVuZ3RoKGJ1ZiwgcCkge1xuICB2YXIgaW5pdGlhbCA9IGJ1ZltwLnBsYWNlKytdO1xuICBpZiAoIShpbml0aWFsICYgMHg4MCkpIHtcbiAgICByZXR1cm4gaW5pdGlhbDtcbiAgfVxuICB2YXIgb2N0ZXRMZW4gPSBpbml0aWFsICYgMHhmO1xuICB2YXIgdmFsID0gMDtcbiAgZm9yICh2YXIgaSA9IDAsIG9mZiA9IHAucGxhY2U7IGkgPCBvY3RldExlbjsgaSsrLCBvZmYrKykge1xuICAgIHZhbCA8PD0gODtcbiAgICB2YWwgfD0gYnVmW29mZl07XG4gIH1cbiAgcC5wbGFjZSA9IG9mZjtcbiAgcmV0dXJuIHZhbDtcbn1cblxuZnVuY3Rpb24gcm1QYWRkaW5nKGJ1Zikge1xuICB2YXIgaSA9IDA7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoIC0gMTtcbiAgd2hpbGUgKCFidWZbaV0gJiYgIShidWZbaSArIDFdICYgMHg4MCkgJiYgaSA8IGxlbikge1xuICAgIGkrKztcbiAgfVxuICBpZiAoaSA9PT0gMCkge1xuICAgIHJldHVybiBidWY7XG4gIH1cbiAgcmV0dXJuIGJ1Zi5zbGljZShpKTtcbn1cblxuU2lnbmF0dXJlLnByb3RvdHlwZS5faW1wb3J0REVSID0gZnVuY3Rpb24gX2ltcG9ydERFUihkYXRhLCBlbmMpIHtcbiAgZGF0YSA9IHV0aWxzLnRvQXJyYXkoZGF0YSwgZW5jKTtcbiAgdmFyIHAgPSBuZXcgUG9zaXRpb24oKTtcbiAgaWYgKGRhdGFbcC5wbGFjZSsrXSAhPT0gMHgzMCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgbGVuID0gZ2V0TGVuZ3RoKGRhdGEsIHApO1xuICBpZiAoKGxlbiArIHAucGxhY2UpICE9PSBkYXRhLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoZGF0YVtwLnBsYWNlKytdICE9PSAweDAyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBybGVuID0gZ2V0TGVuZ3RoKGRhdGEsIHApO1xuICB2YXIgciA9IGRhdGEuc2xpY2UocC5wbGFjZSwgcmxlbiArIHAucGxhY2UpO1xuICBwLnBsYWNlICs9IHJsZW47XG4gIGlmIChkYXRhW3AucGxhY2UrK10gIT09IDB4MDIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHNsZW4gPSBnZXRMZW5ndGgoZGF0YSwgcCk7XG4gIGlmIChkYXRhLmxlbmd0aCAhPT0gc2xlbiArIHAucGxhY2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHMgPSBkYXRhLnNsaWNlKHAucGxhY2UsIHNsZW4gKyBwLnBsYWNlKTtcbiAgaWYgKHJbMF0gPT09IDAgJiYgKHJbMV0gJiAweDgwKSkge1xuICAgIHIgPSByLnNsaWNlKDEpO1xuICB9XG4gIGlmIChzWzBdID09PSAwICYmIChzWzFdICYgMHg4MCkpIHtcbiAgICBzID0gcy5zbGljZSgxKTtcbiAgfVxuXG4gIHRoaXMuciA9IG5ldyBCTihyKTtcbiAgdGhpcy5zID0gbmV3IEJOKHMpO1xuICB0aGlzLnJlY292ZXJ5UGFyYW0gPSBudWxsO1xuXG4gIHJldHVybiB0cnVlO1xufTtcblxuZnVuY3Rpb24gY29uc3RydWN0TGVuZ3RoKGFyciwgbGVuKSB7XG4gIGlmIChsZW4gPCAweDgwKSB7XG4gICAgYXJyLnB1c2gobGVuKTtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIG9jdGV0cyA9IDEgKyAoTWF0aC5sb2cobGVuKSAvIE1hdGguTE4yID4+PiAzKTtcbiAgYXJyLnB1c2gob2N0ZXRzIHwgMHg4MCk7XG4gIHdoaWxlICgtLW9jdGV0cykge1xuICAgIGFyci5wdXNoKChsZW4gPj4+IChvY3RldHMgPDwgMykpICYgMHhmZik7XG4gIH1cbiAgYXJyLnB1c2gobGVuKTtcbn1cblxuU2lnbmF0dXJlLnByb3RvdHlwZS50b0RFUiA9IGZ1bmN0aW9uIHRvREVSKGVuYykge1xuICB2YXIgciA9IHRoaXMuci50b0FycmF5KCk7XG4gIHZhciBzID0gdGhpcy5zLnRvQXJyYXkoKTtcblxuICAvLyBQYWQgdmFsdWVzXG4gIGlmIChyWzBdICYgMHg4MClcbiAgICByID0gWyAwIF0uY29uY2F0KHIpO1xuICAvLyBQYWQgdmFsdWVzXG4gIGlmIChzWzBdICYgMHg4MClcbiAgICBzID0gWyAwIF0uY29uY2F0KHMpO1xuXG4gIHIgPSBybVBhZGRpbmcocik7XG4gIHMgPSBybVBhZGRpbmcocyk7XG5cbiAgd2hpbGUgKCFzWzBdICYmICEoc1sxXSAmIDB4ODApKSB7XG4gICAgcyA9IHMuc2xpY2UoMSk7XG4gIH1cbiAgdmFyIGFyciA9IFsgMHgwMiBdO1xuICBjb25zdHJ1Y3RMZW5ndGgoYXJyLCByLmxlbmd0aCk7XG4gIGFyciA9IGFyci5jb25jYXQocik7XG4gIGFyci5wdXNoKDB4MDIpO1xuICBjb25zdHJ1Y3RMZW5ndGgoYXJyLCBzLmxlbmd0aCk7XG4gIHZhciBiYWNrSGFsZiA9IGFyci5jb25jYXQocyk7XG4gIHZhciByZXMgPSBbIDB4MzAgXTtcbiAgY29uc3RydWN0TGVuZ3RoKHJlcywgYmFja0hhbGYubGVuZ3RoKTtcbiAgcmVzID0gcmVzLmNvbmNhdChiYWNrSGFsZik7XG4gIHJldHVybiB1dGlscy5lbmNvZGUocmVzLCBlbmMpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGhhc2ggPSByZXF1aXJlKCdoYXNoLmpzJyk7XG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi8uLi9lbGxpcHRpYycpO1xudmFyIHV0aWxzID0gZWxsaXB0aWMudXRpbHM7XG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xudmFyIHBhcnNlQnl0ZXMgPSB1dGlscy5wYXJzZUJ5dGVzO1xudmFyIEtleVBhaXIgPSByZXF1aXJlKCcuL2tleScpO1xudmFyIFNpZ25hdHVyZSA9IHJlcXVpcmUoJy4vc2lnbmF0dXJlJyk7XG5cbmZ1bmN0aW9uIEVERFNBKGN1cnZlKSB7XG4gIGFzc2VydChjdXJ2ZSA9PT0gJ2VkMjU1MTknLCAnb25seSB0ZXN0ZWQgd2l0aCBlZDI1NTE5IHNvIGZhcicpO1xuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBFRERTQSkpXG4gICAgcmV0dXJuIG5ldyBFRERTQShjdXJ2ZSk7XG5cbiAgdmFyIGN1cnZlID0gZWxsaXB0aWMuY3VydmVzW2N1cnZlXS5jdXJ2ZTtcbiAgdGhpcy5jdXJ2ZSA9IGN1cnZlO1xuICB0aGlzLmcgPSBjdXJ2ZS5nO1xuICB0aGlzLmcucHJlY29tcHV0ZShjdXJ2ZS5uLmJpdExlbmd0aCgpICsgMSk7XG5cbiAgdGhpcy5wb2ludENsYXNzID0gY3VydmUucG9pbnQoKS5jb25zdHJ1Y3RvcjtcbiAgdGhpcy5lbmNvZGluZ0xlbmd0aCA9IE1hdGguY2VpbChjdXJ2ZS5uLmJpdExlbmd0aCgpIC8gOCk7XG4gIHRoaXMuaGFzaCA9IGhhc2guc2hhNTEyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEVERFNBO1xuXG4vKipcbiogQHBhcmFtIHtBcnJheXxTdHJpbmd9IG1lc3NhZ2UgLSBtZXNzYWdlIGJ5dGVzXG4qIEBwYXJhbSB7QXJyYXl8U3RyaW5nfEtleVBhaXJ9IHNlY3JldCAtIHNlY3JldCBieXRlcyBvciBhIGtleXBhaXJcbiogQHJldHVybnMge1NpZ25hdHVyZX0gLSBzaWduYXR1cmVcbiovXG5FRERTQS5wcm90b3R5cGUuc2lnbiA9IGZ1bmN0aW9uIHNpZ24obWVzc2FnZSwgc2VjcmV0KSB7XG4gIG1lc3NhZ2UgPSBwYXJzZUJ5dGVzKG1lc3NhZ2UpO1xuICB2YXIga2V5ID0gdGhpcy5rZXlGcm9tU2VjcmV0KHNlY3JldCk7XG4gIHZhciByID0gdGhpcy5oYXNoSW50KGtleS5tZXNzYWdlUHJlZml4KCksIG1lc3NhZ2UpO1xuICB2YXIgUiA9IHRoaXMuZy5tdWwocik7XG4gIHZhciBSZW5jb2RlZCA9IHRoaXMuZW5jb2RlUG9pbnQoUik7XG4gIHZhciBzXyA9IHRoaXMuaGFzaEludChSZW5jb2RlZCwga2V5LnB1YkJ5dGVzKCksIG1lc3NhZ2UpXG4gICAgICAgICAgICAgICAubXVsKGtleS5wcml2KCkpO1xuICB2YXIgUyA9IHIuYWRkKHNfKS51bW9kKHRoaXMuY3VydmUubik7XG4gIHJldHVybiB0aGlzLm1ha2VTaWduYXR1cmUoeyBSOiBSLCBTOiBTLCBSZW5jb2RlZDogUmVuY29kZWQgfSk7XG59O1xuXG4vKipcbiogQHBhcmFtIHtBcnJheX0gbWVzc2FnZSAtIG1lc3NhZ2UgYnl0ZXNcbiogQHBhcmFtIHtBcnJheXxTdHJpbmd8U2lnbmF0dXJlfSBzaWcgLSBzaWcgYnl0ZXNcbiogQHBhcmFtIHtBcnJheXxTdHJpbmd8UG9pbnR8S2V5UGFpcn0gcHViIC0gcHVibGljIGtleVxuKiBAcmV0dXJucyB7Qm9vbGVhbn0gLSB0cnVlIGlmIHB1YmxpYyBrZXkgbWF0Y2hlcyBzaWcgb2YgbWVzc2FnZVxuKi9cbkVERFNBLnByb3RvdHlwZS52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSwgc2lnLCBwdWIpIHtcbiAgbWVzc2FnZSA9IHBhcnNlQnl0ZXMobWVzc2FnZSk7XG4gIHNpZyA9IHRoaXMubWFrZVNpZ25hdHVyZShzaWcpO1xuICB2YXIga2V5ID0gdGhpcy5rZXlGcm9tUHVibGljKHB1Yik7XG4gIHZhciBoID0gdGhpcy5oYXNoSW50KHNpZy5SZW5jb2RlZCgpLCBrZXkucHViQnl0ZXMoKSwgbWVzc2FnZSk7XG4gIHZhciBTRyA9IHRoaXMuZy5tdWwoc2lnLlMoKSk7XG4gIHZhciBScGx1c0FoID0gc2lnLlIoKS5hZGQoa2V5LnB1YigpLm11bChoKSk7XG4gIHJldHVybiBScGx1c0FoLmVxKFNHKTtcbn07XG5cbkVERFNBLnByb3RvdHlwZS5oYXNoSW50ID0gZnVuY3Rpb24gaGFzaEludCgpIHtcbiAgdmFyIGhhc2ggPSB0aGlzLmhhc2goKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspXG4gICAgaGFzaC51cGRhdGUoYXJndW1lbnRzW2ldKTtcbiAgcmV0dXJuIHV0aWxzLmludEZyb21MRShoYXNoLmRpZ2VzdCgpKS51bW9kKHRoaXMuY3VydmUubik7XG59O1xuXG5FRERTQS5wcm90b3R5cGUua2V5RnJvbVB1YmxpYyA9IGZ1bmN0aW9uIGtleUZyb21QdWJsaWMocHViKSB7XG4gIHJldHVybiBLZXlQYWlyLmZyb21QdWJsaWModGhpcywgcHViKTtcbn07XG5cbkVERFNBLnByb3RvdHlwZS5rZXlGcm9tU2VjcmV0ID0gZnVuY3Rpb24ga2V5RnJvbVNlY3JldChzZWNyZXQpIHtcbiAgcmV0dXJuIEtleVBhaXIuZnJvbVNlY3JldCh0aGlzLCBzZWNyZXQpO1xufTtcblxuRUREU0EucHJvdG90eXBlLm1ha2VTaWduYXR1cmUgPSBmdW5jdGlvbiBtYWtlU2lnbmF0dXJlKHNpZykge1xuICBpZiAoc2lnIGluc3RhbmNlb2YgU2lnbmF0dXJlKVxuICAgIHJldHVybiBzaWc7XG4gIHJldHVybiBuZXcgU2lnbmF0dXJlKHRoaXMsIHNpZyk7XG59O1xuXG4vKipcbiogKiBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvZHJhZnQtam9zZWZzc29uLWVkZHNhLWVkMjU1MTktMDMjc2VjdGlvbi01LjJcbipcbiogRUREU0EgZGVmaW5lcyBtZXRob2RzIGZvciBlbmNvZGluZyBhbmQgZGVjb2RpbmcgcG9pbnRzIGFuZCBpbnRlZ2Vycy4gVGhlc2UgYXJlXG4qIGhlbHBlciBjb252ZW5pZW5jZSBtZXRob2RzLCB0aGF0IHBhc3MgYWxvbmcgdG8gdXRpbGl0eSBmdW5jdGlvbnMgaW1wbGllZFxuKiBwYXJhbWV0ZXJzLlxuKlxuKi9cbkVERFNBLnByb3RvdHlwZS5lbmNvZGVQb2ludCA9IGZ1bmN0aW9uIGVuY29kZVBvaW50KHBvaW50KSB7XG4gIHZhciBlbmMgPSBwb2ludC5nZXRZKCkudG9BcnJheSgnbGUnLCB0aGlzLmVuY29kaW5nTGVuZ3RoKTtcbiAgZW5jW3RoaXMuZW5jb2RpbmdMZW5ndGggLSAxXSB8PSBwb2ludC5nZXRYKCkuaXNPZGQoKSA/IDB4ODAgOiAwO1xuICByZXR1cm4gZW5jO1xufTtcblxuRUREU0EucHJvdG90eXBlLmRlY29kZVBvaW50ID0gZnVuY3Rpb24gZGVjb2RlUG9pbnQoYnl0ZXMpIHtcbiAgYnl0ZXMgPSB1dGlscy5wYXJzZUJ5dGVzKGJ5dGVzKTtcblxuICB2YXIgbGFzdEl4ID0gYnl0ZXMubGVuZ3RoIC0gMTtcbiAgdmFyIG5vcm1lZCA9IGJ5dGVzLnNsaWNlKDAsIGxhc3RJeCkuY29uY2F0KGJ5dGVzW2xhc3RJeF0gJiB+MHg4MCk7XG4gIHZhciB4SXNPZGQgPSAoYnl0ZXNbbGFzdEl4XSAmIDB4ODApICE9PSAwO1xuXG4gIHZhciB5ID0gdXRpbHMuaW50RnJvbUxFKG5vcm1lZCk7XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50RnJvbVkoeSwgeElzT2RkKTtcbn07XG5cbkVERFNBLnByb3RvdHlwZS5lbmNvZGVJbnQgPSBmdW5jdGlvbiBlbmNvZGVJbnQobnVtKSB7XG4gIHJldHVybiBudW0udG9BcnJheSgnbGUnLCB0aGlzLmVuY29kaW5nTGVuZ3RoKTtcbn07XG5cbkVERFNBLnByb3RvdHlwZS5kZWNvZGVJbnQgPSBmdW5jdGlvbiBkZWNvZGVJbnQoYnl0ZXMpIHtcbiAgcmV0dXJuIHV0aWxzLmludEZyb21MRShieXRlcyk7XG59O1xuXG5FRERTQS5wcm90b3R5cGUuaXNQb2ludCA9IGZ1bmN0aW9uIGlzUG9pbnQodmFsKSB7XG4gIHJldHVybiB2YWwgaW5zdGFuY2VvZiB0aGlzLnBvaW50Q2xhc3M7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi8uLi9lbGxpcHRpYycpO1xudmFyIHV0aWxzID0gZWxsaXB0aWMudXRpbHM7XG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xudmFyIHBhcnNlQnl0ZXMgPSB1dGlscy5wYXJzZUJ5dGVzO1xudmFyIGNhY2hlZFByb3BlcnR5ID0gdXRpbHMuY2FjaGVkUHJvcGVydHk7XG5cbi8qKlxuKiBAcGFyYW0ge0VERFNBfSBlZGRzYSAtIGluc3RhbmNlXG4qIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgLSBwdWJsaWMvcHJpdmF0ZSBrZXkgcGFyYW1ldGVyc1xuKlxuKiBAcGFyYW0ge0FycmF5PEJ5dGU+fSBbcGFyYW1zLnNlY3JldF0gLSBzZWNyZXQgc2VlZCBieXRlc1xuKiBAcGFyYW0ge1BvaW50fSBbcGFyYW1zLnB1Yl0gLSBwdWJsaWMga2V5IHBvaW50IChha2EgYEFgIGluIGVkZHNhIHRlcm1zKVxuKiBAcGFyYW0ge0FycmF5PEJ5dGU+fSBbcGFyYW1zLnB1Yl0gLSBwdWJsaWMga2V5IHBvaW50IGVuY29kZWQgYXMgYnl0ZXNcbipcbiovXG5mdW5jdGlvbiBLZXlQYWlyKGVkZHNhLCBwYXJhbXMpIHtcbiAgdGhpcy5lZGRzYSA9IGVkZHNhO1xuICB0aGlzLl9zZWNyZXQgPSBwYXJzZUJ5dGVzKHBhcmFtcy5zZWNyZXQpO1xuICBpZiAoZWRkc2EuaXNQb2ludChwYXJhbXMucHViKSlcbiAgICB0aGlzLl9wdWIgPSBwYXJhbXMucHViO1xuICBlbHNlXG4gICAgdGhpcy5fcHViQnl0ZXMgPSBwYXJzZUJ5dGVzKHBhcmFtcy5wdWIpO1xufVxuXG5LZXlQYWlyLmZyb21QdWJsaWMgPSBmdW5jdGlvbiBmcm9tUHVibGljKGVkZHNhLCBwdWIpIHtcbiAgaWYgKHB1YiBpbnN0YW5jZW9mIEtleVBhaXIpXG4gICAgcmV0dXJuIHB1YjtcbiAgcmV0dXJuIG5ldyBLZXlQYWlyKGVkZHNhLCB7IHB1YjogcHViIH0pO1xufTtcblxuS2V5UGFpci5mcm9tU2VjcmV0ID0gZnVuY3Rpb24gZnJvbVNlY3JldChlZGRzYSwgc2VjcmV0KSB7XG4gIGlmIChzZWNyZXQgaW5zdGFuY2VvZiBLZXlQYWlyKVxuICAgIHJldHVybiBzZWNyZXQ7XG4gIHJldHVybiBuZXcgS2V5UGFpcihlZGRzYSwgeyBzZWNyZXQ6IHNlY3JldCB9KTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLnNlY3JldCA9IGZ1bmN0aW9uIHNlY3JldCgpIHtcbiAgcmV0dXJuIHRoaXMuX3NlY3JldDtcbn07XG5cbmNhY2hlZFByb3BlcnR5KEtleVBhaXIsIGZ1bmN0aW9uIHB1YkJ5dGVzKCkge1xuICByZXR1cm4gdGhpcy5lZGRzYS5lbmNvZGVQb2ludCh0aGlzLnB1YigpKTtcbn0pO1xuXG5jYWNoZWRQcm9wZXJ0eShLZXlQYWlyLCBmdW5jdGlvbiBwdWIoKSB7XG4gIGlmICh0aGlzLl9wdWJCeXRlcylcbiAgICByZXR1cm4gdGhpcy5lZGRzYS5kZWNvZGVQb2ludCh0aGlzLl9wdWJCeXRlcyk7XG4gIHJldHVybiB0aGlzLmVkZHNhLmcubXVsKHRoaXMucHJpdigpKTtcbn0pO1xuXG5jYWNoZWRQcm9wZXJ0eShLZXlQYWlyLCBmdW5jdGlvbiBwcml2Qnl0ZXMoKSB7XG4gIHZhciBlZGRzYSA9IHRoaXMuZWRkc2E7XG4gIHZhciBoYXNoID0gdGhpcy5oYXNoKCk7XG4gIHZhciBsYXN0SXggPSBlZGRzYS5lbmNvZGluZ0xlbmd0aCAtIDE7XG5cbiAgdmFyIGEgPSBoYXNoLnNsaWNlKDAsIGVkZHNhLmVuY29kaW5nTGVuZ3RoKTtcbiAgYVswXSAmPSAyNDg7XG4gIGFbbGFzdEl4XSAmPSAxMjc7XG4gIGFbbGFzdEl4XSB8PSA2NDtcblxuICByZXR1cm4gYTtcbn0pO1xuXG5jYWNoZWRQcm9wZXJ0eShLZXlQYWlyLCBmdW5jdGlvbiBwcml2KCkge1xuICByZXR1cm4gdGhpcy5lZGRzYS5kZWNvZGVJbnQodGhpcy5wcml2Qnl0ZXMoKSk7XG59KTtcblxuY2FjaGVkUHJvcGVydHkoS2V5UGFpciwgZnVuY3Rpb24gaGFzaCgpIHtcbiAgcmV0dXJuIHRoaXMuZWRkc2EuaGFzaCgpLnVwZGF0ZSh0aGlzLnNlY3JldCgpKS5kaWdlc3QoKTtcbn0pO1xuXG5jYWNoZWRQcm9wZXJ0eShLZXlQYWlyLCBmdW5jdGlvbiBtZXNzYWdlUHJlZml4KCkge1xuICByZXR1cm4gdGhpcy5oYXNoKCkuc2xpY2UodGhpcy5lZGRzYS5lbmNvZGluZ0xlbmd0aCk7XG59KTtcblxuS2V5UGFpci5wcm90b3R5cGUuc2lnbiA9IGZ1bmN0aW9uIHNpZ24obWVzc2FnZSkge1xuICBhc3NlcnQodGhpcy5fc2VjcmV0LCAnS2V5UGFpciBjYW4gb25seSB2ZXJpZnknKTtcbiAgcmV0dXJuIHRoaXMuZWRkc2Euc2lnbihtZXNzYWdlLCB0aGlzKTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlLCBzaWcpIHtcbiAgcmV0dXJuIHRoaXMuZWRkc2EudmVyaWZ5KG1lc3NhZ2UsIHNpZywgdGhpcyk7XG59O1xuXG5LZXlQYWlyLnByb3RvdHlwZS5nZXRTZWNyZXQgPSBmdW5jdGlvbiBnZXRTZWNyZXQoZW5jKSB7XG4gIGFzc2VydCh0aGlzLl9zZWNyZXQsICdLZXlQYWlyIGlzIHB1YmxpYyBvbmx5Jyk7XG4gIHJldHVybiB1dGlscy5lbmNvZGUodGhpcy5zZWNyZXQoKSwgZW5jKTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLmdldFB1YmxpYyA9IGZ1bmN0aW9uIGdldFB1YmxpYyhlbmMpIHtcbiAgcmV0dXJuIHV0aWxzLmVuY29kZSh0aGlzLnB1YkJ5dGVzKCksIGVuYyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEtleVBhaXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi8uLi9lbGxpcHRpYycpO1xudmFyIHV0aWxzID0gZWxsaXB0aWMudXRpbHM7XG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xudmFyIGNhY2hlZFByb3BlcnR5ID0gdXRpbHMuY2FjaGVkUHJvcGVydHk7XG52YXIgcGFyc2VCeXRlcyA9IHV0aWxzLnBhcnNlQnl0ZXM7XG5cbi8qKlxuKiBAcGFyYW0ge0VERFNBfSBlZGRzYSAtIGVkZHNhIGluc3RhbmNlXG4qIEBwYXJhbSB7QXJyYXk8Qnl0ZXM+fE9iamVjdH0gc2lnIC1cbiogQHBhcmFtIHtBcnJheTxCeXRlcz58UG9pbnR9IFtzaWcuUl0gLSBSIHBvaW50IGFzIFBvaW50IG9yIGJ5dGVzXG4qIEBwYXJhbSB7QXJyYXk8Qnl0ZXM+fGJufSBbc2lnLlNdIC0gUyBzY2FsYXIgYXMgYm4gb3IgYnl0ZXNcbiogQHBhcmFtIHtBcnJheTxCeXRlcz59IFtzaWcuUmVuY29kZWRdIC0gUiBwb2ludCBlbmNvZGVkXG4qIEBwYXJhbSB7QXJyYXk8Qnl0ZXM+fSBbc2lnLlNlbmNvZGVkXSAtIFMgc2NhbGFyIGVuY29kZWRcbiovXG5mdW5jdGlvbiBTaWduYXR1cmUoZWRkc2EsIHNpZykge1xuICB0aGlzLmVkZHNhID0gZWRkc2E7XG5cbiAgaWYgKHR5cGVvZiBzaWcgIT09ICdvYmplY3QnKVxuICAgIHNpZyA9IHBhcnNlQnl0ZXMoc2lnKTtcblxuICBpZiAoQXJyYXkuaXNBcnJheShzaWcpKSB7XG4gICAgc2lnID0ge1xuICAgICAgUjogc2lnLnNsaWNlKDAsIGVkZHNhLmVuY29kaW5nTGVuZ3RoKSxcbiAgICAgIFM6IHNpZy5zbGljZShlZGRzYS5lbmNvZGluZ0xlbmd0aClcbiAgICB9O1xuICB9XG5cbiAgYXNzZXJ0KHNpZy5SICYmIHNpZy5TLCAnU2lnbmF0dXJlIHdpdGhvdXQgUiBvciBTJyk7XG5cbiAgaWYgKGVkZHNhLmlzUG9pbnQoc2lnLlIpKVxuICAgIHRoaXMuX1IgPSBzaWcuUjtcbiAgaWYgKHNpZy5TIGluc3RhbmNlb2YgQk4pXG4gICAgdGhpcy5fUyA9IHNpZy5TO1xuXG4gIHRoaXMuX1JlbmNvZGVkID0gQXJyYXkuaXNBcnJheShzaWcuUikgPyBzaWcuUiA6IHNpZy5SZW5jb2RlZDtcbiAgdGhpcy5fU2VuY29kZWQgPSBBcnJheS5pc0FycmF5KHNpZy5TKSA/IHNpZy5TIDogc2lnLlNlbmNvZGVkO1xufVxuXG5jYWNoZWRQcm9wZXJ0eShTaWduYXR1cmUsIGZ1bmN0aW9uIFMoKSB7XG4gIHJldHVybiB0aGlzLmVkZHNhLmRlY29kZUludCh0aGlzLlNlbmNvZGVkKCkpO1xufSk7XG5cbmNhY2hlZFByb3BlcnR5KFNpZ25hdHVyZSwgZnVuY3Rpb24gUigpIHtcbiAgcmV0dXJuIHRoaXMuZWRkc2EuZGVjb2RlUG9pbnQodGhpcy5SZW5jb2RlZCgpKTtcbn0pO1xuXG5jYWNoZWRQcm9wZXJ0eShTaWduYXR1cmUsIGZ1bmN0aW9uIFJlbmNvZGVkKCkge1xuICByZXR1cm4gdGhpcy5lZGRzYS5lbmNvZGVQb2ludCh0aGlzLlIoKSk7XG59KTtcblxuY2FjaGVkUHJvcGVydHkoU2lnbmF0dXJlLCBmdW5jdGlvbiBTZW5jb2RlZCgpIHtcbiAgcmV0dXJuIHRoaXMuZWRkc2EuZW5jb2RlSW50KHRoaXMuUygpKTtcbn0pO1xuXG5TaWduYXR1cmUucHJvdG90eXBlLnRvQnl0ZXMgPSBmdW5jdGlvbiB0b0J5dGVzKCkge1xuICByZXR1cm4gdGhpcy5SZW5jb2RlZCgpLmNvbmNhdCh0aGlzLlNlbmNvZGVkKCkpO1xufTtcblxuU2lnbmF0dXJlLnByb3RvdHlwZS50b0hleCA9IGZ1bmN0aW9uIHRvSGV4KCkge1xuICByZXR1cm4gdXRpbHMuZW5jb2RlKHRoaXMudG9CeXRlcygpLCAnaGV4JykudG9VcHBlckNhc2UoKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gU2lnbmF0dXJlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzaCA9IHJlcXVpcmUoJ2hhc2guanMnKTtcbnZhciBlbGxpcHRpYyA9IHJlcXVpcmUoJy4uL2VsbGlwdGljJyk7XG52YXIgdXRpbHMgPSBlbGxpcHRpYy51dGlscztcbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG5cbmZ1bmN0aW9uIEhtYWNEUkJHKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEhtYWNEUkJHKSlcbiAgICByZXR1cm4gbmV3IEhtYWNEUkJHKG9wdGlvbnMpO1xuICB0aGlzLmhhc2ggPSBvcHRpb25zLmhhc2g7XG4gIHRoaXMucHJlZFJlc2lzdCA9ICEhb3B0aW9ucy5wcmVkUmVzaXN0O1xuXG4gIHRoaXMub3V0TGVuID0gdGhpcy5oYXNoLm91dFNpemU7XG4gIHRoaXMubWluRW50cm9weSA9IG9wdGlvbnMubWluRW50cm9weSB8fCB0aGlzLmhhc2guaG1hY1N0cmVuZ3RoO1xuXG4gIHRoaXMucmVzZWVkID0gbnVsbDtcbiAgdGhpcy5yZXNlZWRJbnRlcnZhbCA9IG51bGw7XG4gIHRoaXMuSyA9IG51bGw7XG4gIHRoaXMuViA9IG51bGw7XG5cbiAgdmFyIGVudHJvcHkgPSB1dGlscy50b0FycmF5KG9wdGlvbnMuZW50cm9weSwgb3B0aW9ucy5lbnRyb3B5RW5jKTtcbiAgdmFyIG5vbmNlID0gdXRpbHMudG9BcnJheShvcHRpb25zLm5vbmNlLCBvcHRpb25zLm5vbmNlRW5jKTtcbiAgdmFyIHBlcnMgPSB1dGlscy50b0FycmF5KG9wdGlvbnMucGVycywgb3B0aW9ucy5wZXJzRW5jKTtcbiAgYXNzZXJ0KGVudHJvcHkubGVuZ3RoID49ICh0aGlzLm1pbkVudHJvcHkgLyA4KSxcbiAgICAgICAgICdOb3QgZW5vdWdoIGVudHJvcHkuIE1pbmltdW0gaXM6ICcgKyB0aGlzLm1pbkVudHJvcHkgKyAnIGJpdHMnKTtcbiAgdGhpcy5faW5pdChlbnRyb3B5LCBub25jZSwgcGVycyk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEhtYWNEUkJHO1xuXG5IbWFjRFJCRy5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiBpbml0KGVudHJvcHksIG5vbmNlLCBwZXJzKSB7XG4gIHZhciBzZWVkID0gZW50cm9weS5jb25jYXQobm9uY2UpLmNvbmNhdChwZXJzKTtcblxuICB0aGlzLksgPSBuZXcgQXJyYXkodGhpcy5vdXRMZW4gLyA4KTtcbiAgdGhpcy5WID0gbmV3IEFycmF5KHRoaXMub3V0TGVuIC8gOCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5WLmxlbmd0aDsgaSsrKSB7XG4gICAgdGhpcy5LW2ldID0gMHgwMDtcbiAgICB0aGlzLlZbaV0gPSAweDAxO1xuICB9XG5cbiAgdGhpcy5fdXBkYXRlKHNlZWQpO1xuICB0aGlzLnJlc2VlZCA9IDE7XG4gIHRoaXMucmVzZWVkSW50ZXJ2YWwgPSAweDEwMDAwMDAwMDAwMDA7ICAvLyAyXjQ4XG59O1xuXG5IbWFjRFJCRy5wcm90b3R5cGUuX2htYWMgPSBmdW5jdGlvbiBobWFjKCkge1xuICByZXR1cm4gbmV3IGhhc2guaG1hYyh0aGlzLmhhc2gsIHRoaXMuSyk7XG59O1xuXG5IbWFjRFJCRy5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIHVwZGF0ZShzZWVkKSB7XG4gIHZhciBrbWFjID0gdGhpcy5faG1hYygpXG4gICAgICAgICAgICAgICAgIC51cGRhdGUodGhpcy5WKVxuICAgICAgICAgICAgICAgICAudXBkYXRlKFsgMHgwMCBdKTtcbiAgaWYgKHNlZWQpXG4gICAga21hYyA9IGttYWMudXBkYXRlKHNlZWQpO1xuICB0aGlzLksgPSBrbWFjLmRpZ2VzdCgpO1xuICB0aGlzLlYgPSB0aGlzLl9obWFjKCkudXBkYXRlKHRoaXMuVikuZGlnZXN0KCk7XG4gIGlmICghc2VlZClcbiAgICByZXR1cm47XG5cbiAgdGhpcy5LID0gdGhpcy5faG1hYygpXG4gICAgICAgICAgICAgICAudXBkYXRlKHRoaXMuVilcbiAgICAgICAgICAgICAgIC51cGRhdGUoWyAweDAxIF0pXG4gICAgICAgICAgICAgICAudXBkYXRlKHNlZWQpXG4gICAgICAgICAgICAgICAuZGlnZXN0KCk7XG4gIHRoaXMuViA9IHRoaXMuX2htYWMoKS51cGRhdGUodGhpcy5WKS5kaWdlc3QoKTtcbn07XG5cbkhtYWNEUkJHLnByb3RvdHlwZS5yZXNlZWQgPSBmdW5jdGlvbiByZXNlZWQoZW50cm9weSwgZW50cm9weUVuYywgYWRkLCBhZGRFbmMpIHtcbiAgLy8gT3B0aW9uYWwgZW50cm9weSBlbmNcbiAgaWYgKHR5cGVvZiBlbnRyb3B5RW5jICE9PSAnc3RyaW5nJykge1xuICAgIGFkZEVuYyA9IGFkZDtcbiAgICBhZGQgPSBlbnRyb3B5RW5jO1xuICAgIGVudHJvcHlFbmMgPSBudWxsO1xuICB9XG5cbiAgZW50cm9weSA9IHV0aWxzLnRvQnVmZmVyKGVudHJvcHksIGVudHJvcHlFbmMpO1xuICBhZGQgPSB1dGlscy50b0J1ZmZlcihhZGQsIGFkZEVuYyk7XG5cbiAgYXNzZXJ0KGVudHJvcHkubGVuZ3RoID49ICh0aGlzLm1pbkVudHJvcHkgLyA4KSxcbiAgICAgICAgICdOb3QgZW5vdWdoIGVudHJvcHkuIE1pbmltdW0gaXM6ICcgKyB0aGlzLm1pbkVudHJvcHkgKyAnIGJpdHMnKTtcblxuICB0aGlzLl91cGRhdGUoZW50cm9weS5jb25jYXQoYWRkIHx8IFtdKSk7XG4gIHRoaXMucmVzZWVkID0gMTtcbn07XG5cbkhtYWNEUkJHLnByb3RvdHlwZS5nZW5lcmF0ZSA9IGZ1bmN0aW9uIGdlbmVyYXRlKGxlbiwgZW5jLCBhZGQsIGFkZEVuYykge1xuICBpZiAodGhpcy5yZXNlZWQgPiB0aGlzLnJlc2VlZEludGVydmFsKVxuICAgIHRocm93IG5ldyBFcnJvcignUmVzZWVkIGlzIHJlcXVpcmVkJyk7XG5cbiAgLy8gT3B0aW9uYWwgZW5jb2RpbmdcbiAgaWYgKHR5cGVvZiBlbmMgIT09ICdzdHJpbmcnKSB7XG4gICAgYWRkRW5jID0gYWRkO1xuICAgIGFkZCA9IGVuYztcbiAgICBlbmMgPSBudWxsO1xuICB9XG5cbiAgLy8gT3B0aW9uYWwgYWRkaXRpb25hbCBkYXRhXG4gIGlmIChhZGQpIHtcbiAgICBhZGQgPSB1dGlscy50b0FycmF5KGFkZCwgYWRkRW5jKTtcbiAgICB0aGlzLl91cGRhdGUoYWRkKTtcbiAgfVxuXG4gIHZhciB0ZW1wID0gW107XG4gIHdoaWxlICh0ZW1wLmxlbmd0aCA8IGxlbikge1xuICAgIHRoaXMuViA9IHRoaXMuX2htYWMoKS51cGRhdGUodGhpcy5WKS5kaWdlc3QoKTtcbiAgICB0ZW1wID0gdGVtcC5jb25jYXQodGhpcy5WKTtcbiAgfVxuXG4gIHZhciByZXMgPSB0ZW1wLnNsaWNlKDAsIGxlbik7XG4gIHRoaXMuX3VwZGF0ZShhZGQpO1xuICB0aGlzLnJlc2VlZCsrO1xuICByZXR1cm4gdXRpbHMuZW5jb2RlKHJlcywgZW5jKTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgZG91Ymxlczoge1xuICAgIHN0ZXA6IDQsXG4gICAgcG9pbnRzOiBbXG4gICAgICBbXG4gICAgICAgICdlNjBmY2U5M2I1OWU5ZWM1MzAxMWFhYmMyMWMyM2U5N2IyYTMxMzY5Yjg3YTVhZTljNDRlZTg5ZTJhNmRlYzBhJyxcbiAgICAgICAgJ2Y3ZTM1MDczOTllNTk1OTI5ZGI5OWYzNGY1NzkzNzEwMTI5Njg5MWU0NGQyM2YwYmUxZjMyY2NlNjk2MTY4MjEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnODI4MjI2MzIxMmM2MDlkOWVhMmE2ZTNlMTcyZGUyMzhkOGMzOWNhYmQ1YWMxY2ExMDY0NmUyM2ZkNWY1MTUwOCcsXG4gICAgICAgICcxMWY4YTgwOTg1NTdkZmU0NWU4MjU2ZTgzMGI2MGFjZTYyZDYxM2FjMmY3YjE3YmVkMzFiNmVhZmY2ZTI2Y2FmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzE3NWUxNTlmNzI4Yjg2NWE3MmY5OWNjNmM2ZmM4NDZkZTBiOTM4MzNmZDIyMjJlZDczZmNlNWI1NTFlNWI3MzknLFxuICAgICAgICAnZDM1MDZlMGQ5ZTNjNzllYmE0ZWY5N2E1MWZmNzFmNWVhY2I1OTU1YWRkMjQzNDVjNmVmYTZmZmVlOWZlZDY5NSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczNjNkOTBkNDQ3YjAwYzljOTljZWFjMDViNjI2MmVlMDUzNDQxYzdlNTU1NTJmZmU1MjZiYWQ4ZjgzZmY0NjQwJyxcbiAgICAgICAgJzRlMjczYWRmYzczMjIyMTk1M2I0NDUzOTdmMzM2MzE0NWI5YTg5MDA4MTk5ZWNiNjIwMDNjN2YzYmVlOWRlOSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4YjRiNWYxNjVkZjNjMmJlOGM2MjQ0YjViNzQ1NjM4ODQzZTRhNzgxYTE1YmNkMWI2OWY3OWE1NWRmZmRmODBjJyxcbiAgICAgICAgJzRhYWQwYTZmNjhkMzA4YjRiM2ZiZDc4MTNhYjBkYTA0ZjllMzM2NTQ2MTYyZWU1NmIzZWZmMGM2NWZkNGZkMzYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzIzY2JhYTZlNWRiOTk2ZDZiZjc3MWMwMGJkNTQ4YzdiNzAwZGJmZmE2YzBlNzdiY2I2MTE1OTI1MjMyZmNkYScsXG4gICAgICAgICc5NmU4NjdiNTU5NWNjNDk4YTkyMTEzNzQ4ODgyNGQ2ZTI2NjBhMDY1Mzc3OTQ5NDgwMWRjMDY5ZDllYjM5ZjVmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2VlYmZhNGQ0OTNiZWJmOThiYTVmZWVjODEyYzJkM2I1MDk0Nzk2MTIzN2E5MTk4MzlhNTMzZWNhMGU3ZGQ3ZmEnLFxuICAgICAgICAnNWQ5YThjYTM5NzBlZjBmMjY5ZWU3ZWRhZjE3ODA4OWQ5YWU0Y2RjM2E3MTFmNzEyZGRmZDRmZGFlMWRlODk5OSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxMDBmNDRkYTY5NmU3MTY3Mjc5MWQwYTA5YjdiZGU0NTlmMTIxNWEyOWIzYzAzYmZlZmQ3ODM1YjM5YTQ4ZGIwJyxcbiAgICAgICAgJ2NkZDllMTMxOTJhMDBiNzcyZWM4ZjMzMDBjMDkwNjY2YjdmZjRhMThmZjUxOTVhYzBmYmQ1Y2Q2MmJjNjVhMDknXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTEwMzFiZTI2MmM3ZWQxYjFkYzkyMjdhNGEwNGMwMTdhNzdmOGQ0NDY0ZjNiMzg1MmM4YWNkZTZlNTM0ZmQyZCcsXG4gICAgICAgICc5ZDcwNjE5Mjg5NDA0MDVlNmJiNmE0MTc2NTk3NTM1YWYyOTJkZDQxOWUxY2VkNzlhNDRmMThmMjk0NTZhMDBkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2ZlZWE2Y2FlNDZkNTViNTMwYWMyODM5ZjE0M2JkN2VjNWNmOGIyNjZhNDFkNmFmNTJkNWU2ODhkOTA5NDY5NmQnLFxuICAgICAgICAnZTU3YzZiNmM5N2RjZTFiYWIwNmU0ZTEyYmYzZWNkNWM5ODFjODk1N2NjNDE0NDJkMzE1NWRlYmYxODA5MDA4OCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkYTY3YTkxZDkxMDQ5Y2RjYjM2N2JlNGJlNmZmY2EzY2ZlZWQ2NTdkODA4NTgzZGUzM2ZhOTc4YmMxZWM2Y2IxJyxcbiAgICAgICAgJzliYWNhYTM1NDgxNjQyYmM0MWY0NjNmN2VjOTc4MGU1ZGVjN2FkYzUwOGY3NDBhMTdlOWVhOGUyN2E2OGJlMWQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNTM5MDRmYWEwYjMzNGNkZGE2ZTAwMDkzNWVmMjIxNTFlYzA4ZDBmN2JiMTEwNjlmNTc1NDVjY2MxYTM3YjdjMCcsXG4gICAgICAgICc1YmMwODdkMGJjODAxMDZkODhjOWVjY2FjMjBkM2MxYzEzOTk5OTgxZTE0NDM0Njk5ZGNiMDk2YjAyMjc3MWM4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzhlN2JjZDBiZDM1OTgzYTc3MTljY2E3NzY0Y2E5MDY3NzliNTNhMDQzYTliOGJjYWVmZjk1OWY0M2FkODYwNDcnLFxuICAgICAgICAnMTBiNzc3MGIyYTNkYTRiMzk0MDMxMDQyMGNhOTUxNDU3OWU4OGUyZTQ3ZmQ2OGIzZWExMDA0N2U4NDYwMzcyYSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczODVlZWQzNGMxY2RmZjIxZTZkMDgxODY4OWI4MWJkZTcxYTdmNGYxODM5N2U2NjkwYTg0MWUxNTk5YzQzODYyJyxcbiAgICAgICAgJzI4M2JlYmMzZThlYTIzZjU2NzAxZGUxOWU5ZWJmNDU3NmIzMDRlZWMyMDg2ZGM4Y2MwNDU4ZmU1NTQyZTU0NTMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNmY5ZDliODAzZWNmMTkxNjM3YzczYTQ0MTNkZmExODBmZGRmODRhNTk0N2ZiYzljNjA2ZWQ4NmMzZmFjM2E3JyxcbiAgICAgICAgJzdjODBjNjhlNjAzMDU5YmE2OWI4ZTJhMzBlNDVjNGQ0N2VhNGRkMmY1YzI4MTAwMmQ4Njg5MDYwM2E4NDIxNjAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzMyMmQ0MDEyNDNjNGUyNTgyYTIxNDdjMTA0ZDZlY2JmNzc0ZDE2M2RiMGY1ZTUzMTNiN2UwZTc0MmQwZTZiZCcsXG4gICAgICAgICc1NmU3MDc5N2U5NjY0ZWY1YmZiMDE5YmM0ZGRhZjliNzI4MDVmNjNlYTI4NzNhZjYyNGYzYTJlOTZjMjhiMmEwJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzg1NjcyYzdkMmRlMGI3ZGEyYmQxNzcwZDg5NjY1ODY4NzQxYjNmOWFmNzY0MzM5NzcyMWQ3NGQyODEzNGFiODMnLFxuICAgICAgICAnN2M0ODFiOWI1YjQzYjJlYjYzNzQwNDliZmE2MmMyZTVlNzdmMTdmY2M1Mjk4ZjQ0YzhlMzA5NGY3OTAzMTNhNidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc5NDhiZjgwOWIxOTg4YTQ2YjA2YzlmMTkxOTQxM2IxMGY5MjI2YzYwZjY2ODgzMmZmZDk1OWFmNjBjODJhMGEnLFxuICAgICAgICAnNTNhNTYyODU2ZGNiNjY0NmRjNmI3NGM1ZDFjMzQxOGM2ZDRkZmYwOGM5N2NkMmJlZDRjYjdmODhkOGM4ZTU4OSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc2MjYwY2U3ZjQ2MTgwMWMzNGYwNjdjZTBmMDI4NzNhOGYxYjBlNDRkZmM2OTc1MmFjY2VjZDgxOWYzOGZkOGU4JyxcbiAgICAgICAgJ2JjMmRhODJiNmZhNWI1NzFhN2YwOTA0OTc3NmExZWY3ZWNkMjkyMjM4MDUxYzE5OGMxYTg0ZTk1YjJiNGFlMTcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTUwMzdkZTBhZmMxZDhkNDNkODM0ODQxNGJiZjQxMDMwNDNlYzhmNTc1YmZkYzQzMjk1M2NjOGQyMDM3ZmEyZCcsXG4gICAgICAgICc0NTcxNTM0YmFhOTRkM2I1ZjlmOThkMDlmYjk5MGJkZGJkNWY1YjAzZWM0ODFmMTBlMGU1ZGM4NDFkNzU1YmRhJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2UwNjM3MmIwZjRhMjA3YWRmNWVhOTA1ZThmMTc3MWI0ZTdlOGRiZDFjNmE2YzViNzI1ODY2YTBhZTRmY2U3MjUnLFxuICAgICAgICAnN2E5MDg5NzRiY2UxOGNmZTEyYTI3YmIyYWQ1YTQ4OGNkNzQ4NGE3Nzg3MTA0ODcwYjI3MDM0Zjk0ZWVlMzFkZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyMTNjN2E3MTVjZDVkNDUzNThkMGJiZjlkYzBjZTAyMjA0YjEwYmRkZTJhM2Y1ODU0MGFkNjkwOGQwNTU5NzU0JyxcbiAgICAgICAgJzRiNmRhZDBiNWFlNDYyNTA3MDEzYWQwNjI0NWJhMTkwYmI0ODUwZjVmMzZhN2VlZGRmZjJjMjc1MzRiNDU4ZjInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNGU3YzI3MmE3YWY0YjM0ZThkYmI5MzUyYTU0MTlhODdlMjgzOGM3MGFkYzYyY2RkZjBjYzNhM2IwOGZiZDUzYycsXG4gICAgICAgICcxNzc0OWM3NjZjOWQwYjE4ZTE2ZmQwOWY2ZGVmNjgxYjUzMGI5NjE0YmZmN2RkMzNlMGIzOTQxODE3ZGNhYWU2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2ZlYTc0ZTNkYmU3NzhiMWIxMGYyMzhhZDYxNjg2YWE1Yzc2ZTNkYjJiZTQzMDU3NjMyNDI3ZTI4NDBmYjI3YjYnLFxuICAgICAgICAnNmUwNTY4ZGI5YjBiMTMyOTdjZjY3NGRlY2NiNmFmOTMxMjZiNTk2Yjk3M2Y3Yjc3NzAxZDNkYjdmMjNjYjk2ZidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3NmU2NDExM2Y2NzdjZjBlMTBhMjU3MGQ1OTk5NjhkMzE1NDRlMTc5Yjc2MDQzMjk1MmMwMmE0NDE3YmRkZTM5JyxcbiAgICAgICAgJ2M5MGRkZjhkZWU0ZTk1Y2Y1NzcwNjZkNzA2ODFmMGQzNWUyYTMzZDJiNTZkMjAzMmI0YjE3NTJkMTkwMWFjMDEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYzczOGM1NmIwM2IyYWJlMWU4MjgxYmFhNzQzZjhmOWE4ZjdjYzY0M2RmMjZjYmVlM2FiMTUwMjQyYmNiYjg5MScsXG4gICAgICAgICc4OTNmYjU3ODk1MWFkMjUzN2Y3MThmMmVhY2JmYmJiYjgyMzE0ZWVmNzg4MGNmZTkxN2U3MzVkOTY5OWE4NGMzJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2Q4OTU2MjY1NDhiNjViODFlMjY0Yzc2MzdjOTcyODc3ZDFkNzJlNWYzYTkyNTAxNDM3MmU5ZjY1ODhmNmMxNGInLFxuICAgICAgICAnZmViZmFhMzhmMmJjN2VhZTcyOGVjNjA4MThjMzQwZWIwMzQyOGQ2MzJiYjA2N2UxNzkzNjNlZDc1ZDdkOTkxZidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdiOGRhOTQwMzJhOTU3NTE4ZWIwZjY0MzM1NzFlODc2MWNlZmZjNzM2OTNlODRlZGQ0OTE1MGE1NjRmNjc2ZTAzJyxcbiAgICAgICAgJzI4MDRkZmE0NDgwNWExZTRkN2M5OWNjOTc2MjgwOGIwOTJjYzU4NGQ5NWZmM2I1MTE0ODhlNGU3NGVmZGY2ZTcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTgwZmVhMTQ0NDFmYjMzYTdkOGFkYWI5NDc1ZDdmYWIyMDE5ZWZmYjUxNTZhNzkyZjFhMTE3NzhlM2MwZGY1ZCcsXG4gICAgICAgICdlZWQxZGU3ZjYzOGUwMDc3MWU4OTc2OGNhM2NhOTQ0NzJkMTU1ZTgwYWYzMjJlYTlmY2I0MjkxYjZhYzllYzc4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2EzMDE2OTdiZGZjZDcwNDMxM2JhNDhlNTFkNTY3NTQzZjJhMTgyMDMxZWZkNjkxNWRkYzA3YmJjYzRlMTYwNzAnLFxuICAgICAgICAnNzM3MGY5MWNmYjY3ZTRmNTA4MTgwOWZhMjVkNDBmOWIxNzM1ZGJmN2MwYTExYTEzMGMwZDFhMDQxZTE3N2VhMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc5MGFkODViMzg5ZDZiOTM2NDYzZjlkMDUxMjY3OGRlMjA4Y2MzMzBiMTEzMDdmZmZhYjdhYzYzZTNmYjA0ZWQ0JyxcbiAgICAgICAgJ2U1MDdhMzYyMGEzODI2MWFmZmRjYmQ5NDI3MjIyYjgzOWFlZmFiZTE1ODI4OTRkOTkxZDRkNDhjYjZlZjE1MCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4ZjY4YjlkMmY2M2I1ZjMzOTIzOWMxYWQ5ODFmMTYyZWU4OGM1Njc4NzIzZWEzMzUxYjdiNDQ0YzllYzRjMGRhJyxcbiAgICAgICAgJzY2MmE5ZjJkYmEwNjM5ODZkZTFkOTBjMmI2YmUyMTVkYmJlYTJjZmU5NTUxMGJmZGYyM2NiZjc5NTAxZmZmODInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTRmM2ZiMDE3NmFmODVkNjVmZjk5ZmY5MTk4YzM2MDkxZjQ4ZTg2NTAzNjgxZTNlNjY4NmZkNTA1MzIzMWUxMScsXG4gICAgICAgICcxZTYzNjMzYWQwZWY0ZjFjMTY2MWE2ZDBlYTAyYjcyODZjYzdlNzRlYzk1MWQxYzk4MjJjMzg1NzZmZWI3M2JjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzhjMDBmYTliMThlYmYzMzFlYjk2MTUzN2E0NWE0MjY2YzcwMzRmMmYwZDRlMWQwNzE2ZmI2ZWFlMjBlYWUyOWUnLFxuICAgICAgICAnZWZhNDcyNjdmZWE1MjFhMWE5ZGMzNDNhMzczNmM5NzRjMmZhZGFmYTgxZTM2YzU0ZTdkMmE0YzY2NzAyNDE0YidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlN2EyNmNlNjlkZDQ4MjlmM2UxMGNlYzBhOWU5OGVkMzE0M2QwODRmMzA4YjkyYzA5OTdmZGRmYzYwY2IzZTQxJyxcbiAgICAgICAgJzJhNzU4ZTMwMGZhNzk4NGI0NzFiMDA2YTFhYWZiYjE4ZDBhNmIyYzA0MjBlODNlMjBlOGE5NDIxY2YyY2ZkNTEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYjY0NTllMGVlMzY2MmVjOGQyMzU0MGMyMjNiY2JkYzU3MWNiY2I5NjdkNzk0MjRmM2NmMjllYjNkZTZiODBlZicsXG4gICAgICAgICc2N2M4NzZkMDZmM2UwNmRlMWRhZGYxNmU1NjYxZGIzYzRiM2FlNmQ0OGUzNWIyZmYzMGJmMGI2MWE3MWJhNDUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDY4YTgwYzgyODBiYjg0MDc5MzIzNGFhMTE4ZjA2MjMxZDZmMWZjNjdlNzNjNWE1ZGVkYTBmNWI0OTY5NDNlOCcsXG4gICAgICAgICdkYjhiYTlmZmY0YjU4NmQwMGM0YjFmOTE3N2IwZTI4YjViMGU3YjhmNzg0NTI5NWEyOTRjODQyNjZiMTMzMTIwJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzMyNGFlZDdkZjY1YzgwNDI1MmRjMDI3MDkwN2EzMGIwOTYxMmFlYjk3MzQ0OWNlYTQwOTU5ODBmYzI4ZDNkNWQnLFxuICAgICAgICAnNjQ4YTM2NTc3NGI2MWYyZmYxMzBjMGMzNWFlYzFmNGYxOTIxM2IwYzdlMzMyODQzOTY3MjI0YWY5NmFiN2M4NCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc0ZGY5YzE0OTE5Y2RlNjFmNmQ1MWRmZGJlNWZlZTVkY2VlYzQxNDNiYThkMWNhODg4ZThiZDM3M2ZkMDU0Yzk2JyxcbiAgICAgICAgJzM1ZWM1MTA5MmQ4NzI4MDUwOTc0YzIzYTFkODVkNGI1ZDUwNmNkYzI4ODQ5MDE5MmViYWMwNmNhZDEwZDVkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzljMzkxOWE4NGE0NzQ4NzBmYWVkOGE5YzFjYzY2MDIxNTIzNDg5MDU0ZDdmMDMwOGNiZmM5OWM4YWMxZjk4Y2QnLFxuICAgICAgICAnZGRiODRmMGY0YTRkZGQ1NzU4NGYwNDRiZjI2MGU2NDE5MDUzMjZmNzZjNjRjOGU2YmU3ZTVlMDNkNGZjNTk5ZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc2MDU3MTcwYjFkZDEyZmRmOGRlMDVmMjgxZDhlMDZiYjkxZTE0OTNhOGI5MWQ0Y2M1YTIxMzgyMTIwYTk1OWU1JyxcbiAgICAgICAgJzlhMWFmMGIyNmE2YTQ4MDdhZGQ5YTJkYWY3MWRmMjYyNDY1MTUyYmMzZWUyNGM2NWU4OTliZTkzMjM4NWEyYTgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYTU3NmRmOGUyM2EwODQxMTQyMTQzOWE0NTE4ZGEzMTg4MGNlZjBmYmE3ZDRkZjEyYjFhNjk3M2VlY2I5NDI2NicsXG4gICAgICAgICc0MGE2YmYyMGU3NjY0MGIyYzkyYjk3YWZlNThjZDgyYzQzMmUxMGE3ZjUxNGQ5ZjNlZThiZTExYWUxYjI4ZWM4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc3NzhhNzhjMjhkZWMzZTMwYTA1ZmU5NjI5ZGU4YzM4YmIzMGQxZjVjZjlhM2EyMDhmNzYzODg5YmU1OGFkNzEnLFxuICAgICAgICAnMzQ2MjZkOWFiNWE1YjIyZmY3MDk4ZTEyZjJmZjU4MDA4N2IzODQxMWZmMjRhYzU2M2I1MTNmYzFmZDlmNDNhYydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc5Mjg5NTVlZTYzN2E4NDQ2MzcyOWZkMzBlN2FmZDJlZDVmOTYyNzRlNWFkN2U1Y2IwOWVkYTljMDZkOTAzYWMnLFxuICAgICAgICAnYzI1NjIxMDAzZDNmNDJhODI3Yjc4YTEzMDkzYTk1ZWVhYzNkMjZlZmE4YThkODNmYzUxODBlOTM1YmNkMDkxZidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4NWQwZmVmM2VjNmRiMTA5Mzk5MDY0ZjNhMGUzYjI4NTU2NDViNGE5MDdhZDM1NDUyN2FhZTc1MTYzZDgyNzUxJyxcbiAgICAgICAgJzFmMDM2NDg0MTNhMzhjMGJlMjlkNDk2ZTU4MmNmNTY2M2U4NzUxZTk2ODc3MzMxNTgyYzIzN2EyNGViMWY5NjInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZmYyYjBkY2U5N2VlY2U5N2MxYzliNjA0MTc5OGI4NWRmZGZiNmQ4ODgyZGEyMDMwOGY1NDA0ODI0NTI2MDg3ZScsXG4gICAgICAgICc0OTNkMTNmZWY1MjRiYTE4OGFmNGM0ZGM1NGQwNzkzNmM3YjdlZDZmYjkwZTJjZWIyYzk1MWUwMWYwYzI5OTA3J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzgyN2ZiYmU0YjFlODgwZWE5ZWQyYjJlNjMwMWIyMTJiNTdmMWVlMTQ4Y2Q2ZGQyODc4MGU1ZTJjZjg1NmUyNDEnLFxuICAgICAgICAnYzYwZjljOTIzYzcyN2IwYjcxYmVmMmM2N2QxZDEyNjg3ZmY3YTYzMTg2OTAzMTY2ZDYwNWI2OGJhZWMyOTNlYydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlYWE2NDlmMjFmNTFiZGJhZTdiZTRhZTM0Y2U2ZTUyMTdhNThmZGNlN2Y0N2Y5YWE3ZjNiNThmYTIxMjBlMmIzJyxcbiAgICAgICAgJ2JlMzI3OWVkNWJiYmIwM2FjNjlhODBmODk4NzlhYTVhMDFhNmI5NjVmMTNmN2U1OWQ0N2E1MzA1YmE1YWQ5M2QnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTRhNDJkNDNjNWNmMTY5ZDkzOTFkZjZkZWNmNDJlZTU0MWI2ZDhmMGM5YTEzNzQwMWUyMzYzMmRkYTM0ZDI0ZicsXG4gICAgICAgICc0ZDlmOTJlNzE2ZDFjNzM1MjZmYzk5Y2NmYjhhZDM0Y2U4ODZlZWRmYThkOGU0ZjEzYTdmNzEzMWRlYmE5NDE0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzFlYzgwZmVmMzYwY2JkZDk1NDE2MGZhZGFiMzUyYjZiOTJiNTM1NzZhODhmZWE0OTQ3MTczYjlkNDMwMGJmMTknLFxuICAgICAgICAnYWVlZmU5Mzc1NmI1MzQwZDJmM2E0OTU4YTdhYmJmNWUwMTQ2ZTc3ZjYyOTVhMDdiNjcxY2RjMWNjMTA3Y2VmZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxNDZhNzc4YzA0NjcwYzJmOTFiMDBhZjQ2ODBkZmE4YmNlMzQ5MDcxN2Q1OGJhODg5ZGRiNTkyODM2NjY0MmJlJyxcbiAgICAgICAgJ2IzMThlMGVjMzM1NDAyOGFkZDY2OTgyN2Y5ZDRiMjg3MGFhYTk3MWQyZjdlNWVkMWQwYjI5NzQ4M2Q4M2VmZDAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZmE1MGMwZjYxZDIyZTVmMDdlM2FjZWJiMWFhMDdiMTI4ZDAwMTIyMDlhMjhiOTc3NmQ3NmE4NzkzMTgwZWVmOScsXG4gICAgICAgICc2Yjg0YzY5MjIzOTdlYmE5YjcyY2QyODcyMjgxYTY4YTVlNjgzMjkzYTU3YTIxM2IzOGNkOGQ3ZDNmNGYyODExJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2RhMWQ2MWQwY2E3MjFhMTFiMWE1YmY2YjdkODhlODQyMWEyODhhYjVkNWJiYTUyMjBlNTNkMzJiNWYwNjdlYzInLFxuICAgICAgICAnODE1N2Y1NWE3Yzk5MzA2Yzc5YzA3NjYxNjFjOTFlMjk2NmE3Mzg5OWQyNzliNDhhNjU1ZmJhMGYxYWQ4MzZmMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhOGUyODJmZjBjOTcwNjkwNzIxNWZmOThlOGZkNDE2NjE1MzExZGUwNDQ2ZjFlMDYyYTczYjA2MTBkMDY0ZTEzJyxcbiAgICAgICAgJzdmOTczNTViOGRiODFjMDlhYmZiN2YzYzViMjUxNTg4OGI2NzlhM2U1MGRkNmJkNmNlZjdjNzMxMTFmNGNjMGMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMTc0YTUzYjljOWEyODU4NzJkMzllNTZlNjkxM2NhYjE1ZDU5YjFmYTUxMjUwOGMwMjJmMzgyZGU4MzE5NDk3YycsXG4gICAgICAgICdjY2M5ZGMzN2FiZmM5YzE2NTdiNDE1NWYyYzQ3ZjllNjY0NmIzYTFkOGNiOTg1NDM4M2RhMTNhYzA3OWFmYTczJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzk1OTM5Njk4MTk0Mzc4NWMzZDNlNTdlZGY1MDE4Y2RiZTAzOWU3MzBlNDkxOGIzZDg4NGZkZmYwOTQ3NWI3YmEnLFxuICAgICAgICAnMmU3ZTU1Mjg4OGMzMzFkZDhiYTAzODZhNGI5Y2Q2ODQ5YzY1M2Y2NGM4NzA5Mzg1ZTliOGFiZjg3NTI0ZjJmZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkMmE2M2E1MGFlNDAxZTU2ZDY0NWExMTUzYjEwOWE4ZmNjYTBhNDNkNTYxZmJhMmRiYjUxMzQwYzlkODJiMTUxJyxcbiAgICAgICAgJ2U4MmQ4NmZiNjQ0M2ZjYjc1NjVhZWU1OGIyOTQ4MjIwYTcwZjc1MGFmNDg0Y2E1MmQ0MTQyMTc0ZGNmODk0MDUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNjQ1ODdlMjMzNTQ3MWViODkwZWU3ODk2ZDdjZmRjODY2YmFjYmRiZDM4MzkzMTdiMzQzNmY5YjQ1NjE3ZTA3MycsXG4gICAgICAgICdkOTlmY2RkNWJmNjkwMmUyYWU5NmRkNjQ0N2MyOTlhMTg1YjkwYTM5MTMzYWVhYjM1ODI5OWU1ZTlmYWY2NTg5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzg0ODFiZGUwZTRlNGQ4ODViM2E1NDZkM2U1NDlkZTA0MmYwYWE2Y2VhMjUwZTdmZDM1OGQ2Yzg2ZGQ0NWU0NTgnLFxuICAgICAgICAnMzhlZTdiOGNiYTU0MDRkZDg0YTI1YmYzOWNlY2IyY2E5MDBhNzljNDJiMjYyZTU1NmQ2NGIxYjU5Nzc5MDU3ZSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxMzQ2NGE1N2E3ODEwMmFhNjJiNjk3OWFlODE3ZjQ2MzdmZmNmZWQzYzRiMWNlMzBiY2Q2MzAzZjZjYWY2NjZiJyxcbiAgICAgICAgJzY5YmUxNTkwMDQ2MTQ1ODBlZjdlNDMzNDUzY2NiMGNhNDhmMzAwYTgxZDA5NDJlMTNmNDk1YTkwN2Y2ZWNjMjcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYmM0YTlkZjViNzEzZmUyZTlhZWY0MzBiY2MxZGM5N2EwY2Q5Y2NlZGUyZjI4NTg4Y2FkYTNhMGQyZDgzZjM2NicsXG4gICAgICAgICdkM2E4MWNhNmU3ODVjMDYzODM5MzdhZGY0Yjc5OGNhYTZlOGE5ZmJmYTU0N2IxNmQ3NThkNjY2NTgxZjMzYzEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOGMyOGE5N2JmODI5OGJjMGQyM2Q4Yzc0OTQ1MmEzMmU2OTRiNjVlMzBhOTQ3MmEzOTU0YWIzMGZlNTMyNGNhYScsXG4gICAgICAgICc0MGEzMDQ2M2EzMzA1MTkzMzc4ZmVkZjMxZjdjYzBlYjdhZTc4NGYwNDUxY2I5NDU5ZTcxZGM3M2NiZWY5NDgyJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzhlYTk2NjYxMzk1MjdhOGMxZGQ5NGNlNGYwNzFmZDIzYzhiMzUwYzVhNGJiMzM3NDhjNGJhMTExZmFjY2FlMCcsXG4gICAgICAgICc2MjBlZmFiYmM4ZWUyNzgyZTI0ZTdjMGNmYjk1YzVkNzM1Yjc4M2JlOWNmMGY4ZTk1NWFmMzRhMzBlNjJiOTQ1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2RkMzYyNWZhZWY1YmEwNjA3NDY2OTcxNmJiZDM3ODhkODliZGRlODE1OTU5OTY4MDkyZjc2Y2M0ZWI5YTk3ODcnLFxuICAgICAgICAnN2ExODhmYTM1MjBlMzBkNDYxZGEyNTAxMDQ1NzMxY2E5NDE0NjE5ODI4ODMzOTU5MzdmNjhkMDBjNjQ0YTU3MydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmNzEwZDc5ZDllYjk2MjI5N2U0ZjYyMzJiNDBlOGY3ZmViMmJjNjM4MTQ2MTRkNjkyYzEyZGU3NTI0MDgyMjFlJyxcbiAgICAgICAgJ2VhOThlNjcyMzJkM2IzMjk1ZDNiNTM1NTMyMTE1Y2NhYzg2MTJjNzIxODUxNjE3NTI2YWU0N2E5Yzc3YmZjODInXG4gICAgICBdXG4gICAgXVxuICB9LFxuICBuYWY6IHtcbiAgICB3bmQ6IDcsXG4gICAgcG9pbnRzOiBbXG4gICAgICBbXG4gICAgICAgICdmOTMwOGEwMTkyNThjMzEwNDkzNDRmODVmODlkNTIyOWI1MzFjODQ1ODM2Zjk5YjA4NjAxZjExM2JjZTAzNmY5JyxcbiAgICAgICAgJzM4OGY3YjBmNjMyZGU4MTQwZmUzMzdlNjJhMzdmMzU2NjUwMGE5OTkzNGMyMjMxYjZjYjlmZDc1ODRiOGU2NzInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMmY4YmRlNGQxYTA3MjA5MzU1YjRhNzI1MGE1YzUxMjhlODhiODRiZGRjNjE5YWI3Y2JhOGQ1NjliMjQwZWZlNCcsXG4gICAgICAgICdkOGFjMjIyNjM2ZTVlM2Q2ZDRkYmE5ZGRhNmM5YzQyNmY3ODgyNzFiYWIwZDY4NDBkY2E4N2QzYWE2YWM2MmQ2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzVjYmRmMDY0NmU1ZGI0ZWFhMzk4ZjM2NWYyZWE3YTBlM2Q0MTliN2UwMzMwZTM5Y2U5MmJkZGVkY2FjNGY5YmMnLFxuICAgICAgICAnNmFlYmNhNDBiYTI1NTk2MGEzMTc4ZDZkODYxYTU0ZGJhODEzZDBiODEzZmRlN2I1YTUwODI2MjgwODcyNjRkYSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhY2Q0ODRlMmYwYzdmNjUzMDlhZDE3OGE5ZjU1OWFiZGUwOTc5Njk3NGM1N2U3MTRjMzVmMTEwZGZjMjdjY2JlJyxcbiAgICAgICAgJ2NjMzM4OTIxYjBhN2Q5ZmQ2NDM4MDk3MTc2M2I2MWU5YWRkODg4YTQzNzVmOGUwZjA1Y2MyNjJhYzY0ZjljMzcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzc0YWU3Zjg1OGE5NDExZTVlZjQyNDZiNzBjNjVhYWM1NjQ5OTgwYmU1YzE3ODkxYmJlYzE3ODk1ZGEwMDhjYicsXG4gICAgICAgICdkOTg0YTAzMmViNmI1ZTE5MDI0M2RkNTZkN2I3YjM2NTM3MmRiMWUyZGZmOWQ2YTgzMDFkNzRjOWM5NTNjNjFiJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2YyODc3M2MyZDk3NTI4OGJjN2QxZDIwNWMzNzQ4NjUxYjA3NWZiYzY2MTBlNThjZGRlZWRkZjhmMTk0MDVhYTgnLFxuICAgICAgICAnYWIwOTAyZThkODgwYTg5NzU4MjEyZWI2NWNkYWY0NzNhMWEwNmRhNTIxZmE5MWYyOWI1Y2I1MmRiMDNlZDgxJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2Q3OTI0ZDRmN2Q0M2VhOTY1YTQ2NWFlMzA5NWZmNDExMzFlNTk0NmYzYzg1Zjc5ZTQ0YWRiY2Y4ZTI3ZTA4MGUnLFxuICAgICAgICAnNTgxZTI4NzJhODZjNzJhNjgzODQyZWMyMjhjYzZkZWZlYTQwYWYyYmQ4OTZkM2E1YzUwNGRjOWZmNmEyNmI1OCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkZWZkZWE0Y2RiNjc3NzUwYTQyMGZlZTgwN2VhY2YyMWViOTg5OGFlNzliOTc2ODc2NmU0ZmFhMDRhMmQ0YTM0JyxcbiAgICAgICAgJzQyMTFhYjA2OTQ2MzUxNjhlOTk3YjBlYWQyYTkzZGFlY2VkMWY0YTA0YTk1YzBmNmNmYjE5OWY2OWU1NmViNzcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMmI0ZWEwYTc5N2E0NDNkMjkzZWY1Y2ZmNDQ0ZjQ5NzlmMDZhY2ZlYmQ3ZTg2ZDI3NzQ3NTY1NjEzODM4NWI2YycsXG4gICAgICAgICc4NWU4OWJjMDM3OTQ1ZDkzYjM0MzA4M2I1YTFjODYxMzFhMDFmNjBjNTAyNjk3NjNiNTcwYzg1NGU1YzA5YjdhJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzM1MmJiZjRhNGNkZDEyNTY0ZjkzZmEzMzJjZTMzMzMwMWQ5YWQ0MDI3MWY4MTA3MTgxMzQwYWVmMjViZTU5ZDUnLFxuICAgICAgICAnMzIxZWI0MDc1MzQ4ZjUzNGQ1OWMxODI1OWRkYTNlMWY0YTFiM2IyZTcxYjEwMzljNjdiZDNkOGJjZjgxOTk4YydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyZmEyMTA0ZDZiMzhkMTFiMDIzMDAxMDU1OTg3OTEyNGU0MmFiOGRmZWZmNWZmMjlkYzljZGFkZDRlY2FjYzNmJyxcbiAgICAgICAgJzJkZTEwNjgyOTVkZDg2NWI2NDU2OTMzNWJkNWRkODAxODFkNzBlY2ZjODgyNjQ4NDIzYmE3NmI1MzJiN2Q2NydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc5MjQ4Mjc5YjA5YjRkNjhkYWIyMWE5YjA2NmVkZGE4MzI2M2MzZDg0ZTA5NTcyZTI2OWNhMGNkN2Y1NDUzNzE0JyxcbiAgICAgICAgJzczMDE2ZjdiZjIzNGFhZGU1ZDFhYTcxYmRlYTJiMWZmM2ZjMGRlMmE4ODc5MTJmZmU1NGEzMmNlOTdjYjM0MDInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZGFlZDRmMmJlM2E4YmYyNzhlNzAxMzJmYjBiZWI3NTIyZjU3MGUxNDRiZjYxNWMwN2U5OTZkNDQzZGVlODcyOScsXG4gICAgICAgICdhNjlkY2U0YTdkNmM5OGU4ZDRhMWFjYTg3ZWY4ZDcwMDNmODNjMjMwZjNhZmE3MjZhYjQwZTUyMjkwYmUxYzU1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2M0NGQxMmM3MDY1ZDgxMmU4YWNmMjhkN2NiYjE5ZjkwMTFlY2Q5ZTlmZGYyODFiMGU2YTNiNWU4N2QyMmU3ZGInLFxuICAgICAgICAnMjExOWE0NjBjZTMyNmNkYzc2YzQ1OTI2Yzk4MmZkYWMwZTEwNmU4NjFlZGY2MWM1YTAzOTA2M2YwZTBlNjQ4MidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc2YTI0NWJmNmRjNjk4NTA0Yzg5YTIwY2ZkZWQ2MDg1MzE1MmI2OTUzMzZjMjgwNjNiNjFjNjVjYmQyNjllNmI0JyxcbiAgICAgICAgJ2UwMjJjZjQyYzJiZDRhNzA4YjNmNTEyNmYxNmEyNGFkOGIzM2JhNDhkMDQyM2I2ZWZkNWU2MzQ4MTAwZDhhODInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMTY5N2ZmYTZmZDlkZTYyN2MwNzdlM2QyZmU1NDEwODRjZTEzMzAwYjBiZWMxMTQ2Zjk1YWU1N2YwZDBiZDZhNScsXG4gICAgICAgICdiOWMzOThmMTg2ODA2ZjVkMjc1NjE1MDZlNDU1NzQzM2EyY2YxNTAwOWU0OThhZTdhZGVlOWQ2M2QwMWIyMzk2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzYwNWJkYjAxOTk4MTcxOGI5ODZkMGYwN2U4MzRjYjBkOWRlYjgzNjBmZmI3ZjYxZGY5ODIzNDVlZjI3YTc0NzknLFxuICAgICAgICAnMjk3MmQyZGU0ZjhkMjA2ODFhNzhkOTNlYzk2ZmUyM2MyNmJmYWU4NGZiMTRkYjQzYjAxZTFlOTA1NmI4YzQ5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzYyZDE0ZGFiNDE1MGJmNDk3NDAyZmRjNDVhMjE1ZTEwZGNiMDFjMzU0OTU5YjEwY2ZlMzFjN2U5ZDg3ZmYzM2QnLFxuICAgICAgICAnODBmYzA2YmQ4Y2M1YjAxMDk4MDg4YTE5NTBlZWQwZGIwMWFhMTMyOTY3YWI0NzIyMzVmNTY0MjQ4M2IyNWVhZidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4MGM2MGFkMDA0MGYyN2RhZGU1YjRiMDZjNDA4ZTU2YjJjNTBlOWY1NmI5YjhiNDI1ZTU1NWMyZjg2MzA4YjZmJyxcbiAgICAgICAgJzFjMzgzMDNmMWNjNWMzMGYyNmU2NmJhZDdmZTcyZjcwYTY1ZWVkNGNiZTcwMjRlYjFhYTAxZjU2NDMwYmQ1N2EnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnN2E5Mzc1YWQ2MTY3YWQ1NGFhNzRjNjM0OGNjNTRkMzQ0Y2M1ZGM5NDg3ZDg0NzA0OWQ1ZWFiYjBmYTAzYzhmYicsXG4gICAgICAgICdkMGUzZmE5ZWNhODcyNjkwOTU1OWUwZDc5MjY5MDQ2YmRjNTllYTEwYzcwY2UyYjAyZDQ5OWVjMjI0ZGM3ZjcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDUyOGVjZDliNjk2YjU0YzkwN2E5ZWQwNDU0NDdhNzliYjQwOGVjMzliNjhkZjUwNGJiNTFmNDU5YmMzZmZjOScsXG4gICAgICAgICdlZWNmNDEyNTMxMzZlNWY5OTk2NmYyMTg4MWZkNjU2ZWJjNDM0NTQwNWM1MjBkYmMwNjM0NjViNTIxNDA5OTMzJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzQ5MzcwYTRiNWY0MzQxMmVhMjVmNTE0ZThlY2RhZDA1MjY2MTE1ZTRhN2VjYjEzODcyMzE4MDhmOGI0NTk2MycsXG4gICAgICAgICc3NThmM2Y0MWFmZDZlZDQyOGIzMDgxYjA1MTJmZDYyYTU0YzNmM2FmYmI1YjY3NjRiNjUzMDUyYTEyOTQ5YzlhJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc3ZjIzMDkzNmVlODhjYmJkNzNkZjkzMGQ2NDcwMmVmODgxZDgxMWUwZTE0OThlMmYxYzEzZWIxZmMzNDVkNzQnLFxuICAgICAgICAnOTU4ZWY0MmE3ODg2YjY0MDBhMDgyNjZlOWJhMWIzNzg5NmM5NTMzMGQ5NzA3N2NiYmU4ZWIzYzc2NzFjNjBkNidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmMmRhYzk5MWNjNGNlNGI5ZWE0NDg4N2U1YzdjMGJjZTU4YzgwMDc0YWI5ZDRkYmFlYjI4NTMxYjc3MzlmNTMwJyxcbiAgICAgICAgJ2UwZGVkYzliM2IyZjhkYWQ0ZGExZjMyZGVjMjUzMWRmOWViNWZiZWIwNTk4ZTRmZDFhMTE3ZGJhNzAzYTNjMzcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNDYzYjNkOWY2NjI2MjFmYjFiNGJlOGZiYmUyNTIwMTI1YTIxNmNkZmM5ZGFlM2RlYmNiYTQ4NTBjNjkwZDQ1YicsXG4gICAgICAgICc1ZWQ0MzBkNzhjMjk2YzM1NDMxMTQzMDZkZDg2MjJkN2M2MjJlMjdjOTcwYTFkZTMxY2IzNzdiMDFhZjczMDdlJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2YxNmY4MDQyNDRlNDZlMmEwOTIzMmQ0YWZmM2I1OTk3NmI5OGZhYzE0MzI4YTJkMWEzMjQ5NmI0OTk5OGYyNDcnLFxuICAgICAgICAnY2VkYWJkOWI4MjIwM2Y3ZTEzZDIwNmZjZGY0ZTMzZDkyYTZjNTNjMjZlNWNjZTI2ZDY1Nzk5NjJjNGUzMWRmNidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdjYWY3NTQyNzJkYzg0NTYzYjAzNTJiN2ExNDMxMWFmNTVkMjQ1MzE1YWNlMjdjNjUzNjllMTVmNzE1MWQ0MWQxJyxcbiAgICAgICAgJ2NiNDc0NjYwZWYzNWY1ZjJhNDFiNjQzZmE1ZTQ2MDU3NWY0ZmE5Yjc5NjIyMzJhNWMzMmY5MDgzMThhMDQ0NzYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMjYwMGNhNGIyODJjYjk4NmY4NWQwZjE3MDk5NzlkOGI0NGEwOWMwN2NiODZkN2MxMjQ0OTdiYzg2ZjA4MjEyMCcsXG4gICAgICAgICc0MTE5Yjg4NzUzYzE1YmQ2YTY5M2IwM2ZjZGRiYjQ1ZDVhYzZiZTc0YWI1ZjBlZjQ0YjBiZTk0NzVhN2U0YjQwJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc2MzVjYTcyZDdlODQzMmMzMzhlYzUzY2QxMjIyMGJjMDFjNDg2ODVlMjRmN2RjOGM2MDJhNzc0Njk5OGU0MzUnLFxuICAgICAgICAnOTFiNjQ5NjA5NDg5ZDYxM2QxZDVlNTkwZjc4ZTZkNzRlY2ZjMDYxZDU3MDQ4YmFkOWU3NmYzMDJjNWI5YzYxJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc1NGUzMjM5ZjMyNTU3MGNkYmJmNGE4N2RlZWU4YTY2YjdmMmIzMzQ3OWQ0NjhmYmMxYTUwNzQzYmY1NmNjMTgnLFxuICAgICAgICAnNjczZmI4NmU1YmRhMzBmYjNjZDBlZDMwNGVhNDlhMDIzZWUzM2QwMTk3YTY5NWQwYzVkOTgwOTNjNTM2NjgzJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2UzZTZiZDEwNzFhMWU5NmFmZjU3ODU5YzgyZDU3MGYwMzMwODAwNjYxZDFjOTUyZjlmZTI2OTQ2OTFkOWI5ZTgnLFxuICAgICAgICAnNTljOWUwYmJhMzk0ZTc2ZjQwYzBhYTU4Mzc5YTNjYjZhNWEyMjgzOTkzZTkwYzQxNjcwMDJhZjQ5MjBlMzdmNSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxODZiNDgzZDA1NmEwMzM4MjZhZTczZDg4ZjczMjk4NWM0Y2NiMWYzMmJhMzVmNGI0Y2M0N2ZkY2YwNGFhNmViJyxcbiAgICAgICAgJzNiOTUyZDMyYzY3Y2Y3N2UyZTE3NDQ2ZTIwNDE4MGFiMjFmYjgwOTA4OTUxMzhiNGE0YTc5N2Y4NmU4MDg4OGInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZGY5ZDcwYTZiOTg3NmNlNTQ0Yzk4NTYxZjRiZTRmNzI1NDQyZTZkMmI3MzdkOWM5MWE4MzIxNzI0Y2UwOTYzZicsXG4gICAgICAgICc1NWViMmRhZmQ4NGQ2Y2NkNWY4NjJiNzg1ZGMzOWQ0YWIxNTcyMjI3MjBlZjlkYTIxN2I4YzQ1Y2YyYmEyNDE3J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzVlZGQ1Y2MyM2M1MWU4N2E0OTdjYTgxNWQ1ZGNlMGY4YWI1MjU1NGY4NDllZDg5OTVkZTY0YzVmMzRjZTcxNDMnLFxuICAgICAgICAnZWZhZTljOGRiYzE0MTMwNjYxZThjZWMwMzBjODlhZDBjMTNjNjZjMGQxN2EyOTA1Y2RjNzA2YWI3Mzk5YTg2OCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyOTA3OThjMmI2NDc2ODMwZGExMmZlMDIyODdlOWU3NzdhYTNmYmExYzM1NWIxN2E3MjJkMzYyZjg0NjE0ZmJhJyxcbiAgICAgICAgJ2UzOGRhNzZkY2Q0NDA2MjE5ODhkMDBiY2Y3OWFmMjVkNWIyOWMwOTRkYjJhMjMxNDZkMDAzYWZkNDE5NDNlN2EnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYWYzYzQyM2E5NWQ5ZjViMzA1NDc1NGVmYTE1MGFjMzljZDI5NTUyZmUzNjAyNTczNjJkZmRlY2VmNDA1M2I0NScsXG4gICAgICAgICdmOThhM2ZkODMxZWIyYjc0OWE5M2IwZTZmMzVjZmI0MGM4Y2Q1YWE2NjdhMTU1ODFiYzJmZWRlZDQ5OGZkOWM2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc2NmRiYjI0ZDEzNGU3NDVjY2NhYTI4Yzk5YmYyNzQ5MDZiYjY2YjI2ZGNmOThkZjhkMmZlZDUwZDg4NDI0OWEnLFxuICAgICAgICAnNzQ0YjExNTJlYWNiZTVlMzhkY2M4ODc5ODBkYTM4Yjg5NzU4NGE2NWZhMDZjZWRkMmM5MjRmOTdjYmFjNTk5NidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc1OWRiZjQ2ZjhjOTQ3NTliYTIxMjc3YzMzNzg0ZjQxNjQ1ZjdiNDRmNmM1OTZhNThjZTkyZTY2NjE5MWFiZTNlJyxcbiAgICAgICAgJ2M1MzRhZDQ0MTc1ZmJjMzAwZjRlYTZjZTY0ODMwOWEwNDJjZTczOWE3OTE5Nzk4Y2Q4NWUyMTZjNGEzMDdmNmUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZjEzYWRhOTUxMDNjNDUzNzMwNWU2OTFlNzRlOWE0YThkZDY0N2U3MTFhOTVlNzNjYjYyZGM2MDE4Y2ZkODdiOCcsXG4gICAgICAgICdlMTM4MTdiNDRlZTE0ZGU2NjNiZjRiYzgwODM0MWYzMjY5NDllMjFhNmE3NWMyNTcwNzc4NDE5YmRhZjU3MzNkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc3NTRiNGZhMGU4YWNlZDA2ZDQxNjdhMmM1OWNjYTRjZGExODY5YzA2ZWJhZGZiNjQ4ODU1MDAxNWE4ODUyMmMnLFxuICAgICAgICAnMzBlOTNlODY0ZTY2OWQ4MjIyNGI5NjdjMzAyMGI4ZmE4ZDFlNGUzNTBiNmNiY2M1MzdhNDhiNTc4NDExNjNhMidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc5NDhkY2FkZjU5OTBlMDQ4YWEzODc0ZDQ2YWJlZjlkNzAxODU4Zjk1ZGU4MDQxZDJhNjgyOGM5OWUyMjYyNTE5JyxcbiAgICAgICAgJ2U0OTFhNDI1MzdmNmU1OTdkNWQyOGEzMjI0YjFiYzI1ZGY5MTU0ZWZiZDJlZjFkMmNiYmEyY2FlNTM0N2Q1N2UnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzk2MjQxNDQ1MGM3NmMxNjg5YzdiNDhmODIwMmVjMzdmYjIyNGNmNWFjMGJmYTE1NzAzMjhhOGEzZDdjNzdhYicsXG4gICAgICAgICcxMDBiNjEwZWM0ZmZiNDc2MGQ1YzFmYzEzM2VmNmY2YjEyNTA3YTA1MWYwNGFjNTc2MGFmYTViMjlkYjgzNDM3J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzM1MTQwODc4MzQ5NjRiNTRiMTViMTYwNjQ0ZDkxNTQ4NWExNjk3NzIyNWI4ODQ3YmIwZGQwODUxMzdlYzQ3Y2EnLFxuICAgICAgICAnZWYwYWZiYjIwNTYyMDU0NDhlMTY1MmM0OGU4MTI3ZmM2MDM5ZTc3YzE1YzIzNzhiN2U3ZDE1YTBkZTI5MzMxMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkM2NjMzBhZDZiNDgzZTRiYzc5Y2UyYzlkZDhiYzU0OTkzZTk0N2ViOGRmNzg3YjQ0Mjk0M2QzZjdiNTI3ZWFmJyxcbiAgICAgICAgJzhiMzc4YTIyZDgyNzI3OGQ4OWM1ZTliZThmOTUwOGFlM2MyYWQ0NjI5MDM1ODYzMGFmYjM0ZGIwNGVlZGUwYTQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMTYyNGQ4NDc4MDczMjg2MGNlMWM3OGZjYmZlZmUwOGIyYjI5ODIzZGI5MTNmNjQ5Mzk3NWJhMGZmNDg0NzYxMCcsXG4gICAgICAgICc2ODY1MWNmOWI2ZGE5MDNlMDkxNDQ0OGM2Y2Q5ZDRjYTg5Njg3OGY1MjgyYmU0YzhjYzA2ZTJhNDA0MDc4NTc1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzczM2NlODBkYTk1NWE4YTI2OTAyYzk1NjMzZTYyYTk4NTE5MjQ3NGI1YWYyMDdkYTZkZjdiNGZkNWZjNjFjZDQnLFxuICAgICAgICAnZjU0MzVhMmJkMmJhZGY3ZDQ4NWE0ZDhiOGRiOWZjY2UzZTFlZjhlMDIwMWU0NTc4YzU0NjczYmMxZGM1ZWExZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxNWQ5NDQxMjU0OTQ1MDY0Y2YxYTFjMzNiYmQzYjQ5Zjg5NjZjNTA5MjE3MWU2OTllZjI1OGRmYWI4MWMwNDVjJyxcbiAgICAgICAgJ2Q1NmViMzBiNjk0NjNlNzIzNGY1MTM3YjczYjg0MTc3NDM0ODAwYmFjZWJmYzY4NWZjMzdiYmU5ZWZlNDA3MGQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYTFkMGZjZjJlYzlkZTY3NWI2MTIxMzZlNWNlNzBkMjcxYzIxNDE3YzlkMmI4YWFhYWMxMzg1OTlkMDcxNzk0MCcsXG4gICAgICAgICdlZGQ3N2Y1MGJjYjVhM2NhYjJlOTA3MzczMDk2NjdmMjY0MTQ2MmE1NDA3MGYzZDUxOTIxMmQzOWMxOTdhNjI5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2UyMmZiZTE1YzBhZjhjY2M1NzgwYzA3MzVmODRkYmU5YTc5MGJhZGVlODI0NWMwNmM3Y2EzNzMzMWNiMzY5ODAnLFxuICAgICAgICAnYTg1NWJhYmFkNWNkNjBjODhiNDMwYTY5ZjUzYTFhN2EzODI4OTE1NDk2NDc5OWJlNDNkMDZkNzdkMzFkYTA2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzMxMTA5MWRkOTg2MGU4ZTIwZWUxMzQ3M2MxMTU1ZjVmNjk2MzVlMzk0NzA0ZWFhNzQwMDk0NTIyNDZjZmE5YjMnLFxuICAgICAgICAnNjZkYjY1NmY4N2QxZjA0ZmZmZDFmMDQ3ODhjMDY4MzA4NzFlYzVhNjRmZWVlNjg1YmQ4MGYwYjEyODZkODM3NCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczNGMxZmQwNGQzMDFiZTg5YjMxYzA0NDJkM2U2YWMyNDg4MzkyOGI0NWE5MzQwNzgxODY3ZDQyMzJlYzJkYmRmJyxcbiAgICAgICAgJzk0MTQ2ODVlOTdiMWI1OTU0YmQ0NmY3MzAxNzQxMzZkNTdmMWNlZWI0ODc0NDNkYzUzMjE4NTdiYTczYWJlZSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmMjE5ZWE1ZDZiNTQ3MDFjMWMxNGRlNWI1NTdlYjQyYThkMTNmM2FiYmNkMDhhZmZjYzJhNWU2YjA0OWI4ZDYzJyxcbiAgICAgICAgJzRjYjk1OTU3ZTgzZDQwYjBmNzNhZjQ1NDRjY2NmNmIxZjRiMDhkM2MwN2IyN2ZiOGQ4YzI5NjJhNDAwNzY2ZDEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDdiODc0MGY3NGE4ZmJhYWIxZjY4M2RiOGY0NWRlMjY1NDNhNTQ5MGJjYTYyNzA4NzIzNjkxMjQ2OWEwYjQ0OCcsXG4gICAgICAgICdmYTc3OTY4MTI4ZDljOTJlZTEwMTBmMzM3YWQ0NzE3ZWZmMTVkYjVlZDNjMDQ5YjM0MTFlMDMxNWVhYTQ1OTNiJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzMyZDMxYzIyMmY4ZjZmMGVmODZmN2M5OGQzYTMzMzVlYWQ1YmNkMzJhYmRkOTQyODlmZTRkMzA5MWFhODI0YmYnLFxuICAgICAgICAnNWYzMDMyZjU4OTIxNTZlMzljY2QzZDc5MTViOWUxZGEyZTZkYWM5ZTZmMjZlOTYxMTE4ZDE0Yjg0NjJlMTY2MSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3NDYxZjM3MTkxNGFiMzI2NzEwNDVhMTU1ZDk4MzFlYTg3OTNkNzdjZDU5NTkyYzQzNDBmODZjYmMxODM0N2I1JyxcbiAgICAgICAgJzhlYzBiYTIzOGI5NmJlYzBjYmRkZGNhZTBhYTQ0MjU0MmVlZTFmZjUwYzk4NmVhNmIzOTg0N2IzY2MwOTJmZjYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZWUwNzlhZGIxZGYxODYwMDc0MzU2YTI1YWEzODIwNmE2ZDcxNmIyYzNlNjc0NTNkMjg3Njk4YmFkN2IyYjJkNicsXG4gICAgICAgICc4ZGMyNDEyYWFmZTNiZTVjNGM1ZjM3ZTBlY2M1ZjlmNmE0NDY5ODlhZjA0YzRlMjVlYmFhYzQ3OWVjMWM4YzFlJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzE2ZWM5M2U0NDdlYzgzZjA0NjdiMTgzMDJlZTYyMGY3ZTY1ZGUzMzE4NzRjOWRjNzJiZmQ4NjE2YmE5ZGE2YjUnLFxuICAgICAgICAnNWU0NjMxMTUwZTYyZmI0MGQwZThjMmE3Y2E1ODA0YTM5ZDU4MTg2YTUwZTQ5NzEzOTYyNjc3OGUyNWIwNjc0ZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlYWE1Zjk4MGMyNDVmNmYwMzg5NzgyOTBhZmE3MGI2YmQ4ODU1ODk3Zjk4YjZhYTQ4NWI5NjA2NWQ1MzdiZDk5JyxcbiAgICAgICAgJ2Y2NWY1ZDNlMjkyYzJlMDgxOWE1MjgzOTFjOTk0NjI0ZDc4NDg2OWQ3ZTZlYTY3ZmIxODA0MTAyNGVkYzA3ZGMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzhjOTQwNzU0NGFjMTMyNjkyZWUxOTEwYTAyNDM5OTU4YWUwNDg3NzE1MTM0MmVhOTZjNGI2YjM1YTQ5ZjUxJyxcbiAgICAgICAgJ2YzZTAzMTkxNjllYjliODVkNTQwNDc5NTUzOWE1ZTY4ZmExZmJkNTgzYzA2NGQyNDYyYjY3NWYxOTRhM2RkYjQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNDk0ZjRiZTIxOWExYTc3MDE2ZGNkODM4NDMxYWVhMDAwMWNkYzhhZTdhNmZjNjg4NzI2NTc4ZDk3MDI4NTdhNScsXG4gICAgICAgICc0MjI0MmE5NjkyODNhNWYzMzliYTdmMDc1ZTM2YmEyYWY5MjVjZTMwZDc2N2VkNmU1NWY0YjAzMTg4MGQ1NjJjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2E1OThhODAzMGRhNmQ4NmM2YmM3ZjJmNTE0NGVhNTQ5ZDI4MjExZWE1OGZhYTcwZWJmNGMxZTY2NWMxZmU5YjUnLFxuICAgICAgICAnMjA0YjVkNmY4NDgyMmMzMDdlNGI0YTcxNDA3MzdhZWMyM2ZjNjNiNjViMzVmODZhMTAwMjZkYmQyZDg2NGU2YidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdjNDE5MTYzNjVhYmIyYjVkMDkxOTJmNWYyZGJlYWZlYzIwOGYwMjBmMTI1NzBhMTg0ZGJhZGMzZTU4NTk1OTk3JyxcbiAgICAgICAgJzRmMTQzNTFkMDA4N2VmYTQ5ZDI0NWIzMjg5ODQ5ODlkNWNhZjk0NTBmMzRiZmMwZWQxNmU5NmI1OGZhOTkxMydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4NDFkNjA2M2E1ODZmYTQ3NWE3MjQ2MDRkYTAzYmM1YjkyYTJlMGQyZTBhMzZhY2ZlNGM3M2E1NTE0NzQyODgxJyxcbiAgICAgICAgJzczODY3ZjU5YzA2NTllODE5MDRmOWExYzc1NDM2OThlNjI1NjJkNjc0NGMxNjljZTdhMzZkZTAxYThkNjE1NCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc1ZTk1YmIzOTlhNjk3MWQzNzYwMjY5NDdmODliZGUyZjI4MmIzMzgxMDkyOGJlNGRlZDExMmFjNGQ3MGUyMGQ1JyxcbiAgICAgICAgJzM5ZjIzZjM2NjgwOTA4NWJlZWJmYzcxMTgxMzEzNzc1YTk5YzlhZWQ3ZDhiYTM4YjE2MTM4NGM3NDYwMTI4NjUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzZlNDY0MWE1Mzk0OGZkNDc2YzM5ZjhhOTlmZDk3NGU1ZWMwNzU2NGI1MzE1ZDhiZjk5NDcxYmNhMGVmMmY2NicsXG4gICAgICAgICdkMjQyNGIxYjFhYmU0ZWI4MTY0MjI3YjA4NWM5YWE5NDU2ZWExMzQ5M2ZkNTYzZTA2ZmQ1MWNmNTY5NGM3OGZjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzMzNjU4MWVhN2JmYmJiMjkwYzE5MWEyZjUwN2E0MWNmNTY0Mzg0MjE3MGU5MTRmYWVhYjI3YzJjNTc5ZjcyNicsXG4gICAgICAgICdlYWQxMjE2ODU5NWZlMWJlOTkyNTIxMjliNmU1NmIzMzkxZjdhYjE0MTBjZDFlMGVmM2RjZGNhYmQyZmRhMjI0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzhhYjg5ODE2ZGFkZmQ2YjZhMWYyNjM0ZmNmMDBlYzg0MDM3ODEwMjVlZDY4OTBjNDg0OTc0MjcwNmJkNDNlZGUnLFxuICAgICAgICAnNmZkY2VmMDlmMmY2ZDBhMDQ0ZTY1NGFlZjYyNDEzNmY1MDNkNDU5YzNlODk4NDU4NThhNDdhOTEyOWNkZDI0ZSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxZTMzZjFhNzQ2YzljNTc3ODEzMzM0NGQ5Mjk5ZmNhYTIwYjA5MzhlOGFjZmYyNTQ0YmI0MDI4NGI4YzVmYjk0JyxcbiAgICAgICAgJzYwNjYwMjU3ZGQxMWIzYWE5YzhlZDYxOGQyNGVkZmYyMzA2ZDMyMGYxZDAzMDEwZTMzYTdkMjA1N2YzYjNiNidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4NWI3YzFkY2IzY2VjMWI3ZWU3ZjMwZGVkNzlkZDIwYTBlZDFmNGNjMThjYmNmY2ZhNDEwMzYxZmQ4ZjA4ZjMxJyxcbiAgICAgICAgJzNkOThhOWNkZDAyNmRkNDNmMzkwNDhmMjVhODg0N2Y0ZmNhZmFkMTg5NWQ3YTYzM2M2ZmVkM2MzNWU5OTk1MTEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMjlkZjlmYmQ4ZDllNDY1MDkyNzVmNGIxMjVkNmQ0NWQ3ZmJlOWEzYjg3OGE3YWY4NzJhMjgwMDY2MWFjNWY1MScsXG4gICAgICAgICdiNGM0ZmU5OWM3NzVhNjA2ZTJkODg2MjE3OTEzOWZmZGE2MWRjODYxYzAxOWU1NWNkMjg3NmViMmEyN2Q4NGInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYTBiMWNhZTA2YjBhODQ3YTNmZWE2ZTY3MWFhZjhhZGZkZmU1OGNhMmY3NjgxMDVjODA4MmIyZTQ0OWZjZTI1MicsXG4gICAgICAgICdhZTQzNDEwMmVkZGUwOTU4ZWM0YjE5ZDkxN2E2YTI4ZTZiNzJkYTE4MzRhZmYwZTY1MGYwNDk1MDNhMjk2Y2YyJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzRlOGNlYWZiOWIzZTlhMTM2ZGM3ZmY2N2U4NDAyOTViNDk5ZGZiM2IyMTMzZTRiYTExM2YyZTRjMGUxMjFlNScsXG4gICAgICAgICdjZjIxNzQxMThjOGI2ZDdhNGI0OGY2ZDUzNGNlNWM3OTQyMmMwODZhNjM0NjA1MDJiODI3Y2U2MmEzMjY2ODNjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2QyNGE0NGUwNDdlMTliNmY1YWZiODFjN2NhMmY2OTA4MGE1MDc2Njg5YTAxMDkxOWY0MjcyNWMyYjc4OWEzM2InLFxuICAgICAgICAnNmZiOGQ1NTkxYjQ2NmY4ZmM2M2RiNTBmMWMwZjFjNjkwMTNmOTk2ODg3YjgyNDRkMmNkZWM0MTdhZmVhOGZhMydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlYTAxNjA2YTdhNmM5Y2RkMjQ5ZmRmY2ZhY2I5OTU4NDAwMWVkZDI4YWJiYWI3N2I1MTA0ZTk4ZThlM2IzNWQ0JyxcbiAgICAgICAgJzMyMmFmNDkwOGM3MzEyYjBjZmJmZTM2OWY3YTdiM2NkYjdkNDQ5NGJjMjgyMzcwMGNmZDY1MjE4OGEzZWE5OGQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYWY4YWRkYmYyYjY2MWM4YTZjNjMyODY1NWViOTY2NTEyNTIwMDdkOGM1ZWEzMWJlNGFkMTk2ZGU4Y2UyMTMxZicsXG4gICAgICAgICc2NzQ5ZTY3YzAyOWI4NWY1MmEwMzRlYWZkMDk2ODM2YjI1MjA4MTg2ODBlMjZhYzhmM2RmYmNkYjcxNzQ5NzAwJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2UzYWUxOTc0NTY2Y2EwNmNjNTE2ZDQ3ZTBmYjE2NWE2NzRhM2RhYmNmY2ExNWU3MjJmMGUzNDUwZjQ1ODg5JyxcbiAgICAgICAgJzJhZWFiZTdlNDUzMTUxMDExNjIxN2YwN2JmNGQwNzMwMGRlOTdlNDg3NGY4MWY1MzM0MjBhNzJlZWIwYmQ2YTQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNTkxZWUzNTUzMTNkOTk3MjFjZjY5OTNmZmVkMWUzZTMwMTk5M2ZmM2VkMjU4ODAyMDc1ZWE4Y2VkMzk3ZTI0NicsXG4gICAgICAgICdiMGVhNTU4YTExM2MzMGJlYTYwZmM0Nzc1NDYwYzc5MDFmZjBiMDUzZDI1Y2EyYmRlZWU5OGYxYTRiZTVkMTk2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzExMzk2ZDU1ZmRhNTRjNDlmMTlhYTk3MzE4ZDhkYTYxZmE4NTg0ZTQ3YjA4NDk0NTA3N2NmMDMyNTViNTI5ODQnLFxuICAgICAgICAnOTk4Yzc0YThjZDQ1YWMwMTI4OWQ1ODMzYTdiZWI0NzQ0ZmY1MzZiMDFiMjU3YmU0YzU3NjdiZWE5M2VhNTdhNCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczYzVkMmExYmEzOWM1YTE3OTAwMDA3MzhjOWUwYzQwYjhkY2RmZDU0Njg3NTRiNjQwNTU0MDE1N2UwMTdhYTdhJyxcbiAgICAgICAgJ2IyMjg0Mjc5OTk1YTM0ZTJmOWQ0ZGU3Mzk2ZmMxOGI4MGY5YjhiOWZkZDI3MGY2NjYxZjc5Y2E0YzgxYmQyNTcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnY2M4NzA0YjhhNjBhMGRlZmEzYTk5YTcyOTlmMmU5YzNmYmMzOTVhZmIwNGFjMDc4NDI1ZWY4YTE3OTNjYzAzMCcsXG4gICAgICAgICdiZGQ0NjAzOWZlZWQxNzg4MWQxZTA4NjJkYjM0N2Y4Y2YzOTViNzRmYzRiY2RjNGU5NDBiNzRlM2FjMWYxYjEzJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2M1MzNlNGY3ZWE4NTU1YWFjZDk3NzdhYzVjYWQyOWI5N2RkNGRlZmNjYzUzZWU3ZWEyMDQxMTliMjg4OWIxOTcnLFxuICAgICAgICAnNmYwYTI1NmJjNWVmZGY0MjlhMmZiNjI0MmYxYTQzYTJkOWI5MjViYjRhNGIzYTI2YmI4ZTBmNDVlYjU5NjA5NidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdjMTRmOGYyY2NiMjdkNmYxMDlmNmQwOGQwM2NjOTZhNjliYThjMzRlZWMwN2JiY2Y1NjZkNDhlMzNkYTY1OTMnLFxuICAgICAgICAnYzM1OWQ2OTIzYmIzOThmN2ZkNDQ3M2UxNmZlMWMyODQ3NWI3NDBkZDA5ODA3NWU2YzBlODY0OTExM2RjM2EzOCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhNmNiYzMwNDZiYzZhNDUwYmFjMjQ3ODlmYTE3MTE1YTRjOTczOWVkNzVmOGYyMWNlNDQxZjcyZTBiOTBlNmVmJyxcbiAgICAgICAgJzIxYWU3ZjQ2ODBlODg5YmIxMzA2MTllMmMwZjk1YTM2MGNlYjU3M2M3MDYwMzEzOTg2MmFmZDYxN2ZhOWI5ZidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczNDdkNmQ5YTAyYzQ4OTI3ZWJmYjg2YzEzNTliMWNhZjEzMGEzYzAyNjdkMTFjZTYzNDRiMzlmOTlkNDNjYzM4JyxcbiAgICAgICAgJzYwZWE3ZjYxYTM1MzUyNGQxYzk4N2Y2ZWNlYzkyZjA4NmQ1NjVhYjY4Nzg3MGNiMTI2ODlmZjFlMzFjNzQ0NDgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZGE2NTQ1ZDIxODFkYjhkOTgzZjdkY2IzNzVlZjU4NjZkNDdjNjdiMWJmMzFjOGNmODU1ZWY3NDM3YjcyNjU2YScsXG4gICAgICAgICc0OWI5NjcxNWFiNjg3OGE3OWU3OGYwN2NlNTY4MGM1ZDY2NzMwNTFiNDkzNWJkODk3ZmVhODI0Yjc3ZGMyMDhhJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2M0MDc0N2NjOWQwMTJjYjFhMTNiODE0ODMwOWM2ZGU3ZWMyNWQ2OTQ1ZDY1NzE0NmI5ZDU5OTRiOGZlYjExMTEnLFxuICAgICAgICAnNWNhNTYwNzUzYmUyYTEyZmM2ZGU2Y2FmMmNiNDg5NTY1ZGI5MzYxNTZiOTUxNGUxYmI1ZTgzMDM3ZTBmYTJkNCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc0ZTQyYzhlYzgyYzk5Nzk4Y2NmM2E2MTBiZTg3MGU3ODMzOGM3ZjcxMzM0OGJkMzRjODIwM2VmNDAzN2YzNTAyJyxcbiAgICAgICAgJzc1NzFkNzRlZTVlMGZiOTJhN2E4YjMzYTA3NzgzMzQxYTU0OTIxNDRjYzU0YmNjNDBhOTQ0NzM2OTM2MDY0MzcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzc3NWFiNzA4OWJjNmFmODIzYWJhMmUxYWY3MGIyMzZkMjUxY2FkYjBjODY3NDMyODc1MjJhMWIzYjBkZWRlYScsXG4gICAgICAgICdiZTUyZDEwN2JjZmEwOWQ4YmNiOTczNmE4MjhjZmE3ZmFjOGRiMTdiZjdhNzZhMmM0MmFkOTYxNDA5MDE4Y2Y3J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2NlZTMxY2JmN2UzNGVjMzc5ZDk0ZmI4MTRkM2Q3NzVhZDk1NDU5NWQxMzE0YmE4ODQ2OTU5ZTNlODJmNzRlMjYnLFxuICAgICAgICAnOGZkNjRhMTRjMDZiNTg5YzI2Yjk0N2FlMmJjZjZiZmEwMTQ5ZWYwYmUxNGVkNGQ4MGY0NDhhMDFjNDNiMWM2ZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdiNGY5ZWFlYTA5YjY5MTc2MTlmNmVhNmE0ZWI1NDY0ZWZkZGI1OGZkNDViMWViZWZjZGMxYTAxZDA4YjQ3OTg2JyxcbiAgICAgICAgJzM5ZTVjOTkyNWI1YTU0YjA3NDMzYTRmMThjNjE3MjZmOGJiMTMxYzAxMmNhNTQyZWIyNGE4YWMwNzIwMDY4MmEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDQyNjNkZmMzZDJkZjkyM2EwMTc5YTQ4OTY2ZDMwY2U4NGUyNTE1YWZjM2RjY2MxYjc3OTA3NzkyZWJjYzYwZScsXG4gICAgICAgICc2MmRmYWYwN2EwZjc4ZmViMzBlMzBkNjI5NTg1M2NlMTg5ZTEyNzc2MGFkNmNmN2ZhZTE2NGUxMjJhMjA4ZDU0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzQ4NDU3NTI0ODIwZmE2NWE0ZjhkMzVlYjY5MzA4NTdjMDAzMmFjYzBhNGEyZGU0MjIyMzNlZWRhODk3NjEyYzQnLFxuICAgICAgICAnMjVhNzQ4YWIzNjc5NzlkOTg3MzNjMzhhMWZhMWMyZTdkYzZjYzA3ZGIyZDYwYTlhZTdhNzZhYWE0OWJkMGY3NydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkZmVlZWYxODgxMTAxZjJjYjExNjQ0ZjNhMmFmZGZjMjA0NWUxOTkxOTE1MjkyM2YzNjdhMTc2N2MxMWNjZWRhJyxcbiAgICAgICAgJ2VjZmI3MDU2Y2YxZGUwNDJmOTQyMGJhYjM5Njc5M2MwYzM5MGJkZTc0YjRiYmRmZjE2YTgzYWUwOWE5YTc1MTcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNmQ3ZWY2YjE3NTQzZjgzNzNjNTczZjQ0ZTFmMzg5ODM1ZDg5YmNiYzYwNjJjZWQzNmM4MmRmODNiOGZhZTg1OScsXG4gICAgICAgICdjZDQ1MGVjMzM1NDM4OTg2ZGZlZmExMGM1N2ZlYTliY2M1MjFhMDk1OWIyZDgwYmJmNzRiMTkwZGNhNzEyZDEwJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2U3NTYwNWQ1OTEwMmE1YTI2ODQ1MDBkM2I5OTFmMmUzZjNjODhiOTMyMjU1NDcwMzVhZjI1YWY2NmUwNDU0MWYnLFxuICAgICAgICAnZjVjNTQ3NTRhOGY3MWVlNTQwYjliNDg3Mjg0NzNlMzE0ZjcyOWFjNTMwOGIwNjkzODM2MDk5MGUyYmZhZDEyNSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlYjk4NjYwZjRjNGRmYWEwNmEyYmU0NTNkNTAyMGJjOTlhMGMyZTYwYWJlMzg4NDU3ZGQ0M2ZlZmIxZWQ2MjBjJyxcbiAgICAgICAgJzZjYjlhODg3NmQ5Y2I4NTIwNjA5YWYzYWRkMjZjZDIwYTBhN2NkOGE5NDExMTMxY2U4NWY0NDEwMDA5OTIyM2UnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMTNlODdiMDI3ZDg1MTRkMzU5MzlmMmU2ODkyYjE5OTIyMTU0NTk2OTQxODg4MzM2ZGMzNTYzZTNiOGRiYTk0MicsXG4gICAgICAgICdmZWY1YTNjNjgwNTlhNmRlYzVkNjI0MTE0YmYxZTkxYWFjMmI5ZGE1NjhkNmFiZWIyNTcwZDU1NjQ2YjhhZGYxJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2VlMTYzMDI2ZTlmZDZmZTAxN2MzOGYwNmE1YmU2ZmMxMjU0MjRiMzcxY2UyNzA4ZTdiZjQ0OTE2OTFlNTc2NGEnLFxuICAgICAgICAnMWFjYjI1MGYyNTVkZDYxYzQzZDk0Y2NjNjcwZDBmNThmNDlhZTNmYTE1Yjk2NjIzZTU0MzBkYTBhZDZjNjJiMidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdiMjY4ZjVlZjlhZDUxZTRkNzhkZTNhNzUwYzJkYzg5YjFlNjI2ZDQzNTA1ODY3OTk5OTMyZTVkYjMzYWYzZDgwJyxcbiAgICAgICAgJzVmMzEwZDRiM2M5OWI5ZWJiMTlmNzdkNDFjMWRlZTAxOGNmMGQzNGZkNDE5MTYxNDAwM2U5NDVhMTIxNmU0MjMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZmYwN2YzMTE4YTlkZjAzNWU5ZmFkODVlYjZjN2JmZTQyYjAyZjAxY2E5OWNlZWEzYmY3ZmZkYmE5M2M0NzUwZCcsXG4gICAgICAgICc0MzgxMzZkNjAzZTg1OGEzYTVjNDQwYzM4ZWNjYmFkZGMxZDI5NDIxMTRlMmVkZGQ0NzQwZDA5OGNlZDFmMGQ4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzhkOGI5ODU1YzdjMDUyYTM0MTQ2ZmQyMGZmYjY1OGJlYTRiOWY2OWUwZDgyNWViZWMxNmU4YzNjZTJiNTI2YTEnLFxuICAgICAgICAnY2RiNTU5ZWVkYzJkNzlmOTI2YmFmNDRmYjg0ZWE0ZDQ0YmNmNTBmZWU1MWQ3Y2ViMzBlMmU3ZjQ2MzAzNjc1OCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc1MmRiMGI1Mzg0ZGZiZjA1YmZhOWQ0NzJkN2FlMjZkZmU0Yjg1MWNlY2E5MWIxZWJhNTQyNjMxODBkYTMyYjYzJyxcbiAgICAgICAgJ2MzYjk5N2QwNTBlZTVkNDIzZWJhZjY2YTZkYjlmNTdiMzE4MGM5MDI4NzU2NzlkZTkyNGI2OWQ4NGE3YjM3NSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlNjJmOTQ5MGQzZDUxZGE2Mzk1ZWZkMjRlODA5MTljYzdkMGYyOWMzZjNmYTQ4YzZmZmY1NDNiZWNiZDQzMzUyJyxcbiAgICAgICAgJzZkODlhZDdiYTQ4NzZiMGIyMmMyY2EyODBjNjgyODYyZjM0MmM4NTkxZjFkYWY1MTcwZTA3YmZkOWNjYWZhN2QnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnN2YzMGVhMjQ3NmIzOTliNDk1NzUwOWM4OGY3N2QwMTkxYWZhMmZmNWNiN2IxNGZkNmQ4ZTdkNjVhYWFiMTE5MycsXG4gICAgICAgICdjYTVlZjdkNGIyMzFjOTRjM2IxNTM4OWE1ZjYzMTFlOWRhZmY3YmI2N2IxMDNlOTg4MGVmNGJmZjYzN2FjYWVjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzUwOThmZjFlMWQ5ZjE0ZmI0NmEyMTBmYWRhNmM5MDNmZWYwZmI3YjRhMWRkMWQ5YWM2MGEwMzYxODAwYjdhMDAnLFxuICAgICAgICAnOTczMTE0MWQ4MWZjOGY4MDg0ZDM3YzZlNzU0MjAwNmIzZWUxYjQwZDYwZGZlNTM2MmE1YjEzMmZkMTdkZGMwJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzMyYjc4YzdkZTllZTUxMmE3Mjg5NWJlNmI5Y2JlZmE2ZTJmM2M0Y2NjZTQ0NWM5NmI5ZjJjODFlMjc3OGFkNTgnLFxuICAgICAgICAnZWUxODQ5ZjUxM2RmNzFlMzJlZmMzODk2ZWUyODI2MGM3M2JiODA1NDdhZTIyNzViYTQ5NzIzNzc5NGM4NzUzYydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlMmNiNzRmZGRjOGU5ZmJjZDA3NmVlZjJhN2M3MmIwY2UzN2Q1MGYwODI2OWRmYzA3NGI1ODE1NTA1NDdhNGY3JyxcbiAgICAgICAgJ2QzYWEyZWQ3MWM5ZGQyMjQ3YTYyZGYwNjI3MzZlYjBiYWRkZWE5ZTM2MTIyZDJiZTg2NDFhYmNiMDA1Y2M0YTQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnODQzODQ0NzU2NmQ0ZDdiZWRhZGMyOTk0OTZhYjM1NzQyNjAwOWEzNWYyMzVjYjE0MWJlMGQ5OWNkMTBhZTNhOCcsXG4gICAgICAgICdjNGUxMDIwOTE2OTgwYTRkYTVkMDFhYzVlNmFkMzMwNzM0ZWYwZDc5MDY2MzFjNGYyMzkwNDI2YjJlZGQ3OTFmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzQxNjJkNDg4Yjg5NDAyMDM5YjU4NGM2ZmM2YzMwODg3MDU4N2Q5YzQ2ZjY2MGI4NzhhYjY1YzgyYzcxMWQ2N2UnLFxuICAgICAgICAnNjcxNjNlOTAzMjM2Mjg5Zjc3NmYyMmMyNWZiOGEzYWZjMTczMmYyYjg0YjRlOTVkYmRhNDdhZTVhMDg1MjY0OSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczZmFkM2ZhODRjYWYwZjM0ZjBmODliZmQyZGNmNTRmYzE3NWQ3NjdhZWMzZTUwNjg0ZjNiYTRhNGJmNWY2ODNkJyxcbiAgICAgICAgJ2NkMWJjN2NiNmNjNDA3YmIyZjBjYTY0N2M3MThhNzMwY2Y3MTg3MmU3ZDBkMmE1M2ZhMjBlZmNkZmU2MTgyNidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc2NzRmMjYwMGEzMDA3YTAwNTY4YzFhN2NlMDVkMDgxNmMxZmI4NGJmMTM3MDc5OGYxYzY5NTMyZmFlYjFhODZiJyxcbiAgICAgICAgJzI5OWQyMWY5NDEzZjMzYjNlZGY0M2IyNTcwMDQ1ODBiNzBkYjU3ZGEwYjE4MjI1OWUwOWVlY2M2OWUwZDM4YTUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDMyZjRkYTU0YWRlNzRhYmI4MWI4MTVhZDFmYjNiMjYzZDgyZDZjNjkyNzE0YmNmZjg3ZDI5YmQ1ZWU5ZjA4ZicsXG4gICAgICAgICdmOTQyOWU3MzhiOGU1M2I5NjhlOTkwMTZjMDU5NzA3NzgyZTE0ZjQ1MzUzNTlkNTgyZmM0MTY5MTBiM2VlYTg3J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzMwZTRlNjcwNDM1Mzg1NTU2ZTU5MzY1NzEzNTg0NWQzNmZiYjY5MzFmNzJiMDhjYjFlZDk1NGYxZTNjZTNmZjYnLFxuICAgICAgICAnNDYyZjliY2U2MTk4OTg2Mzg0OTkzNTAxMTNiYmM5YjEwYTg3OGQzNWRhNzA3NDBkYzY5NWE1NTllYjg4ZGI3YidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdiZTIwNjIwMDNjNTFjYzMwMDQ2ODI5MDQzMzBlNGRlZTdmM2RjZDEwYjAxZTU4MGJmMTk3MWIwNGQ0Y2FkMjk3JyxcbiAgICAgICAgJzYyMTg4YmM0OWQ2MWU1NDI4NTczZDQ4YTc0ZTFjNjU1YjFjNjEwOTA5MDU2ODJhMGQ1NTU4ZWQ3MmRjY2I5YmMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOTMxNDQ0MjNhY2UzNDUxZWQyOWUwZmI5YWMyYWYyMTFjYjZlODRhNjAxZGY1OTkzYzQxOTg1OWZmZjVkZjA0YScsXG4gICAgICAgICc3YzEwZGZiMTY0YzM0MjVmNWM3MWEzZjlkNzk5MjAzOGYxMDY1MjI0ZjcyYmI5ZDFkOTAyYTZkMTMwMzdiNDdjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2IwMTVmODA0NGY1ZmNiZGNmMjFjYTI2ZDZjMzRmYjgxOTc4MjkyMDVjN2I3ZDJhN2NiNjY0MThjMTU3YjExMmMnLFxuICAgICAgICAnYWI4YzFlMDg2ZDA0ZTgxMzc0NGE2NTViMmRmOGQ1ZjgzYjNjZGM2ZmFhMzA4OGMxZDNhZWExNDU0ZTNhMWQ1ZidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkNWU5ZTFkYTY0OWQ5N2Q4OWU0ODY4MTE3YTQ2NWEzYTRmOGExOGRlNTdhMTQwZDM2YjNmMmFmMzQxYTIxYjUyJyxcbiAgICAgICAgJzRjYjA0NDM3ZjM5MWVkNzMxMTFhMTNjYzFkNGRkMGRiMTY5MzQ2NWMyMjQwNDgwZDg5NTVlODU5MmYyNzQ0N2EnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDNhZTQxMDQ3ZGQ3Y2EwNjVkYmY4ZWQ3N2I5OTI0Mzk5ODMwMDVjZDcyZTE2ZDZmOTk2YTUzMTZkMzY5NjZiYicsXG4gICAgICAgICdiZDFhZWIyMWFkMjJlYmIyMmExMGYwMzAzNDE3YzZkOTY0ZjhjZGQ3ZGYwYWNhNjE0YjEwZGMxNGQxMjVhYzQ2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzQ2M2UyNzYzZDg4NWY5NThmYzY2Y2RkMjI4MDBmMGE0ODcxOTdkMGE4MmUzNzdiNDlmODBhZjg3Yzg5N2IwNjUnLFxuICAgICAgICAnYmZlZmFjZGIwZTVkMGZkN2RmM2EzMTFhOTRkZTA2MmIyNmI4MGM2MWZiYzk3NTA4Yjc5OTkyNjcxZWY3Y2E3ZidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3OTg1ZmRmZDEyN2MwNTY3YzZmNTNlYzFiYjYzZWMzMTU4ZTU5N2M0MGJmZTc0N2M4M2NkZGZjOTEwNjQxOTE3JyxcbiAgICAgICAgJzYwM2MxMmRhZjNkOTg2MmVmMmIyNWZlMWRlMjg5YWVkMjRlZDI5MWUwZWM2NzA4NzAzYTViZDU2N2YzMmVkMDMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzRhMWFkNmI1Zjc2ZTM5ZGIyZGQyNDk0MTBlYWM3Zjk5ZTc0YzU5Y2I4M2QyZDBlZDVmZjE1NDNkYTc3MDNlOScsXG4gICAgICAgICdjYzYxNTdlZjE4YzljNjNjZDYxOTNkODM2MzFiYmVhMDA5M2UwOTY4OTQyZThjMzNkNTczN2ZkNzkwZTBkYjA4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzMwNjgyYTUwNzAzMzc1ZjYwMmQ0MTY2NjRiYTE5YjdmYzliYWI0MmM3Mjc0NzQ2M2E3MWQwODk2YjIyZjZkYTMnLFxuICAgICAgICAnNTUzZTA0ZjZiMDE4YjRmYTZjOGYzOWU3ZjMxMWQzMTc2MjkwZDBlMGYxOWNhNzNmMTc3MTRkOTk3N2EyMmZmOCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc5ZTIxNThmMGQ3YzBkNWYyNmMzNzkxZWZlZmE3OTU5NzY1NGU3YTJiMjQ2NGY1MmIxZWU2YzEzNDc3NjllZjU3JyxcbiAgICAgICAgJzcxMmZjZGQxYjkwNTNmMDkwMDNhMzQ4MWZhNzc2MmU5ZmZkN2M4ZWYzNWEzODUwOWUyZmJmMjYyOTAwODM3MydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxNzZlMjY5ODlhNDNjOWNmZWJhNDAyOWMyMDI1MzhjMjgxNzJlNTY2ZTNjNGZjZTczMjI4NTdmM2JlMzI3ZDY2JyxcbiAgICAgICAgJ2VkOGNjOWQwNGIyOWViODc3ZDI3MGI0ODc4ZGM0M2MxOWFlZmQzMWY0ZWVlMDllZTdiNDc4MzRjMWZhNGIxYzMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzVkNDZlZmVhMzc3MWU2ZTY4YWJiODlhMTNhZDc0N2VjZjE4OTIzOTNkZmM0ZjFiNzAwNDc4OGM1MDM3NGRhOCcsXG4gICAgICAgICc5ODUyMzkwYTk5NTA3Njc5ZmQwYjg2ZmQyYjM5YTg2OGQ3ZWZjMjIxNTEzNDZlMWEzY2E0NzI2NTg2YTZiZWQ4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzgwOWEyMGM2N2Q2NDkwMGZmYjY5OGM0YzgyNWY2ZDVmMjMxMGZiMDQ1MWM4NjkzNDViNzMxOWY2NDU2MDU3MjEnLFxuICAgICAgICAnOWU5OTQ5ODBkOTkxN2UyMmI3NmIwNjE5MjdmYTA0MTQzZDA5NmNjYzU0OTYzZTZhNWViZmE1ZjNmOGUyODZjMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxYjM4OTAzYTQzZjdmMTE0ZWQ0NTAwYjRlYWM3MDgzZmRlZmVjZTFjZjI5YzYzNTI4ZDU2MzQ0NmY5NzJjMTgwJyxcbiAgICAgICAgJzQwMzZlZGM5MzFhNjBhZTg4OTM1M2Y3N2ZkNTNkZTRhMjcwOGIyNmI2ZjVkYTcyYWQzMzk0MTE5ZGFmNDA4ZjknXG4gICAgICBdXG4gICAgXVxuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSBleHBvcnRzO1xudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcblxudXRpbHMuYXNzZXJ0ID0gZnVuY3Rpb24gYXNzZXJ0KHZhbCwgbXNnKSB7XG4gIGlmICghdmFsKVxuICAgIHRocm93IG5ldyBFcnJvcihtc2cgfHwgJ0Fzc2VydGlvbiBmYWlsZWQnKTtcbn07XG5cbmZ1bmN0aW9uIHRvQXJyYXkobXNnLCBlbmMpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkobXNnKSlcbiAgICByZXR1cm4gbXNnLnNsaWNlKCk7XG4gIGlmICghbXNnKVxuICAgIHJldHVybiBbXTtcbiAgdmFyIHJlcyA9IFtdO1xuICBpZiAodHlwZW9mIG1zZyAhPT0gJ3N0cmluZycpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKylcbiAgICAgIHJlc1tpXSA9IG1zZ1tpXSB8IDA7XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuICBpZiAoIWVuYykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgYyA9IG1zZy5jaGFyQ29kZUF0KGkpO1xuICAgICAgdmFyIGhpID0gYyA+PiA4O1xuICAgICAgdmFyIGxvID0gYyAmIDB4ZmY7XG4gICAgICBpZiAoaGkpXG4gICAgICAgIHJlcy5wdXNoKGhpLCBsbyk7XG4gICAgICBlbHNlXG4gICAgICAgIHJlcy5wdXNoKGxvKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoZW5jID09PSAnaGV4Jykge1xuICAgIG1zZyA9IG1zZy5yZXBsYWNlKC9bXmEtejAtOV0rL2lnLCAnJyk7XG4gICAgaWYgKG1zZy5sZW5ndGggJSAyICE9PSAwKVxuICAgICAgbXNnID0gJzAnICsgbXNnO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSArPSAyKVxuICAgICAgcmVzLnB1c2gocGFyc2VJbnQobXNnW2ldICsgbXNnW2kgKyAxXSwgMTYpKTtcbiAgfVxuICByZXR1cm4gcmVzO1xufVxudXRpbHMudG9BcnJheSA9IHRvQXJyYXk7XG5cbmZ1bmN0aW9uIHplcm8yKHdvcmQpIHtcbiAgaWYgKHdvcmQubGVuZ3RoID09PSAxKVxuICAgIHJldHVybiAnMCcgKyB3b3JkO1xuICBlbHNlXG4gICAgcmV0dXJuIHdvcmQ7XG59XG51dGlscy56ZXJvMiA9IHplcm8yO1xuXG5mdW5jdGlvbiB0b0hleChtc2cpIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKylcbiAgICByZXMgKz0gemVybzIobXNnW2ldLnRvU3RyaW5nKDE2KSk7XG4gIHJldHVybiByZXM7XG59XG51dGlscy50b0hleCA9IHRvSGV4O1xuXG51dGlscy5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUoYXJyLCBlbmMpIHtcbiAgaWYgKGVuYyA9PT0gJ2hleCcpXG4gICAgcmV0dXJuIHRvSGV4KGFycik7XG4gIGVsc2VcbiAgICByZXR1cm4gYXJyO1xufTtcblxuLy8gUmVwcmVzZW50IG51bSBpbiBhIHctTkFGIGZvcm1cbmZ1bmN0aW9uIGdldE5BRihudW0sIHcpIHtcbiAgdmFyIG5hZiA9IFtdO1xuICB2YXIgd3MgPSAxIDw8ICh3ICsgMSk7XG4gIHZhciBrID0gbnVtLmNsb25lKCk7XG4gIHdoaWxlIChrLmNtcG4oMSkgPj0gMCkge1xuICAgIHZhciB6O1xuICAgIGlmIChrLmlzT2RkKCkpIHtcbiAgICAgIHZhciBtb2QgPSBrLmFuZGxuKHdzIC0gMSk7XG4gICAgICBpZiAobW9kID4gKHdzID4+IDEpIC0gMSlcbiAgICAgICAgeiA9ICh3cyA+PiAxKSAtIG1vZDtcbiAgICAgIGVsc2VcbiAgICAgICAgeiA9IG1vZDtcbiAgICAgIGsuaXN1Ym4oeik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHogPSAwO1xuICAgIH1cbiAgICBuYWYucHVzaCh6KTtcblxuICAgIC8vIE9wdGltaXphdGlvbiwgc2hpZnQgYnkgd29yZCBpZiBwb3NzaWJsZVxuICAgIHZhciBzaGlmdCA9IChrLmNtcG4oMCkgIT09IDAgJiYgay5hbmRsbih3cyAtIDEpID09PSAwKSA/ICh3ICsgMSkgOiAxO1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgc2hpZnQ7IGkrKylcbiAgICAgIG5hZi5wdXNoKDApO1xuICAgIGsuaXVzaHJuKHNoaWZ0KTtcbiAgfVxuXG4gIHJldHVybiBuYWY7XG59XG51dGlscy5nZXROQUYgPSBnZXROQUY7XG5cbi8vIFJlcHJlc2VudCBrMSwgazIgaW4gYSBKb2ludCBTcGFyc2UgRm9ybVxuZnVuY3Rpb24gZ2V0SlNGKGsxLCBrMikge1xuICB2YXIganNmID0gW1xuICAgIFtdLFxuICAgIFtdXG4gIF07XG5cbiAgazEgPSBrMS5jbG9uZSgpO1xuICBrMiA9IGsyLmNsb25lKCk7XG4gIHZhciBkMSA9IDA7XG4gIHZhciBkMiA9IDA7XG4gIHdoaWxlIChrMS5jbXBuKC1kMSkgPiAwIHx8IGsyLmNtcG4oLWQyKSA+IDApIHtcblxuICAgIC8vIEZpcnN0IHBoYXNlXG4gICAgdmFyIG0xNCA9IChrMS5hbmRsbigzKSArIGQxKSAmIDM7XG4gICAgdmFyIG0yNCA9IChrMi5hbmRsbigzKSArIGQyKSAmIDM7XG4gICAgaWYgKG0xNCA9PT0gMylcbiAgICAgIG0xNCA9IC0xO1xuICAgIGlmIChtMjQgPT09IDMpXG4gICAgICBtMjQgPSAtMTtcbiAgICB2YXIgdTE7XG4gICAgaWYgKChtMTQgJiAxKSA9PT0gMCkge1xuICAgICAgdTEgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgbTggPSAoazEuYW5kbG4oNykgKyBkMSkgJiA3O1xuICAgICAgaWYgKChtOCA9PT0gMyB8fCBtOCA9PT0gNSkgJiYgbTI0ID09PSAyKVxuICAgICAgICB1MSA9IC1tMTQ7XG4gICAgICBlbHNlXG4gICAgICAgIHUxID0gbTE0O1xuICAgIH1cbiAgICBqc2ZbMF0ucHVzaCh1MSk7XG5cbiAgICB2YXIgdTI7XG4gICAgaWYgKChtMjQgJiAxKSA9PT0gMCkge1xuICAgICAgdTIgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgbTggPSAoazIuYW5kbG4oNykgKyBkMikgJiA3O1xuICAgICAgaWYgKChtOCA9PT0gMyB8fCBtOCA9PT0gNSkgJiYgbTE0ID09PSAyKVxuICAgICAgICB1MiA9IC1tMjQ7XG4gICAgICBlbHNlXG4gICAgICAgIHUyID0gbTI0O1xuICAgIH1cbiAgICBqc2ZbMV0ucHVzaCh1Mik7XG5cbiAgICAvLyBTZWNvbmQgcGhhc2VcbiAgICBpZiAoMiAqIGQxID09PSB1MSArIDEpXG4gICAgICBkMSA9IDEgLSBkMTtcbiAgICBpZiAoMiAqIGQyID09PSB1MiArIDEpXG4gICAgICBkMiA9IDEgLSBkMjtcbiAgICBrMS5pdXNocm4oMSk7XG4gICAgazIuaXVzaHJuKDEpO1xuICB9XG5cbiAgcmV0dXJuIGpzZjtcbn1cbnV0aWxzLmdldEpTRiA9IGdldEpTRjtcblxuZnVuY3Rpb24gY2FjaGVkUHJvcGVydHkob2JqLCBjb21wdXRlcikge1xuICB2YXIgbmFtZSA9IGNvbXB1dGVyLm5hbWU7XG4gIHZhciBrZXkgPSAnXycgKyBuYW1lO1xuICBvYmoucHJvdG90eXBlW25hbWVdID0gZnVuY3Rpb24gY2FjaGVkUHJvcGVydHkoKSB7XG4gICAgcmV0dXJuIHRoaXNba2V5XSAhPT0gdW5kZWZpbmVkID8gdGhpc1trZXldIDpcbiAgICAgICAgICAgdGhpc1trZXldID0gY29tcHV0ZXIuY2FsbCh0aGlzKTtcbiAgfTtcbn1cbnV0aWxzLmNhY2hlZFByb3BlcnR5ID0gY2FjaGVkUHJvcGVydHk7XG5cbmZ1bmN0aW9uIHBhcnNlQnl0ZXMoYnl0ZXMpIHtcbiAgcmV0dXJuIHR5cGVvZiBieXRlcyA9PT0gJ3N0cmluZycgPyB1dGlscy50b0FycmF5KGJ5dGVzLCAnaGV4JykgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzO1xufVxudXRpbHMucGFyc2VCeXRlcyA9IHBhcnNlQnl0ZXM7XG5cbmZ1bmN0aW9uIGludEZyb21MRShieXRlcykge1xuICByZXR1cm4gbmV3IEJOKGJ5dGVzLCAnaGV4JywgJ2xlJyk7XG59XG51dGlscy5pbnRGcm9tTEUgPSBpbnRGcm9tTEU7XG5cbiIsInZhciByO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJhbmQobGVuKSB7XG4gIGlmICghcilcbiAgICByID0gbmV3IFJhbmQobnVsbCk7XG5cbiAgcmV0dXJuIHIuZ2VuZXJhdGUobGVuKTtcbn07XG5cbmZ1bmN0aW9uIFJhbmQocmFuZCkge1xuICB0aGlzLnJhbmQgPSByYW5kO1xufVxubW9kdWxlLmV4cG9ydHMuUmFuZCA9IFJhbmQ7XG5cblJhbmQucHJvdG90eXBlLmdlbmVyYXRlID0gZnVuY3Rpb24gZ2VuZXJhdGUobGVuKSB7XG4gIHJldHVybiB0aGlzLl9yYW5kKGxlbik7XG59O1xuXG5pZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcpIHtcbiAgaWYgKHdpbmRvdy5jcnlwdG8gJiYgd2luZG93LmNyeXB0by5nZXRSYW5kb21WYWx1ZXMpIHtcbiAgICAvLyBNb2Rlcm4gYnJvd3NlcnNcbiAgICBSYW5kLnByb3RvdHlwZS5fcmFuZCA9IGZ1bmN0aW9uIF9yYW5kKG4pIHtcbiAgICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheShuKTtcbiAgICAgIHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGFycik7XG4gICAgICByZXR1cm4gYXJyO1xuICAgIH07XG4gIH0gZWxzZSBpZiAod2luZG93Lm1zQ3J5cHRvICYmIHdpbmRvdy5tc0NyeXB0by5nZXRSYW5kb21WYWx1ZXMpIHtcbiAgICAvLyBJRVxuICAgIFJhbmQucHJvdG90eXBlLl9yYW5kID0gZnVuY3Rpb24gX3JhbmQobikge1xuICAgICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KG4pO1xuICAgICAgd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcyhhcnIpO1xuICAgICAgcmV0dXJuIGFycjtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIC8vIE9sZCBqdW5rXG4gICAgUmFuZC5wcm90b3R5cGUuX3JhbmQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkIHlldCcpO1xuICAgIH07XG4gIH1cbn0gZWxzZSB7XG4gIC8vIE5vZGUuanMgb3IgV2ViIHdvcmtlclxuICB0cnkge1xuICAgIHZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnknICsgJ3B0bycpO1xuXG4gICAgUmFuZC5wcm90b3R5cGUuX3JhbmQgPSBmdW5jdGlvbiBfcmFuZChuKSB7XG4gICAgICByZXR1cm4gY3J5cHRvLnJhbmRvbUJ5dGVzKG4pO1xuICAgIH07XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBFbXVsYXRlIGNyeXB0byBBUEkgdXNpbmcgcmFuZHlcbiAgICBSYW5kLnByb3RvdHlwZS5fcmFuZCA9IGZ1bmN0aW9uIF9yYW5kKG4pIHtcbiAgICAgIHZhciByZXMgPSBuZXcgVWludDhBcnJheShuKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzLmxlbmd0aDsgaSsrKVxuICAgICAgICByZXNbaV0gPSB0aGlzLnJhbmQuZ2V0Qnl0ZSgpO1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9O1xuICB9XG59XG4iLCJ2YXIgaGFzaCA9IGV4cG9ydHM7XG5cbmhhc2gudXRpbHMgPSByZXF1aXJlKCcuL2hhc2gvdXRpbHMnKTtcbmhhc2guY29tbW9uID0gcmVxdWlyZSgnLi9oYXNoL2NvbW1vbicpO1xuaGFzaC5zaGEgPSByZXF1aXJlKCcuL2hhc2gvc2hhJyk7XG5oYXNoLnJpcGVtZCA9IHJlcXVpcmUoJy4vaGFzaC9yaXBlbWQnKTtcbmhhc2guaG1hYyA9IHJlcXVpcmUoJy4vaGFzaC9obWFjJyk7XG5cbi8vIFByb3h5IGhhc2ggZnVuY3Rpb25zIHRvIHRoZSBtYWluIG9iamVjdFxuaGFzaC5zaGExID0gaGFzaC5zaGEuc2hhMTtcbmhhc2guc2hhMjU2ID0gaGFzaC5zaGEuc2hhMjU2O1xuaGFzaC5zaGEyMjQgPSBoYXNoLnNoYS5zaGEyMjQ7XG5oYXNoLnNoYTM4NCA9IGhhc2guc2hhLnNoYTM4NDtcbmhhc2guc2hhNTEyID0gaGFzaC5zaGEuc2hhNTEyO1xuaGFzaC5yaXBlbWQxNjAgPSBoYXNoLnJpcGVtZC5yaXBlbWQxNjA7XG4iLCJ2YXIgaGFzaCA9IHJlcXVpcmUoJy4uL2hhc2gnKTtcbnZhciB1dGlscyA9IGhhc2gudXRpbHM7XG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xuXG5mdW5jdGlvbiBCbG9ja0hhc2goKSB7XG4gIHRoaXMucGVuZGluZyA9IG51bGw7XG4gIHRoaXMucGVuZGluZ1RvdGFsID0gMDtcbiAgdGhpcy5ibG9ja1NpemUgPSB0aGlzLmNvbnN0cnVjdG9yLmJsb2NrU2l6ZTtcbiAgdGhpcy5vdXRTaXplID0gdGhpcy5jb25zdHJ1Y3Rvci5vdXRTaXplO1xuICB0aGlzLmhtYWNTdHJlbmd0aCA9IHRoaXMuY29uc3RydWN0b3IuaG1hY1N0cmVuZ3RoO1xuICB0aGlzLnBhZExlbmd0aCA9IHRoaXMuY29uc3RydWN0b3IucGFkTGVuZ3RoIC8gODtcbiAgdGhpcy5lbmRpYW4gPSAnYmlnJztcblxuICB0aGlzLl9kZWx0YTggPSB0aGlzLmJsb2NrU2l6ZSAvIDg7XG4gIHRoaXMuX2RlbHRhMzIgPSB0aGlzLmJsb2NrU2l6ZSAvIDMyO1xufVxuZXhwb3J0cy5CbG9ja0hhc2ggPSBCbG9ja0hhc2g7XG5cbkJsb2NrSGFzaC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKG1zZywgZW5jKSB7XG4gIC8vIENvbnZlcnQgbWVzc2FnZSB0byBhcnJheSwgcGFkIGl0LCBhbmQgam9pbiBpbnRvIDMyYml0IGJsb2Nrc1xuICBtc2cgPSB1dGlscy50b0FycmF5KG1zZywgZW5jKTtcbiAgaWYgKCF0aGlzLnBlbmRpbmcpXG4gICAgdGhpcy5wZW5kaW5nID0gbXNnO1xuICBlbHNlXG4gICAgdGhpcy5wZW5kaW5nID0gdGhpcy5wZW5kaW5nLmNvbmNhdChtc2cpO1xuICB0aGlzLnBlbmRpbmdUb3RhbCArPSBtc2cubGVuZ3RoO1xuXG4gIC8vIEVub3VnaCBkYXRhLCB0cnkgdXBkYXRpbmdcbiAgaWYgKHRoaXMucGVuZGluZy5sZW5ndGggPj0gdGhpcy5fZGVsdGE4KSB7XG4gICAgbXNnID0gdGhpcy5wZW5kaW5nO1xuXG4gICAgLy8gUHJvY2VzcyBwZW5kaW5nIGRhdGEgaW4gYmxvY2tzXG4gICAgdmFyIHIgPSBtc2cubGVuZ3RoICUgdGhpcy5fZGVsdGE4O1xuICAgIHRoaXMucGVuZGluZyA9IG1zZy5zbGljZShtc2cubGVuZ3RoIC0gciwgbXNnLmxlbmd0aCk7XG4gICAgaWYgKHRoaXMucGVuZGluZy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLnBlbmRpbmcgPSBudWxsO1xuXG4gICAgbXNnID0gdXRpbHMuam9pbjMyKG1zZywgMCwgbXNnLmxlbmd0aCAtIHIsIHRoaXMuZW5kaWFuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkgKz0gdGhpcy5fZGVsdGEzMilcbiAgICAgIHRoaXMuX3VwZGF0ZShtc2csIGksIGkgKyB0aGlzLl9kZWx0YTMyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIHRoaXMudXBkYXRlKHRoaXMuX3BhZCgpKTtcbiAgYXNzZXJ0KHRoaXMucGVuZGluZyA9PT0gbnVsbCk7XG5cbiAgcmV0dXJuIHRoaXMuX2RpZ2VzdChlbmMpO1xufTtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS5fcGFkID0gZnVuY3Rpb24gcGFkKCkge1xuICB2YXIgbGVuID0gdGhpcy5wZW5kaW5nVG90YWw7XG4gIHZhciBieXRlcyA9IHRoaXMuX2RlbHRhODtcbiAgdmFyIGsgPSBieXRlcyAtICgobGVuICsgdGhpcy5wYWRMZW5ndGgpICUgYnl0ZXMpO1xuICB2YXIgcmVzID0gbmV3IEFycmF5KGsgKyB0aGlzLnBhZExlbmd0aCk7XG4gIHJlc1swXSA9IDB4ODA7XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgazsgaSsrKVxuICAgIHJlc1tpXSA9IDA7XG5cbiAgLy8gQXBwZW5kIGxlbmd0aFxuICBsZW4gPDw9IDM7XG4gIGlmICh0aGlzLmVuZGlhbiA9PT0gJ2JpZycpIHtcbiAgICBmb3IgKHZhciB0ID0gODsgdCA8IHRoaXMucGFkTGVuZ3RoOyB0KyspXG4gICAgICByZXNbaSsrXSA9IDA7XG5cbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAobGVuID4+PiAyNCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMTYpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDgpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IGxlbiAmIDB4ZmY7XG4gIH0gZWxzZSB7XG4gICAgcmVzW2krK10gPSBsZW4gJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gOCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMTYpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDI0KSAmIDB4ZmY7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuXG4gICAgZm9yICh2YXIgdCA9IDg7IHQgPCB0aGlzLnBhZExlbmd0aDsgdCsrKVxuICAgICAgcmVzW2krK10gPSAwO1xuICB9XG5cbiAgcmV0dXJuIHJlcztcbn07XG4iLCJ2YXIgaG1hYyA9IGV4cG9ydHM7XG5cbnZhciBoYXNoID0gcmVxdWlyZSgnLi4vaGFzaCcpO1xudmFyIHV0aWxzID0gaGFzaC51dGlscztcbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG5cbmZ1bmN0aW9uIEhtYWMoaGFzaCwga2V5LCBlbmMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEhtYWMpKVxuICAgIHJldHVybiBuZXcgSG1hYyhoYXNoLCBrZXksIGVuYyk7XG4gIHRoaXMuSGFzaCA9IGhhc2g7XG4gIHRoaXMuYmxvY2tTaXplID0gaGFzaC5ibG9ja1NpemUgLyA4O1xuICB0aGlzLm91dFNpemUgPSBoYXNoLm91dFNpemUgLyA4O1xuICB0aGlzLmlubmVyID0gbnVsbDtcbiAgdGhpcy5vdXRlciA9IG51bGw7XG5cbiAgdGhpcy5faW5pdCh1dGlscy50b0FycmF5KGtleSwgZW5jKSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEhtYWM7XG5cbkhtYWMucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24gaW5pdChrZXkpIHtcbiAgLy8gU2hvcnRlbiBrZXksIGlmIG5lZWRlZFxuICBpZiAoa2V5Lmxlbmd0aCA+IHRoaXMuYmxvY2tTaXplKVxuICAgIGtleSA9IG5ldyB0aGlzLkhhc2goKS51cGRhdGUoa2V5KS5kaWdlc3QoKTtcbiAgYXNzZXJ0KGtleS5sZW5ndGggPD0gdGhpcy5ibG9ja1NpemUpO1xuXG4gIC8vIEFkZCBwYWRkaW5nIHRvIGtleVxuICBmb3IgKHZhciBpID0ga2V5Lmxlbmd0aDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspXG4gICAga2V5LnB1c2goMCk7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXkubGVuZ3RoOyBpKyspXG4gICAga2V5W2ldIF49IDB4MzY7XG4gIHRoaXMuaW5uZXIgPSBuZXcgdGhpcy5IYXNoKCkudXBkYXRlKGtleSk7XG5cbiAgLy8gMHgzNiBeIDB4NWMgPSAweDZhXG4gIGZvciAodmFyIGkgPSAwOyBpIDwga2V5Lmxlbmd0aDsgaSsrKVxuICAgIGtleVtpXSBePSAweDZhO1xuICB0aGlzLm91dGVyID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpO1xufTtcblxuSG1hYy5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKG1zZywgZW5jKSB7XG4gIHRoaXMuaW5uZXIudXBkYXRlKG1zZywgZW5jKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5IbWFjLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIHRoaXMub3V0ZXIudXBkYXRlKHRoaXMuaW5uZXIuZGlnZXN0KCkpO1xuICByZXR1cm4gdGhpcy5vdXRlci5kaWdlc3QoZW5jKTtcbn07XG4iLCJ2YXIgaGFzaCA9IHJlcXVpcmUoJy4uL2hhc2gnKTtcbnZhciB1dGlscyA9IGhhc2gudXRpbHM7XG5cbnZhciByb3RsMzIgPSB1dGlscy5yb3RsMzI7XG52YXIgc3VtMzIgPSB1dGlscy5zdW0zMjtcbnZhciBzdW0zMl8zID0gdXRpbHMuc3VtMzJfMztcbnZhciBzdW0zMl80ID0gdXRpbHMuc3VtMzJfNDtcbnZhciBCbG9ja0hhc2ggPSBoYXNoLmNvbW1vbi5CbG9ja0hhc2g7XG5cbmZ1bmN0aW9uIFJJUEVNRDE2MCgpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJJUEVNRDE2MCkpXG4gICAgcmV0dXJuIG5ldyBSSVBFTUQxNjAoKTtcblxuICBCbG9ja0hhc2guY2FsbCh0aGlzKTtcblxuICB0aGlzLmggPSBbIDB4Njc0NTIzMDEsIDB4ZWZjZGFiODksIDB4OThiYWRjZmUsIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjAgXTtcbiAgdGhpcy5lbmRpYW4gPSAnbGl0dGxlJztcbn1cbnV0aWxzLmluaGVyaXRzKFJJUEVNRDE2MCwgQmxvY2tIYXNoKTtcbmV4cG9ydHMucmlwZW1kMTYwID0gUklQRU1EMTYwO1xuXG5SSVBFTUQxNjAuYmxvY2tTaXplID0gNTEyO1xuUklQRU1EMTYwLm91dFNpemUgPSAxNjA7XG5SSVBFTUQxNjAuaG1hY1N0cmVuZ3RoID0gMTkyO1xuUklQRU1EMTYwLnBhZExlbmd0aCA9IDY0O1xuXG5SSVBFTUQxNjAucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgQSA9IHRoaXMuaFswXTtcbiAgdmFyIEIgPSB0aGlzLmhbMV07XG4gIHZhciBDID0gdGhpcy5oWzJdO1xuICB2YXIgRCA9IHRoaXMuaFszXTtcbiAgdmFyIEUgPSB0aGlzLmhbNF07XG4gIHZhciBBaCA9IEE7XG4gIHZhciBCaCA9IEI7XG4gIHZhciBDaCA9IEM7XG4gIHZhciBEaCA9IEQ7XG4gIHZhciBFaCA9IEU7XG4gIGZvciAodmFyIGogPSAwOyBqIDwgODA7IGorKykge1xuICAgIHZhciBUID0gc3VtMzIoXG4gICAgICByb3RsMzIoXG4gICAgICAgIHN1bTMyXzQoQSwgZihqLCBCLCBDLCBEKSwgbXNnW3Jbal0gKyBzdGFydF0sIEsoaikpLFxuICAgICAgICBzW2pdKSxcbiAgICAgIEUpO1xuICAgIEEgPSBFO1xuICAgIEUgPSBEO1xuICAgIEQgPSByb3RsMzIoQywgMTApO1xuICAgIEMgPSBCO1xuICAgIEIgPSBUO1xuICAgIFQgPSBzdW0zMihcbiAgICAgIHJvdGwzMihcbiAgICAgICAgc3VtMzJfNChBaCwgZig3OSAtIGosIEJoLCBDaCwgRGgpLCBtc2dbcmhbal0gKyBzdGFydF0sIEtoKGopKSxcbiAgICAgICAgc2hbal0pLFxuICAgICAgRWgpO1xuICAgIEFoID0gRWg7XG4gICAgRWggPSBEaDtcbiAgICBEaCA9IHJvdGwzMihDaCwgMTApO1xuICAgIENoID0gQmg7XG4gICAgQmggPSBUO1xuICB9XG4gIFQgPSBzdW0zMl8zKHRoaXMuaFsxXSwgQywgRGgpO1xuICB0aGlzLmhbMV0gPSBzdW0zMl8zKHRoaXMuaFsyXSwgRCwgRWgpO1xuICB0aGlzLmhbMl0gPSBzdW0zMl8zKHRoaXMuaFszXSwgRSwgQWgpO1xuICB0aGlzLmhbM10gPSBzdW0zMl8zKHRoaXMuaFs0XSwgQSwgQmgpO1xuICB0aGlzLmhbNF0gPSBzdW0zMl8zKHRoaXMuaFswXSwgQiwgQ2gpO1xuICB0aGlzLmhbMF0gPSBUO1xufTtcblxuUklQRU1EMTYwLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdsaXR0bGUnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2xpdHRsZScpO1xufTtcblxuZnVuY3Rpb24gZihqLCB4LCB5LCB6KSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiB4IF4geSBeIHo7XG4gIGVsc2UgaWYgKGogPD0gMzEpXG4gICAgcmV0dXJuICh4ICYgeSkgfCAoKH54KSAmIHopO1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAoeCB8ICh+eSkpIF4gejtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gKHggJiB6KSB8ICh5ICYgKH56KSk7XG4gIGVsc2VcbiAgICByZXR1cm4geCBeICh5IHwgKH56KSk7XG59XG5cbmZ1bmN0aW9uIEsoaikge1xuICBpZiAoaiA8PSAxNSlcbiAgICByZXR1cm4gMHgwMDAwMDAwMDtcbiAgZWxzZSBpZiAoaiA8PSAzMSlcbiAgICByZXR1cm4gMHg1YTgyNzk5OTtcbiAgZWxzZSBpZiAoaiA8PSA0NylcbiAgICByZXR1cm4gMHg2ZWQ5ZWJhMTtcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gMHg4ZjFiYmNkYztcbiAgZWxzZVxuICAgIHJldHVybiAweGE5NTNmZDRlO1xufVxuXG5mdW5jdGlvbiBLaChqKSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiAweDUwYTI4YmU2O1xuICBlbHNlIGlmIChqIDw9IDMxKVxuICAgIHJldHVybiAweDVjNGRkMTI0O1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAweDZkNzAzZWYzO1xuICBlbHNlIGlmIChqIDw9IDYzKVxuICAgIHJldHVybiAweDdhNmQ3NmU5O1xuICBlbHNlXG4gICAgcmV0dXJuIDB4MDAwMDAwMDA7XG59XG5cbnZhciByID0gW1xuICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LFxuICA3LCA0LCAxMywgMSwgMTAsIDYsIDE1LCAzLCAxMiwgMCwgOSwgNSwgMiwgMTQsIDExLCA4LFxuICAzLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyLFxuICAxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyLFxuICA0LCAwLCA1LCA5LCA3LCAxMiwgMiwgMTAsIDE0LCAxLCAzLCA4LCAxMSwgNiwgMTUsIDEzXG5dO1xuXG52YXIgcmggPSBbXG4gIDUsIDE0LCA3LCAwLCA5LCAyLCAxMSwgNCwgMTMsIDYsIDE1LCA4LCAxLCAxMCwgMywgMTIsXG4gIDYsIDExLCAzLCA3LCAwLCAxMywgNSwgMTAsIDE0LCAxNSwgOCwgMTIsIDQsIDksIDEsIDIsXG4gIDE1LCA1LCAxLCAzLCA3LCAxNCwgNiwgOSwgMTEsIDgsIDEyLCAyLCAxMCwgMCwgNCwgMTMsXG4gIDgsIDYsIDQsIDEsIDMsIDExLCAxNSwgMCwgNSwgMTIsIDIsIDEzLCA5LCA3LCAxMCwgMTQsXG4gIDEyLCAxNSwgMTAsIDQsIDEsIDUsIDgsIDcsIDYsIDIsIDEzLCAxNCwgMCwgMywgOSwgMTFcbl07XG5cbnZhciBzID0gW1xuICAxMSwgMTQsIDE1LCAxMiwgNSwgOCwgNywgOSwgMTEsIDEzLCAxNCwgMTUsIDYsIDcsIDksIDgsXG4gIDcsIDYsIDgsIDEzLCAxMSwgOSwgNywgMTUsIDcsIDEyLCAxNSwgOSwgMTEsIDcsIDEzLCAxMixcbiAgMTEsIDEzLCA2LCA3LCAxNCwgOSwgMTMsIDE1LCAxNCwgOCwgMTMsIDYsIDUsIDEyLCA3LCA1LFxuICAxMSwgMTIsIDE0LCAxNSwgMTQsIDE1LCA5LCA4LCA5LCAxNCwgNSwgNiwgOCwgNiwgNSwgMTIsXG4gIDksIDE1LCA1LCAxMSwgNiwgOCwgMTMsIDEyLCA1LCAxMiwgMTMsIDE0LCAxMSwgOCwgNSwgNlxuXTtcblxudmFyIHNoID0gW1xuICA4LCA5LCA5LCAxMSwgMTMsIDE1LCAxNSwgNSwgNywgNywgOCwgMTEsIDE0LCAxNCwgMTIsIDYsXG4gIDksIDEzLCAxNSwgNywgMTIsIDgsIDksIDExLCA3LCA3LCAxMiwgNywgNiwgMTUsIDEzLCAxMSxcbiAgOSwgNywgMTUsIDExLCA4LCA2LCA2LCAxNCwgMTIsIDEzLCA1LCAxNCwgMTMsIDEzLCA3LCA1LFxuICAxNSwgNSwgOCwgMTEsIDE0LCAxNCwgNiwgMTQsIDYsIDksIDEyLCA5LCAxMiwgNSwgMTUsIDgsXG4gIDgsIDUsIDEyLCA5LCAxMiwgNSwgMTQsIDYsIDgsIDEzLCA2LCA1LCAxNSwgMTMsIDExLCAxMVxuXTtcbiIsInZhciBoYXNoID0gcmVxdWlyZSgnLi4vaGFzaCcpO1xudmFyIHV0aWxzID0gaGFzaC51dGlscztcbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG5cbnZhciByb3RyMzIgPSB1dGlscy5yb3RyMzI7XG52YXIgcm90bDMyID0gdXRpbHMucm90bDMyO1xudmFyIHN1bTMyID0gdXRpbHMuc3VtMzI7XG52YXIgc3VtMzJfNCA9IHV0aWxzLnN1bTMyXzQ7XG52YXIgc3VtMzJfNSA9IHV0aWxzLnN1bTMyXzU7XG52YXIgcm90cjY0X2hpID0gdXRpbHMucm90cjY0X2hpO1xudmFyIHJvdHI2NF9sbyA9IHV0aWxzLnJvdHI2NF9sbztcbnZhciBzaHI2NF9oaSA9IHV0aWxzLnNocjY0X2hpO1xudmFyIHNocjY0X2xvID0gdXRpbHMuc2hyNjRfbG87XG52YXIgc3VtNjQgPSB1dGlscy5zdW02NDtcbnZhciBzdW02NF9oaSA9IHV0aWxzLnN1bTY0X2hpO1xudmFyIHN1bTY0X2xvID0gdXRpbHMuc3VtNjRfbG87XG52YXIgc3VtNjRfNF9oaSA9IHV0aWxzLnN1bTY0XzRfaGk7XG52YXIgc3VtNjRfNF9sbyA9IHV0aWxzLnN1bTY0XzRfbG87XG52YXIgc3VtNjRfNV9oaSA9IHV0aWxzLnN1bTY0XzVfaGk7XG52YXIgc3VtNjRfNV9sbyA9IHV0aWxzLnN1bTY0XzVfbG87XG52YXIgQmxvY2tIYXNoID0gaGFzaC5jb21tb24uQmxvY2tIYXNoO1xuXG52YXIgc2hhMjU2X0sgPSBbXG4gIDB4NDI4YTJmOTgsIDB4NzEzNzQ0OTEsIDB4YjVjMGZiY2YsIDB4ZTliNWRiYTUsXG4gIDB4Mzk1NmMyNWIsIDB4NTlmMTExZjEsIDB4OTIzZjgyYTQsIDB4YWIxYzVlZDUsXG4gIDB4ZDgwN2FhOTgsIDB4MTI4MzViMDEsIDB4MjQzMTg1YmUsIDB4NTUwYzdkYzMsXG4gIDB4NzJiZTVkNzQsIDB4ODBkZWIxZmUsIDB4OWJkYzA2YTcsIDB4YzE5YmYxNzQsXG4gIDB4ZTQ5YjY5YzEsIDB4ZWZiZTQ3ODYsIDB4MGZjMTlkYzYsIDB4MjQwY2ExY2MsXG4gIDB4MmRlOTJjNmYsIDB4NGE3NDg0YWEsIDB4NWNiMGE5ZGMsIDB4NzZmOTg4ZGEsXG4gIDB4OTgzZTUxNTIsIDB4YTgzMWM2NmQsIDB4YjAwMzI3YzgsIDB4YmY1OTdmYzcsXG4gIDB4YzZlMDBiZjMsIDB4ZDVhNzkxNDcsIDB4MDZjYTYzNTEsIDB4MTQyOTI5NjcsXG4gIDB4MjdiNzBhODUsIDB4MmUxYjIxMzgsIDB4NGQyYzZkZmMsIDB4NTMzODBkMTMsXG4gIDB4NjUwYTczNTQsIDB4NzY2YTBhYmIsIDB4ODFjMmM5MmUsIDB4OTI3MjJjODUsXG4gIDB4YTJiZmU4YTEsIDB4YTgxYTY2NGIsIDB4YzI0YjhiNzAsIDB4Yzc2YzUxYTMsXG4gIDB4ZDE5MmU4MTksIDB4ZDY5OTA2MjQsIDB4ZjQwZTM1ODUsIDB4MTA2YWEwNzAsXG4gIDB4MTlhNGMxMTYsIDB4MWUzNzZjMDgsIDB4Mjc0ODc3NGMsIDB4MzRiMGJjYjUsXG4gIDB4MzkxYzBjYjMsIDB4NGVkOGFhNGEsIDB4NWI5Y2NhNGYsIDB4NjgyZTZmZjMsXG4gIDB4NzQ4ZjgyZWUsIDB4NzhhNTYzNmYsIDB4ODRjODc4MTQsIDB4OGNjNzAyMDgsXG4gIDB4OTBiZWZmZmEsIDB4YTQ1MDZjZWIsIDB4YmVmOWEzZjcsIDB4YzY3MTc4ZjJcbl07XG5cbnZhciBzaGE1MTJfSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHhkNzI4YWUyMiwgMHg3MTM3NDQ5MSwgMHgyM2VmNjVjZCxcbiAgMHhiNWMwZmJjZiwgMHhlYzRkM2IyZiwgMHhlOWI1ZGJhNSwgMHg4MTg5ZGJiYyxcbiAgMHgzOTU2YzI1YiwgMHhmMzQ4YjUzOCwgMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOSxcbiAgMHg5MjNmODJhNCwgMHhhZjE5NGY5YiwgMHhhYjFjNWVkNSwgMHhkYTZkODExOCxcbiAgMHhkODA3YWE5OCwgMHhhMzAzMDI0MiwgMHgxMjgzNWIwMSwgMHg0NTcwNmZiZSxcbiAgMHgyNDMxODViZSwgMHg0ZWU0YjI4YywgMHg1NTBjN2RjMywgMHhkNWZmYjRlMixcbiAgMHg3MmJlNWQ3NCwgMHhmMjdiODk2ZiwgMHg4MGRlYjFmZSwgMHgzYjE2OTZiMSxcbiAgMHg5YmRjMDZhNywgMHgyNWM3MTIzNSwgMHhjMTliZjE3NCwgMHhjZjY5MjY5NCxcbiAgMHhlNDliNjljMSwgMHg5ZWYxNGFkMiwgMHhlZmJlNDc4NiwgMHgzODRmMjVlMyxcbiAgMHgwZmMxOWRjNiwgMHg4YjhjZDViNSwgMHgyNDBjYTFjYywgMHg3N2FjOWM2NSxcbiAgMHgyZGU5MmM2ZiwgMHg1OTJiMDI3NSwgMHg0YTc0ODRhYSwgMHg2ZWE2ZTQ4MyxcbiAgMHg1Y2IwYTlkYywgMHhiZDQxZmJkNCwgMHg3NmY5ODhkYSwgMHg4MzExNTNiNSxcbiAgMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYiwgMHhhODMxYzY2ZCwgMHgyZGI0MzIxMCxcbiAgMHhiMDAzMjdjOCwgMHg5OGZiMjEzZiwgMHhiZjU5N2ZjNywgMHhiZWVmMGVlNCxcbiAgMHhjNmUwMGJmMywgMHgzZGE4OGZjMiwgMHhkNWE3OTE0NywgMHg5MzBhYTcyNSxcbiAgMHgwNmNhNjM1MSwgMHhlMDAzODI2ZiwgMHgxNDI5Mjk2NywgMHgwYTBlNmU3MCxcbiAgMHgyN2I3MGE4NSwgMHg0NmQyMmZmYywgMHgyZTFiMjEzOCwgMHg1YzI2YzkyNixcbiAgMHg0ZDJjNmRmYywgMHg1YWM0MmFlZCwgMHg1MzM4MGQxMywgMHg5ZDk1YjNkZixcbiAgMHg2NTBhNzM1NCwgMHg4YmFmNjNkZSwgMHg3NjZhMGFiYiwgMHgzYzc3YjJhOCxcbiAgMHg4MWMyYzkyZSwgMHg0N2VkYWVlNiwgMHg5MjcyMmM4NSwgMHgxNDgyMzUzYixcbiAgMHhhMmJmZThhMSwgMHg0Y2YxMDM2NCwgMHhhODFhNjY0YiwgMHhiYzQyMzAwMSxcbiAgMHhjMjRiOGI3MCwgMHhkMGY4OTc5MSwgMHhjNzZjNTFhMywgMHgwNjU0YmUzMCxcbiAgMHhkMTkyZTgxOSwgMHhkNmVmNTIxOCwgMHhkNjk5MDYyNCwgMHg1NTY1YTkxMCxcbiAgMHhmNDBlMzU4NSwgMHg1NzcxMjAyYSwgMHgxMDZhYTA3MCwgMHgzMmJiZDFiOCxcbiAgMHgxOWE0YzExNiwgMHhiOGQyZDBjOCwgMHgxZTM3NmMwOCwgMHg1MTQxYWI1MyxcbiAgMHgyNzQ4Nzc0YywgMHhkZjhlZWI5OSwgMHgzNGIwYmNiNSwgMHhlMTliNDhhOCxcbiAgMHgzOTFjMGNiMywgMHhjNWM5NWE2MywgMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYixcbiAgMHg1YjljY2E0ZiwgMHg3NzYzZTM3MywgMHg2ODJlNmZmMywgMHhkNmIyYjhhMyxcbiAgMHg3NDhmODJlZSwgMHg1ZGVmYjJmYywgMHg3OGE1NjM2ZiwgMHg0MzE3MmY2MCxcbiAgMHg4NGM4NzgxNCwgMHhhMWYwYWI3MiwgMHg4Y2M3MDIwOCwgMHgxYTY0MzllYyxcbiAgMHg5MGJlZmZmYSwgMHgyMzYzMWUyOCwgMHhhNDUwNmNlYiwgMHhkZTgyYmRlOSxcbiAgMHhiZWY5YTNmNywgMHhiMmM2NzkxNSwgMHhjNjcxNzhmMiwgMHhlMzcyNTMyYixcbiAgMHhjYTI3M2VjZSwgMHhlYTI2NjE5YywgMHhkMTg2YjhjNywgMHgyMWMwYzIwNyxcbiAgMHhlYWRhN2RkNiwgMHhjZGUwZWIxZSwgMHhmNTdkNGY3ZiwgMHhlZTZlZDE3OCxcbiAgMHgwNmYwNjdhYSwgMHg3MjE3NmZiYSwgMHgwYTYzN2RjNSwgMHhhMmM4OThhNixcbiAgMHgxMTNmOTgwNCwgMHhiZWY5MGRhZSwgMHgxYjcxMGIzNSwgMHgxMzFjNDcxYixcbiAgMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NCwgMHgzMmNhYWI3YiwgMHg0MGM3MjQ5MyxcbiAgMHgzYzllYmUwYSwgMHgxNWM5YmViYywgMHg0MzFkNjdjNCwgMHg5YzEwMGQ0YyxcbiAgMHg0Y2M1ZDRiZSwgMHhjYjNlNDJiNiwgMHg1OTdmMjk5YywgMHhmYzY1N2UyYSxcbiAgMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlYywgMHg2YzQ0MTk4YywgMHg0YTQ3NTgxN1xuXTtcblxudmFyIHNoYTFfSyA9IFtcbiAgMHg1QTgyNzk5OSwgMHg2RUQ5RUJBMSxcbiAgMHg4RjFCQkNEQywgMHhDQTYyQzFENlxuXTtcblxuZnVuY3Rpb24gU0hBMjU2KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMjU2KSlcbiAgICByZXR1cm4gbmV3IFNIQTI1NigpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbIDB4NmEwOWU2NjcsIDB4YmI2N2FlODUsIDB4M2M2ZWYzNzIsIDB4YTU0ZmY1M2EsXG4gICAgICAgICAgICAgMHg1MTBlNTI3ZiwgMHg5YjA1Njg4YywgMHgxZjgzZDlhYiwgMHg1YmUwY2QxOSBdO1xuICB0aGlzLmsgPSBzaGEyNTZfSztcbiAgdGhpcy5XID0gbmV3IEFycmF5KDY0KTtcbn1cbnV0aWxzLmluaGVyaXRzKFNIQTI1NiwgQmxvY2tIYXNoKTtcbmV4cG9ydHMuc2hhMjU2ID0gU0hBMjU2O1xuXG5TSEEyNTYuYmxvY2tTaXplID0gNTEyO1xuU0hBMjU2Lm91dFNpemUgPSAyNTY7XG5TSEEyNTYuaG1hY1N0cmVuZ3RoID0gMTkyO1xuU0hBMjU2LnBhZExlbmd0aCA9IDY0O1xuXG5TSEEyNTYucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiBfdXBkYXRlKG1zZywgc3RhcnQpIHtcbiAgdmFyIFcgPSB0aGlzLlc7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKVxuICAgIFdbaV0gPSBtc2dbc3RhcnQgKyBpXTtcbiAgZm9yICg7IGkgPCBXLmxlbmd0aDsgaSsrKVxuICAgIFdbaV0gPSBzdW0zMl80KGcxXzI1NihXW2kgLSAyXSksIFdbaSAtIDddLCBnMF8yNTYoV1tpIC0gMTVdKSwgV1tpIC0gMTZdKTtcblxuICB2YXIgYSA9IHRoaXMuaFswXTtcbiAgdmFyIGIgPSB0aGlzLmhbMV07XG4gIHZhciBjID0gdGhpcy5oWzJdO1xuICB2YXIgZCA9IHRoaXMuaFszXTtcbiAgdmFyIGUgPSB0aGlzLmhbNF07XG4gIHZhciBmID0gdGhpcy5oWzVdO1xuICB2YXIgZyA9IHRoaXMuaFs2XTtcbiAgdmFyIGggPSB0aGlzLmhbN107XG5cbiAgYXNzZXJ0KHRoaXMuay5sZW5ndGggPT09IFcubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIFQxID0gc3VtMzJfNShoLCBzMV8yNTYoZSksIGNoMzIoZSwgZiwgZyksIHRoaXMua1tpXSwgV1tpXSk7XG4gICAgdmFyIFQyID0gc3VtMzIoczBfMjU2KGEpLCBtYWozMihhLCBiLCBjKSk7XG4gICAgaCA9IGc7XG4gICAgZyA9IGY7XG4gICAgZiA9IGU7XG4gICAgZSA9IHN1bTMyKGQsIFQxKTtcbiAgICBkID0gYztcbiAgICBjID0gYjtcbiAgICBiID0gYTtcbiAgICBhID0gc3VtMzIoVDEsIFQyKTtcbiAgfVxuXG4gIHRoaXMuaFswXSA9IHN1bTMyKHRoaXMuaFswXSwgYSk7XG4gIHRoaXMuaFsxXSA9IHN1bTMyKHRoaXMuaFsxXSwgYik7XG4gIHRoaXMuaFsyXSA9IHN1bTMyKHRoaXMuaFsyXSwgYyk7XG4gIHRoaXMuaFszXSA9IHN1bTMyKHRoaXMuaFszXSwgZCk7XG4gIHRoaXMuaFs0XSA9IHN1bTMyKHRoaXMuaFs0XSwgZSk7XG4gIHRoaXMuaFs1XSA9IHN1bTMyKHRoaXMuaFs1XSwgZik7XG4gIHRoaXMuaFs2XSA9IHN1bTMyKHRoaXMuaFs2XSwgZyk7XG4gIHRoaXMuaFs3XSA9IHN1bTMyKHRoaXMuaFs3XSwgaCk7XG59O1xuXG5TSEEyNTYucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaCwgJ2JpZycpO1xuICBlbHNlXG4gICAgcmV0dXJuIHV0aWxzLnNwbGl0MzIodGhpcy5oLCAnYmlnJyk7XG59O1xuXG5mdW5jdGlvbiBTSEEyMjQoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTSEEyMjQpKVxuICAgIHJldHVybiBuZXcgU0hBMjI0KCk7XG5cbiAgU0hBMjU2LmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFsgMHhjMTA1OWVkOCwgMHgzNjdjZDUwNywgMHgzMDcwZGQxNywgMHhmNzBlNTkzOSxcbiAgICAgICAgICAgICAweGZmYzAwYjMxLCAweDY4NTgxNTExLCAweDY0Zjk4ZmE3LCAweGJlZmE0ZmE0IF07XG59XG51dGlscy5pbmhlcml0cyhTSEEyMjQsIFNIQTI1Nik7XG5leHBvcnRzLnNoYTIyNCA9IFNIQTIyNDtcblxuU0hBMjI0LmJsb2NrU2l6ZSA9IDUxMjtcblNIQTIyNC5vdXRTaXplID0gMjI0O1xuU0hBMjI0LmhtYWNTdHJlbmd0aCA9IDE5MjtcblNIQTIyNC5wYWRMZW5ndGggPSA2NDtcblxuU0hBMjI0LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICAvLyBKdXN0IHRydW5jYXRlIG91dHB1dFxuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmguc2xpY2UoMCwgNyksICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaC5zbGljZSgwLCA3KSwgJ2JpZycpO1xufTtcblxuZnVuY3Rpb24gU0hBNTEyKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBNTEyKSlcbiAgICByZXR1cm4gbmV3IFNIQTUxMigpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbIDB4NmEwOWU2NjcsIDB4ZjNiY2M5MDgsXG4gICAgICAgICAgICAgMHhiYjY3YWU4NSwgMHg4NGNhYTczYixcbiAgICAgICAgICAgICAweDNjNmVmMzcyLCAweGZlOTRmODJiLFxuICAgICAgICAgICAgIDB4YTU0ZmY1M2EsIDB4NWYxZDM2ZjEsXG4gICAgICAgICAgICAgMHg1MTBlNTI3ZiwgMHhhZGU2ODJkMSxcbiAgICAgICAgICAgICAweDliMDU2ODhjLCAweDJiM2U2YzFmLFxuICAgICAgICAgICAgIDB4MWY4M2Q5YWIsIDB4ZmI0MWJkNmIsXG4gICAgICAgICAgICAgMHg1YmUwY2QxOSwgMHgxMzdlMjE3OSBdO1xuICB0aGlzLmsgPSBzaGE1MTJfSztcbiAgdGhpcy5XID0gbmV3IEFycmF5KDE2MCk7XG59XG51dGlscy5pbmhlcml0cyhTSEE1MTIsIEJsb2NrSGFzaCk7XG5leHBvcnRzLnNoYTUxMiA9IFNIQTUxMjtcblxuU0hBNTEyLmJsb2NrU2l6ZSA9IDEwMjQ7XG5TSEE1MTIub3V0U2l6ZSA9IDUxMjtcblNIQTUxMi5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEE1MTIucGFkTGVuZ3RoID0gMTI4O1xuXG5TSEE1MTIucHJvdG90eXBlLl9wcmVwYXJlQmxvY2sgPSBmdW5jdGlvbiBfcHJlcGFyZUJsb2NrKG1zZywgc3RhcnQpIHtcbiAgdmFyIFcgPSB0aGlzLlc7XG5cbiAgLy8gMzIgeCAzMmJpdCB3b3Jkc1xuICBmb3IgKHZhciBpID0gMDsgaSA8IDMyOyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuICBmb3IgKDsgaSA8IFcubGVuZ3RoOyBpICs9IDIpIHtcbiAgICB2YXIgYzBfaGkgPSBnMV81MTJfaGkoV1tpIC0gNF0sIFdbaSAtIDNdKTsgIC8vIGkgLSAyXG4gICAgdmFyIGMwX2xvID0gZzFfNTEyX2xvKFdbaSAtIDRdLCBXW2kgLSAzXSk7XG4gICAgdmFyIGMxX2hpID0gV1tpIC0gMTRdOyAgLy8gaSAtIDdcbiAgICB2YXIgYzFfbG8gPSBXW2kgLSAxM107XG4gICAgdmFyIGMyX2hpID0gZzBfNTEyX2hpKFdbaSAtIDMwXSwgV1tpIC0gMjldKTsgIC8vIGkgLSAxNVxuICAgIHZhciBjMl9sbyA9IGcwXzUxMl9sbyhXW2kgLSAzMF0sIFdbaSAtIDI5XSk7XG4gICAgdmFyIGMzX2hpID0gV1tpIC0gMzJdOyAgLy8gaSAtIDE2XG4gICAgdmFyIGMzX2xvID0gV1tpIC0gMzFdO1xuXG4gICAgV1tpXSA9IHN1bTY0XzRfaGkoYzBfaGksIGMwX2xvLFxuICAgICAgICAgICAgICAgICAgICAgIGMxX2hpLCBjMV9sbyxcbiAgICAgICAgICAgICAgICAgICAgICBjMl9oaSwgYzJfbG8sXG4gICAgICAgICAgICAgICAgICAgICAgYzNfaGksIGMzX2xvKTtcbiAgICBXW2kgKyAxXSA9IHN1bTY0XzRfbG8oYzBfaGksIGMwX2xvLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBjMV9oaSwgYzFfbG8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGMyX2hpLCBjMl9sbyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYzNfaGksIGMzX2xvKTtcbiAgfVxufTtcblxuU0hBNTEyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gX3VwZGF0ZShtc2csIHN0YXJ0KSB7XG4gIHRoaXMuX3ByZXBhcmVCbG9jayhtc2csIHN0YXJ0KTtcblxuICB2YXIgVyA9IHRoaXMuVztcblxuICB2YXIgYWggPSB0aGlzLmhbMF07XG4gIHZhciBhbCA9IHRoaXMuaFsxXTtcbiAgdmFyIGJoID0gdGhpcy5oWzJdO1xuICB2YXIgYmwgPSB0aGlzLmhbM107XG4gIHZhciBjaCA9IHRoaXMuaFs0XTtcbiAgdmFyIGNsID0gdGhpcy5oWzVdO1xuICB2YXIgZGggPSB0aGlzLmhbNl07XG4gIHZhciBkbCA9IHRoaXMuaFs3XTtcbiAgdmFyIGVoID0gdGhpcy5oWzhdO1xuICB2YXIgZWwgPSB0aGlzLmhbOV07XG4gIHZhciBmaCA9IHRoaXMuaFsxMF07XG4gIHZhciBmbCA9IHRoaXMuaFsxMV07XG4gIHZhciBnaCA9IHRoaXMuaFsxMl07XG4gIHZhciBnbCA9IHRoaXMuaFsxM107XG4gIHZhciBoaCA9IHRoaXMuaFsxNF07XG4gIHZhciBobCA9IHRoaXMuaFsxNV07XG5cbiAgYXNzZXJ0KHRoaXMuay5sZW5ndGggPT09IFcubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgdmFyIGMwX2hpID0gaGg7XG4gICAgdmFyIGMwX2xvID0gaGw7XG4gICAgdmFyIGMxX2hpID0gczFfNTEyX2hpKGVoLCBlbCk7XG4gICAgdmFyIGMxX2xvID0gczFfNTEyX2xvKGVoLCBlbCk7XG4gICAgdmFyIGMyX2hpID0gY2g2NF9oaShlaCwgZWwsIGZoLCBmbCwgZ2gsIGdsKTtcbiAgICB2YXIgYzJfbG8gPSBjaDY0X2xvKGVoLCBlbCwgZmgsIGZsLCBnaCwgZ2wpO1xuICAgIHZhciBjM19oaSA9IHRoaXMua1tpXTtcbiAgICB2YXIgYzNfbG8gPSB0aGlzLmtbaSArIDFdO1xuICAgIHZhciBjNF9oaSA9IFdbaV07XG4gICAgdmFyIGM0X2xvID0gV1tpICsgMV07XG5cbiAgICB2YXIgVDFfaGkgPSBzdW02NF81X2hpKGMwX2hpLCBjMF9sbyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGMxX2hpLCBjMV9sbyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGMyX2hpLCBjMl9sbyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGMzX2hpLCBjM19sbyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGM0X2hpLCBjNF9sbyk7XG4gICAgdmFyIFQxX2xvID0gc3VtNjRfNV9sbyhjMF9oaSwgYzBfbG8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBjMV9oaSwgYzFfbG8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBjMl9oaSwgYzJfbG8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBjM19oaSwgYzNfbG8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBjNF9oaSwgYzRfbG8pO1xuXG4gICAgdmFyIGMwX2hpID0gczBfNTEyX2hpKGFoLCBhbCk7XG4gICAgdmFyIGMwX2xvID0gczBfNTEyX2xvKGFoLCBhbCk7XG4gICAgdmFyIGMxX2hpID0gbWFqNjRfaGkoYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCk7XG4gICAgdmFyIGMxX2xvID0gbWFqNjRfbG8oYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCk7XG5cbiAgICB2YXIgVDJfaGkgPSBzdW02NF9oaShjMF9oaSwgYzBfbG8sIGMxX2hpLCBjMV9sbyk7XG4gICAgdmFyIFQyX2xvID0gc3VtNjRfbG8oYzBfaGksIGMwX2xvLCBjMV9oaSwgYzFfbG8pO1xuXG4gICAgaGggPSBnaDtcbiAgICBobCA9IGdsO1xuXG4gICAgZ2ggPSBmaDtcbiAgICBnbCA9IGZsO1xuXG4gICAgZmggPSBlaDtcbiAgICBmbCA9IGVsO1xuXG4gICAgZWggPSBzdW02NF9oaShkaCwgZGwsIFQxX2hpLCBUMV9sbyk7XG4gICAgZWwgPSBzdW02NF9sbyhkbCwgZGwsIFQxX2hpLCBUMV9sbyk7XG5cbiAgICBkaCA9IGNoO1xuICAgIGRsID0gY2w7XG5cbiAgICBjaCA9IGJoO1xuICAgIGNsID0gYmw7XG5cbiAgICBiaCA9IGFoO1xuICAgIGJsID0gYWw7XG5cbiAgICBhaCA9IHN1bTY0X2hpKFQxX2hpLCBUMV9sbywgVDJfaGksIFQyX2xvKTtcbiAgICBhbCA9IHN1bTY0X2xvKFQxX2hpLCBUMV9sbywgVDJfaGksIFQyX2xvKTtcbiAgfVxuXG4gIHN1bTY0KHRoaXMuaCwgMCwgYWgsIGFsKTtcbiAgc3VtNjQodGhpcy5oLCAyLCBiaCwgYmwpO1xuICBzdW02NCh0aGlzLmgsIDQsIGNoLCBjbCk7XG4gIHN1bTY0KHRoaXMuaCwgNiwgZGgsIGRsKTtcbiAgc3VtNjQodGhpcy5oLCA4LCBlaCwgZWwpO1xuICBzdW02NCh0aGlzLmgsIDEwLCBmaCwgZmwpO1xuICBzdW02NCh0aGlzLmgsIDEyLCBnaCwgZ2wpO1xuICBzdW02NCh0aGlzLmgsIDE0LCBoaCwgaGwpO1xufTtcblxuU0hBNTEyLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2JpZycpO1xufTtcblxuZnVuY3Rpb24gU0hBMzg0KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMzg0KSlcbiAgICByZXR1cm4gbmV3IFNIQTM4NCgpO1xuXG4gIFNIQTUxMi5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbIDB4Y2JiYjlkNWQsIDB4YzEwNTllZDgsXG4gICAgICAgICAgICAgMHg2MjlhMjkyYSwgMHgzNjdjZDUwNyxcbiAgICAgICAgICAgICAweDkxNTkwMTVhLCAweDMwNzBkZDE3LFxuICAgICAgICAgICAgIDB4MTUyZmVjZDgsIDB4ZjcwZTU5MzksXG4gICAgICAgICAgICAgMHg2NzMzMjY2NywgMHhmZmMwMGIzMSxcbiAgICAgICAgICAgICAweDhlYjQ0YTg3LCAweDY4NTgxNTExLFxuICAgICAgICAgICAgIDB4ZGIwYzJlMGQsIDB4NjRmOThmYTcsXG4gICAgICAgICAgICAgMHg0N2I1NDgxZCwgMHhiZWZhNGZhNCBdO1xufVxudXRpbHMuaW5oZXJpdHMoU0hBMzg0LCBTSEE1MTIpO1xuZXhwb3J0cy5zaGEzODQgPSBTSEEzODQ7XG5cblNIQTM4NC5ibG9ja1NpemUgPSAxMDI0O1xuU0hBMzg0Lm91dFNpemUgPSAzODQ7XG5TSEEzODQuaG1hY1N0cmVuZ3RoID0gMTkyO1xuU0hBMzg0LnBhZExlbmd0aCA9IDEyODtcblxuU0hBMzg0LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmguc2xpY2UoMCwgMTIpLCAnYmlnJyk7XG4gIGVsc2VcbiAgICByZXR1cm4gdXRpbHMuc3BsaXQzMih0aGlzLmguc2xpY2UoMCwgMTIpLCAnYmlnJyk7XG59O1xuXG5mdW5jdGlvbiBTSEExKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMSkpXG4gICAgcmV0dXJuIG5ldyBTSEExKCk7XG5cbiAgQmxvY2tIYXNoLmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFsgMHg2NzQ1MjMwMSwgMHhlZmNkYWI4OSwgMHg5OGJhZGNmZSxcbiAgICAgICAgICAgICAweDEwMzI1NDc2LCAweGMzZDJlMWYwIF07XG4gIHRoaXMuVyA9IG5ldyBBcnJheSg4MCk7XG59XG5cbnV0aWxzLmluaGVyaXRzKFNIQTEsIEJsb2NrSGFzaCk7XG5leHBvcnRzLnNoYTEgPSBTSEExO1xuXG5TSEExLmJsb2NrU2l6ZSA9IDUxMjtcblNIQTEub3V0U2l6ZSA9IDE2MDtcblNIQTEuaG1hY1N0cmVuZ3RoID0gODA7XG5TSEExLnBhZExlbmd0aCA9IDY0O1xuXG5TSEExLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gX3VwZGF0ZShtc2csIHN0YXJ0KSB7XG4gIHZhciBXID0gdGhpcy5XO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKylcbiAgICBXW2ldID0gbXNnW3N0YXJ0ICsgaV07XG5cbiAgZm9yKDsgaSA8IFcubGVuZ3RoOyBpKyspXG4gICAgV1tpXSA9IHJvdGwzMihXW2kgLSAzXSBeIFdbaSAtIDhdIF4gV1tpIC0gMTRdIF4gV1tpIC0gMTZdLCAxKTtcblxuICB2YXIgYSA9IHRoaXMuaFswXTtcbiAgdmFyIGIgPSB0aGlzLmhbMV07XG4gIHZhciBjID0gdGhpcy5oWzJdO1xuICB2YXIgZCA9IHRoaXMuaFszXTtcbiAgdmFyIGUgPSB0aGlzLmhbNF07XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHMgPSB+fihpIC8gMjApO1xuICAgIHZhciB0ID0gc3VtMzJfNShyb3RsMzIoYSwgNSksIGZ0XzEocywgYiwgYywgZCksIGUsIFdbaV0sIHNoYTFfS1tzXSk7XG4gICAgZSA9IGQ7XG4gICAgZCA9IGM7XG4gICAgYyA9IHJvdGwzMihiLCAzMCk7XG4gICAgYiA9IGE7XG4gICAgYSA9IHQ7XG4gIH1cblxuICB0aGlzLmhbMF0gPSBzdW0zMih0aGlzLmhbMF0sIGEpO1xuICB0aGlzLmhbMV0gPSBzdW0zMih0aGlzLmhbMV0sIGIpO1xuICB0aGlzLmhbMl0gPSBzdW0zMih0aGlzLmhbMl0sIGMpO1xuICB0aGlzLmhbM10gPSBzdW0zMih0aGlzLmhbM10sIGQpO1xuICB0aGlzLmhbNF0gPSBzdW0zMih0aGlzLmhbNF0sIGUpO1xufTtcblxuU0hBMS5wcm90b3R5cGUuX2RpZ2VzdCA9IGZ1bmN0aW9uIGRpZ2VzdChlbmMpIHtcbiAgaWYgKGVuYyA9PT0gJ2hleCcpXG4gICAgcmV0dXJuIHV0aWxzLnRvSGV4MzIodGhpcy5oLCAnYmlnJyk7XG4gIGVsc2VcbiAgICByZXR1cm4gdXRpbHMuc3BsaXQzMih0aGlzLmgsICdiaWcnKTtcbn07XG5cbmZ1bmN0aW9uIGNoMzIoeCwgeSwgeikge1xuICByZXR1cm4gKHggJiB5KSBeICgofngpICYgeik7XG59XG5cbmZ1bmN0aW9uIG1hajMyKHgsIHksIHopIHtcbiAgcmV0dXJuICh4ICYgeSkgXiAoeCAmIHopIF4gKHkgJiB6KTtcbn1cblxuZnVuY3Rpb24gcDMyKHgsIHksIHopIHtcbiAgcmV0dXJuIHggXiB5IF4gejtcbn1cblxuZnVuY3Rpb24gczBfMjU2KHgpIHtcbiAgcmV0dXJuIHJvdHIzMih4LCAyKSBeIHJvdHIzMih4LCAxMykgXiByb3RyMzIoeCwgMjIpO1xufVxuXG5mdW5jdGlvbiBzMV8yNTYoeCkge1xuICByZXR1cm4gcm90cjMyKHgsIDYpIF4gcm90cjMyKHgsIDExKSBeIHJvdHIzMih4LCAyNSk7XG59XG5cbmZ1bmN0aW9uIGcwXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgNykgXiByb3RyMzIoeCwgMTgpIF4gKHggPj4+IDMpO1xufVxuXG5mdW5jdGlvbiBnMV8yNTYoeCkge1xuICByZXR1cm4gcm90cjMyKHgsIDE3KSBeIHJvdHIzMih4LCAxOSkgXiAoeCA+Pj4gMTApO1xufVxuXG5mdW5jdGlvbiBmdF8xKHMsIHgsIHksIHopIHtcbiAgaWYgKHMgPT09IDApXG4gICAgcmV0dXJuIGNoMzIoeCwgeSwgeik7XG4gIGlmIChzID09PSAxIHx8IHMgPT09IDMpXG4gICAgcmV0dXJuIHAzMih4LCB5LCB6KTtcbiAgaWYgKHMgPT09IDIpXG4gICAgcmV0dXJuIG1hajMyKHgsIHksIHopO1xufVxuXG5mdW5jdGlvbiBjaDY0X2hpKHhoLCB4bCwgeWgsIHlsLCB6aCwgemwpIHtcbiAgdmFyIHIgPSAoeGggJiB5aCkgXiAoKH54aCkgJiB6aCk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gY2g2NF9sbyh4aCwgeGwsIHloLCB5bCwgemgsIHpsKSB7XG4gIHZhciByID0gKHhsICYgeWwpIF4gKCh+eGwpICYgemwpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIG1hajY0X2hpKHhoLCB4bCwgeWgsIHlsLCB6aCwgemwpIHtcbiAgdmFyIHIgPSAoeGggJiB5aCkgXiAoeGggJiB6aCkgXiAoeWggJiB6aCk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gbWFqNjRfbG8oeGgsIHhsLCB5aCwgeWwsIHpoLCB6bCkge1xuICB2YXIgciA9ICh4bCAmIHlsKSBeICh4bCAmIHpsKSBeICh5bCAmIHpsKTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBzMF81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDI4KTtcbiAgdmFyIGMxX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgMik7ICAvLyAzNFxuICB2YXIgYzJfaGkgPSByb3RyNjRfaGkoeGwsIHhoLCA3KTsgIC8vIDM5XG5cbiAgdmFyIHIgPSBjMF9oaSBeIGMxX2hpIF4gYzJfaGk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gczBfNTEyX2xvKHhoLCB4bCkge1xuICB2YXIgYzBfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCAyOCk7XG4gIHZhciBjMV9sbyA9IHJvdHI2NF9sbyh4bCwgeGgsIDIpOyAgLy8gMzRcbiAgdmFyIGMyX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgNyk7ICAvLyAzOVxuXG4gIHZhciByID0gYzBfbG8gXiBjMV9sbyBeIGMyX2xvO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMxXzUxMl9oaSh4aCwgeGwpIHtcbiAgdmFyIGMwX2hpID0gcm90cjY0X2hpKHhoLCB4bCwgMTQpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCAxOCk7XG4gIHZhciBjMl9oaSA9IHJvdHI2NF9oaSh4bCwgeGgsIDkpOyAgLy8gNDFcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBzMV81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDE0KTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhoLCB4bCwgMTgpO1xuICB2YXIgYzJfbG8gPSByb3RyNjRfbG8oeGwsIHhoLCA5KTsgIC8vIDQxXG5cbiAgdmFyIHIgPSBjMF9sbyBeIGMxX2xvIF4gYzJfbG87XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gZzBfNTEyX2hpKHhoLCB4bCkge1xuICB2YXIgYzBfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCAxKTtcbiAgdmFyIGMxX2hpID0gcm90cjY0X2hpKHhoLCB4bCwgOCk7XG4gIHZhciBjMl9oaSA9IHNocjY0X2hpKHhoLCB4bCwgNyk7XG5cbiAgdmFyIHIgPSBjMF9oaSBeIGMxX2hpIF4gYzJfaGk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gZzBfNTEyX2xvKHhoLCB4bCkge1xuICB2YXIgYzBfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCAxKTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhoLCB4bCwgOCk7XG4gIHZhciBjMl9sbyA9IHNocjY0X2xvKHhoLCB4bCwgNyk7XG5cbiAgdmFyIHIgPSBjMF9sbyBeIGMxX2xvIF4gYzJfbG87XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gZzFfNTEyX2hpKHhoLCB4bCkge1xuICB2YXIgYzBfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCAxOSk7XG4gIHZhciBjMV9oaSA9IHJvdHI2NF9oaSh4bCwgeGgsIDI5KTsgIC8vIDYxXG4gIHZhciBjMl9oaSA9IHNocjY0X2hpKHhoLCB4bCwgNik7XG5cbiAgdmFyIHIgPSBjMF9oaSBeIGMxX2hpIF4gYzJfaGk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gZzFfNTEyX2xvKHhoLCB4bCkge1xuICB2YXIgYzBfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCAxOSk7XG4gIHZhciBjMV9sbyA9IHJvdHI2NF9sbyh4bCwgeGgsIDI5KTsgIC8vIDYxXG4gIHZhciBjMl9sbyA9IHNocjY0X2xvKHhoLCB4bCwgNik7XG5cbiAgdmFyIHIgPSBjMF9sbyBeIGMxX2xvIF4gYzJfbG87XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cbiIsInZhciB1dGlscyA9IGV4cG9ydHM7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG5mdW5jdGlvbiB0b0FycmF5KG1zZywgZW5jKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KG1zZykpXG4gICAgcmV0dXJuIG1zZy5zbGljZSgpO1xuICBpZiAoIW1zZylcbiAgICByZXR1cm4gW107XG4gIHZhciByZXMgPSBbXTtcbiAgaWYgKHR5cGVvZiBtc2cgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKCFlbmMpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjID0gbXNnLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIHZhciBoaSA9IGMgPj4gODtcbiAgICAgICAgdmFyIGxvID0gYyAmIDB4ZmY7XG4gICAgICAgIGlmIChoaSlcbiAgICAgICAgICByZXMucHVzaChoaSwgbG8pO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgcmVzLnB1c2gobG8pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZW5jID09PSAnaGV4Jykge1xuICAgICAgbXNnID0gbXNnLnJlcGxhY2UoL1teYS16MC05XSsvaWcsICcnKTtcbiAgICAgIGlmIChtc2cubGVuZ3RoICUgMiAhPT0gMClcbiAgICAgICAgbXNnID0gJzAnICsgbXNnO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpICs9IDIpXG4gICAgICAgIHJlcy5wdXNoKHBhcnNlSW50KG1zZ1tpXSArIG1zZ1tpICsgMV0sIDE2KSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKVxuICAgICAgcmVzW2ldID0gbXNnW2ldIHwgMDtcbiAgfVxuICByZXR1cm4gcmVzO1xufVxudXRpbHMudG9BcnJheSA9IHRvQXJyYXk7XG5cbmZ1bmN0aW9uIHRvSGV4KG1zZykge1xuICB2YXIgcmVzID0gJyc7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKVxuICAgIHJlcyArPSB6ZXJvMihtc2dbaV0udG9TdHJpbmcoMTYpKTtcbiAgcmV0dXJuIHJlcztcbn1cbnV0aWxzLnRvSGV4ID0gdG9IZXg7XG5cbmZ1bmN0aW9uIGh0b25sKHcpIHtcbiAgdmFyIHJlcyA9ICh3ID4+PiAyNCkgfFxuICAgICAgICAgICAgKCh3ID4+PiA4KSAmIDB4ZmYwMCkgfFxuICAgICAgICAgICAgKCh3IDw8IDgpICYgMHhmZjAwMDApIHxcbiAgICAgICAgICAgICgodyAmIDB4ZmYpIDw8IDI0KTtcbiAgcmV0dXJuIHJlcyA+Pj4gMDtcbn1cbnV0aWxzLmh0b25sID0gaHRvbmw7XG5cbmZ1bmN0aW9uIHRvSGV4MzIobXNnLCBlbmRpYW4pIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKykge1xuICAgIHZhciB3ID0gbXNnW2ldO1xuICAgIGlmIChlbmRpYW4gPT09ICdsaXR0bGUnKVxuICAgICAgdyA9IGh0b25sKHcpO1xuICAgIHJlcyArPSB6ZXJvOCh3LnRvU3RyaW5nKDE2KSk7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbnV0aWxzLnRvSGV4MzIgPSB0b0hleDMyO1xuXG5mdW5jdGlvbiB6ZXJvMih3b3JkKSB7XG4gIGlmICh3b3JkLmxlbmd0aCA9PT0gMSlcbiAgICByZXR1cm4gJzAnICsgd29yZDtcbiAgZWxzZVxuICAgIHJldHVybiB3b3JkO1xufVxudXRpbHMuemVybzIgPSB6ZXJvMjtcblxuZnVuY3Rpb24gemVybzgod29yZCkge1xuICBpZiAod29yZC5sZW5ndGggPT09IDcpXG4gICAgcmV0dXJuICcwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSA2KVxuICAgIHJldHVybiAnMDAnICsgd29yZDtcbiAgZWxzZSBpZiAod29yZC5sZW5ndGggPT09IDUpXG4gICAgcmV0dXJuICcwMDAnICsgd29yZDtcbiAgZWxzZSBpZiAod29yZC5sZW5ndGggPT09IDQpXG4gICAgcmV0dXJuICcwMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSAzKVxuICAgIHJldHVybiAnMDAwMDAnICsgd29yZDtcbiAgZWxzZSBpZiAod29yZC5sZW5ndGggPT09IDIpXG4gICAgcmV0dXJuICcwMDAwMDAnICsgd29yZDtcbiAgZWxzZSBpZiAod29yZC5sZW5ndGggPT09IDEpXG4gICAgcmV0dXJuICcwMDAwMDAwJyArIHdvcmQ7XG4gIGVsc2VcbiAgICByZXR1cm4gd29yZDtcbn1cbnV0aWxzLnplcm84ID0gemVybzg7XG5cbmZ1bmN0aW9uIGpvaW4zMihtc2csIHN0YXJ0LCBlbmQsIGVuZGlhbikge1xuICB2YXIgbGVuID0gZW5kIC0gc3RhcnQ7XG4gIGFzc2VydChsZW4gJSA0ID09PSAwKTtcbiAgdmFyIHJlcyA9IG5ldyBBcnJheShsZW4gLyA0KTtcbiAgZm9yICh2YXIgaSA9IDAsIGsgPSBzdGFydDsgaSA8IHJlcy5sZW5ndGg7IGkrKywgayArPSA0KSB7XG4gICAgdmFyIHc7XG4gICAgaWYgKGVuZGlhbiA9PT0gJ2JpZycpXG4gICAgICB3ID0gKG1zZ1trXSA8PCAyNCkgfCAobXNnW2sgKyAxXSA8PCAxNikgfCAobXNnW2sgKyAyXSA8PCA4KSB8IG1zZ1trICsgM107XG4gICAgZWxzZVxuICAgICAgdyA9IChtc2dbayArIDNdIDw8IDI0KSB8IChtc2dbayArIDJdIDw8IDE2KSB8IChtc2dbayArIDFdIDw8IDgpIHwgbXNnW2tdO1xuICAgIHJlc1tpXSA9IHcgPj4+IDA7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbnV0aWxzLmpvaW4zMiA9IGpvaW4zMjtcblxuZnVuY3Rpb24gc3BsaXQzMihtc2csIGVuZGlhbikge1xuICB2YXIgcmVzID0gbmV3IEFycmF5KG1zZy5sZW5ndGggKiA0KTtcbiAgZm9yICh2YXIgaSA9IDAsIGsgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrLCBrICs9IDQpIHtcbiAgICB2YXIgbSA9IG1zZ1tpXTtcbiAgICBpZiAoZW5kaWFuID09PSAnYmlnJykge1xuICAgICAgcmVzW2tdID0gbSA+Pj4gMjQ7XG4gICAgICByZXNbayArIDFdID0gKG0gPj4+IDE2KSAmIDB4ZmY7XG4gICAgICByZXNbayArIDJdID0gKG0gPj4+IDgpICYgMHhmZjtcbiAgICAgIHJlc1trICsgM10gPSBtICYgMHhmZjtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzW2sgKyAzXSA9IG0gPj4+IDI0O1xuICAgICAgcmVzW2sgKyAyXSA9IChtID4+PiAxNikgJiAweGZmO1xuICAgICAgcmVzW2sgKyAxXSA9IChtID4+PiA4KSAmIDB4ZmY7XG4gICAgICByZXNba10gPSBtICYgMHhmZjtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbnV0aWxzLnNwbGl0MzIgPSBzcGxpdDMyO1xuXG5mdW5jdGlvbiByb3RyMzIodywgYikge1xuICByZXR1cm4gKHcgPj4+IGIpIHwgKHcgPDwgKDMyIC0gYikpO1xufVxudXRpbHMucm90cjMyID0gcm90cjMyO1xuXG5mdW5jdGlvbiByb3RsMzIodywgYikge1xuICByZXR1cm4gKHcgPDwgYikgfCAodyA+Pj4gKDMyIC0gYikpO1xufVxudXRpbHMucm90bDMyID0gcm90bDMyO1xuXG5mdW5jdGlvbiBzdW0zMihhLCBiKSB7XG4gIHJldHVybiAoYSArIGIpID4+PiAwO1xufVxudXRpbHMuc3VtMzIgPSBzdW0zMjtcblxuZnVuY3Rpb24gc3VtMzJfMyhhLCBiLCBjKSB7XG4gIHJldHVybiAoYSArIGIgKyBjKSA+Pj4gMDtcbn1cbnV0aWxzLnN1bTMyXzMgPSBzdW0zMl8zO1xuXG5mdW5jdGlvbiBzdW0zMl80KGEsIGIsIGMsIGQpIHtcbiAgcmV0dXJuIChhICsgYiArIGMgKyBkKSA+Pj4gMDtcbn1cbnV0aWxzLnN1bTMyXzQgPSBzdW0zMl80O1xuXG5mdW5jdGlvbiBzdW0zMl81KGEsIGIsIGMsIGQsIGUpIHtcbiAgcmV0dXJuIChhICsgYiArIGMgKyBkICsgZSkgPj4+IDA7XG59XG51dGlscy5zdW0zMl81ID0gc3VtMzJfNTtcblxuZnVuY3Rpb24gYXNzZXJ0KGNvbmQsIG1zZykge1xuICBpZiAoIWNvbmQpXG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZyB8fCAnQXNzZXJ0aW9uIGZhaWxlZCcpO1xufVxudXRpbHMuYXNzZXJ0ID0gYXNzZXJ0O1xuXG51dGlscy5pbmhlcml0cyA9IGluaGVyaXRzO1xuXG5mdW5jdGlvbiBzdW02NChidWYsIHBvcywgYWgsIGFsKSB7XG4gIHZhciBiaCA9IGJ1Zltwb3NdO1xuICB2YXIgYmwgPSBidWZbcG9zICsgMV07XG5cbiAgdmFyIGxvID0gKGFsICsgYmwpID4+PiAwO1xuICB2YXIgaGkgPSAobG8gPCBhbCA/IDEgOiAwKSArIGFoICsgYmg7XG4gIGJ1Zltwb3NdID0gaGkgPj4+IDA7XG4gIGJ1Zltwb3MgKyAxXSA9IGxvO1xufVxuZXhwb3J0cy5zdW02NCA9IHN1bTY0O1xuXG5mdW5jdGlvbiBzdW02NF9oaShhaCwgYWwsIGJoLCBibCkge1xuICB2YXIgbG8gPSAoYWwgKyBibCkgPj4+IDA7XG4gIHZhciBoaSA9IChsbyA8IGFsID8gMSA6IDApICsgYWggKyBiaDtcbiAgcmV0dXJuIGhpID4+PiAwO1xufTtcbmV4cG9ydHMuc3VtNjRfaGkgPSBzdW02NF9oaTtcblxuZnVuY3Rpb24gc3VtNjRfbG8oYWgsIGFsLCBiaCwgYmwpIHtcbiAgdmFyIGxvID0gYWwgKyBibDtcbiAgcmV0dXJuIGxvID4+PiAwO1xufTtcbmV4cG9ydHMuc3VtNjRfbG8gPSBzdW02NF9sbztcblxuZnVuY3Rpb24gc3VtNjRfNF9oaShhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgdmFyIGxvID0gYWw7XG4gIGxvID0gKGxvICsgYmwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGFsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgY2wpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGNsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZGwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGRsID8gMSA6IDA7XG5cbiAgdmFyIGhpID0gYWggKyBiaCArIGNoICsgZGggKyBjYXJyeTtcbiAgcmV0dXJuIGhpID4+PiAwO1xufTtcbmV4cG9ydHMuc3VtNjRfNF9oaSA9IHN1bTY0XzRfaGk7XG5cbmZ1bmN0aW9uIHN1bTY0XzRfbG8oYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCwgZGgsIGRsKSB7XG4gIHZhciBsbyA9IGFsICsgYmwgKyBjbCArIGRsO1xuICByZXR1cm4gbG8gPj4+IDA7XG59O1xuZXhwb3J0cy5zdW02NF80X2xvID0gc3VtNjRfNF9sbztcblxuZnVuY3Rpb24gc3VtNjRfNV9oaShhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwsIGVoLCBlbCkge1xuICB2YXIgY2FycnkgPSAwO1xuICB2YXIgbG8gPSBhbDtcbiAgbG8gPSAobG8gKyBibCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgYWwgPyAxIDogMDtcbiAgbG8gPSAobG8gKyBjbCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgY2wgPyAxIDogMDtcbiAgbG8gPSAobG8gKyBkbCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgZGwgPyAxIDogMDtcbiAgbG8gPSAobG8gKyBlbCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgZWwgPyAxIDogMDtcblxuICB2YXIgaGkgPSBhaCArIGJoICsgY2ggKyBkaCArIGVoICsgY2Fycnk7XG4gIHJldHVybiBoaSA+Pj4gMDtcbn07XG5leHBvcnRzLnN1bTY0XzVfaGkgPSBzdW02NF81X2hpO1xuXG5mdW5jdGlvbiBzdW02NF81X2xvKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wsIGRoLCBkbCwgZWgsIGVsKSB7XG4gIHZhciBsbyA9IGFsICsgYmwgKyBjbCArIGRsICsgZWw7XG5cbiAgcmV0dXJuIGxvID4+PiAwO1xufTtcbmV4cG9ydHMuc3VtNjRfNV9sbyA9IHN1bTY0XzVfbG87XG5cbmZ1bmN0aW9uIHJvdHI2NF9oaShhaCwgYWwsIG51bSkge1xuICB2YXIgciA9IChhbCA8PCAoMzIgLSBudW0pKSB8IChhaCA+Pj4gbnVtKTtcbiAgcmV0dXJuIHIgPj4+IDA7XG59O1xuZXhwb3J0cy5yb3RyNjRfaGkgPSByb3RyNjRfaGk7XG5cbmZ1bmN0aW9uIHJvdHI2NF9sbyhhaCwgYWwsIG51bSkge1xuICB2YXIgciA9IChhaCA8PCAoMzIgLSBudW0pKSB8IChhbCA+Pj4gbnVtKTtcbiAgcmV0dXJuIHIgPj4+IDA7XG59O1xuZXhwb3J0cy5yb3RyNjRfbG8gPSByb3RyNjRfbG87XG5cbmZ1bmN0aW9uIHNocjY0X2hpKGFoLCBhbCwgbnVtKSB7XG4gIHJldHVybiBhaCA+Pj4gbnVtO1xufTtcbmV4cG9ydHMuc2hyNjRfaGkgPSBzaHI2NF9oaTtcblxuZnVuY3Rpb24gc2hyNjRfbG8oYWgsIGFsLCBudW0pIHtcbiAgdmFyIHIgPSAoYWggPDwgKDMyIC0gbnVtKSkgfCAoYWwgPj4+IG51bSk7XG4gIHJldHVybiByID4+PiAwO1xufTtcbmV4cG9ydHMuc2hyNjRfbG8gPSBzaHI2NF9sbztcbiIsIm1vZHVsZS5leHBvcnRzPXtcbiAgXCJuYW1lXCI6IFwiZWxsaXB0aWNcIixcbiAgXCJ2ZXJzaW9uXCI6IFwiNi4yLjNcIixcbiAgXCJkZXNjcmlwdGlvblwiOiBcIkVDIGNyeXB0b2dyYXBoeVwiLFxuICBcIm1haW5cIjogXCJsaWIvZWxsaXB0aWMuanNcIixcbiAgXCJmaWxlc1wiOiBbXG4gICAgXCJsaWJcIlxuICBdLFxuICBcInNjcmlwdHNcIjoge1xuICAgIFwiY292ZXJhZ2VcIjogXCJucG0gcnVuIHVuaXQgLS1jb3ZlcmFnZVwiLFxuICAgIFwiY292ZXJhbGxzXCI6IFwibnBtIHJ1biBjb3ZlcmFnZSAmJiBjYXQgLi9jb3ZlcmFnZS9sY292LmluZm8gfCBjb3ZlcmFsbHNcIixcbiAgICBcImpzY3NcIjogXCJqc2NzIGJlbmNobWFya3MvKi5qcyBsaWIvKi5qcyBsaWIvKiovKi5qcyBsaWIvKiovKiovKi5qcyB0ZXN0LyouanNcIixcbiAgICBcImpzaGludFwiOiBcImpzY3MgYmVuY2htYXJrcy8qLmpzIGxpYi8qLmpzIGxpYi8qKi8qLmpzIGxpYi8qKi8qKi8qLmpzIHRlc3QvKi5qc1wiLFxuICAgIFwibGludFwiOiBcIm5wbSBydW4ganNjcyAmJiBucG0gcnVuIGpzaGludFwiLFxuICAgIFwidGVzdFwiOiBcIm5wbSBydW4gbGludCAmJiBucG0gcnVuIHVuaXRcIixcbiAgICBcInVuaXRcIjogXCJpc3RhbmJ1bCB0ZXN0IF9tb2NoYSAtLXJlcG9ydGVyPXNwZWMgdGVzdC8qLXRlc3QuanNcIlxuICB9LFxuICBcInJlcG9zaXRvcnlcIjoge1xuICAgIFwidHlwZVwiOiBcImdpdFwiLFxuICAgIFwidXJsXCI6IFwiZ2l0K3NzaDovL2dpdEBnaXRodWIuY29tL2luZHV0bnkvZWxsaXB0aWMuZ2l0XCJcbiAgfSxcbiAgXCJrZXl3b3Jkc1wiOiBbXG4gICAgXCJFQ1wiLFxuICAgIFwiRWxsaXB0aWNcIixcbiAgICBcImN1cnZlXCIsXG4gICAgXCJDcnlwdG9ncmFwaHlcIlxuICBdLFxuICBcImF1dGhvclwiOiB7XG4gICAgXCJuYW1lXCI6IFwiRmVkb3IgSW5kdXRueVwiLFxuICAgIFwiZW1haWxcIjogXCJmZWRvckBpbmR1dG55LmNvbVwiXG4gIH0sXG4gIFwibGljZW5zZVwiOiBcIk1JVFwiLFxuICBcImJ1Z3NcIjoge1xuICAgIFwidXJsXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL2luZHV0bnkvZWxsaXB0aWMvaXNzdWVzXCJcbiAgfSxcbiAgXCJob21lcGFnZVwiOiBcImh0dHBzOi8vZ2l0aHViLmNvbS9pbmR1dG55L2VsbGlwdGljXCIsXG4gIFwiZGV2RGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcImNvdmVyYWxsc1wiOiBcIl4yLjExLjNcIixcbiAgICBcImlzdGFuYnVsXCI6IFwiXjAuNC4yXCIsXG4gICAgXCJqc2NzXCI6IFwiXjIuOS4wXCIsXG4gICAgXCJqc2hpbnRcIjogXCJeMi42LjBcIixcbiAgICBcIm1vY2hhXCI6IFwiXjIuMS4wXCJcbiAgfSxcbiAgXCJkZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiYm4uanNcIjogXCJeNC4wLjBcIixcbiAgICBcImJyb3JhbmRcIjogXCJeMS4wLjFcIixcbiAgICBcImhhc2guanNcIjogXCJeMS4wLjBcIixcbiAgICBcImluaGVyaXRzXCI6IFwiXjIuMC4xXCJcbiAgfSxcbiAgXCJnaXRIZWFkXCI6IFwiYzMyZjIwYjIyYjQyMGViNmFmM2M2ZGRhMjg5NjNkZWI3ZmFjZjgyM1wiLFxuICBcIl9pZFwiOiBcImVsbGlwdGljQDYuMi4zXCIsXG4gIFwiX3NoYXN1bVwiOiBcIjE4ZTQ2ZDczMDZiMDk1MTI3NWEyZDQyMDYzMjcwYTE0Yjc0ZWJlOTlcIixcbiAgXCJfZnJvbVwiOiBcImVsbGlwdGljQF42LjAuMFwiLFxuICBcIl9ucG1WZXJzaW9uXCI6IFwiMy4zLjEyXCIsXG4gIFwiX25vZGVWZXJzaW9uXCI6IFwiNS40LjFcIixcbiAgXCJfbnBtVXNlclwiOiB7XG4gICAgXCJuYW1lXCI6IFwiaW5kdXRueVwiLFxuICAgIFwiZW1haWxcIjogXCJmZWRvckBpbmR1dG55LmNvbVwiXG4gIH0sXG4gIFwiZGlzdFwiOiB7XG4gICAgXCJzaGFzdW1cIjogXCIxOGU0NmQ3MzA2YjA5NTEyNzVhMmQ0MjA2MzI3MGExNGI3NGViZTk5XCIsXG4gICAgXCJ0YXJiYWxsXCI6IFwiaHR0cDovL3JlZ2lzdHJ5Lm5wbWpzLm9yZy9lbGxpcHRpYy8tL2VsbGlwdGljLTYuMi4zLnRnelwiXG4gIH0sXG4gIFwibWFpbnRhaW5lcnNcIjogW1xuICAgIHtcbiAgICAgIFwibmFtZVwiOiBcImluZHV0bnlcIixcbiAgICAgIFwiZW1haWxcIjogXCJmZWRvckBpbmR1dG55LmNvbVwiXG4gICAgfVxuICBdLFxuICBcImRpcmVjdG9yaWVzXCI6IHt9LFxuICBcIl9yZXNvbHZlZFwiOiBcImh0dHBzOi8vcmVnaXN0cnkubnBtanMub3JnL2VsbGlwdGljLy0vZWxsaXB0aWMtNi4yLjMudGd6XCJcbn1cbiIsIm1vZHVsZS5leHBvcnRzPXtcIjIuMTYuODQwLjEuMTAxLjMuNC4xLjFcIjogXCJhZXMtMTI4LWVjYlwiLFxuXCIyLjE2Ljg0MC4xLjEwMS4zLjQuMS4yXCI6IFwiYWVzLTEyOC1jYmNcIixcblwiMi4xNi44NDAuMS4xMDEuMy40LjEuM1wiOiBcImFlcy0xMjgtb2ZiXCIsXG5cIjIuMTYuODQwLjEuMTAxLjMuNC4xLjRcIjogXCJhZXMtMTI4LWNmYlwiLFxuXCIyLjE2Ljg0MC4xLjEwMS4zLjQuMS4yMVwiOiBcImFlcy0xOTItZWNiXCIsXG5cIjIuMTYuODQwLjEuMTAxLjMuNC4xLjIyXCI6IFwiYWVzLTE5Mi1jYmNcIixcblwiMi4xNi44NDAuMS4xMDEuMy40LjEuMjNcIjogXCJhZXMtMTkyLW9mYlwiLFxuXCIyLjE2Ljg0MC4xLjEwMS4zLjQuMS4yNFwiOiBcImFlcy0xOTItY2ZiXCIsXG5cIjIuMTYuODQwLjEuMTAxLjMuNC4xLjQxXCI6IFwiYWVzLTI1Ni1lY2JcIixcblwiMi4xNi44NDAuMS4xMDEuMy40LjEuNDJcIjogXCJhZXMtMjU2LWNiY1wiLFxuXCIyLjE2Ljg0MC4xLjEwMS4zLjQuMS40M1wiOiBcImFlcy0yNTYtb2ZiXCIsXG5cIjIuMTYuODQwLjEuMTAxLjMuNC4xLjQ0XCI6IFwiYWVzLTI1Ni1jZmJcIlxufSIsIi8vIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2luZHV0bnkvc2VsZi1zaWduZWQvYmxvYi9naC1wYWdlcy9saWIvYXNuMS5qc1xuLy8gRmVkb3IsIHlvdSBhcmUgYW1hemluZy5cblxudmFyIGFzbjEgPSByZXF1aXJlKCdhc24xLmpzJylcblxudmFyIFJTQVByaXZhdGVLZXkgPSBhc24xLmRlZmluZSgnUlNBUHJpdmF0ZUtleScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ3ZlcnNpb24nKS5pbnQoKSxcbiAgICB0aGlzLmtleSgnbW9kdWx1cycpLmludCgpLFxuICAgIHRoaXMua2V5KCdwdWJsaWNFeHBvbmVudCcpLmludCgpLFxuICAgIHRoaXMua2V5KCdwcml2YXRlRXhwb25lbnQnKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncHJpbWUxJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3ByaW1lMicpLmludCgpLFxuICAgIHRoaXMua2V5KCdleHBvbmVudDEnKS5pbnQoKSxcbiAgICB0aGlzLmtleSgnZXhwb25lbnQyJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ2NvZWZmaWNpZW50JykuaW50KClcbiAgKVxufSlcbmV4cG9ydHMuUlNBUHJpdmF0ZUtleSA9IFJTQVByaXZhdGVLZXlcblxudmFyIFJTQVB1YmxpY0tleSA9IGFzbjEuZGVmaW5lKCdSU0FQdWJsaWNLZXknLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCdtb2R1bHVzJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3B1YmxpY0V4cG9uZW50JykuaW50KClcbiAgKVxufSlcbmV4cG9ydHMuUlNBUHVibGljS2V5ID0gUlNBUHVibGljS2V5XG5cbnZhciBQdWJsaWNLZXkgPSBhc24xLmRlZmluZSgnU3ViamVjdFB1YmxpY0tleUluZm8nLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCdhbGdvcml0aG0nKS51c2UoQWxnb3JpdGhtSWRlbnRpZmllciksXG4gICAgdGhpcy5rZXkoJ3N1YmplY3RQdWJsaWNLZXknKS5iaXRzdHIoKVxuICApXG59KVxuZXhwb3J0cy5QdWJsaWNLZXkgPSBQdWJsaWNLZXlcblxudmFyIEFsZ29yaXRobUlkZW50aWZpZXIgPSBhc24xLmRlZmluZSgnQWxnb3JpdGhtSWRlbnRpZmllcicsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ2FsZ29yaXRobScpLm9iamlkKCksXG4gICAgdGhpcy5rZXkoJ25vbmUnKS5udWxsXygpLm9wdGlvbmFsKCksXG4gICAgdGhpcy5rZXkoJ2N1cnZlJykub2JqaWQoKS5vcHRpb25hbCgpLFxuICAgIHRoaXMua2V5KCdwYXJhbXMnKS5zZXEoKS5vYmooXG4gICAgICB0aGlzLmtleSgncCcpLmludCgpLFxuICAgICAgdGhpcy5rZXkoJ3EnKS5pbnQoKSxcbiAgICAgIHRoaXMua2V5KCdnJykuaW50KClcbiAgICApLm9wdGlvbmFsKClcbiAgKVxufSlcblxudmFyIFByaXZhdGVLZXlJbmZvID0gYXNuMS5kZWZpbmUoJ1ByaXZhdGVLZXlJbmZvJywgZnVuY3Rpb24gKCkge1xuICB0aGlzLnNlcSgpLm9iaihcbiAgICB0aGlzLmtleSgndmVyc2lvbicpLmludCgpLFxuICAgIHRoaXMua2V5KCdhbGdvcml0aG0nKS51c2UoQWxnb3JpdGhtSWRlbnRpZmllciksXG4gICAgdGhpcy5rZXkoJ3N1YmplY3RQcml2YXRlS2V5Jykub2N0c3RyKClcbiAgKVxufSlcbmV4cG9ydHMuUHJpdmF0ZUtleSA9IFByaXZhdGVLZXlJbmZvXG52YXIgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gPSBhc24xLmRlZmluZSgnRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8nLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCdhbGdvcml0aG0nKS5zZXEoKS5vYmooXG4gICAgICB0aGlzLmtleSgnaWQnKS5vYmppZCgpLFxuICAgICAgdGhpcy5rZXkoJ2RlY3J5cHQnKS5zZXEoKS5vYmooXG4gICAgICAgIHRoaXMua2V5KCdrZGUnKS5zZXEoKS5vYmooXG4gICAgICAgICAgdGhpcy5rZXkoJ2lkJykub2JqaWQoKSxcbiAgICAgICAgICB0aGlzLmtleSgna2RlcGFyYW1zJykuc2VxKCkub2JqKFxuICAgICAgICAgICAgdGhpcy5rZXkoJ3NhbHQnKS5vY3RzdHIoKSxcbiAgICAgICAgICAgIHRoaXMua2V5KCdpdGVycycpLmludCgpXG4gICAgICAgICAgKVxuICAgICAgICApLFxuICAgICAgICB0aGlzLmtleSgnY2lwaGVyJykuc2VxKCkub2JqKFxuICAgICAgICAgIHRoaXMua2V5KCdhbGdvJykub2JqaWQoKSxcbiAgICAgICAgICB0aGlzLmtleSgnaXYnKS5vY3RzdHIoKVxuICAgICAgICApXG4gICAgICApXG4gICAgKSxcbiAgICB0aGlzLmtleSgnc3ViamVjdFByaXZhdGVLZXknKS5vY3RzdHIoKVxuICApXG59KVxuXG5leHBvcnRzLkVuY3J5cHRlZFByaXZhdGVLZXkgPSBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mb1xuXG52YXIgRFNBUHJpdmF0ZUtleSA9IGFzbjEuZGVmaW5lKCdEU0FQcml2YXRlS2V5JywgZnVuY3Rpb24gKCkge1xuICB0aGlzLnNlcSgpLm9iaihcbiAgICB0aGlzLmtleSgndmVyc2lvbicpLmludCgpLFxuICAgIHRoaXMua2V5KCdwJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3EnKS5pbnQoKSxcbiAgICB0aGlzLmtleSgnZycpLmludCgpLFxuICAgIHRoaXMua2V5KCdwdWJfa2V5JykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3ByaXZfa2V5JykuaW50KClcbiAgKVxufSlcbmV4cG9ydHMuRFNBUHJpdmF0ZUtleSA9IERTQVByaXZhdGVLZXlcblxuZXhwb3J0cy5EU0FwYXJhbSA9IGFzbjEuZGVmaW5lKCdEU0FwYXJhbScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5pbnQoKVxufSlcbnZhciBFQ1ByaXZhdGVLZXkgPSBhc24xLmRlZmluZSgnRUNQcml2YXRlS2V5JywgZnVuY3Rpb24gKCkge1xuICB0aGlzLnNlcSgpLm9iaihcbiAgICB0aGlzLmtleSgndmVyc2lvbicpLmludCgpLFxuICAgIHRoaXMua2V5KCdwcml2YXRlS2V5Jykub2N0c3RyKCksXG4gICAgdGhpcy5rZXkoJ3BhcmFtZXRlcnMnKS5vcHRpb25hbCgpLmV4cGxpY2l0KDApLnVzZShFQ1BhcmFtZXRlcnMpLFxuICAgIHRoaXMua2V5KCdwdWJsaWNLZXknKS5vcHRpb25hbCgpLmV4cGxpY2l0KDEpLmJpdHN0cigpXG4gIClcbn0pXG5leHBvcnRzLkVDUHJpdmF0ZUtleSA9IEVDUHJpdmF0ZUtleVxudmFyIEVDUGFyYW1ldGVycyA9IGFzbjEuZGVmaW5lKCdFQ1BhcmFtZXRlcnMnLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuY2hvaWNlKHtcbiAgICBuYW1lZEN1cnZlOiB0aGlzLm9iamlkKClcbiAgfSlcbn0pXG5cbmV4cG9ydHMuc2lnbmF0dXJlID0gYXNuMS5kZWZpbmUoJ3NpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ3InKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncycpLmludCgpXG4gIClcbn0pXG4iLCIvLyBhZGFwdGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2FwYXRpbC9wZW1zdHJpcFxudmFyIGZpbmRQcm9jID0gL1Byb2MtVHlwZTogNCxFTkNSWVBURURcXHI/XFxuREVLLUluZm86IEFFUy0oKD86MTI4KXwoPzoxOTIpfCg/OjI1NikpLUNCQywoWzAtOUEtSF0rKVxccj9cXG5cXHI/XFxuKFswLTlBLXpcXG5cXHJcXCtcXC9cXD1dKylcXHI/XFxuL21cbnZhciBzdGFydFJlZ2V4ID0gL14tLS0tLUJFR0lOICguKikgS0VZLS0tLS1cXHI/XFxuL21cbnZhciBmdWxsUmVnZXggPSAvXi0tLS0tQkVHSU4gKC4qKSBLRVktLS0tLVxccj9cXG4oWzAtOUEtelxcblxcclxcK1xcL1xcPV0rKVxccj9cXG4tLS0tLUVORCBcXDEgS0VZLS0tLS0kL21cbnZhciBldnAgPSByZXF1aXJlKCdldnBfYnl0ZXN0b2tleScpXG52YXIgY2lwaGVycyA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktYWVzJylcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9rZXksIHBhc3N3b3JkKSB7XG4gIHZhciBrZXkgPSBva2V5LnRvU3RyaW5nKClcbiAgdmFyIG1hdGNoID0ga2V5Lm1hdGNoKGZpbmRQcm9jKVxuICB2YXIgZGVjcnlwdGVkXG4gIGlmICghbWF0Y2gpIHtcbiAgICB2YXIgbWF0Y2gyID0ga2V5Lm1hdGNoKGZ1bGxSZWdleClcbiAgICBkZWNyeXB0ZWQgPSBuZXcgQnVmZmVyKG1hdGNoMlsyXS5yZXBsYWNlKC9cXHI/XFxuL2csICcnKSwgJ2Jhc2U2NCcpXG4gIH0gZWxzZSB7XG4gICAgdmFyIHN1aXRlID0gJ2FlcycgKyBtYXRjaFsxXVxuICAgIHZhciBpdiA9IG5ldyBCdWZmZXIobWF0Y2hbMl0sICdoZXgnKVxuICAgIHZhciBjaXBoZXJUZXh0ID0gbmV3IEJ1ZmZlcihtYXRjaFszXS5yZXBsYWNlKC9cXHI/XFxuL2csICcnKSwgJ2Jhc2U2NCcpXG4gICAgdmFyIGNpcGhlcktleSA9IGV2cChwYXNzd29yZCwgaXYuc2xpY2UoMCwgOCksIHBhcnNlSW50KG1hdGNoWzFdLCAxMCkpLmtleVxuICAgIHZhciBvdXQgPSBbXVxuICAgIHZhciBjaXBoZXIgPSBjaXBoZXJzLmNyZWF0ZURlY2lwaGVyaXYoc3VpdGUsIGNpcGhlcktleSwgaXYpXG4gICAgb3V0LnB1c2goY2lwaGVyLnVwZGF0ZShjaXBoZXJUZXh0KSlcbiAgICBvdXQucHVzaChjaXBoZXIuZmluYWwoKSlcbiAgICBkZWNyeXB0ZWQgPSBCdWZmZXIuY29uY2F0KG91dClcbiAgfVxuICB2YXIgdGFnID0ga2V5Lm1hdGNoKHN0YXJ0UmVnZXgpWzFdICsgJyBLRVknXG4gIHJldHVybiB7XG4gICAgdGFnOiB0YWcsXG4gICAgZGF0YTogZGVjcnlwdGVkXG4gIH1cbn1cbiIsInZhciBhc24xID0gcmVxdWlyZSgnLi9hc24xJylcbnZhciBhZXNpZCA9IHJlcXVpcmUoJy4vYWVzaWQuanNvbicpXG52YXIgZml4UHJvYyA9IHJlcXVpcmUoJy4vZml4UHJvYycpXG52YXIgY2lwaGVycyA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktYWVzJylcbnZhciBjb21wYXQgPSByZXF1aXJlKCdwYmtkZjInKVxubW9kdWxlLmV4cG9ydHMgPSBwYXJzZUtleXNcblxuZnVuY3Rpb24gcGFyc2VLZXlzIChidWZmZXIpIHtcbiAgdmFyIHBhc3N3b3JkXG4gIGlmICh0eXBlb2YgYnVmZmVyID09PSAnb2JqZWN0JyAmJiAhQnVmZmVyLmlzQnVmZmVyKGJ1ZmZlcikpIHtcbiAgICBwYXNzd29yZCA9IGJ1ZmZlci5wYXNzcGhyYXNlXG4gICAgYnVmZmVyID0gYnVmZmVyLmtleVxuICB9XG4gIGlmICh0eXBlb2YgYnVmZmVyID09PSAnc3RyaW5nJykge1xuICAgIGJ1ZmZlciA9IG5ldyBCdWZmZXIoYnVmZmVyKVxuICB9XG5cbiAgdmFyIHN0cmlwcGVkID0gZml4UHJvYyhidWZmZXIsIHBhc3N3b3JkKVxuXG4gIHZhciB0eXBlID0gc3RyaXBwZWQudGFnXG4gIHZhciBkYXRhID0gc3RyaXBwZWQuZGF0YVxuICB2YXIgc3VidHlwZSwgbmRhdGFcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnUFVCTElDIEtFWSc6XG4gICAgICBuZGF0YSA9IGFzbjEuUHVibGljS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIHN1YnR5cGUgPSBuZGF0YS5hbGdvcml0aG0uYWxnb3JpdGhtLmpvaW4oJy4nKVxuICAgICAgc3dpdGNoIChzdWJ0eXBlKSB7XG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTEzNTQ5LjEuMS4xJzpcbiAgICAgICAgICByZXR1cm4gYXNuMS5SU0FQdWJsaWNLZXkuZGVjb2RlKG5kYXRhLnN1YmplY3RQdWJsaWNLZXkuZGF0YSwgJ2RlcicpXG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTAwNDUuMi4xJzpcbiAgICAgICAgICBuZGF0YS5zdWJqZWN0UHJpdmF0ZUtleSA9IG5kYXRhLnN1YmplY3RQdWJsaWNLZXlcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ2VjJyxcbiAgICAgICAgICAgIGRhdGE6IG5kYXRhXG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICcxLjIuODQwLjEwMDQwLjQuMSc6XG4gICAgICAgICAgbmRhdGEuYWxnb3JpdGhtLnBhcmFtcy5wdWJfa2V5ID0gYXNuMS5EU0FwYXJhbS5kZWNvZGUobmRhdGEuc3ViamVjdFB1YmxpY0tleS5kYXRhLCAnZGVyJylcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ2RzYScsXG4gICAgICAgICAgICBkYXRhOiBuZGF0YS5hbGdvcml0aG0ucGFyYW1zXG4gICAgICAgICAgfVxuICAgICAgICBkZWZhdWx0OiB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24ga2V5IGlkICcgKyBzdWJ0eXBlKVxuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGtleSB0eXBlICcgKyB0eXBlKVxuICAgIGNhc2UgJ0VOQ1JZUFRFRCBQUklWQVRFIEtFWSc6XG4gICAgICBkYXRhID0gYXNuMS5FbmNyeXB0ZWRQcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIGRhdGEgPSBkZWNyeXB0KGRhdGEsIHBhc3N3b3JkKVxuICAgICAgLy8gZmFsbHMgdGhyb3VnaFxuICAgIGNhc2UgJ1BSSVZBVEUgS0VZJzpcbiAgICAgIG5kYXRhID0gYXNuMS5Qcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIHN1YnR5cGUgPSBuZGF0YS5hbGdvcml0aG0uYWxnb3JpdGhtLmpvaW4oJy4nKVxuICAgICAgc3dpdGNoIChzdWJ0eXBlKSB7XG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTEzNTQ5LjEuMS4xJzpcbiAgICAgICAgICByZXR1cm4gYXNuMS5SU0FQcml2YXRlS2V5LmRlY29kZShuZGF0YS5zdWJqZWN0UHJpdmF0ZUtleSwgJ2RlcicpXG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTAwNDUuMi4xJzpcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3VydmU6IG5kYXRhLmFsZ29yaXRobS5jdXJ2ZSxcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IGFzbjEuRUNQcml2YXRlS2V5LmRlY29kZShuZGF0YS5zdWJqZWN0UHJpdmF0ZUtleSwgJ2RlcicpLnByaXZhdGVLZXlcbiAgICAgICAgICB9XG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTAwNDAuNC4xJzpcbiAgICAgICAgICBuZGF0YS5hbGdvcml0aG0ucGFyYW1zLnByaXZfa2V5ID0gYXNuMS5EU0FwYXJhbS5kZWNvZGUobmRhdGEuc3ViamVjdFByaXZhdGVLZXksICdkZXInKVxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAnZHNhJyxcbiAgICAgICAgICAgIHBhcmFtczogbmRhdGEuYWxnb3JpdGhtLnBhcmFtc1xuICAgICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGtleSBpZCAnICsgc3VidHlwZSlcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBrZXkgdHlwZSAnICsgdHlwZSlcbiAgICBjYXNlICdSU0EgUFVCTElDIEtFWSc6XG4gICAgICByZXR1cm4gYXNuMS5SU0FQdWJsaWNLZXkuZGVjb2RlKGRhdGEsICdkZXInKVxuICAgIGNhc2UgJ1JTQSBQUklWQVRFIEtFWSc6XG4gICAgICByZXR1cm4gYXNuMS5SU0FQcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICBjYXNlICdEU0EgUFJJVkFURSBLRVknOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2RzYScsXG4gICAgICAgIHBhcmFtczogYXNuMS5EU0FQcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIH1cbiAgICBjYXNlICdFQyBQUklWQVRFIEtFWSc6XG4gICAgICBkYXRhID0gYXNuMS5FQ1ByaXZhdGVLZXkuZGVjb2RlKGRhdGEsICdkZXInKVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY3VydmU6IGRhdGEucGFyYW1ldGVycy52YWx1ZSxcbiAgICAgICAgcHJpdmF0ZUtleTogZGF0YS5wcml2YXRlS2V5XG4gICAgICB9XG4gICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGtleSB0eXBlICcgKyB0eXBlKVxuICB9XG59XG5wYXJzZUtleXMuc2lnbmF0dXJlID0gYXNuMS5zaWduYXR1cmVcbmZ1bmN0aW9uIGRlY3J5cHQgKGRhdGEsIHBhc3N3b3JkKSB7XG4gIHZhciBzYWx0ID0gZGF0YS5hbGdvcml0aG0uZGVjcnlwdC5rZGUua2RlcGFyYW1zLnNhbHRcbiAgdmFyIGl0ZXJzID0gcGFyc2VJbnQoZGF0YS5hbGdvcml0aG0uZGVjcnlwdC5rZGUua2RlcGFyYW1zLml0ZXJzLnRvU3RyaW5nKCksIDEwKVxuICB2YXIgYWxnbyA9IGFlc2lkW2RhdGEuYWxnb3JpdGhtLmRlY3J5cHQuY2lwaGVyLmFsZ28uam9pbignLicpXVxuICB2YXIgaXYgPSBkYXRhLmFsZ29yaXRobS5kZWNyeXB0LmNpcGhlci5pdlxuICB2YXIgY2lwaGVyVGV4dCA9IGRhdGEuc3ViamVjdFByaXZhdGVLZXlcbiAgdmFyIGtleWxlbiA9IHBhcnNlSW50KGFsZ28uc3BsaXQoJy0nKVsxXSwgMTApIC8gOFxuICB2YXIga2V5ID0gY29tcGF0LnBia2RmMlN5bmMocGFzc3dvcmQsIHNhbHQsIGl0ZXJzLCBrZXlsZW4pXG4gIHZhciBjaXBoZXIgPSBjaXBoZXJzLmNyZWF0ZURlY2lwaGVyaXYoYWxnbywga2V5LCBpdilcbiAgdmFyIG91dCA9IFtdXG4gIG91dC5wdXNoKGNpcGhlci51cGRhdGUoY2lwaGVyVGV4dCkpXG4gIG91dC5wdXNoKGNpcGhlci5maW5hbCgpKVxuICByZXR1cm4gQnVmZmVyLmNvbmNhdChvdXQpXG59XG4iLCJ2YXIgYXNuMSA9IGV4cG9ydHM7XG5cbmFzbjEuYmlnbnVtID0gcmVxdWlyZSgnYm4uanMnKTtcblxuYXNuMS5kZWZpbmUgPSByZXF1aXJlKCcuL2FzbjEvYXBpJykuZGVmaW5lO1xuYXNuMS5iYXNlID0gcmVxdWlyZSgnLi9hc24xL2Jhc2UnKTtcbmFzbjEuY29uc3RhbnRzID0gcmVxdWlyZSgnLi9hc24xL2NvbnN0YW50cycpO1xuYXNuMS5kZWNvZGVycyA9IHJlcXVpcmUoJy4vYXNuMS9kZWNvZGVycycpO1xuYXNuMS5lbmNvZGVycyA9IHJlcXVpcmUoJy4vYXNuMS9lbmNvZGVycycpO1xuIiwidmFyIGFzbjEgPSByZXF1aXJlKCcuLi9hc24xJyk7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG52YXIgYXBpID0gZXhwb3J0cztcblxuYXBpLmRlZmluZSA9IGZ1bmN0aW9uIGRlZmluZShuYW1lLCBib2R5KSB7XG4gIHJldHVybiBuZXcgRW50aXR5KG5hbWUsIGJvZHkpO1xufTtcblxuZnVuY3Rpb24gRW50aXR5KG5hbWUsIGJvZHkpIHtcbiAgdGhpcy5uYW1lID0gbmFtZTtcbiAgdGhpcy5ib2R5ID0gYm9keTtcblxuICB0aGlzLmRlY29kZXJzID0ge307XG4gIHRoaXMuZW5jb2RlcnMgPSB7fTtcbn07XG5cbkVudGl0eS5wcm90b3R5cGUuX2NyZWF0ZU5hbWVkID0gZnVuY3Rpb24gY3JlYXRlTmFtZWQoYmFzZSkge1xuICB2YXIgbmFtZWQ7XG4gIHRyeSB7XG4gICAgbmFtZWQgPSByZXF1aXJlKCd2bScpLnJ1bkluVGhpc0NvbnRleHQoXG4gICAgICAnKGZ1bmN0aW9uICcgKyB0aGlzLm5hbWUgKyAnKGVudGl0eSkge1xcbicgK1xuICAgICAgJyAgdGhpcy5faW5pdE5hbWVkKGVudGl0eSk7XFxuJyArXG4gICAgICAnfSknXG4gICAgKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIG5hbWVkID0gZnVuY3Rpb24gKGVudGl0eSkge1xuICAgICAgdGhpcy5faW5pdE5hbWVkKGVudGl0eSk7XG4gICAgfTtcbiAgfVxuICBpbmhlcml0cyhuYW1lZCwgYmFzZSk7XG4gIG5hbWVkLnByb3RvdHlwZS5faW5pdE5hbWVkID0gZnVuY3Rpb24gaW5pdG5hbWVkKGVudGl0eSkge1xuICAgIGJhc2UuY2FsbCh0aGlzLCBlbnRpdHkpO1xuICB9O1xuXG4gIHJldHVybiBuZXcgbmFtZWQodGhpcyk7XG59O1xuXG5FbnRpdHkucHJvdG90eXBlLl9nZXREZWNvZGVyID0gZnVuY3Rpb24gX2dldERlY29kZXIoZW5jKSB7XG4gIC8vIExhemlseSBjcmVhdGUgZGVjb2RlclxuICBpZiAoIXRoaXMuZGVjb2RlcnMuaGFzT3duUHJvcGVydHkoZW5jKSlcbiAgICB0aGlzLmRlY29kZXJzW2VuY10gPSB0aGlzLl9jcmVhdGVOYW1lZChhc24xLmRlY29kZXJzW2VuY10pO1xuICByZXR1cm4gdGhpcy5kZWNvZGVyc1tlbmNdO1xufTtcblxuRW50aXR5LnByb3RvdHlwZS5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUoZGF0YSwgZW5jLCBvcHRpb25zKSB7XG4gIHJldHVybiB0aGlzLl9nZXREZWNvZGVyKGVuYykuZGVjb2RlKGRhdGEsIG9wdGlvbnMpO1xufTtcblxuRW50aXR5LnByb3RvdHlwZS5fZ2V0RW5jb2RlciA9IGZ1bmN0aW9uIF9nZXRFbmNvZGVyKGVuYykge1xuICAvLyBMYXppbHkgY3JlYXRlIGVuY29kZXJcbiAgaWYgKCF0aGlzLmVuY29kZXJzLmhhc093blByb3BlcnR5KGVuYykpXG4gICAgdGhpcy5lbmNvZGVyc1tlbmNdID0gdGhpcy5fY3JlYXRlTmFtZWQoYXNuMS5lbmNvZGVyc1tlbmNdKTtcbiAgcmV0dXJuIHRoaXMuZW5jb2RlcnNbZW5jXTtcbn07XG5cbkVudGl0eS5wcm90b3R5cGUuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKGRhdGEsIGVuYywgLyogaW50ZXJuYWwgKi8gcmVwb3J0ZXIpIHtcbiAgcmV0dXJuIHRoaXMuX2dldEVuY29kZXIoZW5jKS5lbmNvZGUoZGF0YSwgcmVwb3J0ZXIpO1xufTtcbiIsInZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG52YXIgUmVwb3J0ZXIgPSByZXF1aXJlKCcuLi9iYXNlJykuUmVwb3J0ZXI7XG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuXG5mdW5jdGlvbiBEZWNvZGVyQnVmZmVyKGJhc2UsIG9wdGlvbnMpIHtcbiAgUmVwb3J0ZXIuY2FsbCh0aGlzLCBvcHRpb25zKTtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYmFzZSkpIHtcbiAgICB0aGlzLmVycm9yKCdJbnB1dCBub3QgQnVmZmVyJyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5iYXNlID0gYmFzZTtcbiAgdGhpcy5vZmZzZXQgPSAwO1xuICB0aGlzLmxlbmd0aCA9IGJhc2UubGVuZ3RoO1xufVxuaW5oZXJpdHMoRGVjb2RlckJ1ZmZlciwgUmVwb3J0ZXIpO1xuZXhwb3J0cy5EZWNvZGVyQnVmZmVyID0gRGVjb2RlckJ1ZmZlcjtcblxuRGVjb2RlckJ1ZmZlci5wcm90b3R5cGUuc2F2ZSA9IGZ1bmN0aW9uIHNhdmUoKSB7XG4gIHJldHVybiB7IG9mZnNldDogdGhpcy5vZmZzZXQsIHJlcG9ydGVyOiBSZXBvcnRlci5wcm90b3R5cGUuc2F2ZS5jYWxsKHRoaXMpIH07XG59O1xuXG5EZWNvZGVyQnVmZmVyLnByb3RvdHlwZS5yZXN0b3JlID0gZnVuY3Rpb24gcmVzdG9yZShzYXZlKSB7XG4gIC8vIFJldHVybiBza2lwcGVkIGRhdGFcbiAgdmFyIHJlcyA9IG5ldyBEZWNvZGVyQnVmZmVyKHRoaXMuYmFzZSk7XG4gIHJlcy5vZmZzZXQgPSBzYXZlLm9mZnNldDtcbiAgcmVzLmxlbmd0aCA9IHRoaXMub2Zmc2V0O1xuXG4gIHRoaXMub2Zmc2V0ID0gc2F2ZS5vZmZzZXQ7XG4gIFJlcG9ydGVyLnByb3RvdHlwZS5yZXN0b3JlLmNhbGwodGhpcywgc2F2ZS5yZXBvcnRlcik7XG5cbiAgcmV0dXJuIHJlcztcbn07XG5cbkRlY29kZXJCdWZmZXIucHJvdG90eXBlLmlzRW1wdHkgPSBmdW5jdGlvbiBpc0VtcHR5KCkge1xuICByZXR1cm4gdGhpcy5vZmZzZXQgPT09IHRoaXMubGVuZ3RoO1xufTtcblxuRGVjb2RlckJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gcmVhZFVJbnQ4KGZhaWwpIHtcbiAgaWYgKHRoaXMub2Zmc2V0ICsgMSA8PSB0aGlzLmxlbmd0aClcbiAgICByZXR1cm4gdGhpcy5iYXNlLnJlYWRVSW50OCh0aGlzLm9mZnNldCsrLCB0cnVlKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmVycm9yKGZhaWwgfHwgJ0RlY29kZXJCdWZmZXIgb3ZlcnJ1bicpO1xufVxuXG5EZWNvZGVyQnVmZmVyLnByb3RvdHlwZS5za2lwID0gZnVuY3Rpb24gc2tpcChieXRlcywgZmFpbCkge1xuICBpZiAoISh0aGlzLm9mZnNldCArIGJ5dGVzIDw9IHRoaXMubGVuZ3RoKSlcbiAgICByZXR1cm4gdGhpcy5lcnJvcihmYWlsIHx8ICdEZWNvZGVyQnVmZmVyIG92ZXJydW4nKTtcblxuICB2YXIgcmVzID0gbmV3IERlY29kZXJCdWZmZXIodGhpcy5iYXNlKTtcblxuICAvLyBTaGFyZSByZXBvcnRlciBzdGF0ZVxuICByZXMuX3JlcG9ydGVyU3RhdGUgPSB0aGlzLl9yZXBvcnRlclN0YXRlO1xuXG4gIHJlcy5vZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgcmVzLmxlbmd0aCA9IHRoaXMub2Zmc2V0ICsgYnl0ZXM7XG4gIHRoaXMub2Zmc2V0ICs9IGJ5dGVzO1xuICByZXR1cm4gcmVzO1xufVxuXG5EZWNvZGVyQnVmZmVyLnByb3RvdHlwZS5yYXcgPSBmdW5jdGlvbiByYXcoc2F2ZSkge1xuICByZXR1cm4gdGhpcy5iYXNlLnNsaWNlKHNhdmUgPyBzYXZlLm9mZnNldCA6IHRoaXMub2Zmc2V0LCB0aGlzLmxlbmd0aCk7XG59XG5cbmZ1bmN0aW9uIEVuY29kZXJCdWZmZXIodmFsdWUsIHJlcG9ydGVyKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHRoaXMubGVuZ3RoID0gMDtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWUubWFwKGZ1bmN0aW9uKGl0ZW0pIHtcbiAgICAgIGlmICghKGl0ZW0gaW5zdGFuY2VvZiBFbmNvZGVyQnVmZmVyKSlcbiAgICAgICAgaXRlbSA9IG5ldyBFbmNvZGVyQnVmZmVyKGl0ZW0sIHJlcG9ydGVyKTtcbiAgICAgIHRoaXMubGVuZ3RoICs9IGl0ZW0ubGVuZ3RoO1xuICAgICAgcmV0dXJuIGl0ZW07XG4gICAgfSwgdGhpcyk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIGlmICghKDAgPD0gdmFsdWUgJiYgdmFsdWUgPD0gMHhmZikpXG4gICAgICByZXR1cm4gcmVwb3J0ZXIuZXJyb3IoJ25vbi1ieXRlIEVuY29kZXJCdWZmZXIgdmFsdWUnKTtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgdGhpcy5sZW5ndGggPSAxO1xuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgdGhpcy5sZW5ndGggPSBCdWZmZXIuYnl0ZUxlbmd0aCh2YWx1ZSk7XG4gIH0gZWxzZSBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbHVlKSkge1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLmxlbmd0aCA9IHZhbHVlLmxlbmd0aDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcmVwb3J0ZXIuZXJyb3IoJ1Vuc3VwcG9ydGVkIHR5cGU6ICcgKyB0eXBlb2YgdmFsdWUpO1xuICB9XG59XG5leHBvcnRzLkVuY29kZXJCdWZmZXIgPSBFbmNvZGVyQnVmZmVyO1xuXG5FbmNvZGVyQnVmZmVyLnByb3RvdHlwZS5qb2luID0gZnVuY3Rpb24gam9pbihvdXQsIG9mZnNldCkge1xuICBpZiAoIW91dClcbiAgICBvdXQgPSBuZXcgQnVmZmVyKHRoaXMubGVuZ3RoKTtcbiAgaWYgKCFvZmZzZXQpXG4gICAgb2Zmc2V0ID0gMDtcblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApXG4gICAgcmV0dXJuIG91dDtcblxuICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLnZhbHVlKSkge1xuICAgIHRoaXMudmFsdWUuZm9yRWFjaChmdW5jdGlvbihpdGVtKSB7XG4gICAgICBpdGVtLmpvaW4ob3V0LCBvZmZzZXQpO1xuICAgICAgb2Zmc2V0ICs9IGl0ZW0ubGVuZ3RoO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGlmICh0eXBlb2YgdGhpcy52YWx1ZSA9PT0gJ251bWJlcicpXG4gICAgICBvdXRbb2Zmc2V0XSA9IHRoaXMudmFsdWU7XG4gICAgZWxzZSBpZiAodHlwZW9mIHRoaXMudmFsdWUgPT09ICdzdHJpbmcnKVxuICAgICAgb3V0LndyaXRlKHRoaXMudmFsdWUsIG9mZnNldCk7XG4gICAgZWxzZSBpZiAoQnVmZmVyLmlzQnVmZmVyKHRoaXMudmFsdWUpKVxuICAgICAgdGhpcy52YWx1ZS5jb3B5KG91dCwgb2Zmc2V0KTtcbiAgICBvZmZzZXQgKz0gdGhpcy5sZW5ndGg7XG4gIH1cblxuICByZXR1cm4gb3V0O1xufTtcbiIsInZhciBiYXNlID0gZXhwb3J0cztcblxuYmFzZS5SZXBvcnRlciA9IHJlcXVpcmUoJy4vcmVwb3J0ZXInKS5SZXBvcnRlcjtcbmJhc2UuRGVjb2RlckJ1ZmZlciA9IHJlcXVpcmUoJy4vYnVmZmVyJykuRGVjb2RlckJ1ZmZlcjtcbmJhc2UuRW5jb2RlckJ1ZmZlciA9IHJlcXVpcmUoJy4vYnVmZmVyJykuRW5jb2RlckJ1ZmZlcjtcbmJhc2UuTm9kZSA9IHJlcXVpcmUoJy4vbm9kZScpO1xuIiwidmFyIFJlcG9ydGVyID0gcmVxdWlyZSgnLi4vYmFzZScpLlJlcG9ydGVyO1xudmFyIEVuY29kZXJCdWZmZXIgPSByZXF1aXJlKCcuLi9iYXNlJykuRW5jb2RlckJ1ZmZlcjtcbnZhciBhc3NlcnQgPSByZXF1aXJlKCdtaW5pbWFsaXN0aWMtYXNzZXJ0Jyk7XG5cbi8vIFN1cHBvcnRlZCB0YWdzXG52YXIgdGFncyA9IFtcbiAgJ3NlcScsICdzZXFvZicsICdzZXQnLCAnc2V0b2YnLCAnb2N0c3RyJywgJ2JpdHN0cicsICdvYmppZCcsICdib29sJyxcbiAgJ2dlbnRpbWUnLCAndXRjdGltZScsICdudWxsXycsICdlbnVtJywgJ2ludCcsICdpYTVzdHInLCAndXRmOHN0cicsICdibXBzdHInLFxuICAnbnVtc3RyJywgJ3ByaW50c3RyJ1xuXTtcblxuLy8gUHVibGljIG1ldGhvZHMgbGlzdFxudmFyIG1ldGhvZHMgPSBbXG4gICdrZXknLCAnb2JqJywgJ3VzZScsICdvcHRpb25hbCcsICdleHBsaWNpdCcsICdpbXBsaWNpdCcsICdkZWYnLCAnY2hvaWNlJyxcbiAgJ2FueSdcbl0uY29uY2F0KHRhZ3MpO1xuXG4vLyBPdmVycmlkZWQgbWV0aG9kcyBsaXN0XG52YXIgb3ZlcnJpZGVkID0gW1xuICAnX3BlZWtUYWcnLCAnX2RlY29kZVRhZycsICdfdXNlJyxcbiAgJ19kZWNvZGVTdHInLCAnX2RlY29kZU9iamlkJywgJ19kZWNvZGVUaW1lJyxcbiAgJ19kZWNvZGVOdWxsJywgJ19kZWNvZGVJbnQnLCAnX2RlY29kZUJvb2wnLCAnX2RlY29kZUxpc3QnLFxuXG4gICdfZW5jb2RlQ29tcG9zaXRlJywgJ19lbmNvZGVTdHInLCAnX2VuY29kZU9iamlkJywgJ19lbmNvZGVUaW1lJyxcbiAgJ19lbmNvZGVOdWxsJywgJ19lbmNvZGVJbnQnLCAnX2VuY29kZUJvb2wnXG5dO1xuXG5mdW5jdGlvbiBOb2RlKGVuYywgcGFyZW50KSB7XG4gIHZhciBzdGF0ZSA9IHt9O1xuICB0aGlzLl9iYXNlU3RhdGUgPSBzdGF0ZTtcblxuICBzdGF0ZS5lbmMgPSBlbmM7XG5cbiAgc3RhdGUucGFyZW50ID0gcGFyZW50IHx8IG51bGw7XG4gIHN0YXRlLmNoaWxkcmVuID0gbnVsbDtcblxuICAvLyBTdGF0ZVxuICBzdGF0ZS50YWcgPSBudWxsO1xuICBzdGF0ZS5hcmdzID0gbnVsbDtcbiAgc3RhdGUucmV2ZXJzZUFyZ3MgPSBudWxsO1xuICBzdGF0ZS5jaG9pY2UgPSBudWxsO1xuICBzdGF0ZS5vcHRpb25hbCA9IGZhbHNlO1xuICBzdGF0ZS5hbnkgPSBmYWxzZTtcbiAgc3RhdGUub2JqID0gZmFsc2U7XG4gIHN0YXRlLnVzZSA9IG51bGw7XG4gIHN0YXRlLnVzZURlY29kZXIgPSBudWxsO1xuICBzdGF0ZS5rZXkgPSBudWxsO1xuICBzdGF0ZVsnZGVmYXVsdCddID0gbnVsbDtcbiAgc3RhdGUuZXhwbGljaXQgPSBudWxsO1xuICBzdGF0ZS5pbXBsaWNpdCA9IG51bGw7XG5cbiAgLy8gU2hvdWxkIGNyZWF0ZSBuZXcgaW5zdGFuY2Ugb24gZWFjaCBtZXRob2RcbiAgaWYgKCFzdGF0ZS5wYXJlbnQpIHtcbiAgICBzdGF0ZS5jaGlsZHJlbiA9IFtdO1xuICAgIHRoaXMuX3dyYXAoKTtcbiAgfVxufVxubW9kdWxlLmV4cG9ydHMgPSBOb2RlO1xuXG52YXIgc3RhdGVQcm9wcyA9IFtcbiAgJ2VuYycsICdwYXJlbnQnLCAnY2hpbGRyZW4nLCAndGFnJywgJ2FyZ3MnLCAncmV2ZXJzZUFyZ3MnLCAnY2hvaWNlJyxcbiAgJ29wdGlvbmFsJywgJ2FueScsICdvYmonLCAndXNlJywgJ2FsdGVyZWRVc2UnLCAna2V5JywgJ2RlZmF1bHQnLCAnZXhwbGljaXQnLFxuICAnaW1wbGljaXQnXG5dO1xuXG5Ob2RlLnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uIGNsb25lKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG4gIHZhciBjc3RhdGUgPSB7fTtcbiAgc3RhdGVQcm9wcy5mb3JFYWNoKGZ1bmN0aW9uKHByb3ApIHtcbiAgICBjc3RhdGVbcHJvcF0gPSBzdGF0ZVtwcm9wXTtcbiAgfSk7XG4gIHZhciByZXMgPSBuZXcgdGhpcy5jb25zdHJ1Y3Rvcihjc3RhdGUucGFyZW50KTtcbiAgcmVzLl9iYXNlU3RhdGUgPSBjc3RhdGU7XG4gIHJldHVybiByZXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5fd3JhcCA9IGZ1bmN0aW9uIHdyYXAoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgbWV0aG9kcy5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgIHRoaXNbbWV0aG9kXSA9IGZ1bmN0aW9uIF93cmFwcGVkTWV0aG9kKCkge1xuICAgICAgdmFyIGNsb25lID0gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcyk7XG4gICAgICBzdGF0ZS5jaGlsZHJlbi5wdXNoKGNsb25lKTtcbiAgICAgIHJldHVybiBjbG9uZVttZXRob2RdLmFwcGx5KGNsb25lLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH0sIHRoaXMpO1xufTtcblxuTm9kZS5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiBpbml0KGJvZHkpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIGFzc2VydChzdGF0ZS5wYXJlbnQgPT09IG51bGwpO1xuICBib2R5LmNhbGwodGhpcyk7XG5cbiAgLy8gRmlsdGVyIGNoaWxkcmVuXG4gIHN0YXRlLmNoaWxkcmVuID0gc3RhdGUuY2hpbGRyZW4uZmlsdGVyKGZ1bmN0aW9uKGNoaWxkKSB7XG4gICAgcmV0dXJuIGNoaWxkLl9iYXNlU3RhdGUucGFyZW50ID09PSB0aGlzO1xuICB9LCB0aGlzKTtcbiAgYXNzZXJ0LmVxdWFsKHN0YXRlLmNoaWxkcmVuLmxlbmd0aCwgMSwgJ1Jvb3Qgbm9kZSBjYW4gaGF2ZSBvbmx5IG9uZSBjaGlsZCcpO1xufTtcblxuTm9kZS5wcm90b3R5cGUuX3VzZUFyZ3MgPSBmdW5jdGlvbiB1c2VBcmdzKGFyZ3MpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIC8vIEZpbHRlciBjaGlsZHJlbiBhbmQgYXJnc1xuICB2YXIgY2hpbGRyZW4gPSBhcmdzLmZpbHRlcihmdW5jdGlvbihhcmcpIHtcbiAgICByZXR1cm4gYXJnIGluc3RhbmNlb2YgdGhpcy5jb25zdHJ1Y3RvcjtcbiAgfSwgdGhpcyk7XG4gIGFyZ3MgPSBhcmdzLmZpbHRlcihmdW5jdGlvbihhcmcpIHtcbiAgICByZXR1cm4gIShhcmcgaW5zdGFuY2VvZiB0aGlzLmNvbnN0cnVjdG9yKTtcbiAgfSwgdGhpcyk7XG5cbiAgaWYgKGNoaWxkcmVuLmxlbmd0aCAhPT0gMCkge1xuICAgIGFzc2VydChzdGF0ZS5jaGlsZHJlbiA9PT0gbnVsbCk7XG4gICAgc3RhdGUuY2hpbGRyZW4gPSBjaGlsZHJlbjtcblxuICAgIC8vIFJlcGxhY2UgcGFyZW50IHRvIG1haW50YWluIGJhY2t3YXJkIGxpbmtcbiAgICBjaGlsZHJlbi5mb3JFYWNoKGZ1bmN0aW9uKGNoaWxkKSB7XG4gICAgICBjaGlsZC5fYmFzZVN0YXRlLnBhcmVudCA9IHRoaXM7XG4gICAgfSwgdGhpcyk7XG4gIH1cbiAgaWYgKGFyZ3MubGVuZ3RoICE9PSAwKSB7XG4gICAgYXNzZXJ0KHN0YXRlLmFyZ3MgPT09IG51bGwpO1xuICAgIHN0YXRlLmFyZ3MgPSBhcmdzO1xuICAgIHN0YXRlLnJldmVyc2VBcmdzID0gYXJncy5tYXAoZnVuY3Rpb24oYXJnKSB7XG4gICAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ29iamVjdCcgfHwgYXJnLmNvbnN0cnVjdG9yICE9PSBPYmplY3QpXG4gICAgICAgIHJldHVybiBhcmc7XG5cbiAgICAgIHZhciByZXMgPSB7fTtcbiAgICAgIE9iamVjdC5rZXlzKGFyZykuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgaWYgKGtleSA9PSAoa2V5IHwgMCkpXG4gICAgICAgICAga2V5IHw9IDA7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFyZ1trZXldO1xuICAgICAgICByZXNbdmFsdWVdID0ga2V5O1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzO1xuICAgIH0pO1xuICB9XG59O1xuXG4vL1xuLy8gT3ZlcnJpZGVkIG1ldGhvZHNcbi8vXG5cbm92ZXJyaWRlZC5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZCkge1xuICBOb2RlLnByb3RvdHlwZVttZXRob2RdID0gZnVuY3Rpb24gX292ZXJyaWRlZCgpIHtcbiAgICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG4gICAgdGhyb3cgbmV3IEVycm9yKG1ldGhvZCArICcgbm90IGltcGxlbWVudGVkIGZvciBlbmNvZGluZzogJyArIHN0YXRlLmVuYyk7XG4gIH07XG59KTtcblxuLy9cbi8vIFB1YmxpYyBtZXRob2RzXG4vL1xuXG50YWdzLmZvckVhY2goZnVuY3Rpb24odGFnKSB7XG4gIE5vZGUucHJvdG90eXBlW3RhZ10gPSBmdW5jdGlvbiBfdGFnTWV0aG9kKCkge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cbiAgICBhc3NlcnQoc3RhdGUudGFnID09PSBudWxsKTtcbiAgICBzdGF0ZS50YWcgPSB0YWc7XG5cbiAgICB0aGlzLl91c2VBcmdzKGFyZ3MpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG59KTtcblxuTm9kZS5wcm90b3R5cGUudXNlID0gZnVuY3Rpb24gdXNlKGl0ZW0pIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIGFzc2VydChzdGF0ZS51c2UgPT09IG51bGwpO1xuICBzdGF0ZS51c2UgPSBpdGVtO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuTm9kZS5wcm90b3R5cGUub3B0aW9uYWwgPSBmdW5jdGlvbiBvcHRpb25hbCgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIHN0YXRlLm9wdGlvbmFsID0gdHJ1ZTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbk5vZGUucHJvdG90eXBlLmRlZiA9IGZ1bmN0aW9uIGRlZih2YWwpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIGFzc2VydChzdGF0ZVsnZGVmYXVsdCddID09PSBudWxsKTtcbiAgc3RhdGVbJ2RlZmF1bHQnXSA9IHZhbDtcbiAgc3RhdGUub3B0aW9uYWwgPSB0cnVlO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuTm9kZS5wcm90b3R5cGUuZXhwbGljaXQgPSBmdW5jdGlvbiBleHBsaWNpdChudW0pIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIGFzc2VydChzdGF0ZS5leHBsaWNpdCA9PT0gbnVsbCAmJiBzdGF0ZS5pbXBsaWNpdCA9PT0gbnVsbCk7XG4gIHN0YXRlLmV4cGxpY2l0ID0gbnVtO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuTm9kZS5wcm90b3R5cGUuaW1wbGljaXQgPSBmdW5jdGlvbiBpbXBsaWNpdChudW0pIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIGFzc2VydChzdGF0ZS5leHBsaWNpdCA9PT0gbnVsbCAmJiBzdGF0ZS5pbXBsaWNpdCA9PT0gbnVsbCk7XG4gIHN0YXRlLmltcGxpY2l0ID0gbnVtO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuTm9kZS5wcm90b3R5cGUub2JqID0gZnVuY3Rpb24gb2JqKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG4gIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblxuICBzdGF0ZS5vYmogPSB0cnVlO1xuXG4gIGlmIChhcmdzLmxlbmd0aCAhPT0gMClcbiAgICB0aGlzLl91c2VBcmdzKGFyZ3MpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuTm9kZS5wcm90b3R5cGUua2V5ID0gZnVuY3Rpb24ga2V5KG5ld0tleSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlLmtleSA9PT0gbnVsbCk7XG4gIHN0YXRlLmtleSA9IG5ld0tleTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbk5vZGUucHJvdG90eXBlLmFueSA9IGZ1bmN0aW9uIGFueSgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIHN0YXRlLmFueSA9IHRydWU7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5jaG9pY2UgPSBmdW5jdGlvbiBjaG9pY2Uob2JqKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICBhc3NlcnQoc3RhdGUuY2hvaWNlID09PSBudWxsKTtcbiAgc3RhdGUuY2hvaWNlID0gb2JqO1xuICB0aGlzLl91c2VBcmdzKE9iamVjdC5rZXlzKG9iaikubWFwKGZ1bmN0aW9uKGtleSkge1xuICAgIHJldHVybiBvYmpba2V5XTtcbiAgfSkpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy9cbi8vIERlY29kaW5nXG4vL1xuXG5Ob2RlLnByb3RvdHlwZS5fZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKGlucHV0KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICAvLyBEZWNvZGUgcm9vdCBub2RlXG4gIGlmIChzdGF0ZS5wYXJlbnQgPT09IG51bGwpXG4gICAgcmV0dXJuIGlucHV0LndyYXBSZXN1bHQoc3RhdGUuY2hpbGRyZW5bMF0uX2RlY29kZShpbnB1dCkpO1xuXG4gIHZhciByZXN1bHQgPSBzdGF0ZVsnZGVmYXVsdCddO1xuICB2YXIgcHJlc2VudCA9IHRydWU7XG5cbiAgdmFyIHByZXZLZXk7XG4gIGlmIChzdGF0ZS5rZXkgIT09IG51bGwpXG4gICAgcHJldktleSA9IGlucHV0LmVudGVyS2V5KHN0YXRlLmtleSk7XG5cbiAgLy8gQ2hlY2sgaWYgdGFnIGlzIHRoZXJlXG4gIGlmIChzdGF0ZS5vcHRpb25hbCkge1xuICAgIHZhciB0YWcgPSBudWxsO1xuICAgIGlmIChzdGF0ZS5leHBsaWNpdCAhPT0gbnVsbClcbiAgICAgIHRhZyA9IHN0YXRlLmV4cGxpY2l0O1xuICAgIGVsc2UgaWYgKHN0YXRlLmltcGxpY2l0ICE9PSBudWxsKVxuICAgICAgdGFnID0gc3RhdGUuaW1wbGljaXQ7XG4gICAgZWxzZSBpZiAoc3RhdGUudGFnICE9PSBudWxsKVxuICAgICAgdGFnID0gc3RhdGUudGFnO1xuXG4gICAgaWYgKHRhZyA9PT0gbnVsbCAmJiAhc3RhdGUuYW55KSB7XG4gICAgICAvLyBUcmlhbCBhbmQgRXJyb3JcbiAgICAgIHZhciBzYXZlID0gaW5wdXQuc2F2ZSgpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKHN0YXRlLmNob2ljZSA9PT0gbnVsbClcbiAgICAgICAgICB0aGlzLl9kZWNvZGVHZW5lcmljKHN0YXRlLnRhZywgaW5wdXQpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgdGhpcy5fZGVjb2RlQ2hvaWNlKGlucHV0KTtcbiAgICAgICAgcHJlc2VudCA9IHRydWU7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHByZXNlbnQgPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlucHV0LnJlc3RvcmUoc2F2ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByZXNlbnQgPSB0aGlzLl9wZWVrVGFnKGlucHV0LCB0YWcsIHN0YXRlLmFueSk7XG5cbiAgICAgIGlmIChpbnB1dC5pc0Vycm9yKHByZXNlbnQpKVxuICAgICAgICByZXR1cm4gcHJlc2VudDtcbiAgICB9XG4gIH1cblxuICAvLyBQdXNoIG9iamVjdCBvbiBzdGFja1xuICB2YXIgcHJldk9iajtcbiAgaWYgKHN0YXRlLm9iaiAmJiBwcmVzZW50KVxuICAgIHByZXZPYmogPSBpbnB1dC5lbnRlck9iamVjdCgpO1xuXG4gIGlmIChwcmVzZW50KSB7XG4gICAgLy8gVW53cmFwIGV4cGxpY2l0IHZhbHVlc1xuICAgIGlmIChzdGF0ZS5leHBsaWNpdCAhPT0gbnVsbCkge1xuICAgICAgdmFyIGV4cGxpY2l0ID0gdGhpcy5fZGVjb2RlVGFnKGlucHV0LCBzdGF0ZS5leHBsaWNpdCk7XG4gICAgICBpZiAoaW5wdXQuaXNFcnJvcihleHBsaWNpdCkpXG4gICAgICAgIHJldHVybiBleHBsaWNpdDtcbiAgICAgIGlucHV0ID0gZXhwbGljaXQ7XG4gICAgfVxuXG4gICAgLy8gVW53cmFwIGltcGxpY2l0IGFuZCBub3JtYWwgdmFsdWVzXG4gICAgaWYgKHN0YXRlLnVzZSA9PT0gbnVsbCAmJiBzdGF0ZS5jaG9pY2UgPT09IG51bGwpIHtcbiAgICAgIGlmIChzdGF0ZS5hbnkpXG4gICAgICAgIHZhciBzYXZlID0gaW5wdXQuc2F2ZSgpO1xuICAgICAgdmFyIGJvZHkgPSB0aGlzLl9kZWNvZGVUYWcoXG4gICAgICAgIGlucHV0LFxuICAgICAgICBzdGF0ZS5pbXBsaWNpdCAhPT0gbnVsbCA/IHN0YXRlLmltcGxpY2l0IDogc3RhdGUudGFnLFxuICAgICAgICBzdGF0ZS5hbnlcbiAgICAgICk7XG4gICAgICBpZiAoaW5wdXQuaXNFcnJvcihib2R5KSlcbiAgICAgICAgcmV0dXJuIGJvZHk7XG5cbiAgICAgIGlmIChzdGF0ZS5hbnkpXG4gICAgICAgIHJlc3VsdCA9IGlucHV0LnJhdyhzYXZlKTtcbiAgICAgIGVsc2VcbiAgICAgICAgaW5wdXQgPSBib2R5O1xuICAgIH1cblxuICAgIC8vIFNlbGVjdCBwcm9wZXIgbWV0aG9kIGZvciB0YWdcbiAgICBpZiAoc3RhdGUuYW55KVxuICAgICAgcmVzdWx0ID0gcmVzdWx0O1xuICAgIGVsc2UgaWYgKHN0YXRlLmNob2ljZSA9PT0gbnVsbClcbiAgICAgIHJlc3VsdCA9IHRoaXMuX2RlY29kZUdlbmVyaWMoc3RhdGUudGFnLCBpbnB1dCk7XG4gICAgZWxzZVxuICAgICAgcmVzdWx0ID0gdGhpcy5fZGVjb2RlQ2hvaWNlKGlucHV0KTtcblxuICAgIGlmIChpbnB1dC5pc0Vycm9yKHJlc3VsdCkpXG4gICAgICByZXR1cm4gcmVzdWx0O1xuXG4gICAgLy8gRGVjb2RlIGNoaWxkcmVuXG4gICAgaWYgKCFzdGF0ZS5hbnkgJiYgc3RhdGUuY2hvaWNlID09PSBudWxsICYmIHN0YXRlLmNoaWxkcmVuICE9PSBudWxsKSB7XG4gICAgICB2YXIgZmFpbCA9IHN0YXRlLmNoaWxkcmVuLnNvbWUoZnVuY3Rpb24gZGVjb2RlQ2hpbGRyZW4oY2hpbGQpIHtcbiAgICAgICAgLy8gTk9URTogV2UgYXJlIGlnbm9yaW5nIGVycm9ycyBoZXJlLCB0byBsZXQgcGFyc2VyIGNvbnRpbnVlIHdpdGggb3RoZXJcbiAgICAgICAgLy8gcGFydHMgb2YgZW5jb2RlZCBkYXRhXG4gICAgICAgIGNoaWxkLl9kZWNvZGUoaW5wdXQpO1xuICAgICAgfSk7XG4gICAgICBpZiAoZmFpbClcbiAgICAgICAgcmV0dXJuIGVycjtcbiAgICB9XG4gIH1cblxuICAvLyBQb3Agb2JqZWN0XG4gIGlmIChzdGF0ZS5vYmogJiYgcHJlc2VudClcbiAgICByZXN1bHQgPSBpbnB1dC5sZWF2ZU9iamVjdChwcmV2T2JqKTtcblxuICAvLyBTZXQga2V5XG4gIGlmIChzdGF0ZS5rZXkgIT09IG51bGwgJiYgKHJlc3VsdCAhPT0gbnVsbCB8fCBwcmVzZW50ID09PSB0cnVlKSlcbiAgICBpbnB1dC5sZWF2ZUtleShwcmV2S2V5LCBzdGF0ZS5rZXksIHJlc3VsdCk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbk5vZGUucHJvdG90eXBlLl9kZWNvZGVHZW5lcmljID0gZnVuY3Rpb24gZGVjb2RlR2VuZXJpYyh0YWcsIGlucHV0KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICBpZiAodGFnID09PSAnc2VxJyB8fCB0YWcgPT09ICdzZXQnKVxuICAgIHJldHVybiBudWxsO1xuICBpZiAodGFnID09PSAnc2Vxb2YnIHx8IHRhZyA9PT0gJ3NldG9mJylcbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlTGlzdChpbnB1dCwgdGFnLCBzdGF0ZS5hcmdzWzBdKTtcbiAgZWxzZSBpZiAodGFnID09PSAnb2N0c3RyJyB8fCB0YWcgPT09ICdiaXRzdHInKVxuICAgIHJldHVybiB0aGlzLl9kZWNvZGVTdHIoaW5wdXQsIHRhZyk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ2lhNXN0cicgfHwgdGFnID09PSAndXRmOHN0cicgfHwgdGFnID09PSAnYm1wc3RyJylcbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlU3RyKGlucHV0LCB0YWcpO1xuICBlbHNlIGlmICh0YWcgPT09ICdudW1zdHInIHx8IHRhZyA9PT0gJ3ByaW50c3RyJylcbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlU3RyKGlucHV0LCB0YWcpO1xuICBlbHNlIGlmICh0YWcgPT09ICdvYmppZCcgJiYgc3RhdGUuYXJncylcbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlT2JqaWQoaW5wdXQsIHN0YXRlLmFyZ3NbMF0sIHN0YXRlLmFyZ3NbMV0pO1xuICBlbHNlIGlmICh0YWcgPT09ICdvYmppZCcpXG4gICAgcmV0dXJuIHRoaXMuX2RlY29kZU9iamlkKGlucHV0LCBudWxsLCBudWxsKTtcbiAgZWxzZSBpZiAodGFnID09PSAnZ2VudGltZScgfHwgdGFnID09PSAndXRjdGltZScpXG4gICAgcmV0dXJuIHRoaXMuX2RlY29kZVRpbWUoaW5wdXQsIHRhZyk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ251bGxfJylcbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlTnVsbChpbnB1dCk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ2Jvb2wnKVxuICAgIHJldHVybiB0aGlzLl9kZWNvZGVCb29sKGlucHV0KTtcbiAgZWxzZSBpZiAodGFnID09PSAnaW50JyB8fCB0YWcgPT09ICdlbnVtJylcbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlSW50KGlucHV0LCBzdGF0ZS5hcmdzICYmIHN0YXRlLmFyZ3NbMF0pO1xuICBlbHNlIGlmIChzdGF0ZS51c2UgIT09IG51bGwpXG4gICAgcmV0dXJuIHRoaXMuX2dldFVzZShzdGF0ZS51c2UsIGlucHV0Ll9yZXBvcnRlclN0YXRlLm9iaikuX2RlY29kZShpbnB1dCk7XG4gIGVsc2VcbiAgICByZXR1cm4gaW5wdXQuZXJyb3IoJ3Vua25vd24gdGFnOiAnICsgdGFnKTtcblxuICByZXR1cm4gbnVsbDtcbn07XG5cbk5vZGUucHJvdG90eXBlLl9nZXRVc2UgPSBmdW5jdGlvbiBfZ2V0VXNlKGVudGl0eSwgb2JqKSB7XG5cbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuICAvLyBDcmVhdGUgYWx0ZXJlZCB1c2UgZGVjb2RlciBpZiBpbXBsaWNpdCBpcyBzZXRcbiAgc3RhdGUudXNlRGVjb2RlciA9IHRoaXMuX3VzZShlbnRpdHksIG9iaik7XG4gIGFzc2VydChzdGF0ZS51c2VEZWNvZGVyLl9iYXNlU3RhdGUucGFyZW50ID09PSBudWxsKTtcbiAgc3RhdGUudXNlRGVjb2RlciA9IHN0YXRlLnVzZURlY29kZXIuX2Jhc2VTdGF0ZS5jaGlsZHJlblswXTtcbiAgaWYgKHN0YXRlLmltcGxpY2l0ICE9PSBzdGF0ZS51c2VEZWNvZGVyLl9iYXNlU3RhdGUuaW1wbGljaXQpIHtcbiAgICBzdGF0ZS51c2VEZWNvZGVyID0gc3RhdGUudXNlRGVjb2Rlci5jbG9uZSgpO1xuICAgIHN0YXRlLnVzZURlY29kZXIuX2Jhc2VTdGF0ZS5pbXBsaWNpdCA9IHN0YXRlLmltcGxpY2l0O1xuICB9XG4gIHJldHVybiBzdGF0ZS51c2VEZWNvZGVyO1xufTtcblxuTm9kZS5wcm90b3R5cGUuX2RlY29kZUNob2ljZSA9IGZ1bmN0aW9uIGRlY29kZUNob2ljZShpbnB1dCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG4gIHZhciByZXN1bHQgPSBudWxsO1xuICB2YXIgbWF0Y2ggPSBmYWxzZTtcblxuICBPYmplY3Qua2V5cyhzdGF0ZS5jaG9pY2UpLnNvbWUoZnVuY3Rpb24oa2V5KSB7XG4gICAgdmFyIHNhdmUgPSBpbnB1dC5zYXZlKCk7XG4gICAgdmFyIG5vZGUgPSBzdGF0ZS5jaG9pY2Vba2V5XTtcbiAgICB0cnkge1xuICAgICAgdmFyIHZhbHVlID0gbm9kZS5fZGVjb2RlKGlucHV0KTtcbiAgICAgIGlmIChpbnB1dC5pc0Vycm9yKHZhbHVlKSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgICByZXN1bHQgPSB7IHR5cGU6IGtleSwgdmFsdWU6IHZhbHVlIH07XG4gICAgICBtYXRjaCA9IHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaW5wdXQucmVzdG9yZShzYXZlKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH0sIHRoaXMpO1xuXG4gIGlmICghbWF0Y2gpXG4gICAgcmV0dXJuIGlucHV0LmVycm9yKCdDaG9pY2Ugbm90IG1hdGNoZWQnKTtcblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuLy9cbi8vIEVuY29kaW5nXG4vL1xuXG5Ob2RlLnByb3RvdHlwZS5fY3JlYXRlRW5jb2RlckJ1ZmZlciA9IGZ1bmN0aW9uIGNyZWF0ZUVuY29kZXJCdWZmZXIoZGF0YSkge1xuICByZXR1cm4gbmV3IEVuY29kZXJCdWZmZXIoZGF0YSwgdGhpcy5yZXBvcnRlcik7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5fZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKGRhdGEsIHJlcG9ydGVyLCBwYXJlbnQpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuICBpZiAoc3RhdGVbJ2RlZmF1bHQnXSAhPT0gbnVsbCAmJiBzdGF0ZVsnZGVmYXVsdCddID09PSBkYXRhKVxuICAgIHJldHVybjtcblxuICB2YXIgcmVzdWx0ID0gdGhpcy5fZW5jb2RlVmFsdWUoZGF0YSwgcmVwb3J0ZXIsIHBhcmVudCk7XG4gIGlmIChyZXN1bHQgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm47XG5cbiAgaWYgKHRoaXMuX3NraXBEZWZhdWx0KHJlc3VsdCwgcmVwb3J0ZXIsIHBhcmVudCkpXG4gICAgcmV0dXJuO1xuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5fZW5jb2RlVmFsdWUgPSBmdW5jdGlvbiBlbmNvZGUoZGF0YSwgcmVwb3J0ZXIsIHBhcmVudCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgLy8gRGVjb2RlIHJvb3Qgbm9kZVxuICBpZiAoc3RhdGUucGFyZW50ID09PSBudWxsKVxuICAgIHJldHVybiBzdGF0ZS5jaGlsZHJlblswXS5fZW5jb2RlKGRhdGEsIHJlcG9ydGVyIHx8IG5ldyBSZXBvcnRlcigpKTtcblxuICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgdmFyIHByZXNlbnQgPSB0cnVlO1xuXG4gIC8vIFNldCByZXBvcnRlciB0byBzaGFyZSBpdCB3aXRoIGEgY2hpbGQgY2xhc3NcbiAgdGhpcy5yZXBvcnRlciA9IHJlcG9ydGVyO1xuXG4gIC8vIENoZWNrIGlmIGRhdGEgaXMgdGhlcmVcbiAgaWYgKHN0YXRlLm9wdGlvbmFsICYmIGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChzdGF0ZVsnZGVmYXVsdCddICE9PSBudWxsKVxuICAgICAgZGF0YSA9IHN0YXRlWydkZWZhdWx0J11cbiAgICBlbHNlXG4gICAgICByZXR1cm47XG4gIH1cblxuICAvLyBGb3IgZXJyb3IgcmVwb3J0aW5nXG4gIHZhciBwcmV2S2V5O1xuXG4gIC8vIEVuY29kZSBjaGlsZHJlbiBmaXJzdFxuICB2YXIgY29udGVudCA9IG51bGw7XG4gIHZhciBwcmltaXRpdmUgPSBmYWxzZTtcbiAgaWYgKHN0YXRlLmFueSkge1xuICAgIC8vIEFueXRoaW5nIHRoYXQgd2FzIGdpdmVuIGlzIHRyYW5zbGF0ZWQgdG8gYnVmZmVyXG4gICAgcmVzdWx0ID0gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihkYXRhKTtcbiAgfSBlbHNlIGlmIChzdGF0ZS5jaG9pY2UpIHtcbiAgICByZXN1bHQgPSB0aGlzLl9lbmNvZGVDaG9pY2UoZGF0YSwgcmVwb3J0ZXIpO1xuICB9IGVsc2UgaWYgKHN0YXRlLmNoaWxkcmVuKSB7XG4gICAgY29udGVudCA9IHN0YXRlLmNoaWxkcmVuLm1hcChmdW5jdGlvbihjaGlsZCkge1xuICAgICAgaWYgKGNoaWxkLl9iYXNlU3RhdGUudGFnID09PSAnbnVsbF8nKVxuICAgICAgICByZXR1cm4gY2hpbGQuX2VuY29kZShudWxsLCByZXBvcnRlciwgZGF0YSk7XG5cbiAgICAgIGlmIChjaGlsZC5fYmFzZVN0YXRlLmtleSA9PT0gbnVsbClcbiAgICAgICAgcmV0dXJuIHJlcG9ydGVyLmVycm9yKCdDaGlsZCBzaG91bGQgaGF2ZSBhIGtleScpO1xuICAgICAgdmFyIHByZXZLZXkgPSByZXBvcnRlci5lbnRlcktleShjaGlsZC5fYmFzZVN0YXRlLmtleSk7XG5cbiAgICAgIGlmICh0eXBlb2YgZGF0YSAhPT0gJ29iamVjdCcpXG4gICAgICAgIHJldHVybiByZXBvcnRlci5lcnJvcignQ2hpbGQgZXhwZWN0ZWQsIGJ1dCBpbnB1dCBpcyBub3Qgb2JqZWN0Jyk7XG5cbiAgICAgIHZhciByZXMgPSBjaGlsZC5fZW5jb2RlKGRhdGFbY2hpbGQuX2Jhc2VTdGF0ZS5rZXldLCByZXBvcnRlciwgZGF0YSk7XG4gICAgICByZXBvcnRlci5sZWF2ZUtleShwcmV2S2V5KTtcblxuICAgICAgcmV0dXJuIHJlcztcbiAgICB9LCB0aGlzKS5maWx0ZXIoZnVuY3Rpb24oY2hpbGQpIHtcbiAgICAgIHJldHVybiBjaGlsZDtcbiAgICB9KTtcblxuICAgIGNvbnRlbnQgPSB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKGNvbnRlbnQpO1xuICB9IGVsc2Uge1xuICAgIGlmIChzdGF0ZS50YWcgPT09ICdzZXFvZicgfHwgc3RhdGUudGFnID09PSAnc2V0b2YnKSB7XG4gICAgICAvLyBUT0RPKGluZHV0bnkpOiB0aGlzIHNob3VsZCBiZSB0aHJvd24gb24gRFNMIGxldmVsXG4gICAgICBpZiAoIShzdGF0ZS5hcmdzICYmIHN0YXRlLmFyZ3MubGVuZ3RoID09PSAxKSlcbiAgICAgICAgcmV0dXJuIHJlcG9ydGVyLmVycm9yKCdUb28gbWFueSBhcmdzIGZvciA6ICcgKyBzdGF0ZS50YWcpO1xuXG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoZGF0YSkpXG4gICAgICAgIHJldHVybiByZXBvcnRlci5lcnJvcignc2Vxb2Yvc2V0b2YsIGJ1dCBkYXRhIGlzIG5vdCBBcnJheScpO1xuXG4gICAgICB2YXIgY2hpbGQgPSB0aGlzLmNsb25lKCk7XG4gICAgICBjaGlsZC5fYmFzZVN0YXRlLmltcGxpY2l0ID0gbnVsbDtcbiAgICAgIGNvbnRlbnQgPSB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKGRhdGEubWFwKGZ1bmN0aW9uKGl0ZW0pIHtcbiAgICAgICAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRVc2Uoc3RhdGUuYXJnc1swXSwgZGF0YSkuX2VuY29kZShpdGVtLCByZXBvcnRlcik7XG4gICAgICB9LCBjaGlsZCkpO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUudXNlICE9PSBudWxsKSB7XG4gICAgICByZXN1bHQgPSB0aGlzLl9nZXRVc2Uoc3RhdGUudXNlLCBwYXJlbnQpLl9lbmNvZGUoZGF0YSwgcmVwb3J0ZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZW50ID0gdGhpcy5fZW5jb2RlUHJpbWl0aXZlKHN0YXRlLnRhZywgZGF0YSk7XG4gICAgICBwcmltaXRpdmUgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8vIEVuY29kZSBkYXRhIGl0c2VsZlxuICB2YXIgcmVzdWx0O1xuICBpZiAoIXN0YXRlLmFueSAmJiBzdGF0ZS5jaG9pY2UgPT09IG51bGwpIHtcbiAgICB2YXIgdGFnID0gc3RhdGUuaW1wbGljaXQgIT09IG51bGwgPyBzdGF0ZS5pbXBsaWNpdCA6IHN0YXRlLnRhZztcbiAgICB2YXIgY2xzID0gc3RhdGUuaW1wbGljaXQgPT09IG51bGwgPyAndW5pdmVyc2FsJyA6ICdjb250ZXh0JztcblxuICAgIGlmICh0YWcgPT09IG51bGwpIHtcbiAgICAgIGlmIChzdGF0ZS51c2UgPT09IG51bGwpXG4gICAgICAgIHJlcG9ydGVyLmVycm9yKCdUYWcgY291bGQgYmUgb21taXRlZCBvbmx5IGZvciAudXNlKCknKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHN0YXRlLnVzZSA9PT0gbnVsbClcbiAgICAgICAgcmVzdWx0ID0gdGhpcy5fZW5jb2RlQ29tcG9zaXRlKHRhZywgcHJpbWl0aXZlLCBjbHMsIGNvbnRlbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFdyYXAgaW4gZXhwbGljaXRcbiAgaWYgKHN0YXRlLmV4cGxpY2l0ICE9PSBudWxsKVxuICAgIHJlc3VsdCA9IHRoaXMuX2VuY29kZUNvbXBvc2l0ZShzdGF0ZS5leHBsaWNpdCwgZmFsc2UsICdjb250ZXh0JywgcmVzdWx0KTtcblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuTm9kZS5wcm90b3R5cGUuX2VuY29kZUNob2ljZSA9IGZ1bmN0aW9uIGVuY29kZUNob2ljZShkYXRhLCByZXBvcnRlcikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgdmFyIG5vZGUgPSBzdGF0ZS5jaG9pY2VbZGF0YS50eXBlXTtcbiAgaWYgKCFub2RlKSB7XG4gICAgYXNzZXJ0KFxuICAgICAgICBmYWxzZSxcbiAgICAgICAgZGF0YS50eXBlICsgJyBub3QgZm91bmQgaW4gJyArXG4gICAgICAgICAgICBKU09OLnN0cmluZ2lmeShPYmplY3Qua2V5cyhzdGF0ZS5jaG9pY2UpKSk7XG4gIH1cbiAgcmV0dXJuIG5vZGUuX2VuY29kZShkYXRhLnZhbHVlLCByZXBvcnRlcik7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5fZW5jb2RlUHJpbWl0aXZlID0gZnVuY3Rpb24gZW5jb2RlUHJpbWl0aXZlKHRhZywgZGF0YSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgaWYgKHRhZyA9PT0gJ29jdHN0cicgfHwgdGFnID09PSAnYml0c3RyJyB8fCB0YWcgPT09ICdpYTVzdHInKVxuICAgIHJldHVybiB0aGlzLl9lbmNvZGVTdHIoZGF0YSwgdGFnKTtcbiAgZWxzZSBpZiAodGFnID09PSAndXRmOHN0cicgfHwgdGFnID09PSAnYm1wc3RyJylcbiAgICByZXR1cm4gdGhpcy5fZW5jb2RlU3RyKGRhdGEsIHRhZyk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ251bXN0cicgfHwgdGFnID09PSAncHJpbnRzdHInKVxuICAgIHJldHVybiB0aGlzLl9lbmNvZGVTdHIoZGF0YSwgdGFnKTtcbiAgZWxzZSBpZiAodGFnID09PSAnb2JqaWQnICYmIHN0YXRlLmFyZ3MpXG4gICAgcmV0dXJuIHRoaXMuX2VuY29kZU9iamlkKGRhdGEsIHN0YXRlLnJldmVyc2VBcmdzWzBdLCBzdGF0ZS5hcmdzWzFdKTtcbiAgZWxzZSBpZiAodGFnID09PSAnb2JqaWQnKVxuICAgIHJldHVybiB0aGlzLl9lbmNvZGVPYmppZChkYXRhLCBudWxsLCBudWxsKTtcbiAgZWxzZSBpZiAodGFnID09PSAnZ2VudGltZScgfHwgdGFnID09PSAndXRjdGltZScpXG4gICAgcmV0dXJuIHRoaXMuX2VuY29kZVRpbWUoZGF0YSwgdGFnKTtcbiAgZWxzZSBpZiAodGFnID09PSAnbnVsbF8nKVxuICAgIHJldHVybiB0aGlzLl9lbmNvZGVOdWxsKCk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ2ludCcgfHwgdGFnID09PSAnZW51bScpXG4gICAgcmV0dXJuIHRoaXMuX2VuY29kZUludChkYXRhLCBzdGF0ZS5hcmdzICYmIHN0YXRlLnJldmVyc2VBcmdzWzBdKTtcbiAgZWxzZSBpZiAodGFnID09PSAnYm9vbCcpXG4gICAgcmV0dXJuIHRoaXMuX2VuY29kZUJvb2woZGF0YSk7XG4gIGVsc2VcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIHRhZzogJyArIHRhZyk7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5faXNOdW1zdHIgPSBmdW5jdGlvbiBpc051bXN0cihzdHIpIHtcbiAgcmV0dXJuIC9eWzAtOSBdKiQvLnRlc3Qoc3RyKTtcbn07XG5cbk5vZGUucHJvdG90eXBlLl9pc1ByaW50c3RyID0gZnVuY3Rpb24gaXNQcmludHN0cihzdHIpIHtcbiAgcmV0dXJuIC9eW0EtWmEtejAtOSAnXFwoXFwpXFwrLFxcLVxcLlxcLzo9XFw/XSokLy50ZXN0KHN0cik7XG59OyIsInZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmZ1bmN0aW9uIFJlcG9ydGVyKG9wdGlvbnMpIHtcbiAgdGhpcy5fcmVwb3J0ZXJTdGF0ZSA9IHtcbiAgICBvYmo6IG51bGwsXG4gICAgcGF0aDogW10sXG4gICAgb3B0aW9uczogb3B0aW9ucyB8fCB7fSxcbiAgICBlcnJvcnM6IFtdXG4gIH07XG59XG5leHBvcnRzLlJlcG9ydGVyID0gUmVwb3J0ZXI7XG5cblJlcG9ydGVyLnByb3RvdHlwZS5pc0Vycm9yID0gZnVuY3Rpb24gaXNFcnJvcihvYmopIHtcbiAgcmV0dXJuIG9iaiBpbnN0YW5jZW9mIFJlcG9ydGVyRXJyb3I7XG59O1xuXG5SZXBvcnRlci5wcm90b3R5cGUuc2F2ZSA9IGZ1bmN0aW9uIHNhdmUoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlcG9ydGVyU3RhdGU7XG5cbiAgcmV0dXJuIHsgb2JqOiBzdGF0ZS5vYmosIHBhdGhMZW46IHN0YXRlLnBhdGgubGVuZ3RoIH07XG59O1xuXG5SZXBvcnRlci5wcm90b3R5cGUucmVzdG9yZSA9IGZ1bmN0aW9uIHJlc3RvcmUoZGF0YSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZXBvcnRlclN0YXRlO1xuXG4gIHN0YXRlLm9iaiA9IGRhdGEub2JqO1xuICBzdGF0ZS5wYXRoID0gc3RhdGUucGF0aC5zbGljZSgwLCBkYXRhLnBhdGhMZW4pO1xufTtcblxuUmVwb3J0ZXIucHJvdG90eXBlLmVudGVyS2V5ID0gZnVuY3Rpb24gZW50ZXJLZXkoa2V5KSB7XG4gIHJldHVybiB0aGlzLl9yZXBvcnRlclN0YXRlLnBhdGgucHVzaChrZXkpO1xufTtcblxuUmVwb3J0ZXIucHJvdG90eXBlLmxlYXZlS2V5ID0gZnVuY3Rpb24gbGVhdmVLZXkoaW5kZXgsIGtleSwgdmFsdWUpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVwb3J0ZXJTdGF0ZTtcblxuICBzdGF0ZS5wYXRoID0gc3RhdGUucGF0aC5zbGljZSgwLCBpbmRleCAtIDEpO1xuICBpZiAoc3RhdGUub2JqICE9PSBudWxsKVxuICAgIHN0YXRlLm9ialtrZXldID0gdmFsdWU7XG59O1xuXG5SZXBvcnRlci5wcm90b3R5cGUuZW50ZXJPYmplY3QgPSBmdW5jdGlvbiBlbnRlck9iamVjdCgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVwb3J0ZXJTdGF0ZTtcblxuICB2YXIgcHJldiA9IHN0YXRlLm9iajtcbiAgc3RhdGUub2JqID0ge307XG4gIHJldHVybiBwcmV2O1xufTtcblxuUmVwb3J0ZXIucHJvdG90eXBlLmxlYXZlT2JqZWN0ID0gZnVuY3Rpb24gbGVhdmVPYmplY3QocHJldikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZXBvcnRlclN0YXRlO1xuXG4gIHZhciBub3cgPSBzdGF0ZS5vYmo7XG4gIHN0YXRlLm9iaiA9IHByZXY7XG4gIHJldHVybiBub3c7XG59O1xuXG5SZXBvcnRlci5wcm90b3R5cGUuZXJyb3IgPSBmdW5jdGlvbiBlcnJvcihtc2cpIHtcbiAgdmFyIGVycjtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVwb3J0ZXJTdGF0ZTtcblxuICB2YXIgaW5oZXJpdGVkID0gbXNnIGluc3RhbmNlb2YgUmVwb3J0ZXJFcnJvcjtcbiAgaWYgKGluaGVyaXRlZCkge1xuICAgIGVyciA9IG1zZztcbiAgfSBlbHNlIHtcbiAgICBlcnIgPSBuZXcgUmVwb3J0ZXJFcnJvcihzdGF0ZS5wYXRoLm1hcChmdW5jdGlvbihlbGVtKSB7XG4gICAgICByZXR1cm4gJ1snICsgSlNPTi5zdHJpbmdpZnkoZWxlbSkgKyAnXSc7XG4gICAgfSkuam9pbignJyksIG1zZy5tZXNzYWdlIHx8IG1zZywgbXNnLnN0YWNrKTtcbiAgfVxuXG4gIGlmICghc3RhdGUub3B0aW9ucy5wYXJ0aWFsKVxuICAgIHRocm93IGVycjtcblxuICBpZiAoIWluaGVyaXRlZClcbiAgICBzdGF0ZS5lcnJvcnMucHVzaChlcnIpO1xuXG4gIHJldHVybiBlcnI7XG59O1xuXG5SZXBvcnRlci5wcm90b3R5cGUud3JhcFJlc3VsdCA9IGZ1bmN0aW9uIHdyYXBSZXN1bHQocmVzdWx0KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlcG9ydGVyU3RhdGU7XG4gIGlmICghc3RhdGUub3B0aW9ucy5wYXJ0aWFsKVxuICAgIHJldHVybiByZXN1bHQ7XG5cbiAgcmV0dXJuIHtcbiAgICByZXN1bHQ6IHRoaXMuaXNFcnJvcihyZXN1bHQpID8gbnVsbCA6IHJlc3VsdCxcbiAgICBlcnJvcnM6IHN0YXRlLmVycm9yc1xuICB9O1xufTtcblxuZnVuY3Rpb24gUmVwb3J0ZXJFcnJvcihwYXRoLCBtc2cpIHtcbiAgdGhpcy5wYXRoID0gcGF0aDtcbiAgdGhpcy5yZXRocm93KG1zZyk7XG59O1xuaW5oZXJpdHMoUmVwb3J0ZXJFcnJvciwgRXJyb3IpO1xuXG5SZXBvcnRlckVycm9yLnByb3RvdHlwZS5yZXRocm93ID0gZnVuY3Rpb24gcmV0aHJvdyhtc2cpIHtcbiAgdGhpcy5tZXNzYWdlID0gbXNnICsgJyBhdDogJyArICh0aGlzLnBhdGggfHwgJyhzaGFsbG93KScpO1xuICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBSZXBvcnRlckVycm9yKTtcblxuICByZXR1cm4gdGhpcztcbn07XG4iLCJ2YXIgY29uc3RhbnRzID0gcmVxdWlyZSgnLi4vY29uc3RhbnRzJyk7XG5cbmV4cG9ydHMudGFnQ2xhc3MgPSB7XG4gIDA6ICd1bml2ZXJzYWwnLFxuICAxOiAnYXBwbGljYXRpb24nLFxuICAyOiAnY29udGV4dCcsXG4gIDM6ICdwcml2YXRlJ1xufTtcbmV4cG9ydHMudGFnQ2xhc3NCeU5hbWUgPSBjb25zdGFudHMuX3JldmVyc2UoZXhwb3J0cy50YWdDbGFzcyk7XG5cbmV4cG9ydHMudGFnID0ge1xuICAweDAwOiAnZW5kJyxcbiAgMHgwMTogJ2Jvb2wnLFxuICAweDAyOiAnaW50JyxcbiAgMHgwMzogJ2JpdHN0cicsXG4gIDB4MDQ6ICdvY3RzdHInLFxuICAweDA1OiAnbnVsbF8nLFxuICAweDA2OiAnb2JqaWQnLFxuICAweDA3OiAnb2JqRGVzYycsXG4gIDB4MDg6ICdleHRlcm5hbCcsXG4gIDB4MDk6ICdyZWFsJyxcbiAgMHgwYTogJ2VudW0nLFxuICAweDBiOiAnZW1iZWQnLFxuICAweDBjOiAndXRmOHN0cicsXG4gIDB4MGQ6ICdyZWxhdGl2ZU9pZCcsXG4gIDB4MTA6ICdzZXEnLFxuICAweDExOiAnc2V0JyxcbiAgMHgxMjogJ251bXN0cicsXG4gIDB4MTM6ICdwcmludHN0cicsXG4gIDB4MTQ6ICd0NjFzdHInLFxuICAweDE1OiAndmlkZW9zdHInLFxuICAweDE2OiAnaWE1c3RyJyxcbiAgMHgxNzogJ3V0Y3RpbWUnLFxuICAweDE4OiAnZ2VudGltZScsXG4gIDB4MTk6ICdncmFwaHN0cicsXG4gIDB4MWE6ICdpc282NDZzdHInLFxuICAweDFiOiAnZ2Vuc3RyJyxcbiAgMHgxYzogJ3VuaXN0cicsXG4gIDB4MWQ6ICdjaGFyc3RyJyxcbiAgMHgxZTogJ2JtcHN0cidcbn07XG5leHBvcnRzLnRhZ0J5TmFtZSA9IGNvbnN0YW50cy5fcmV2ZXJzZShleHBvcnRzLnRhZyk7XG4iLCJ2YXIgY29uc3RhbnRzID0gZXhwb3J0cztcblxuLy8gSGVscGVyXG5jb25zdGFudHMuX3JldmVyc2UgPSBmdW5jdGlvbiByZXZlcnNlKG1hcCkge1xuICB2YXIgcmVzID0ge307XG5cbiAgT2JqZWN0LmtleXMobWFwKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIC8vIENvbnZlcnQga2V5IHRvIGludGVnZXIgaWYgaXQgaXMgc3RyaW5naWZpZWRcbiAgICBpZiAoKGtleSB8IDApID09IGtleSlcbiAgICAgIGtleSA9IGtleSB8IDA7XG5cbiAgICB2YXIgdmFsdWUgPSBtYXBba2V5XTtcbiAgICByZXNbdmFsdWVdID0ga2V5O1xuICB9KTtcblxuICByZXR1cm4gcmVzO1xufTtcblxuY29uc3RhbnRzLmRlciA9IHJlcXVpcmUoJy4vZGVyJyk7XG4iLCJ2YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG52YXIgYXNuMSA9IHJlcXVpcmUoJy4uLy4uL2FzbjEnKTtcbnZhciBiYXNlID0gYXNuMS5iYXNlO1xudmFyIGJpZ251bSA9IGFzbjEuYmlnbnVtO1xuXG4vLyBJbXBvcnQgREVSIGNvbnN0YW50c1xudmFyIGRlciA9IGFzbjEuY29uc3RhbnRzLmRlcjtcblxuZnVuY3Rpb24gREVSRGVjb2RlcihlbnRpdHkpIHtcbiAgdGhpcy5lbmMgPSAnZGVyJztcbiAgdGhpcy5uYW1lID0gZW50aXR5Lm5hbWU7XG4gIHRoaXMuZW50aXR5ID0gZW50aXR5O1xuXG4gIC8vIENvbnN0cnVjdCBiYXNlIHRyZWVcbiAgdGhpcy50cmVlID0gbmV3IERFUk5vZGUoKTtcbiAgdGhpcy50cmVlLl9pbml0KGVudGl0eS5ib2R5KTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IERFUkRlY29kZXI7XG5cbkRFUkRlY29kZXIucHJvdG90eXBlLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShkYXRhLCBvcHRpb25zKSB7XG4gIGlmICghKGRhdGEgaW5zdGFuY2VvZiBiYXNlLkRlY29kZXJCdWZmZXIpKVxuICAgIGRhdGEgPSBuZXcgYmFzZS5EZWNvZGVyQnVmZmVyKGRhdGEsIG9wdGlvbnMpO1xuXG4gIHJldHVybiB0aGlzLnRyZWUuX2RlY29kZShkYXRhLCBvcHRpb25zKTtcbn07XG5cbi8vIFRyZWUgbWV0aG9kc1xuXG5mdW5jdGlvbiBERVJOb2RlKHBhcmVudCkge1xuICBiYXNlLk5vZGUuY2FsbCh0aGlzLCAnZGVyJywgcGFyZW50KTtcbn1cbmluaGVyaXRzKERFUk5vZGUsIGJhc2UuTm9kZSk7XG5cbkRFUk5vZGUucHJvdG90eXBlLl9wZWVrVGFnID0gZnVuY3Rpb24gcGVla1RhZyhidWZmZXIsIHRhZywgYW55KSB7XG4gIGlmIChidWZmZXIuaXNFbXB0eSgpKVxuICAgIHJldHVybiBmYWxzZTtcblxuICB2YXIgc3RhdGUgPSBidWZmZXIuc2F2ZSgpO1xuICB2YXIgZGVjb2RlZFRhZyA9IGRlckRlY29kZVRhZyhidWZmZXIsICdGYWlsZWQgdG8gcGVlayB0YWc6IFwiJyArIHRhZyArICdcIicpO1xuICBpZiAoYnVmZmVyLmlzRXJyb3IoZGVjb2RlZFRhZykpXG4gICAgcmV0dXJuIGRlY29kZWRUYWc7XG5cbiAgYnVmZmVyLnJlc3RvcmUoc3RhdGUpO1xuXG4gIHJldHVybiBkZWNvZGVkVGFnLnRhZyA9PT0gdGFnIHx8IGRlY29kZWRUYWcudGFnU3RyID09PSB0YWcgfHwgYW55O1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2RlY29kZVRhZyA9IGZ1bmN0aW9uIGRlY29kZVRhZyhidWZmZXIsIHRhZywgYW55KSB7XG4gIHZhciBkZWNvZGVkVGFnID0gZGVyRGVjb2RlVGFnKGJ1ZmZlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0ZhaWxlZCB0byBkZWNvZGUgdGFnIG9mIFwiJyArIHRhZyArICdcIicpO1xuICBpZiAoYnVmZmVyLmlzRXJyb3IoZGVjb2RlZFRhZykpXG4gICAgcmV0dXJuIGRlY29kZWRUYWc7XG5cbiAgdmFyIGxlbiA9IGRlckRlY29kZUxlbihidWZmZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgZGVjb2RlZFRhZy5wcmltaXRpdmUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgJ0ZhaWxlZCB0byBnZXQgbGVuZ3RoIG9mIFwiJyArIHRhZyArICdcIicpO1xuXG4gIC8vIEZhaWx1cmVcbiAgaWYgKGJ1ZmZlci5pc0Vycm9yKGxlbikpXG4gICAgcmV0dXJuIGxlbjtcblxuICBpZiAoIWFueSAmJlxuICAgICAgZGVjb2RlZFRhZy50YWcgIT09IHRhZyAmJlxuICAgICAgZGVjb2RlZFRhZy50YWdTdHIgIT09IHRhZyAmJlxuICAgICAgZGVjb2RlZFRhZy50YWdTdHIgKyAnb2YnICE9PSB0YWcpIHtcbiAgICByZXR1cm4gYnVmZmVyLmVycm9yKCdGYWlsZWQgdG8gbWF0Y2ggdGFnOiBcIicgKyB0YWcgKyAnXCInKTtcbiAgfVxuXG4gIGlmIChkZWNvZGVkVGFnLnByaW1pdGl2ZSB8fCBsZW4gIT09IG51bGwpXG4gICAgcmV0dXJuIGJ1ZmZlci5za2lwKGxlbiwgJ0ZhaWxlZCB0byBtYXRjaCBib2R5IG9mOiBcIicgKyB0YWcgKyAnXCInKTtcblxuICAvLyBJbmRlZmluaXRlIGxlbmd0aC4uLiBmaW5kIEVORCB0YWdcbiAgdmFyIHN0YXRlID0gYnVmZmVyLnNhdmUoKTtcbiAgdmFyIHJlcyA9IHRoaXMuX3NraXBVbnRpbEVuZChcbiAgICAgIGJ1ZmZlcixcbiAgICAgICdGYWlsZWQgdG8gc2tpcCBpbmRlZmluaXRlIGxlbmd0aCBib2R5OiBcIicgKyB0aGlzLnRhZyArICdcIicpO1xuICBpZiAoYnVmZmVyLmlzRXJyb3IocmVzKSlcbiAgICByZXR1cm4gcmVzO1xuXG4gIGxlbiA9IGJ1ZmZlci5vZmZzZXQgLSBzdGF0ZS5vZmZzZXQ7XG4gIGJ1ZmZlci5yZXN0b3JlKHN0YXRlKTtcbiAgcmV0dXJuIGJ1ZmZlci5za2lwKGxlbiwgJ0ZhaWxlZCB0byBtYXRjaCBib2R5IG9mOiBcIicgKyB0YWcgKyAnXCInKTtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9za2lwVW50aWxFbmQgPSBmdW5jdGlvbiBza2lwVW50aWxFbmQoYnVmZmVyLCBmYWlsKSB7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgdmFyIHRhZyA9IGRlckRlY29kZVRhZyhidWZmZXIsIGZhaWwpO1xuICAgIGlmIChidWZmZXIuaXNFcnJvcih0YWcpKVxuICAgICAgcmV0dXJuIHRhZztcbiAgICB2YXIgbGVuID0gZGVyRGVjb2RlTGVuKGJ1ZmZlciwgdGFnLnByaW1pdGl2ZSwgZmFpbCk7XG4gICAgaWYgKGJ1ZmZlci5pc0Vycm9yKGxlbikpXG4gICAgICByZXR1cm4gbGVuO1xuXG4gICAgdmFyIHJlcztcbiAgICBpZiAodGFnLnByaW1pdGl2ZSB8fCBsZW4gIT09IG51bGwpXG4gICAgICByZXMgPSBidWZmZXIuc2tpcChsZW4pXG4gICAgZWxzZVxuICAgICAgcmVzID0gdGhpcy5fc2tpcFVudGlsRW5kKGJ1ZmZlciwgZmFpbCk7XG5cbiAgICAvLyBGYWlsdXJlXG4gICAgaWYgKGJ1ZmZlci5pc0Vycm9yKHJlcykpXG4gICAgICByZXR1cm4gcmVzO1xuXG4gICAgaWYgKHRhZy50YWdTdHIgPT09ICdlbmQnKVxuICAgICAgYnJlYWs7XG4gIH1cbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9kZWNvZGVMaXN0ID0gZnVuY3Rpb24gZGVjb2RlTGlzdChidWZmZXIsIHRhZywgZGVjb2Rlcikge1xuICB2YXIgcmVzdWx0ID0gW107XG4gIHdoaWxlICghYnVmZmVyLmlzRW1wdHkoKSkge1xuICAgIHZhciBwb3NzaWJsZUVuZCA9IHRoaXMuX3BlZWtUYWcoYnVmZmVyLCAnZW5kJyk7XG4gICAgaWYgKGJ1ZmZlci5pc0Vycm9yKHBvc3NpYmxlRW5kKSlcbiAgICAgIHJldHVybiBwb3NzaWJsZUVuZDtcblxuICAgIHZhciByZXMgPSBkZWNvZGVyLmRlY29kZShidWZmZXIsICdkZXInKTtcbiAgICBpZiAoYnVmZmVyLmlzRXJyb3IocmVzKSAmJiBwb3NzaWJsZUVuZClcbiAgICAgIGJyZWFrO1xuICAgIHJlc3VsdC5wdXNoKHJlcyk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9kZWNvZGVTdHIgPSBmdW5jdGlvbiBkZWNvZGVTdHIoYnVmZmVyLCB0YWcpIHtcbiAgaWYgKHRhZyA9PT0gJ29jdHN0cicpIHtcbiAgICByZXR1cm4gYnVmZmVyLnJhdygpO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ2JpdHN0cicpIHtcbiAgICB2YXIgdW51c2VkID0gYnVmZmVyLnJlYWRVSW50OCgpO1xuICAgIGlmIChidWZmZXIuaXNFcnJvcih1bnVzZWQpKVxuICAgICAgcmV0dXJuIHVudXNlZDtcblxuICAgIHJldHVybiB7IHVudXNlZDogdW51c2VkLCBkYXRhOiBidWZmZXIucmF3KCkgfTtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICdpYTVzdHInIHx8IHRhZyA9PT0gJ3V0ZjhzdHInKSB7XG4gICAgcmV0dXJuIGJ1ZmZlci5yYXcoKS50b1N0cmluZygpO1xuICB9IGVsc2UgaWYodGFnID09PSAnbnVtc3RyJykge1xuICAgIHZhciBudW1zdHIgPSBidWZmZXIucmF3KCkudG9TdHJpbmcoJ2FzY2lpJyk7XG4gICAgaWYgKCF0aGlzLl9pc051bXN0cihudW1zdHIpKSB7XG4gICAgICByZXR1cm4gYnVmZmVyLmVycm9yKCdEZWNvZGluZyBvZiBzdHJpbmcgdHlwZTogJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdudW1zdHIgdW5zdXBwb3J0ZWQgY2hhcmFjdGVycycpO1xuICAgIH1cblxuICAgIHJldHVybiBudW1zdHI7XG4gIH0gZWxzZSBpZiAodGFnID09PSAncHJpbnRzdHInKSB7XG4gICAgdmFyIHByaW50c3RyID0gYnVmZmVyLnJhdygpLnRvU3RyaW5nKCdhc2NpaScpO1xuICAgIGlmICghdGhpcy5faXNQcmludHN0cihwcmludHN0cikpIHtcbiAgICAgIHJldHVybiBidWZmZXIuZXJyb3IoJ0RlY29kaW5nIG9mIHN0cmluZyB0eXBlOiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ3ByaW50c3RyIHVuc3VwcG9ydGVkIGNoYXJhY3RlcnMnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcHJpbnRzdHI7XG4gIH0gZWxzZSBpZih0YWcgPT09ICdibXBzdHInKSB7XG4gICAgdmFyIHJhdyA9IGJ1ZmZlci5yYXcoKTtcbiAgICBpZiAocmF3Lmxlbmd0aCAlIDIgPT09IDEpXG4gICAgICByZXR1cm4gYnVmZmVyLmVycm9yKCdEZWNvZGluZyBvZiBzdHJpbmcgdHlwZTogYm1wc3RyIGxlbmd0aCBtaXNtYXRjaCcpO1xuXG4gICAgdmFyIHN0ciA9ICcnO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmF3Lmxlbmd0aCAvIDI7IGkrKykge1xuICAgICAgc3RyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUocmF3LnJlYWRVSW50MTZCRShpICogMikpO1xuICAgIH1cbiAgICByZXR1cm4gc3RyO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBidWZmZXIuZXJyb3IoJ0RlY29kaW5nIG9mIHN0cmluZyB0eXBlOiAnICsgdGFnICsgJyB1bnN1cHBvcnRlZCcpO1xuICB9XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZGVjb2RlT2JqaWQgPSBmdW5jdGlvbiBkZWNvZGVPYmppZChidWZmZXIsIHZhbHVlcywgcmVsYXRpdmUpIHtcbiAgdmFyIGlkZW50aWZpZXJzID0gW107XG4gIHZhciBpZGVudCA9IDA7XG4gIHdoaWxlICghYnVmZmVyLmlzRW1wdHkoKSkge1xuICAgIHZhciBzdWJpZGVudCA9IGJ1ZmZlci5yZWFkVUludDgoKTtcbiAgICBpZGVudCA8PD0gNztcbiAgICBpZGVudCB8PSBzdWJpZGVudCAmIDB4N2Y7XG4gICAgaWYgKChzdWJpZGVudCAmIDB4ODApID09PSAwKSB7XG4gICAgICBpZGVudGlmaWVycy5wdXNoKGlkZW50KTtcbiAgICAgIGlkZW50ID0gMDtcbiAgICB9XG4gIH1cbiAgaWYgKHN1YmlkZW50ICYgMHg4MClcbiAgICBpZGVudGlmaWVycy5wdXNoKGlkZW50KTtcblxuICB2YXIgZmlyc3QgPSAoaWRlbnRpZmllcnNbMF0gLyA0MCkgfCAwO1xuICB2YXIgc2Vjb25kID0gaWRlbnRpZmllcnNbMF0gJSA0MDtcblxuICBpZiAocmVsYXRpdmUpXG4gICAgcmVzdWx0ID0gaWRlbnRpZmllcnM7XG4gIGVsc2VcbiAgICByZXN1bHQgPSBbZmlyc3QsIHNlY29uZF0uY29uY2F0KGlkZW50aWZpZXJzLnNsaWNlKDEpKTtcblxuICBpZiAodmFsdWVzKSB7XG4gICAgdmFyIHRtcCA9IHZhbHVlc1tyZXN1bHQuam9pbignICcpXTtcbiAgICBpZiAodG1wID09PSB1bmRlZmluZWQpXG4gICAgICB0bXAgPSB2YWx1ZXNbcmVzdWx0LmpvaW4oJy4nKV07XG4gICAgaWYgKHRtcCAhPT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0ID0gdG1wO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9kZWNvZGVUaW1lID0gZnVuY3Rpb24gZGVjb2RlVGltZShidWZmZXIsIHRhZykge1xuICB2YXIgc3RyID0gYnVmZmVyLnJhdygpLnRvU3RyaW5nKCk7XG4gIGlmICh0YWcgPT09ICdnZW50aW1lJykge1xuICAgIHZhciB5ZWFyID0gc3RyLnNsaWNlKDAsIDQpIHwgMDtcbiAgICB2YXIgbW9uID0gc3RyLnNsaWNlKDQsIDYpIHwgMDtcbiAgICB2YXIgZGF5ID0gc3RyLnNsaWNlKDYsIDgpIHwgMDtcbiAgICB2YXIgaG91ciA9IHN0ci5zbGljZSg4LCAxMCkgfCAwO1xuICAgIHZhciBtaW4gPSBzdHIuc2xpY2UoMTAsIDEyKSB8IDA7XG4gICAgdmFyIHNlYyA9IHN0ci5zbGljZSgxMiwgMTQpIHwgMDtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICd1dGN0aW1lJykge1xuICAgIHZhciB5ZWFyID0gc3RyLnNsaWNlKDAsIDIpIHwgMDtcbiAgICB2YXIgbW9uID0gc3RyLnNsaWNlKDIsIDQpIHwgMDtcbiAgICB2YXIgZGF5ID0gc3RyLnNsaWNlKDQsIDYpIHwgMDtcbiAgICB2YXIgaG91ciA9IHN0ci5zbGljZSg2LCA4KSB8IDA7XG4gICAgdmFyIG1pbiA9IHN0ci5zbGljZSg4LCAxMCkgfCAwO1xuICAgIHZhciBzZWMgPSBzdHIuc2xpY2UoMTAsIDEyKSB8IDA7XG4gICAgaWYgKHllYXIgPCA3MClcbiAgICAgIHllYXIgPSAyMDAwICsgeWVhcjtcbiAgICBlbHNlXG4gICAgICB5ZWFyID0gMTkwMCArIHllYXI7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJ1ZmZlci5lcnJvcignRGVjb2RpbmcgJyArIHRhZyArICcgdGltZSBpcyBub3Qgc3VwcG9ydGVkIHlldCcpO1xuICB9XG5cbiAgcmV0dXJuIERhdGUuVVRDKHllYXIsIG1vbiAtIDEsIGRheSwgaG91ciwgbWluLCBzZWMsIDApO1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2RlY29kZU51bGwgPSBmdW5jdGlvbiBkZWNvZGVOdWxsKGJ1ZmZlcikge1xuICByZXR1cm4gbnVsbDtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9kZWNvZGVCb29sID0gZnVuY3Rpb24gZGVjb2RlQm9vbChidWZmZXIpIHtcbiAgdmFyIHJlcyA9IGJ1ZmZlci5yZWFkVUludDgoKTtcbiAgaWYgKGJ1ZmZlci5pc0Vycm9yKHJlcykpXG4gICAgcmV0dXJuIHJlcztcbiAgZWxzZVxuICAgIHJldHVybiByZXMgIT09IDA7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZGVjb2RlSW50ID0gZnVuY3Rpb24gZGVjb2RlSW50KGJ1ZmZlciwgdmFsdWVzKSB7XG4gIC8vIEJpZ2ludCwgcmV0dXJuIGFzIGl0IGlzIChhc3N1bWUgYmlnIGVuZGlhbilcbiAgdmFyIHJhdyA9IGJ1ZmZlci5yYXcoKTtcbiAgdmFyIHJlcyA9IG5ldyBiaWdudW0ocmF3KTtcblxuICBpZiAodmFsdWVzKVxuICAgIHJlcyA9IHZhbHVlc1tyZXMudG9TdHJpbmcoMTApXSB8fCByZXM7XG5cbiAgcmV0dXJuIHJlcztcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl91c2UgPSBmdW5jdGlvbiB1c2UoZW50aXR5LCBvYmopIHtcbiAgaWYgKHR5cGVvZiBlbnRpdHkgPT09ICdmdW5jdGlvbicpXG4gICAgZW50aXR5ID0gZW50aXR5KG9iaik7XG4gIHJldHVybiBlbnRpdHkuX2dldERlY29kZXIoJ2RlcicpLnRyZWU7XG59O1xuXG4vLyBVdGlsaXR5IG1ldGhvZHNcblxuZnVuY3Rpb24gZGVyRGVjb2RlVGFnKGJ1ZiwgZmFpbCkge1xuICB2YXIgdGFnID0gYnVmLnJlYWRVSW50OChmYWlsKTtcbiAgaWYgKGJ1Zi5pc0Vycm9yKHRhZykpXG4gICAgcmV0dXJuIHRhZztcblxuICB2YXIgY2xzID0gZGVyLnRhZ0NsYXNzW3RhZyA+PiA2XTtcbiAgdmFyIHByaW1pdGl2ZSA9ICh0YWcgJiAweDIwKSA9PT0gMDtcblxuICAvLyBNdWx0aS1vY3RldCB0YWcgLSBsb2FkXG4gIGlmICgodGFnICYgMHgxZikgPT09IDB4MWYpIHtcbiAgICB2YXIgb2N0ID0gdGFnO1xuICAgIHRhZyA9IDA7XG4gICAgd2hpbGUgKChvY3QgJiAweDgwKSA9PT0gMHg4MCkge1xuICAgICAgb2N0ID0gYnVmLnJlYWRVSW50OChmYWlsKTtcbiAgICAgIGlmIChidWYuaXNFcnJvcihvY3QpKVxuICAgICAgICByZXR1cm4gb2N0O1xuXG4gICAgICB0YWcgPDw9IDc7XG4gICAgICB0YWcgfD0gb2N0ICYgMHg3ZjtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGFnICY9IDB4MWY7XG4gIH1cbiAgdmFyIHRhZ1N0ciA9IGRlci50YWdbdGFnXTtcblxuICByZXR1cm4ge1xuICAgIGNsczogY2xzLFxuICAgIHByaW1pdGl2ZTogcHJpbWl0aXZlLFxuICAgIHRhZzogdGFnLFxuICAgIHRhZ1N0cjogdGFnU3RyXG4gIH07XG59XG5cbmZ1bmN0aW9uIGRlckRlY29kZUxlbihidWYsIHByaW1pdGl2ZSwgZmFpbCkge1xuICB2YXIgbGVuID0gYnVmLnJlYWRVSW50OChmYWlsKTtcbiAgaWYgKGJ1Zi5pc0Vycm9yKGxlbikpXG4gICAgcmV0dXJuIGxlbjtcblxuICAvLyBJbmRlZmluaXRlIGZvcm1cbiAgaWYgKCFwcmltaXRpdmUgJiYgbGVuID09PSAweDgwKVxuICAgIHJldHVybiBudWxsO1xuXG4gIC8vIERlZmluaXRlIGZvcm1cbiAgaWYgKChsZW4gJiAweDgwKSA9PT0gMCkge1xuICAgIC8vIFNob3J0IGZvcm1cbiAgICByZXR1cm4gbGVuO1xuICB9XG5cbiAgLy8gTG9uZyBmb3JtXG4gIHZhciBudW0gPSBsZW4gJiAweDdmO1xuICBpZiAobnVtID49IDQpXG4gICAgcmV0dXJuIGJ1Zi5lcnJvcignbGVuZ3RoIG9jdGVjdCBpcyB0b28gbG9uZycpO1xuXG4gIGxlbiA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbnVtOyBpKyspIHtcbiAgICBsZW4gPDw9IDg7XG4gICAgdmFyIGogPSBidWYucmVhZFVJbnQ4KGZhaWwpO1xuICAgIGlmIChidWYuaXNFcnJvcihqKSlcbiAgICAgIHJldHVybiBqO1xuICAgIGxlbiB8PSBqO1xuICB9XG5cbiAgcmV0dXJuIGxlbjtcbn1cbiIsInZhciBkZWNvZGVycyA9IGV4cG9ydHM7XG5cbmRlY29kZXJzLmRlciA9IHJlcXVpcmUoJy4vZGVyJyk7XG5kZWNvZGVycy5wZW0gPSByZXF1aXJlKCcuL3BlbScpO1xuIiwidmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG5cbnZhciBhc24xID0gcmVxdWlyZSgnLi4vLi4vYXNuMScpO1xudmFyIERFUkRlY29kZXIgPSByZXF1aXJlKCcuL2RlcicpO1xuXG5mdW5jdGlvbiBQRU1EZWNvZGVyKGVudGl0eSkge1xuICBERVJEZWNvZGVyLmNhbGwodGhpcywgZW50aXR5KTtcbiAgdGhpcy5lbmMgPSAncGVtJztcbn07XG5pbmhlcml0cyhQRU1EZWNvZGVyLCBERVJEZWNvZGVyKTtcbm1vZHVsZS5leHBvcnRzID0gUEVNRGVjb2RlcjtcblxuUEVNRGVjb2Rlci5wcm90b3R5cGUuZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKGRhdGEsIG9wdGlvbnMpIHtcbiAgdmFyIGxpbmVzID0gZGF0YS50b1N0cmluZygpLnNwbGl0KC9bXFxyXFxuXSsvZyk7XG5cbiAgdmFyIGxhYmVsID0gb3B0aW9ucy5sYWJlbC50b1VwcGVyQ2FzZSgpO1xuXG4gIHZhciByZSA9IC9eLS0tLS0oQkVHSU58RU5EKSAoW14tXSspLS0tLS0kLztcbiAgdmFyIHN0YXJ0ID0gLTE7XG4gIHZhciBlbmQgPSAtMTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBtYXRjaCA9IGxpbmVzW2ldLm1hdGNoKHJlKTtcbiAgICBpZiAobWF0Y2ggPT09IG51bGwpXG4gICAgICBjb250aW51ZTtcblxuICAgIGlmIChtYXRjaFsyXSAhPT0gbGFiZWwpXG4gICAgICBjb250aW51ZTtcblxuICAgIGlmIChzdGFydCA9PT0gLTEpIHtcbiAgICAgIGlmIChtYXRjaFsxXSAhPT0gJ0JFR0lOJylcbiAgICAgICAgYnJlYWs7XG4gICAgICBzdGFydCA9IGk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChtYXRjaFsxXSAhPT0gJ0VORCcpXG4gICAgICAgIGJyZWFrO1xuICAgICAgZW5kID0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBpZiAoc3RhcnQgPT09IC0xIHx8IGVuZCA9PT0gLTEpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdQRU0gc2VjdGlvbiBub3QgZm91bmQgZm9yOiAnICsgbGFiZWwpO1xuXG4gIHZhciBiYXNlNjQgPSBsaW5lcy5zbGljZShzdGFydCArIDEsIGVuZCkuam9pbignJyk7XG4gIC8vIFJlbW92ZSBleGNlc3NpdmUgc3ltYm9sc1xuICBiYXNlNjQucmVwbGFjZSgvW15hLXowLTlcXCtcXC89XSsvZ2ksICcnKTtcblxuICB2YXIgaW5wdXQgPSBuZXcgQnVmZmVyKGJhc2U2NCwgJ2Jhc2U2NCcpO1xuICByZXR1cm4gREVSRGVjb2Rlci5wcm90b3R5cGUuZGVjb2RlLmNhbGwodGhpcywgaW5wdXQsIG9wdGlvbnMpO1xufTtcbiIsInZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuXG52YXIgYXNuMSA9IHJlcXVpcmUoJy4uLy4uL2FzbjEnKTtcbnZhciBiYXNlID0gYXNuMS5iYXNlO1xudmFyIGJpZ251bSA9IGFzbjEuYmlnbnVtO1xuXG4vLyBJbXBvcnQgREVSIGNvbnN0YW50c1xudmFyIGRlciA9IGFzbjEuY29uc3RhbnRzLmRlcjtcblxuZnVuY3Rpb24gREVSRW5jb2RlcihlbnRpdHkpIHtcbiAgdGhpcy5lbmMgPSAnZGVyJztcbiAgdGhpcy5uYW1lID0gZW50aXR5Lm5hbWU7XG4gIHRoaXMuZW50aXR5ID0gZW50aXR5O1xuXG4gIC8vIENvbnN0cnVjdCBiYXNlIHRyZWVcbiAgdGhpcy50cmVlID0gbmV3IERFUk5vZGUoKTtcbiAgdGhpcy50cmVlLl9pbml0KGVudGl0eS5ib2R5KTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IERFUkVuY29kZXI7XG5cbkRFUkVuY29kZXIucHJvdG90eXBlLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShkYXRhLCByZXBvcnRlcikge1xuICByZXR1cm4gdGhpcy50cmVlLl9lbmNvZGUoZGF0YSwgcmVwb3J0ZXIpLmpvaW4oKTtcbn07XG5cbi8vIFRyZWUgbWV0aG9kc1xuXG5mdW5jdGlvbiBERVJOb2RlKHBhcmVudCkge1xuICBiYXNlLk5vZGUuY2FsbCh0aGlzLCAnZGVyJywgcGFyZW50KTtcbn1cbmluaGVyaXRzKERFUk5vZGUsIGJhc2UuTm9kZSk7XG5cbkRFUk5vZGUucHJvdG90eXBlLl9lbmNvZGVDb21wb3NpdGUgPSBmdW5jdGlvbiBlbmNvZGVDb21wb3NpdGUodGFnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmltaXRpdmUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNscyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudCkge1xuICB2YXIgZW5jb2RlZFRhZyA9IGVuY29kZVRhZyh0YWcsIHByaW1pdGl2ZSwgY2xzLCB0aGlzLnJlcG9ydGVyKTtcblxuICAvLyBTaG9ydCBmb3JtXG4gIGlmIChjb250ZW50Lmxlbmd0aCA8IDB4ODApIHtcbiAgICB2YXIgaGVhZGVyID0gbmV3IEJ1ZmZlcigyKTtcbiAgICBoZWFkZXJbMF0gPSBlbmNvZGVkVGFnO1xuICAgIGhlYWRlclsxXSA9IGNvbnRlbnQubGVuZ3RoO1xuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKFsgaGVhZGVyLCBjb250ZW50IF0pO1xuICB9XG5cbiAgLy8gTG9uZyBmb3JtXG4gIC8vIENvdW50IG9jdGV0cyByZXF1aXJlZCB0byBzdG9yZSBsZW5ndGhcbiAgdmFyIGxlbk9jdGV0cyA9IDE7XG4gIGZvciAodmFyIGkgPSBjb250ZW50Lmxlbmd0aDsgaSA+PSAweDEwMDsgaSA+Pj0gOClcbiAgICBsZW5PY3RldHMrKztcblxuICB2YXIgaGVhZGVyID0gbmV3IEJ1ZmZlcigxICsgMSArIGxlbk9jdGV0cyk7XG4gIGhlYWRlclswXSA9IGVuY29kZWRUYWc7XG4gIGhlYWRlclsxXSA9IDB4ODAgfCBsZW5PY3RldHM7XG5cbiAgZm9yICh2YXIgaSA9IDEgKyBsZW5PY3RldHMsIGogPSBjb250ZW50Lmxlbmd0aDsgaiA+IDA7IGktLSwgaiA+Pj0gOClcbiAgICBoZWFkZXJbaV0gPSBqICYgMHhmZjtcblxuICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihbIGhlYWRlciwgY29udGVudCBdKTtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9lbmNvZGVTdHIgPSBmdW5jdGlvbiBlbmNvZGVTdHIoc3RyLCB0YWcpIHtcbiAgaWYgKHRhZyA9PT0gJ29jdHN0cicpIHtcbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihzdHIpO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ2JpdHN0cicpIHtcbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihbIHN0ci51bnVzZWQgfCAwLCBzdHIuZGF0YSBdKTtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICdpYTVzdHInIHx8IHRhZyA9PT0gJ3V0ZjhzdHInKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoc3RyKTtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICdibXBzdHInKSB7XG4gICAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoc3RyLmxlbmd0aCAqIDIpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBidWYud3JpdGVVSW50MTZCRShzdHIuY2hhckNvZGVBdChpKSwgaSAqIDIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihidWYpO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ251bXN0cicpIHtcbiAgICBpZiAoIXRoaXMuX2lzTnVtc3RyKHN0cikpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlcG9ydGVyLmVycm9yKCdFbmNvZGluZyBvZiBzdHJpbmcgdHlwZTogbnVtc3RyIHN1cHBvcnRzICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ29ubHkgZGlnaXRzIGFuZCBzcGFjZScpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKHN0cik7XG4gIH0gZWxzZSBpZiAodGFnID09PSAncHJpbnRzdHInKSB7XG4gICAgaWYgKCF0aGlzLl9pc1ByaW50c3RyKHN0cikpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlcG9ydGVyLmVycm9yKCdFbmNvZGluZyBvZiBzdHJpbmcgdHlwZTogcHJpbnRzdHIgc3VwcG9ydHMgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnb25seSBsYXRpbiB1cHBlciBhbmQgbG93ZXIgY2FzZSBsZXR0ZXJzLCAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkaWdpdHMsIHNwYWNlLCBhcG9zdHJvcGhlLCBsZWZ0IGFuZCByaWd0aCAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwYXJlbnRoZXNpcywgcGx1cyBzaWduLCBjb21tYSwgaHlwaGVuLCAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkb3QsIHNsYXNoLCBjb2xvbiwgZXF1YWwgc2lnbiwgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncXVlc3Rpb24gbWFyaycpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKHN0cik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHRoaXMucmVwb3J0ZXIuZXJyb3IoJ0VuY29kaW5nIG9mIHN0cmluZyB0eXBlOiAnICsgdGFnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnIHVuc3VwcG9ydGVkJyk7XG4gIH1cbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9lbmNvZGVPYmppZCA9IGZ1bmN0aW9uIGVuY29kZU9iamlkKGlkLCB2YWx1ZXMsIHJlbGF0aXZlKSB7XG4gIGlmICh0eXBlb2YgaWQgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKCF2YWx1ZXMpXG4gICAgICByZXR1cm4gdGhpcy5yZXBvcnRlci5lcnJvcignc3RyaW5nIG9iamlkIGdpdmVuLCBidXQgbm8gdmFsdWVzIG1hcCBmb3VuZCcpO1xuICAgIGlmICghdmFsdWVzLmhhc093blByb3BlcnR5KGlkKSlcbiAgICAgIHJldHVybiB0aGlzLnJlcG9ydGVyLmVycm9yKCdvYmppZCBub3QgZm91bmQgaW4gdmFsdWVzIG1hcCcpO1xuICAgIGlkID0gdmFsdWVzW2lkXS5zcGxpdCgvW1xcc1xcLl0rL2cpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaWQubGVuZ3RoOyBpKyspXG4gICAgICBpZFtpXSB8PSAwO1xuICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoaWQpKSB7XG4gICAgaWQgPSBpZC5zbGljZSgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaWQubGVuZ3RoOyBpKyspXG4gICAgICBpZFtpXSB8PSAwO1xuICB9XG5cbiAgaWYgKCFBcnJheS5pc0FycmF5KGlkKSkge1xuICAgIHJldHVybiB0aGlzLnJlcG9ydGVyLmVycm9yKCdvYmppZCgpIHNob3VsZCBiZSBlaXRoZXIgYXJyYXkgb3Igc3RyaW5nLCAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZ290OiAnICsgSlNPTi5zdHJpbmdpZnkoaWQpKTtcbiAgfVxuXG4gIGlmICghcmVsYXRpdmUpIHtcbiAgICBpZiAoaWRbMV0gPj0gNDApXG4gICAgICByZXR1cm4gdGhpcy5yZXBvcnRlci5lcnJvcignU2Vjb25kIG9iamlkIGlkZW50aWZpZXIgT09CJyk7XG4gICAgaWQuc3BsaWNlKDAsIDIsIGlkWzBdICogNDAgKyBpZFsxXSk7XG4gIH1cblxuICAvLyBDb3VudCBudW1iZXIgb2Ygb2N0ZXRzXG4gIHZhciBzaXplID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBpZC5sZW5ndGg7IGkrKykge1xuICAgIHZhciBpZGVudCA9IGlkW2ldO1xuICAgIGZvciAoc2l6ZSsrOyBpZGVudCA+PSAweDgwOyBpZGVudCA+Pj0gNylcbiAgICAgIHNpemUrKztcbiAgfVxuXG4gIHZhciBvYmppZCA9IG5ldyBCdWZmZXIoc2l6ZSk7XG4gIHZhciBvZmZzZXQgPSBvYmppZC5sZW5ndGggLSAxO1xuICBmb3IgKHZhciBpID0gaWQubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICB2YXIgaWRlbnQgPSBpZFtpXTtcbiAgICBvYmppZFtvZmZzZXQtLV0gPSBpZGVudCAmIDB4N2Y7XG4gICAgd2hpbGUgKChpZGVudCA+Pj0gNykgPiAwKVxuICAgICAgb2JqaWRbb2Zmc2V0LS1dID0gMHg4MCB8IChpZGVudCAmIDB4N2YpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIob2JqaWQpO1xufTtcblxuZnVuY3Rpb24gdHdvKG51bSkge1xuICBpZiAobnVtIDwgMTApXG4gICAgcmV0dXJuICcwJyArIG51bTtcbiAgZWxzZVxuICAgIHJldHVybiBudW07XG59XG5cbkRFUk5vZGUucHJvdG90eXBlLl9lbmNvZGVUaW1lID0gZnVuY3Rpb24gZW5jb2RlVGltZSh0aW1lLCB0YWcpIHtcbiAgdmFyIHN0cjtcbiAgdmFyIGRhdGUgPSBuZXcgRGF0ZSh0aW1lKTtcblxuICBpZiAodGFnID09PSAnZ2VudGltZScpIHtcbiAgICBzdHIgPSBbXG4gICAgICB0d28oZGF0ZS5nZXRGdWxsWWVhcigpKSxcbiAgICAgIHR3byhkYXRlLmdldFVUQ01vbnRoKCkgKyAxKSxcbiAgICAgIHR3byhkYXRlLmdldFVUQ0RhdGUoKSksXG4gICAgICB0d28oZGF0ZS5nZXRVVENIb3VycygpKSxcbiAgICAgIHR3byhkYXRlLmdldFVUQ01pbnV0ZXMoKSksXG4gICAgICB0d28oZGF0ZS5nZXRVVENTZWNvbmRzKCkpLFxuICAgICAgJ1onXG4gICAgXS5qb2luKCcnKTtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICd1dGN0aW1lJykge1xuICAgIHN0ciA9IFtcbiAgICAgIHR3byhkYXRlLmdldEZ1bGxZZWFyKCkgJSAxMDApLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDTW9udGgoKSArIDEpLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDRGF0ZSgpKSxcbiAgICAgIHR3byhkYXRlLmdldFVUQ0hvdXJzKCkpLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDTWludXRlcygpKSxcbiAgICAgIHR3byhkYXRlLmdldFVUQ1NlY29uZHMoKSksXG4gICAgICAnWidcbiAgICBdLmpvaW4oJycpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMucmVwb3J0ZXIuZXJyb3IoJ0VuY29kaW5nICcgKyB0YWcgKyAnIHRpbWUgaXMgbm90IHN1cHBvcnRlZCB5ZXQnKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9lbmNvZGVTdHIoc3RyLCAnb2N0c3RyJyk7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZW5jb2RlTnVsbCA9IGZ1bmN0aW9uIGVuY29kZU51bGwoKSB7XG4gIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKCcnKTtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9lbmNvZGVJbnQgPSBmdW5jdGlvbiBlbmNvZGVJbnQobnVtLCB2YWx1ZXMpIHtcbiAgaWYgKHR5cGVvZiBudW0gPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKCF2YWx1ZXMpXG4gICAgICByZXR1cm4gdGhpcy5yZXBvcnRlci5lcnJvcignU3RyaW5nIGludCBvciBlbnVtIGdpdmVuLCBidXQgbm8gdmFsdWVzIG1hcCcpO1xuICAgIGlmICghdmFsdWVzLmhhc093blByb3BlcnR5KG51bSkpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlcG9ydGVyLmVycm9yKCdWYWx1ZXMgbWFwIGRvZXNuXFwndCBjb250YWluOiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KG51bSkpO1xuICAgIH1cbiAgICBudW0gPSB2YWx1ZXNbbnVtXTtcbiAgfVxuXG4gIC8vIEJpZ251bSwgYXNzdW1lIGJpZyBlbmRpYW5cbiAgaWYgKHR5cGVvZiBudW0gIT09ICdudW1iZXInICYmICFCdWZmZXIuaXNCdWZmZXIobnVtKSkge1xuICAgIHZhciBudW1BcnJheSA9IG51bS50b0FycmF5KCk7XG4gICAgaWYgKCFudW0uc2lnbiAmJiBudW1BcnJheVswXSAmIDB4ODApIHtcbiAgICAgIG51bUFycmF5LnVuc2hpZnQoMCk7XG4gICAgfVxuICAgIG51bSA9IG5ldyBCdWZmZXIobnVtQXJyYXkpO1xuICB9XG5cbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihudW0pKSB7XG4gICAgdmFyIHNpemUgPSBudW0ubGVuZ3RoO1xuICAgIGlmIChudW0ubGVuZ3RoID09PSAwKVxuICAgICAgc2l6ZSsrO1xuXG4gICAgdmFyIG91dCA9IG5ldyBCdWZmZXIoc2l6ZSk7XG4gICAgbnVtLmNvcHkob3V0KTtcbiAgICBpZiAobnVtLmxlbmd0aCA9PT0gMClcbiAgICAgIG91dFswXSA9IDBcbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihvdXQpO1xuICB9XG5cbiAgaWYgKG51bSA8IDB4ODApXG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIobnVtKTtcblxuICBpZiAobnVtIDwgMHgxMDApXG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoWzAsIG51bV0pO1xuXG4gIHZhciBzaXplID0gMTtcbiAgZm9yICh2YXIgaSA9IG51bTsgaSA+PSAweDEwMDsgaSA+Pj0gOClcbiAgICBzaXplKys7XG5cbiAgdmFyIG91dCA9IG5ldyBBcnJheShzaXplKTtcbiAgZm9yICh2YXIgaSA9IG91dC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIG91dFtpXSA9IG51bSAmIDB4ZmY7XG4gICAgbnVtID4+PSA4O1xuICB9XG4gIGlmKG91dFswXSAmIDB4ODApIHtcbiAgICBvdXQudW5zaGlmdCgwKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKG5ldyBCdWZmZXIob3V0KSk7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZW5jb2RlQm9vbCA9IGZ1bmN0aW9uIGVuY29kZUJvb2wodmFsdWUpIHtcbiAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIodmFsdWUgPyAweGZmIDogMCk7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fdXNlID0gZnVuY3Rpb24gdXNlKGVudGl0eSwgb2JqKSB7XG4gIGlmICh0eXBlb2YgZW50aXR5ID09PSAnZnVuY3Rpb24nKVxuICAgIGVudGl0eSA9IGVudGl0eShvYmopO1xuICByZXR1cm4gZW50aXR5Ll9nZXRFbmNvZGVyKCdkZXInKS50cmVlO1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX3NraXBEZWZhdWx0ID0gZnVuY3Rpb24gc2tpcERlZmF1bHQoZGF0YUJ1ZmZlciwgcmVwb3J0ZXIsIHBhcmVudCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG4gIHZhciBpO1xuICBpZiAoc3RhdGVbJ2RlZmF1bHQnXSA9PT0gbnVsbClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGRhdGEgPSBkYXRhQnVmZmVyLmpvaW4oKTtcbiAgaWYgKHN0YXRlLmRlZmF1bHRCdWZmZXIgPT09IHVuZGVmaW5lZClcbiAgICBzdGF0ZS5kZWZhdWx0QnVmZmVyID0gdGhpcy5fZW5jb2RlVmFsdWUoc3RhdGVbJ2RlZmF1bHQnXSwgcmVwb3J0ZXIsIHBhcmVudCkuam9pbigpO1xuXG4gIGlmIChkYXRhLmxlbmd0aCAhPT0gc3RhdGUuZGVmYXVsdEJ1ZmZlci5sZW5ndGgpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIGZvciAoaT0wOyBpIDwgZGF0YS5sZW5ndGg7IGkrKylcbiAgICBpZiAoZGF0YVtpXSAhPT0gc3RhdGUuZGVmYXVsdEJ1ZmZlcltpXSlcbiAgICAgIHJldHVybiBmYWxzZTtcblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8vIFV0aWxpdHkgbWV0aG9kc1xuXG5mdW5jdGlvbiBlbmNvZGVUYWcodGFnLCBwcmltaXRpdmUsIGNscywgcmVwb3J0ZXIpIHtcbiAgdmFyIHJlcztcblxuICBpZiAodGFnID09PSAnc2Vxb2YnKVxuICAgIHRhZyA9ICdzZXEnO1xuICBlbHNlIGlmICh0YWcgPT09ICdzZXRvZicpXG4gICAgdGFnID0gJ3NldCc7XG5cbiAgaWYgKGRlci50YWdCeU5hbWUuaGFzT3duUHJvcGVydHkodGFnKSlcbiAgICByZXMgPSBkZXIudGFnQnlOYW1lW3RhZ107XG4gIGVsc2UgaWYgKHR5cGVvZiB0YWcgPT09ICdudW1iZXInICYmICh0YWcgfCAwKSA9PT0gdGFnKVxuICAgIHJlcyA9IHRhZztcbiAgZWxzZVxuICAgIHJldHVybiByZXBvcnRlci5lcnJvcignVW5rbm93biB0YWc6ICcgKyB0YWcpO1xuXG4gIGlmIChyZXMgPj0gMHgxZilcbiAgICByZXR1cm4gcmVwb3J0ZXIuZXJyb3IoJ011bHRpLW9jdGV0IHRhZyBlbmNvZGluZyB1bnN1cHBvcnRlZCcpO1xuXG4gIGlmICghcHJpbWl0aXZlKVxuICAgIHJlcyB8PSAweDIwO1xuXG4gIHJlcyB8PSAoZGVyLnRhZ0NsYXNzQnlOYW1lW2NscyB8fCAndW5pdmVyc2FsJ10gPDwgNik7XG5cbiAgcmV0dXJuIHJlcztcbn1cbiIsInZhciBlbmNvZGVycyA9IGV4cG9ydHM7XG5cbmVuY29kZXJzLmRlciA9IHJlcXVpcmUoJy4vZGVyJyk7XG5lbmNvZGVycy5wZW0gPSByZXF1aXJlKCcuL3BlbScpO1xuIiwidmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG5cbnZhciBhc24xID0gcmVxdWlyZSgnLi4vLi4vYXNuMScpO1xudmFyIERFUkVuY29kZXIgPSByZXF1aXJlKCcuL2RlcicpO1xuXG5mdW5jdGlvbiBQRU1FbmNvZGVyKGVudGl0eSkge1xuICBERVJFbmNvZGVyLmNhbGwodGhpcywgZW50aXR5KTtcbiAgdGhpcy5lbmMgPSAncGVtJztcbn07XG5pbmhlcml0cyhQRU1FbmNvZGVyLCBERVJFbmNvZGVyKTtcbm1vZHVsZS5leHBvcnRzID0gUEVNRW5jb2RlcjtcblxuUEVNRW5jb2Rlci5wcm90b3R5cGUuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKGRhdGEsIG9wdGlvbnMpIHtcbiAgdmFyIGJ1ZiA9IERFUkVuY29kZXIucHJvdG90eXBlLmVuY29kZS5jYWxsKHRoaXMsIGRhdGEpO1xuXG4gIHZhciBwID0gYnVmLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgdmFyIG91dCA9IFsgJy0tLS0tQkVHSU4gJyArIG9wdGlvbnMubGFiZWwgKyAnLS0tLS0nIF07XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkgKz0gNjQpXG4gICAgb3V0LnB1c2gocC5zbGljZShpLCBpICsgNjQpKTtcbiAgb3V0LnB1c2goJy0tLS0tRU5EICcgKyBvcHRpb25zLmxhYmVsICsgJy0tLS0tJyk7XG4gIHJldHVybiBvdXQuam9pbignXFxuJyk7XG59O1xuIiwiLy8gYmFzZWQgb24gdGhlIGFlcyBpbXBsaW1lbnRhdGlvbiBpbiB0cmlwbGUgc2VjXG4vLyBodHRwczovL2dpdGh1Yi5jb20va2V5YmFzZS90cmlwbGVzZWNcblxuLy8gd2hpY2ggaXMgaW4gdHVybiBiYXNlZCBvbiB0aGUgb25lIGZyb20gY3J5cHRvLWpzXG4vLyBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qcy9cblxudmFyIHVpbnRfbWF4ID0gTWF0aC5wb3coMiwgMzIpXG5mdW5jdGlvbiBmaXh1cF91aW50MzIgKHgpIHtcbiAgdmFyIHJldCwgeF9wb3NcbiAgcmV0ID0geCA+IHVpbnRfbWF4IHx8IHggPCAwID8gKHhfcG9zID0gTWF0aC5hYnMoeCkgJSB1aW50X21heCwgeCA8IDAgPyB1aW50X21heCAtIHhfcG9zIDogeF9wb3MpIDogeFxuICByZXR1cm4gcmV0XG59XG5mdW5jdGlvbiBzY3J1Yl92ZWMgKHYpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB2Lmxlbmd0aDsgdisrKSB7XG4gICAgdltpXSA9IDBcbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cblxuZnVuY3Rpb24gR2xvYmFsICgpIHtcbiAgdGhpcy5TQk9YID0gW11cbiAgdGhpcy5JTlZfU0JPWCA9IFtdXG4gIHRoaXMuU1VCX01JWCA9IFtbXSwgW10sIFtdLCBbXV1cbiAgdGhpcy5JTlZfU1VCX01JWCA9IFtbXSwgW10sIFtdLCBbXV1cbiAgdGhpcy5pbml0KClcbiAgdGhpcy5SQ09OID0gWzB4MDAsIDB4MDEsIDB4MDIsIDB4MDQsIDB4MDgsIDB4MTAsIDB4MjAsIDB4NDAsIDB4ODAsIDB4MWIsIDB4MzZdXG59XG5cbkdsb2JhbC5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGQsIGksIHN4LCB0LCB4LCB4MiwgeDQsIHg4LCB4aSwgX2lcbiAgZCA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIF9pLCBfcmVzdWx0c1xuICAgIF9yZXN1bHRzID0gW11cbiAgICBmb3IgKGkgPSBfaSA9IDA7IF9pIDwgMjU2OyBpID0gKytfaSkge1xuICAgICAgaWYgKGkgPCAxMjgpIHtcbiAgICAgICAgX3Jlc3VsdHMucHVzaChpIDw8IDEpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfcmVzdWx0cy5wdXNoKChpIDw8IDEpIF4gMHgxMWIpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBfcmVzdWx0c1xuICB9KSgpXG4gIHggPSAwXG4gIHhpID0gMFxuICBmb3IgKGkgPSBfaSA9IDA7IF9pIDwgMjU2OyBpID0gKytfaSkge1xuICAgIHN4ID0geGkgXiAoeGkgPDwgMSkgXiAoeGkgPDwgMikgXiAoeGkgPDwgMykgXiAoeGkgPDwgNClcbiAgICBzeCA9IChzeCA+Pj4gOCkgXiAoc3ggJiAweGZmKSBeIDB4NjNcbiAgICB0aGlzLlNCT1hbeF0gPSBzeFxuICAgIHRoaXMuSU5WX1NCT1hbc3hdID0geFxuICAgIHgyID0gZFt4XVxuICAgIHg0ID0gZFt4Ml1cbiAgICB4OCA9IGRbeDRdXG4gICAgdCA9IChkW3N4XSAqIDB4MTAxKSBeIChzeCAqIDB4MTAxMDEwMClcbiAgICB0aGlzLlNVQl9NSVhbMF1beF0gPSAodCA8PCAyNCkgfCAodCA+Pj4gOClcbiAgICB0aGlzLlNVQl9NSVhbMV1beF0gPSAodCA8PCAxNikgfCAodCA+Pj4gMTYpXG4gICAgdGhpcy5TVUJfTUlYWzJdW3hdID0gKHQgPDwgOCkgfCAodCA+Pj4gMjQpXG4gICAgdGhpcy5TVUJfTUlYWzNdW3hdID0gdFxuICAgIHQgPSAoeDggKiAweDEwMTAxMDEpIF4gKHg0ICogMHgxMDAwMSkgXiAoeDIgKiAweDEwMSkgXiAoeCAqIDB4MTAxMDEwMClcbiAgICB0aGlzLklOVl9TVUJfTUlYWzBdW3N4XSA9ICh0IDw8IDI0KSB8ICh0ID4+PiA4KVxuICAgIHRoaXMuSU5WX1NVQl9NSVhbMV1bc3hdID0gKHQgPDwgMTYpIHwgKHQgPj4+IDE2KVxuICAgIHRoaXMuSU5WX1NVQl9NSVhbMl1bc3hdID0gKHQgPDwgOCkgfCAodCA+Pj4gMjQpXG4gICAgdGhpcy5JTlZfU1VCX01JWFszXVtzeF0gPSB0XG4gICAgaWYgKHggPT09IDApIHtcbiAgICAgIHggPSB4aSA9IDFcbiAgICB9IGVsc2Uge1xuICAgICAgeCA9IHgyIF4gZFtkW2RbeDggXiB4Ml1dXVxuICAgICAgeGkgXj0gZFtkW3hpXV1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWVcbn1cblxudmFyIEcgPSBuZXcgR2xvYmFsKClcblxuQUVTLmJsb2NrU2l6ZSA9IDQgKiA0XG5cbkFFUy5wcm90b3R5cGUuYmxvY2tTaXplID0gQUVTLmJsb2NrU2l6ZVxuXG5BRVMua2V5U2l6ZSA9IDI1NiAvIDhcblxuQUVTLnByb3RvdHlwZS5rZXlTaXplID0gQUVTLmtleVNpemVcblxuZnVuY3Rpb24gYnVmZmVyVG9BcnJheSAoYnVmKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoIC8gNFxuICB2YXIgb3V0ID0gbmV3IEFycmF5KGxlbilcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgb3V0W2ldID0gYnVmLnJlYWRVSW50MzJCRShpICogNClcbiAgfVxuICByZXR1cm4gb3V0XG59XG5mdW5jdGlvbiBBRVMgKGtleSkge1xuICB0aGlzLl9rZXkgPSBidWZmZXJUb0FycmF5KGtleSlcbiAgdGhpcy5fZG9SZXNldCgpXG59XG5cbkFFUy5wcm90b3R5cGUuX2RvUmVzZXQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBpbnZLc1Jvdywga2V5U2l6ZSwga2V5V29yZHMsIGtzUm93LCBrc1Jvd3MsIHRcbiAga2V5V29yZHMgPSB0aGlzLl9rZXlcbiAga2V5U2l6ZSA9IGtleVdvcmRzLmxlbmd0aFxuICB0aGlzLl9uUm91bmRzID0ga2V5U2l6ZSArIDZcbiAga3NSb3dzID0gKHRoaXMuX25Sb3VuZHMgKyAxKSAqIDRcbiAgdGhpcy5fa2V5U2NoZWR1bGUgPSBbXVxuICBmb3IgKGtzUm93ID0gMDsga3NSb3cgPCBrc1Jvd3M7IGtzUm93KyspIHtcbiAgICB0aGlzLl9rZXlTY2hlZHVsZVtrc1Jvd10gPSBrc1JvdyA8IGtleVNpemUgPyBrZXlXb3Jkc1trc1Jvd10gOiAodCA9IHRoaXMuX2tleVNjaGVkdWxlW2tzUm93IC0gMV0sIChrc1JvdyAlIGtleVNpemUpID09PSAwID8gKHQgPSAodCA8PCA4KSB8ICh0ID4+PiAyNCksIHQgPSAoRy5TQk9YW3QgPj4+IDI0XSA8PCAyNCkgfCAoRy5TQk9YWyh0ID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoRy5TQk9YWyh0ID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgRy5TQk9YW3QgJiAweGZmXSwgdCBePSBHLlJDT05bKGtzUm93IC8ga2V5U2l6ZSkgfCAwXSA8PCAyNCkgOiBrZXlTaXplID4gNiAmJiBrc1JvdyAlIGtleVNpemUgPT09IDQgPyB0ID0gKEcuU0JPWFt0ID4+PiAyNF0gPDwgMjQpIHwgKEcuU0JPWFsodCA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKEcuU0JPWFsodCA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IEcuU0JPWFt0ICYgMHhmZl0gOiB2b2lkIDAsIHRoaXMuX2tleVNjaGVkdWxlW2tzUm93IC0ga2V5U2l6ZV0gXiB0KVxuICB9XG4gIHRoaXMuX2ludktleVNjaGVkdWxlID0gW11cbiAgZm9yIChpbnZLc1JvdyA9IDA7IGludktzUm93IDwga3NSb3dzOyBpbnZLc1JvdysrKSB7XG4gICAga3NSb3cgPSBrc1Jvd3MgLSBpbnZLc1Jvd1xuICAgIHQgPSB0aGlzLl9rZXlTY2hlZHVsZVtrc1JvdyAtIChpbnZLc1JvdyAlIDQgPyAwIDogNCldXG4gICAgdGhpcy5faW52S2V5U2NoZWR1bGVbaW52S3NSb3ddID0gaW52S3NSb3cgPCA0IHx8IGtzUm93IDw9IDQgPyB0IDogRy5JTlZfU1VCX01JWFswXVtHLlNCT1hbdCA+Pj4gMjRdXSBeIEcuSU5WX1NVQl9NSVhbMV1bRy5TQk9YWyh0ID4+PiAxNikgJiAweGZmXV0gXiBHLklOVl9TVUJfTUlYWzJdW0cuU0JPWFsodCA+Pj4gOCkgJiAweGZmXV0gXiBHLklOVl9TVUJfTUlYWzNdW0cuU0JPWFt0ICYgMHhmZl1dXG4gIH1cbiAgcmV0dXJuIHRydWVcbn1cblxuQUVTLnByb3RvdHlwZS5lbmNyeXB0QmxvY2sgPSBmdW5jdGlvbiAoTSkge1xuICBNID0gYnVmZmVyVG9BcnJheShuZXcgQnVmZmVyKE0pKVxuICB2YXIgb3V0ID0gdGhpcy5fZG9DcnlwdEJsb2NrKE0sIHRoaXMuX2tleVNjaGVkdWxlLCBHLlNVQl9NSVgsIEcuU0JPWClcbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoMTYpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFswXSwgMClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzFdLCA0KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMl0sIDgpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFszXSwgMTIpXG4gIHJldHVybiBidWZcbn1cblxuQUVTLnByb3RvdHlwZS5kZWNyeXB0QmxvY2sgPSBmdW5jdGlvbiAoTSkge1xuICBNID0gYnVmZmVyVG9BcnJheShuZXcgQnVmZmVyKE0pKVxuICB2YXIgdGVtcCA9IFtNWzNdLCBNWzFdXVxuICBNWzFdID0gdGVtcFswXVxuICBNWzNdID0gdGVtcFsxXVxuICB2YXIgb3V0ID0gdGhpcy5fZG9DcnlwdEJsb2NrKE0sIHRoaXMuX2ludktleVNjaGVkdWxlLCBHLklOVl9TVUJfTUlYLCBHLklOVl9TQk9YKVxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcigxNilcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzBdLCAwKVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbM10sIDQpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsyXSwgOClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzFdLCAxMilcbiAgcmV0dXJuIGJ1ZlxufVxuXG5BRVMucHJvdG90eXBlLnNjcnViID0gZnVuY3Rpb24gKCkge1xuICBzY3J1Yl92ZWModGhpcy5fa2V5U2NoZWR1bGUpXG4gIHNjcnViX3ZlYyh0aGlzLl9pbnZLZXlTY2hlZHVsZSlcbiAgc2NydWJfdmVjKHRoaXMuX2tleSlcbn1cblxuQUVTLnByb3RvdHlwZS5fZG9DcnlwdEJsb2NrID0gZnVuY3Rpb24gKE0sIGtleVNjaGVkdWxlLCBTVUJfTUlYLCBTQk9YKSB7XG4gIHZhciBrc1JvdywgczAsIHMxLCBzMiwgczMsIHQwLCB0MSwgdDIsIHQzXG5cbiAgczAgPSBNWzBdIF4ga2V5U2NoZWR1bGVbMF1cbiAgczEgPSBNWzFdIF4ga2V5U2NoZWR1bGVbMV1cbiAgczIgPSBNWzJdIF4ga2V5U2NoZWR1bGVbMl1cbiAgczMgPSBNWzNdIF4ga2V5U2NoZWR1bGVbM11cbiAga3NSb3cgPSA0XG4gIGZvciAodmFyIHJvdW5kID0gMTsgcm91bmQgPCB0aGlzLl9uUm91bmRzOyByb3VuZCsrKSB7XG4gICAgdDAgPSBTVUJfTUlYWzBdW3MwID4+PiAyNF0gXiBTVUJfTUlYWzFdWyhzMSA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYWzJdWyhzMiA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhbM11bczMgJiAweGZmXSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gICAgdDEgPSBTVUJfTUlYWzBdW3MxID4+PiAyNF0gXiBTVUJfTUlYWzFdWyhzMiA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYWzJdWyhzMyA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhbM11bczAgJiAweGZmXSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gICAgdDIgPSBTVUJfTUlYWzBdW3MyID4+PiAyNF0gXiBTVUJfTUlYWzFdWyhzMyA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYWzJdWyhzMCA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhbM11bczEgJiAweGZmXSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gICAgdDMgPSBTVUJfTUlYWzBdW3MzID4+PiAyNF0gXiBTVUJfTUlYWzFdWyhzMCA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYWzJdWyhzMSA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhbM11bczIgJiAweGZmXSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gICAgczAgPSB0MFxuICAgIHMxID0gdDFcbiAgICBzMiA9IHQyXG4gICAgczMgPSB0M1xuICB9XG4gIHQwID0gKChTQk9YW3MwID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMxID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczIgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MzICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgdDEgPSAoKFNCT1hbczEgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczIgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMyA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczAgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICB0MiA9ICgoU0JPWFtzMiA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMyA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMwID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMSAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gIHQzID0gKChTQk9YW3MzID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMwID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczEgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MyICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgcmV0dXJuIFtcbiAgICBmaXh1cF91aW50MzIodDApLFxuICAgIGZpeHVwX3VpbnQzMih0MSksXG4gICAgZml4dXBfdWludDMyKHQyKSxcbiAgICBmaXh1cF91aW50MzIodDMpXG4gIF1cbn1cblxuZXhwb3J0cy5BRVMgPSBBRVNcbiIsInZhciBhZXMgPSByZXF1aXJlKCcuL2FlcycpXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEdIQVNIID0gcmVxdWlyZSgnLi9naGFzaCcpXG52YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG5pbmhlcml0cyhTdHJlYW1DaXBoZXIsIFRyYW5zZm9ybSlcbm1vZHVsZS5leHBvcnRzID0gU3RyZWFtQ2lwaGVyXG5cbmZ1bmN0aW9uIFN0cmVhbUNpcGhlciAobW9kZSwga2V5LCBpdiwgZGVjcnlwdCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3RyZWFtQ2lwaGVyKSkge1xuICAgIHJldHVybiBuZXcgU3RyZWFtQ2lwaGVyKG1vZGUsIGtleSwgaXYpXG4gIH1cbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5fZmluSUQgPSBCdWZmZXIuY29uY2F0KFtpdiwgbmV3IEJ1ZmZlcihbMCwgMCwgMCwgMV0pXSlcbiAgaXYgPSBCdWZmZXIuY29uY2F0KFtpdiwgbmV3IEJ1ZmZlcihbMCwgMCwgMCwgMl0pXSlcbiAgdGhpcy5fY2lwaGVyID0gbmV3IGFlcy5BRVMoa2V5KVxuICB0aGlzLl9wcmV2ID0gbmV3IEJ1ZmZlcihpdi5sZW5ndGgpXG4gIHRoaXMuX2NhY2hlID0gbmV3IEJ1ZmZlcignJylcbiAgdGhpcy5fc2VjQ2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxuICB0aGlzLl9kZWNyeXB0ID0gZGVjcnlwdFxuICB0aGlzLl9hbGVuID0gMFxuICB0aGlzLl9sZW4gPSAwXG4gIGl2LmNvcHkodGhpcy5fcHJldilcbiAgdGhpcy5fbW9kZSA9IG1vZGVcbiAgdmFyIGggPSBuZXcgQnVmZmVyKDQpXG4gIGguZmlsbCgwKVxuICB0aGlzLl9naGFzaCA9IG5ldyBHSEFTSCh0aGlzLl9jaXBoZXIuZW5jcnlwdEJsb2NrKGgpKVxuICB0aGlzLl9hdXRoVGFnID0gbnVsbFxuICB0aGlzLl9jYWxsZWQgPSBmYWxzZVxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gIGlmICghdGhpcy5fY2FsbGVkICYmIHRoaXMuX2FsZW4pIHtcbiAgICB2YXIgcnVtcCA9IDE2IC0gKHRoaXMuX2FsZW4gJSAxNilcbiAgICBpZiAocnVtcCA8IDE2KSB7XG4gICAgICBydW1wID0gbmV3IEJ1ZmZlcihydW1wKVxuICAgICAgcnVtcC5maWxsKDApXG4gICAgICB0aGlzLl9naGFzaC51cGRhdGUocnVtcClcbiAgICB9XG4gIH1cbiAgdGhpcy5fY2FsbGVkID0gdHJ1ZVxuICB2YXIgb3V0ID0gdGhpcy5fbW9kZS5lbmNyeXB0KHRoaXMsIGNodW5rKVxuICBpZiAodGhpcy5fZGVjcnlwdCkge1xuICAgIHRoaXMuX2doYXNoLnVwZGF0ZShjaHVuaylcbiAgfSBlbHNlIHtcbiAgICB0aGlzLl9naGFzaC51cGRhdGUob3V0KVxuICB9XG4gIHRoaXMuX2xlbiArPSBjaHVuay5sZW5ndGhcbiAgcmV0dXJuIG91dFxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLl9kZWNyeXB0ICYmICF0aGlzLl9hdXRoVGFnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBzdGF0ZSBvciB1bmFibGUgdG8gYXV0aGVudGljYXRlIGRhdGEnKVxuICB9XG4gIHZhciB0YWcgPSB4b3IodGhpcy5fZ2hhc2guZmluYWwodGhpcy5fYWxlbiAqIDgsIHRoaXMuX2xlbiAqIDgpLCB0aGlzLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHRoaXMuX2ZpbklEKSlcbiAgaWYgKHRoaXMuX2RlY3J5cHQpIHtcbiAgICBpZiAoeG9yVGVzdCh0YWcsIHRoaXMuX2F1dGhUYWcpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIHN0YXRlIG9yIHVuYWJsZSB0byBhdXRoZW50aWNhdGUgZGF0YScpXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRoaXMuX2F1dGhUYWcgPSB0YWdcbiAgfVxuICB0aGlzLl9jaXBoZXIuc2NydWIoKVxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5nZXRBdXRoVGFnID0gZnVuY3Rpb24gZ2V0QXV0aFRhZyAoKSB7XG4gIGlmICghdGhpcy5fZGVjcnlwdCAmJiBCdWZmZXIuaXNCdWZmZXIodGhpcy5fYXV0aFRhZykpIHtcbiAgICByZXR1cm4gdGhpcy5fYXV0aFRhZ1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignQXR0ZW1wdGluZyB0byBnZXQgYXV0aCB0YWcgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxuICB9XG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLnNldEF1dGhUYWcgPSBmdW5jdGlvbiBzZXRBdXRoVGFnICh0YWcpIHtcbiAgaWYgKHRoaXMuX2RlY3J5cHQpIHtcbiAgICB0aGlzLl9hdXRoVGFnID0gdGFnXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIHNldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG4gIH1cbn1cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuc2V0QUFEID0gZnVuY3Rpb24gc2V0QUFEIChidWYpIHtcbiAgaWYgKCF0aGlzLl9jYWxsZWQpIHtcbiAgICB0aGlzLl9naGFzaC51cGRhdGUoYnVmKVxuICAgIHRoaXMuX2FsZW4gKz0gYnVmLmxlbmd0aFxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignQXR0ZW1wdGluZyB0byBzZXQgQUFEIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbiAgfVxufVxuZnVuY3Rpb24geG9yVGVzdCAoYSwgYikge1xuICB2YXIgb3V0ID0gMFxuICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSB7XG4gICAgb3V0KytcbiAgfVxuICB2YXIgbGVuID0gTWF0aC5taW4oYS5sZW5ndGgsIGIubGVuZ3RoKVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXQgKz0gKGFbaV0gXiBiW2ldKVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsInZhciBhZXMgPSByZXF1aXJlKCcuL2FlcycpXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIG1vZGVzID0gcmVxdWlyZSgnLi9tb2RlcycpXG52YXIgU3RyZWFtQ2lwaGVyID0gcmVxdWlyZSgnLi9zdHJlYW1DaXBoZXInKVxudmFyIEF1dGhDaXBoZXIgPSByZXF1aXJlKCcuL2F1dGhDaXBoZXInKVxudmFyIGVidGsgPSByZXF1aXJlKCdldnBfYnl0ZXN0b2tleScpXG5cbmluaGVyaXRzKERlY2lwaGVyLCBUcmFuc2Zvcm0pXG5mdW5jdGlvbiBEZWNpcGhlciAobW9kZSwga2V5LCBpdikge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgRGVjaXBoZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBEZWNpcGhlcihtb2RlLCBrZXksIGl2KVxuICB9XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG4gIHRoaXMuX2NhY2hlID0gbmV3IFNwbGl0dGVyKClcbiAgdGhpcy5fbGFzdCA9IHZvaWQgMFxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHRoaXMuX3ByZXYgPSBuZXcgQnVmZmVyKGl2Lmxlbmd0aClcbiAgaXYuY29weSh0aGlzLl9wcmV2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxuICB0aGlzLl9hdXRvcGFkZGluZyA9IHRydWVcbn1cbkRlY2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5fY2FjaGUuYWRkKGRhdGEpXG4gIHZhciBjaHVua1xuICB2YXIgdGhpbmdcbiAgdmFyIG91dCA9IFtdXG4gIHdoaWxlICgoY2h1bmsgPSB0aGlzLl9jYWNoZS5nZXQodGhpcy5fYXV0b3BhZGRpbmcpKSkge1xuICAgIHRoaW5nID0gdGhpcy5fbW9kZS5kZWNyeXB0KHRoaXMsIGNodW5rKVxuICAgIG91dC5wdXNoKHRoaW5nKVxuICB9XG4gIHJldHVybiBCdWZmZXIuY29uY2F0KG91dClcbn1cbkRlY2lwaGVyLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBjaHVuayA9IHRoaXMuX2NhY2hlLmZsdXNoKClcbiAgaWYgKHRoaXMuX2F1dG9wYWRkaW5nKSB7XG4gICAgcmV0dXJuIHVucGFkKHRoaXMuX21vZGUuZGVjcnlwdCh0aGlzLCBjaHVuaykpXG4gIH0gZWxzZSBpZiAoY2h1bmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RhdGEgbm90IG11bHRpcGxlIG9mIGJsb2NrIGxlbmd0aCcpXG4gIH1cbn1cbkRlY2lwaGVyLnByb3RvdHlwZS5zZXRBdXRvUGFkZGluZyA9IGZ1bmN0aW9uIChzZXRUbykge1xuICB0aGlzLl9hdXRvcGFkZGluZyA9ICEhc2V0VG9cbiAgcmV0dXJuIHRoaXNcbn1cbmZ1bmN0aW9uIFNwbGl0dGVyICgpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNwbGl0dGVyKSkge1xuICAgIHJldHVybiBuZXcgU3BsaXR0ZXIoKVxuICB9XG4gIHRoaXMuY2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxufVxuU3BsaXR0ZXIucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuY2FjaGUgPSBCdWZmZXIuY29uY2F0KFt0aGlzLmNhY2hlLCBkYXRhXSlcbn1cblxuU3BsaXR0ZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChhdXRvUGFkZGluZykge1xuICB2YXIgb3V0XG4gIGlmIChhdXRvUGFkZGluZykge1xuICAgIGlmICh0aGlzLmNhY2hlLmxlbmd0aCA+IDE2KSB7XG4gICAgICBvdXQgPSB0aGlzLmNhY2hlLnNsaWNlKDAsIDE2KVxuICAgICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgICByZXR1cm4gb3V0XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmICh0aGlzLmNhY2hlLmxlbmd0aCA+PSAxNikge1xuICAgICAgb3V0ID0gdGhpcy5jYWNoZS5zbGljZSgwLCAxNilcbiAgICAgIHRoaXMuY2FjaGUgPSB0aGlzLmNhY2hlLnNsaWNlKDE2KVxuICAgICAgcmV0dXJuIG91dFxuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbFxufVxuU3BsaXR0ZXIucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jYWNoZS5sZW5ndGgpIHtcbiAgICByZXR1cm4gdGhpcy5jYWNoZVxuICB9XG59XG5mdW5jdGlvbiB1bnBhZCAobGFzdCkge1xuICB2YXIgcGFkZGVkID0gbGFzdFsxNV1cbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgcGFkZGVkKSB7XG4gICAgaWYgKGxhc3RbKGkgKyAoMTYgLSBwYWRkZWQpKV0gIT09IHBhZGRlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmFibGUgdG8gZGVjcnlwdCBkYXRhJylcbiAgICB9XG4gIH1cbiAgaWYgKHBhZGRlZCA9PT0gMTYpIHtcbiAgICByZXR1cm5cbiAgfVxuICByZXR1cm4gbGFzdC5zbGljZSgwLCAxNiAtIHBhZGRlZClcbn1cblxudmFyIG1vZGVsaXN0ID0ge1xuICBFQ0I6IHJlcXVpcmUoJy4vbW9kZXMvZWNiJyksXG4gIENCQzogcmVxdWlyZSgnLi9tb2Rlcy9jYmMnKSxcbiAgQ0ZCOiByZXF1aXJlKCcuL21vZGVzL2NmYicpLFxuICBDRkI4OiByZXF1aXJlKCcuL21vZGVzL2NmYjgnKSxcbiAgQ0ZCMTogcmVxdWlyZSgnLi9tb2Rlcy9jZmIxJyksXG4gIE9GQjogcmVxdWlyZSgnLi9tb2Rlcy9vZmInKSxcbiAgQ1RSOiByZXF1aXJlKCcuL21vZGVzL2N0cicpLFxuICBHQ006IHJlcXVpcmUoJy4vbW9kZXMvY3RyJylcbn1cblxuZnVuY3Rpb24gY3JlYXRlRGVjaXBoZXJpdiAoc3VpdGUsIHBhc3N3b3JkLCBpdikge1xuICB2YXIgY29uZmlnID0gbW9kZXNbc3VpdGUudG9Mb3dlckNhc2UoKV1cbiAgaWYgKCFjb25maWcpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuICB9XG4gIGlmICh0eXBlb2YgaXYgPT09ICdzdHJpbmcnKSB7XG4gICAgaXYgPSBuZXcgQnVmZmVyKGl2KVxuICB9XG4gIGlmICh0eXBlb2YgcGFzc3dvcmQgPT09ICdzdHJpbmcnKSB7XG4gICAgcGFzc3dvcmQgPSBuZXcgQnVmZmVyKHBhc3N3b3JkKVxuICB9XG4gIGlmIChwYXNzd29yZC5sZW5ndGggIT09IGNvbmZpZy5rZXkgLyA4KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBrZXkgbGVuZ3RoICcgKyBwYXNzd29yZC5sZW5ndGgpXG4gIH1cbiAgaWYgKGl2Lmxlbmd0aCAhPT0gY29uZmlnLml2KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBpdiBsZW5ndGggJyArIGl2Lmxlbmd0aClcbiAgfVxuICBpZiAoY29uZmlnLnR5cGUgPT09ICdzdHJlYW0nKSB7XG4gICAgcmV0dXJuIG5ldyBTdHJlYW1DaXBoZXIobW9kZWxpc3RbY29uZmlnLm1vZGVdLCBwYXNzd29yZCwgaXYsIHRydWUpXG4gIH0gZWxzZSBpZiAoY29uZmlnLnR5cGUgPT09ICdhdXRoJykge1xuICAgIHJldHVybiBuZXcgQXV0aENpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdiwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gbmV3IERlY2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2KVxufVxuXG5mdW5jdGlvbiBjcmVhdGVEZWNpcGhlciAoc3VpdGUsIHBhc3N3b3JkKSB7XG4gIHZhciBjb25maWcgPSBtb2Rlc1tzdWl0ZS50b0xvd2VyQ2FzZSgpXVxuICBpZiAoIWNvbmZpZykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgdmFyIGtleXMgPSBlYnRrKHBhc3N3b3JkLCBmYWxzZSwgY29uZmlnLmtleSwgY29uZmlnLml2KVxuICByZXR1cm4gY3JlYXRlRGVjaXBoZXJpdihzdWl0ZSwga2V5cy5rZXksIGtleXMuaXYpXG59XG5leHBvcnRzLmNyZWF0ZURlY2lwaGVyID0gY3JlYXRlRGVjaXBoZXJcbmV4cG9ydHMuY3JlYXRlRGVjaXBoZXJpdiA9IGNyZWF0ZURlY2lwaGVyaXZcbiIsInZhciBhZXMgPSByZXF1aXJlKCcuL2FlcycpXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIG1vZGVzID0gcmVxdWlyZSgnLi9tb2RlcycpXG52YXIgZWJ0ayA9IHJlcXVpcmUoJ2V2cF9ieXRlc3Rva2V5JylcbnZhciBTdHJlYW1DaXBoZXIgPSByZXF1aXJlKCcuL3N0cmVhbUNpcGhlcicpXG52YXIgQXV0aENpcGhlciA9IHJlcXVpcmUoJy4vYXV0aENpcGhlcicpXG5pbmhlcml0cyhDaXBoZXIsIFRyYW5zZm9ybSlcbmZ1bmN0aW9uIENpcGhlciAobW9kZSwga2V5LCBpdikge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQ2lwaGVyKSkge1xuICAgIHJldHVybiBuZXcgQ2lwaGVyKG1vZGUsIGtleSwgaXYpXG4gIH1cbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5fY2FjaGUgPSBuZXcgU3BsaXR0ZXIoKVxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHRoaXMuX3ByZXYgPSBuZXcgQnVmZmVyKGl2Lmxlbmd0aClcbiAgaXYuY29weSh0aGlzLl9wcmV2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxuICB0aGlzLl9hdXRvcGFkZGluZyA9IHRydWVcbn1cbkNpcGhlci5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuX2NhY2hlLmFkZChkYXRhKVxuICB2YXIgY2h1bmtcbiAgdmFyIHRoaW5nXG4gIHZhciBvdXQgPSBbXVxuICB3aGlsZSAoKGNodW5rID0gdGhpcy5fY2FjaGUuZ2V0KCkpKSB7XG4gICAgdGhpbmcgPSB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmspXG4gICAgb3V0LnB1c2godGhpbmcpXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5jb25jYXQob3V0KVxufVxuQ2lwaGVyLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBjaHVuayA9IHRoaXMuX2NhY2hlLmZsdXNoKClcbiAgaWYgKHRoaXMuX2F1dG9wYWRkaW5nKSB7XG4gICAgY2h1bmsgPSB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmspXG4gICAgdGhpcy5fY2lwaGVyLnNjcnViKClcbiAgICByZXR1cm4gY2h1bmtcbiAgfSBlbHNlIGlmIChjaHVuay50b1N0cmluZygnaGV4JykgIT09ICcxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMCcpIHtcbiAgICB0aGlzLl9jaXBoZXIuc2NydWIoKVxuICAgIHRocm93IG5ldyBFcnJvcignZGF0YSBub3QgbXVsdGlwbGUgb2YgYmxvY2sgbGVuZ3RoJylcbiAgfVxufVxuQ2lwaGVyLnByb3RvdHlwZS5zZXRBdXRvUGFkZGluZyA9IGZ1bmN0aW9uIChzZXRUbykge1xuICB0aGlzLl9hdXRvcGFkZGluZyA9ICEhc2V0VG9cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gU3BsaXR0ZXIgKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3BsaXR0ZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBTcGxpdHRlcigpXG4gIH1cbiAgdGhpcy5jYWNoZSA9IG5ldyBCdWZmZXIoJycpXG59XG5TcGxpdHRlci5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIGRhdGFdKVxufVxuXG5TcGxpdHRlci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jYWNoZS5sZW5ndGggPiAxNSkge1xuICAgIHZhciBvdXQgPSB0aGlzLmNhY2hlLnNsaWNlKDAsIDE2KVxuICAgIHRoaXMuY2FjaGUgPSB0aGlzLmNhY2hlLnNsaWNlKDE2KVxuICAgIHJldHVybiBvdXRcbiAgfVxuICByZXR1cm4gbnVsbFxufVxuU3BsaXR0ZXIucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbGVuID0gMTYgLSB0aGlzLmNhY2hlLmxlbmd0aFxuICB2YXIgcGFkQnVmZiA9IG5ldyBCdWZmZXIobGVuKVxuXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIHBhZEJ1ZmYud3JpdGVVSW50OChsZW4sIGkpXG4gIH1cbiAgdmFyIG91dCA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIHBhZEJ1ZmZdKVxuICByZXR1cm4gb3V0XG59XG52YXIgbW9kZWxpc3QgPSB7XG4gIEVDQjogcmVxdWlyZSgnLi9tb2Rlcy9lY2InKSxcbiAgQ0JDOiByZXF1aXJlKCcuL21vZGVzL2NiYycpLFxuICBDRkI6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiJyksXG4gIENGQjg6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiOCcpLFxuICBDRkIxOiByZXF1aXJlKCcuL21vZGVzL2NmYjEnKSxcbiAgT0ZCOiByZXF1aXJlKCcuL21vZGVzL29mYicpLFxuICBDVFI6IHJlcXVpcmUoJy4vbW9kZXMvY3RyJyksXG4gIEdDTTogcmVxdWlyZSgnLi9tb2Rlcy9jdHInKVxufVxuXG5mdW5jdGlvbiBjcmVhdGVDaXBoZXJpdiAoc3VpdGUsIHBhc3N3b3JkLCBpdikge1xuICB2YXIgY29uZmlnID0gbW9kZXNbc3VpdGUudG9Mb3dlckNhc2UoKV1cbiAgaWYgKCFjb25maWcpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuICB9XG4gIGlmICh0eXBlb2YgaXYgPT09ICdzdHJpbmcnKSB7XG4gICAgaXYgPSBuZXcgQnVmZmVyKGl2KVxuICB9XG4gIGlmICh0eXBlb2YgcGFzc3dvcmQgPT09ICdzdHJpbmcnKSB7XG4gICAgcGFzc3dvcmQgPSBuZXcgQnVmZmVyKHBhc3N3b3JkKVxuICB9XG4gIGlmIChwYXNzd29yZC5sZW5ndGggIT09IGNvbmZpZy5rZXkgLyA4KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBrZXkgbGVuZ3RoICcgKyBwYXNzd29yZC5sZW5ndGgpXG4gIH1cbiAgaWYgKGl2Lmxlbmd0aCAhPT0gY29uZmlnLml2KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBpdiBsZW5ndGggJyArIGl2Lmxlbmd0aClcbiAgfVxuICBpZiAoY29uZmlnLnR5cGUgPT09ICdzdHJlYW0nKSB7XG4gICAgcmV0dXJuIG5ldyBTdHJlYW1DaXBoZXIobW9kZWxpc3RbY29uZmlnLm1vZGVdLCBwYXNzd29yZCwgaXYpXG4gIH0gZWxzZSBpZiAoY29uZmlnLnR5cGUgPT09ICdhdXRoJykge1xuICAgIHJldHVybiBuZXcgQXV0aENpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdilcbiAgfVxuICByZXR1cm4gbmV3IENpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdilcbn1cbmZ1bmN0aW9uIGNyZWF0ZUNpcGhlciAoc3VpdGUsIHBhc3N3b3JkKSB7XG4gIHZhciBjb25maWcgPSBtb2Rlc1tzdWl0ZS50b0xvd2VyQ2FzZSgpXVxuICBpZiAoIWNvbmZpZykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgdmFyIGtleXMgPSBlYnRrKHBhc3N3b3JkLCBmYWxzZSwgY29uZmlnLmtleSwgY29uZmlnLml2KVxuICByZXR1cm4gY3JlYXRlQ2lwaGVyaXYoc3VpdGUsIGtleXMua2V5LCBrZXlzLml2KVxufVxuXG5leHBvcnRzLmNyZWF0ZUNpcGhlcml2ID0gY3JlYXRlQ2lwaGVyaXZcbmV4cG9ydHMuY3JlYXRlQ2lwaGVyID0gY3JlYXRlQ2lwaGVyXG4iLCJ2YXIgemVyb3MgPSBuZXcgQnVmZmVyKDE2KVxuemVyb3MuZmlsbCgwKVxubW9kdWxlLmV4cG9ydHMgPSBHSEFTSFxuZnVuY3Rpb24gR0hBU0ggKGtleSkge1xuICB0aGlzLmggPSBrZXlcbiAgdGhpcy5zdGF0ZSA9IG5ldyBCdWZmZXIoMTYpXG4gIHRoaXMuc3RhdGUuZmlsbCgwKVxuICB0aGlzLmNhY2hlID0gbmV3IEJ1ZmZlcignJylcbn1cbi8vIGZyb20gaHR0cDovL2JpdHdpc2VzaGlmdGxlZnQuZ2l0aHViLmlvL3NqY2wvZG9jL3N5bWJvbHMvc3JjL2NvcmVfZ2NtLmpzLmh0bWxcbi8vIGJ5IEp1aG8gVsOkaMOkLUhlcnR0dWFcbkdIQVNILnByb3RvdHlwZS5naGFzaCA9IGZ1bmN0aW9uIChibG9jaykge1xuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBibG9jay5sZW5ndGgpIHtcbiAgICB0aGlzLnN0YXRlW2ldIF49IGJsb2NrW2ldXG4gIH1cbiAgdGhpcy5fbXVsdGlwbHkoKVxufVxuXG5HSEFTSC5wcm90b3R5cGUuX211bHRpcGx5ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgVmkgPSB0b0FycmF5KHRoaXMuaClcbiAgdmFyIFppID0gWzAsIDAsIDAsIDBdXG4gIHZhciBqLCB4aSwgbHNiX1ZpXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IDEyOCkge1xuICAgIHhpID0gKHRoaXMuc3RhdGVbfn4oaSAvIDgpXSAmICgxIDw8ICg3IC0gaSAlIDgpKSkgIT09IDBcbiAgICBpZiAoeGkpIHtcbiAgICAgIC8vIFpfaSsxID0gWl9pIF4gVl9pXG4gICAgICBaaSA9IHhvcihaaSwgVmkpXG4gICAgfVxuXG4gICAgLy8gU3RvcmUgdGhlIHZhbHVlIG9mIExTQihWX2kpXG4gICAgbHNiX1ZpID0gKFZpWzNdICYgMSkgIT09IDBcblxuICAgIC8vIFZfaSsxID0gVl9pID4+IDFcbiAgICBmb3IgKGogPSAzOyBqID4gMDsgai0tKSB7XG4gICAgICBWaVtqXSA9IChWaVtqXSA+Pj4gMSkgfCAoKFZpW2ogLSAxXSAmIDEpIDw8IDMxKVxuICAgIH1cbiAgICBWaVswXSA9IFZpWzBdID4+PiAxXG5cbiAgICAvLyBJZiBMU0IoVl9pKSBpcyAxLCBWX2krMSA9IChWX2kgPj4gMSkgXiBSXG4gICAgaWYgKGxzYl9WaSkge1xuICAgICAgVmlbMF0gPSBWaVswXSBeICgweGUxIDw8IDI0KVxuICAgIH1cbiAgfVxuICB0aGlzLnN0YXRlID0gZnJvbUFycmF5KFppKVxufVxuR0hBU0gucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChidWYpIHtcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIGJ1Zl0pXG4gIHZhciBjaHVua1xuICB3aGlsZSAodGhpcy5jYWNoZS5sZW5ndGggPj0gMTYpIHtcbiAgICBjaHVuayA9IHRoaXMuY2FjaGUuc2xpY2UoMCwgMTYpXG4gICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgdGhpcy5naGFzaChjaHVuaylcbiAgfVxufVxuR0hBU0gucHJvdG90eXBlLmZpbmFsID0gZnVuY3Rpb24gKGFibCwgYmwpIHtcbiAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoKSB7XG4gICAgdGhpcy5naGFzaChCdWZmZXIuY29uY2F0KFt0aGlzLmNhY2hlLCB6ZXJvc10sIDE2KSlcbiAgfVxuICB0aGlzLmdoYXNoKGZyb21BcnJheShbXG4gICAgMCwgYWJsLFxuICAgIDAsIGJsXG4gIF0pKVxuICByZXR1cm4gdGhpcy5zdGF0ZVxufVxuXG5mdW5jdGlvbiB0b0FycmF5IChidWYpIHtcbiAgcmV0dXJuIFtcbiAgICBidWYucmVhZFVJbnQzMkJFKDApLFxuICAgIGJ1Zi5yZWFkVUludDMyQkUoNCksXG4gICAgYnVmLnJlYWRVSW50MzJCRSg4KSxcbiAgICBidWYucmVhZFVJbnQzMkJFKDEyKVxuICBdXG59XG5mdW5jdGlvbiBmcm9tQXJyYXkgKG91dCkge1xuICBvdXQgPSBvdXQubWFwKGZpeHVwX3VpbnQzMilcbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoMTYpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFswXSwgMClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzFdLCA0KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMl0sIDgpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFszXSwgMTIpXG4gIHJldHVybiBidWZcbn1cbnZhciB1aW50X21heCA9IE1hdGgucG93KDIsIDMyKVxuZnVuY3Rpb24gZml4dXBfdWludDMyICh4KSB7XG4gIHZhciByZXQsIHhfcG9zXG4gIHJldCA9IHggPiB1aW50X21heCB8fCB4IDwgMCA/ICh4X3BvcyA9IE1hdGguYWJzKHgpICUgdWludF9tYXgsIHggPCAwID8gdWludF9tYXggLSB4X3BvcyA6IHhfcG9zKSA6IHhcbiAgcmV0dXJuIHJldFxufVxuZnVuY3Rpb24geG9yIChhLCBiKSB7XG4gIHJldHVybiBbXG4gICAgYVswXSBeIGJbMF0sXG4gICAgYVsxXSBeIGJbMV0sXG4gICAgYVsyXSBeIGJbMl0sXG4gICAgYVszXSBeIGJbM11cbiAgXVxufVxuIiwidmFyIHhvciA9IHJlcXVpcmUoJ2J1ZmZlci14b3InKVxuXG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgZGF0YSwgZGVjcnlwdCkge1xuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcignJylcbiAgdmFyIGxlblxuXG4gIHdoaWxlIChkYXRhLmxlbmd0aCkge1xuICAgIGlmIChzZWxmLl9jYWNoZS5sZW5ndGggPT09IDApIHtcbiAgICAgIHNlbGYuX2NhY2hlID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhzZWxmLl9wcmV2KVxuICAgICAgc2VsZi5fcHJldiA9IG5ldyBCdWZmZXIoJycpXG4gICAgfVxuXG4gICAgaWYgKHNlbGYuX2NhY2hlLmxlbmd0aCA8PSBkYXRhLmxlbmd0aCkge1xuICAgICAgbGVuID0gc2VsZi5fY2FjaGUubGVuZ3RoXG4gICAgICBvdXQgPSBCdWZmZXIuY29uY2F0KFtvdXQsIGVuY3J5cHRTdGFydChzZWxmLCBkYXRhLnNsaWNlKDAsIGxlbiksIGRlY3J5cHQpXSlcbiAgICAgIGRhdGEgPSBkYXRhLnNsaWNlKGxlbilcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0ID0gQnVmZmVyLmNvbmNhdChbb3V0LCBlbmNyeXB0U3RhcnQoc2VsZiwgZGF0YSwgZGVjcnlwdCldKVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gb3V0XG59XG5mdW5jdGlvbiBlbmNyeXB0U3RhcnQgKHNlbGYsIGRhdGEsIGRlY3J5cHQpIHtcbiAgdmFyIGxlbiA9IGRhdGEubGVuZ3RoXG4gIHZhciBvdXQgPSB4b3IoZGF0YSwgc2VsZi5fY2FjaGUpXG4gIHNlbGYuX2NhY2hlID0gc2VsZi5fY2FjaGUuc2xpY2UobGVuKVxuICBzZWxmLl9wcmV2ID0gQnVmZmVyLmNvbmNhdChbc2VsZi5fcHJldiwgZGVjcnlwdCA/IGRhdGEgOiBvdXRdKVxuICByZXR1cm4gb3V0XG59XG4iLCJmdW5jdGlvbiBlbmNyeXB0Qnl0ZSAoc2VsZiwgYnl0ZVBhcmFtLCBkZWNyeXB0KSB7XG4gIHZhciBwYWRcbiAgdmFyIGkgPSAtMVxuICB2YXIgbGVuID0gOFxuICB2YXIgb3V0ID0gMFxuICB2YXIgYml0LCB2YWx1ZVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgcGFkID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhzZWxmLl9wcmV2KVxuICAgIGJpdCA9IChieXRlUGFyYW0gJiAoMSA8PCAoNyAtIGkpKSkgPyAweDgwIDogMFxuICAgIHZhbHVlID0gcGFkWzBdIF4gYml0XG4gICAgb3V0ICs9ICgodmFsdWUgJiAweDgwKSA+PiAoaSAlIDgpKVxuICAgIHNlbGYuX3ByZXYgPSBzaGlmdEluKHNlbGYuX3ByZXYsIGRlY3J5cHQgPyBiaXQgOiB2YWx1ZSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgY2h1bmssIGRlY3J5cHQpIHtcbiAgdmFyIGxlbiA9IGNodW5rLmxlbmd0aFxuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihsZW4pXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dFtpXSA9IGVuY3J5cHRCeXRlKHNlbGYsIGNodW5rW2ldLCBkZWNyeXB0KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbmZ1bmN0aW9uIHNoaWZ0SW4gKGJ1ZmZlciwgdmFsdWUpIHtcbiAgdmFyIGxlbiA9IGJ1ZmZlci5sZW5ndGhcbiAgdmFyIGkgPSAtMVxuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihidWZmZXIubGVuZ3RoKVxuICBidWZmZXIgPSBCdWZmZXIuY29uY2F0KFtidWZmZXIsIG5ldyBCdWZmZXIoW3ZhbHVlXSldKVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgb3V0W2ldID0gYnVmZmVyW2ldIDw8IDEgfCBidWZmZXJbaSArIDFdID4+ICg3KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsImZ1bmN0aW9uIGVuY3J5cHRCeXRlIChzZWxmLCBieXRlUGFyYW0sIGRlY3J5cHQpIHtcbiAgdmFyIHBhZCA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soc2VsZi5fcHJldilcbiAgdmFyIG91dCA9IHBhZFswXSBeIGJ5dGVQYXJhbVxuICBzZWxmLl9wcmV2ID0gQnVmZmVyLmNvbmNhdChbc2VsZi5fcHJldi5zbGljZSgxKSwgbmV3IEJ1ZmZlcihbZGVjcnlwdCA/IGJ5dGVQYXJhbSA6IG91dF0pXSlcbiAgcmV0dXJuIG91dFxufVxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGNodW5rLCBkZWNyeXB0KSB7XG4gIHZhciBsZW4gPSBjaHVuay5sZW5ndGhcbiAgdmFyIG91dCA9IG5ldyBCdWZmZXIobGVuKVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXRbaV0gPSBlbmNyeXB0Qnl0ZShzZWxmLCBjaHVua1tpXSwgZGVjcnlwdClcbiAgfVxuICByZXR1cm4gb3V0XG59XG4iLCJ2YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG5cbmZ1bmN0aW9uIGluY3IzMiAoaXYpIHtcbiAgdmFyIGxlbiA9IGl2Lmxlbmd0aFxuICB2YXIgaXRlbVxuICB3aGlsZSAobGVuLS0pIHtcbiAgICBpdGVtID0gaXYucmVhZFVJbnQ4KGxlbilcbiAgICBpZiAoaXRlbSA9PT0gMjU1KSB7XG4gICAgICBpdi53cml0ZVVJbnQ4KDAsIGxlbilcbiAgICB9IGVsc2Uge1xuICAgICAgaXRlbSsrXG4gICAgICBpdi53cml0ZVVJbnQ4KGl0ZW0sIGxlbilcbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGdldEJsb2NrIChzZWxmKSB7XG4gIHZhciBvdXQgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gIGluY3IzMihzZWxmLl9wcmV2KVxuICByZXR1cm4gb3V0XG59XG5cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBjaHVuaykge1xuICB3aGlsZSAoc2VsZi5fY2FjaGUubGVuZ3RoIDwgY2h1bmsubGVuZ3RoKSB7XG4gICAgc2VsZi5fY2FjaGUgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9jYWNoZSwgZ2V0QmxvY2soc2VsZildKVxuICB9XG4gIHZhciBwYWQgPSBzZWxmLl9jYWNoZS5zbGljZSgwLCBjaHVuay5sZW5ndGgpXG4gIHNlbGYuX2NhY2hlID0gc2VsZi5fY2FjaGUuc2xpY2UoY2h1bmsubGVuZ3RoKVxuICByZXR1cm4geG9yKGNodW5rLCBwYWQpXG59XG4iLCJ2YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG5cbmZ1bmN0aW9uIGdldEJsb2NrIChzZWxmKSB7XG4gIHNlbGYuX3ByZXYgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gIHJldHVybiBzZWxmLl9wcmV2XG59XG5cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBjaHVuaykge1xuICB3aGlsZSAoc2VsZi5fY2FjaGUubGVuZ3RoIDwgY2h1bmsubGVuZ3RoKSB7XG4gICAgc2VsZi5fY2FjaGUgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9jYWNoZSwgZ2V0QmxvY2soc2VsZildKVxuICB9XG5cbiAgdmFyIHBhZCA9IHNlbGYuX2NhY2hlLnNsaWNlKDAsIGNodW5rLmxlbmd0aClcbiAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jYWNoZS5zbGljZShjaHVuay5sZW5ndGgpXG4gIHJldHVybiB4b3IoY2h1bmssIHBhZClcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24geG9yIChhLCBiKSB7XG4gIHZhciBsZW5ndGggPSBNYXRoLm1pbihhLmxlbmd0aCwgYi5sZW5ndGgpXG4gIHZhciBidWZmZXIgPSBuZXcgQnVmZmVyKGxlbmd0aClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgYnVmZmVyW2ldID0gYVtpXSBeIGJbaV1cbiAgfVxuXG4gIHJldHVybiBidWZmZXJcbn1cbiIsInZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdzdHJlYW0nKS5UcmFuc2Zvcm1cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXInKS5TdHJpbmdEZWNvZGVyXG5tb2R1bGUuZXhwb3J0cyA9IENpcGhlckJhc2VcbmluaGVyaXRzKENpcGhlckJhc2UsIFRyYW5zZm9ybSlcbmZ1bmN0aW9uIENpcGhlckJhc2UgKGhhc2hNb2RlKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG4gIHRoaXMuaGFzaE1vZGUgPSB0eXBlb2YgaGFzaE1vZGUgPT09ICdzdHJpbmcnXG4gIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgdGhpc1toYXNoTW9kZV0gPSB0aGlzLl9maW5hbE9yRGlnZXN0XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5maW5hbCA9IHRoaXMuX2ZpbmFsT3JEaWdlc3RcbiAgfVxuICB0aGlzLl9kZWNvZGVyID0gbnVsbFxuICB0aGlzLl9lbmNvZGluZyA9IG51bGxcbn1cbkNpcGhlckJhc2UucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhLCBpbnB1dEVuYywgb3V0cHV0RW5jKSB7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICBkYXRhID0gbmV3IEJ1ZmZlcihkYXRhLCBpbnB1dEVuYylcbiAgfVxuICB2YXIgb3V0RGF0YSA9IHRoaXMuX3VwZGF0ZShkYXRhKVxuICBpZiAodGhpcy5oYXNoTW9kZSkge1xuICAgIHJldHVybiB0aGlzXG4gIH1cbiAgaWYgKG91dHB1dEVuYykge1xuICAgIG91dERhdGEgPSB0aGlzLl90b1N0cmluZyhvdXREYXRhLCBvdXRwdXRFbmMpXG4gIH1cbiAgcmV0dXJuIG91dERhdGFcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuc2V0QXV0b1BhZGRpbmcgPSBmdW5jdGlvbiAoKSB7fVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5nZXRBdXRoVGFnID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3RyeWluZyB0byBnZXQgYXV0aCB0YWcgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBdXRoVGFnID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3RyeWluZyB0byBzZXQgYXV0aCB0YWcgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBQUQgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIHNldCBhYWQgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24gKGRhdGEsIF8sIG5leHQpIHtcbiAgdmFyIGVyclxuICB0cnkge1xuICAgIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgICB0aGlzLl91cGRhdGUoZGF0YSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wdXNoKHRoaXMuX3VwZGF0ZShkYXRhKSlcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBlcnIgPSBlXG4gIH0gZmluYWxseSB7XG4gICAgbmV4dChlcnIpXG4gIH1cbn1cbkNpcGhlckJhc2UucHJvdG90eXBlLl9mbHVzaCA9IGZ1bmN0aW9uIChkb25lKSB7XG4gIHZhciBlcnJcbiAgdHJ5IHtcbiAgICB0aGlzLnB1c2godGhpcy5fZmluYWwoKSlcbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfSBmaW5hbGx5IHtcbiAgICBkb25lKGVycilcbiAgfVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZpbmFsT3JEaWdlc3QgPSBmdW5jdGlvbiAob3V0cHV0RW5jKSB7XG4gIHZhciBvdXREYXRhID0gdGhpcy5fZmluYWwoKSB8fCBuZXcgQnVmZmVyKCcnKVxuICBpZiAob3V0cHV0RW5jKSB7XG4gICAgb3V0RGF0YSA9IHRoaXMuX3RvU3RyaW5nKG91dERhdGEsIG91dHB1dEVuYywgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb3V0RGF0YVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fdG9TdHJpbmcgPSBmdW5jdGlvbiAodmFsdWUsIGVuYywgZmluYWwpIHtcbiAgaWYgKCF0aGlzLl9kZWNvZGVyKSB7XG4gICAgdGhpcy5fZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKGVuYylcbiAgICB0aGlzLl9lbmNvZGluZyA9IGVuY1xuICB9XG4gIGlmICh0aGlzLl9lbmNvZGluZyAhPT0gZW5jKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjYW5cXCd0IHN3aXRjaCBlbmNvZGluZ3MnKVxuICB9XG4gIHZhciBvdXQgPSB0aGlzLl9kZWNvZGVyLndyaXRlKHZhbHVlKVxuICBpZiAoZmluYWwpIHtcbiAgICBvdXQgKz0gdGhpcy5fZGVjb2Rlci5lbmQoKVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsInZhciBhZXMgPSByZXF1aXJlKCcuL2FlcycpXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxuXG5pbmhlcml0cyhTdHJlYW1DaXBoZXIsIFRyYW5zZm9ybSlcbm1vZHVsZS5leHBvcnRzID0gU3RyZWFtQ2lwaGVyXG5mdW5jdGlvbiBTdHJlYW1DaXBoZXIgKG1vZGUsIGtleSwgaXYsIGRlY3J5cHQpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFN0cmVhbUNpcGhlcikpIHtcbiAgICByZXR1cm4gbmV3IFN0cmVhbUNpcGhlcihtb2RlLCBrZXksIGl2KVxuICB9XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG4gIHRoaXMuX2NpcGhlciA9IG5ldyBhZXMuQUVTKGtleSlcbiAgdGhpcy5fcHJldiA9IG5ldyBCdWZmZXIoaXYubGVuZ3RoKVxuICB0aGlzLl9jYWNoZSA9IG5ldyBCdWZmZXIoJycpXG4gIHRoaXMuX3NlY0NhY2hlID0gbmV3IEJ1ZmZlcignJylcbiAgdGhpcy5fZGVjcnlwdCA9IGRlY3J5cHRcbiAgaXYuY29weSh0aGlzLl9wcmV2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gIHJldHVybiB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmssIHRoaXMuX2RlY3J5cHQpXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fY2lwaGVyLnNjcnViKClcbn1cbiIsInZhciBtZDUgPSByZXF1aXJlKCdjcmVhdGUtaGFzaC9tZDUnKVxubW9kdWxlLmV4cG9ydHMgPSBFVlBfQnl0ZXNUb0tleVxuZnVuY3Rpb24gRVZQX0J5dGVzVG9LZXkgKHBhc3N3b3JkLCBzYWx0LCBrZXlMZW4sIGl2TGVuKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHBhc3N3b3JkKSkge1xuICAgIHBhc3N3b3JkID0gbmV3IEJ1ZmZlcihwYXNzd29yZCwgJ2JpbmFyeScpXG4gIH1cbiAgaWYgKHNhbHQgJiYgIUJ1ZmZlci5pc0J1ZmZlcihzYWx0KSkge1xuICAgIHNhbHQgPSBuZXcgQnVmZmVyKHNhbHQsICdiaW5hcnknKVxuICB9XG4gIGtleUxlbiA9IGtleUxlbiAvIDhcbiAgaXZMZW4gPSBpdkxlbiB8fCAwXG4gIHZhciBraSA9IDBcbiAgdmFyIGlpID0gMFxuICB2YXIga2V5ID0gbmV3IEJ1ZmZlcihrZXlMZW4pXG4gIHZhciBpdiA9IG5ldyBCdWZmZXIoaXZMZW4pXG4gIHZhciBhZGRtZCA9IDBcbiAgdmFyIG1kX2J1ZlxuICB2YXIgaVxuICB2YXIgYnVmcyA9IFtdXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgaWYgKGFkZG1kKysgPiAwKSB7XG4gICAgICBidWZzLnB1c2gobWRfYnVmKVxuICAgIH1cbiAgICBidWZzLnB1c2gocGFzc3dvcmQpXG4gICAgaWYgKHNhbHQpIHtcbiAgICAgIGJ1ZnMucHVzaChzYWx0KVxuICAgIH1cbiAgICBtZF9idWYgPSBtZDUoQnVmZmVyLmNvbmNhdChidWZzKSlcbiAgICBidWZzID0gW11cbiAgICBpID0gMFxuICAgIGlmIChrZXlMZW4gPiAwKSB7XG4gICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBpZiAoa2V5TGVuID09PSAwKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaSA9PT0gbWRfYnVmLmxlbmd0aCkge1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAga2V5W2tpKytdID0gbWRfYnVmW2ldXG4gICAgICAgIGtleUxlbi0tXG4gICAgICAgIGkrK1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXZMZW4gPiAwICYmIGkgIT09IG1kX2J1Zi5sZW5ndGgpIHtcbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGlmIChpdkxlbiA9PT0gMCkge1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGkgPT09IG1kX2J1Zi5sZW5ndGgpIHtcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICAgIGl2W2lpKytdID0gbWRfYnVmW2ldXG4gICAgICAgIGl2TGVuLS1cbiAgICAgICAgaSsrXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChrZXlMZW4gPT09IDAgJiYgaXZMZW4gPT09IDApIHtcbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG4gIGZvciAoaSA9IDA7IGkgPCBtZF9idWYubGVuZ3RoOyBpKyspIHtcbiAgICBtZF9idWZbaV0gPSAwXG4gIH1cbiAgcmV0dXJuIHtcbiAgICBrZXk6IGtleSxcbiAgICBpdjogaXZcbiAgfVxufVxuIiwiLy8gbXVjaCBvZiB0aGlzIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9pbmR1dG55L3NlbGYtc2lnbmVkL2Jsb2IvZ2gtcGFnZXMvbGliL3JzYS5qc1xudmFyIGNyZWF0ZUhtYWMgPSByZXF1aXJlKCdjcmVhdGUtaG1hYycpXG52YXIgY3J0ID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1yc2EnKVxudmFyIGN1cnZlcyA9IHJlcXVpcmUoJy4vY3VydmVzJylcbnZhciBlbGxpcHRpYyA9IHJlcXVpcmUoJ2VsbGlwdGljJylcbnZhciBwYXJzZUtleXMgPSByZXF1aXJlKCdwYXJzZS1hc24xJylcblxudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKVxudmFyIEVDID0gZWxsaXB0aWMuZWNcblxuZnVuY3Rpb24gc2lnbiAoaGFzaCwga2V5LCBoYXNoVHlwZSwgc2lnblR5cGUpIHtcbiAgdmFyIHByaXYgPSBwYXJzZUtleXMoa2V5KVxuICBpZiAocHJpdi5jdXJ2ZSkge1xuICAgIGlmIChzaWduVHlwZSAhPT0gJ2VjZHNhJykgdGhyb3cgbmV3IEVycm9yKCd3cm9uZyBwcml2YXRlIGtleSB0eXBlJylcblxuICAgIHJldHVybiBlY1NpZ24oaGFzaCwgcHJpdilcbiAgfSBlbHNlIGlmIChwcml2LnR5cGUgPT09ICdkc2EnKSB7XG4gICAgaWYgKHNpZ25UeXBlICE9PSAnZHNhJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd3cm9uZyBwcml2YXRlIGtleSB0eXBlJylcbiAgICB9XG4gICAgcmV0dXJuIGRzYVNpZ24oaGFzaCwgcHJpdiwgaGFzaFR5cGUpXG4gIH0gZWxzZSB7XG4gICAgaWYgKHNpZ25UeXBlICE9PSAncnNhJykgdGhyb3cgbmV3IEVycm9yKCd3cm9uZyBwcml2YXRlIGtleSB0eXBlJylcbiAgfVxuXG4gIHZhciBsZW4gPSBwcml2Lm1vZHVsdXMuYnl0ZUxlbmd0aCgpXG4gIHZhciBwYWQgPSBbIDAsIDEgXVxuICB3aGlsZSAoaGFzaC5sZW5ndGggKyBwYWQubGVuZ3RoICsgMSA8IGxlbikge1xuICAgIHBhZC5wdXNoKDB4ZmYpXG4gIH1cbiAgcGFkLnB1c2goMHgwMClcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgaGFzaC5sZW5ndGgpIHtcbiAgICBwYWQucHVzaChoYXNoW2ldKVxuICB9XG5cbiAgdmFyIG91dCA9IGNydChwYWQsIHByaXYpXG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gZWNTaWduIChoYXNoLCBwcml2KSB7XG4gIHZhciBjdXJ2ZUlkID0gY3VydmVzW3ByaXYuY3VydmUuam9pbignLicpXVxuICBpZiAoIWN1cnZlSWQpIHRocm93IG5ldyBFcnJvcigndW5rbm93biBjdXJ2ZSAnICsgcHJpdi5jdXJ2ZS5qb2luKCcuJykpXG5cbiAgdmFyIGN1cnZlID0gbmV3IEVDKGN1cnZlSWQpXG4gIHZhciBrZXkgPSBjdXJ2ZS5nZW5LZXlQYWlyKClcblxuICBrZXkuX2ltcG9ydFByaXZhdGUocHJpdi5wcml2YXRlS2V5KVxuICB2YXIgb3V0ID0ga2V5LnNpZ24oaGFzaClcblxuICByZXR1cm4gbmV3IEJ1ZmZlcihvdXQudG9ERVIoKSlcbn1cblxuZnVuY3Rpb24gZHNhU2lnbiAoaGFzaCwgcHJpdiwgYWxnbykge1xuICB2YXIgeCA9IHByaXYucGFyYW1zLnByaXZfa2V5XG4gIHZhciBwID0gcHJpdi5wYXJhbXMucFxuICB2YXIgcSA9IHByaXYucGFyYW1zLnFcbiAgdmFyIGcgPSBwcml2LnBhcmFtcy5nXG4gIHZhciByID0gbmV3IEJOKDApXG4gIHZhciBrXG4gIHZhciBIID0gYml0czJpbnQoaGFzaCwgcSkubW9kKHEpXG4gIHZhciBzID0gZmFsc2VcbiAgdmFyIGt2ID0gZ2V0S2V5KHgsIHEsIGhhc2gsIGFsZ28pXG4gIHdoaWxlIChzID09PSBmYWxzZSkge1xuICAgIGsgPSBtYWtlS2V5KHEsIGt2LCBhbGdvKVxuICAgIHIgPSBtYWtlUihnLCBrLCBwLCBxKVxuICAgIHMgPSBrLmludm0ocSkuaW11bChILmFkZCh4Lm11bChyKSkpLm1vZChxKVxuICAgIGlmICghcy5jbXBuKDApKSB7XG4gICAgICBzID0gZmFsc2VcbiAgICAgIHIgPSBuZXcgQk4oMClcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRvREVSKHIsIHMpXG59XG5cbmZ1bmN0aW9uIHRvREVSIChyLCBzKSB7XG4gIHIgPSByLnRvQXJyYXkoKVxuICBzID0gcy50b0FycmF5KClcblxuICAvLyBQYWQgdmFsdWVzXG4gIGlmIChyWzBdICYgMHg4MCkge1xuICAgIHIgPSBbIDAgXS5jb25jYXQocilcbiAgfVxuICAvLyBQYWQgdmFsdWVzXG4gIGlmIChzWzBdICYgMHg4MCkge1xuICAgIHMgPSBbMF0uY29uY2F0KHMpXG4gIH1cblxuICB2YXIgdG90YWwgPSByLmxlbmd0aCArIHMubGVuZ3RoICsgNFxuICB2YXIgcmVzID0gWyAweDMwLCB0b3RhbCwgMHgwMiwgci5sZW5ndGggXVxuICByZXMgPSByZXMuY29uY2F0KHIsIFsgMHgwMiwgcy5sZW5ndGggXSwgcylcbiAgcmV0dXJuIG5ldyBCdWZmZXIocmVzKVxufVxuXG5mdW5jdGlvbiBnZXRLZXkgKHgsIHEsIGhhc2gsIGFsZ28pIHtcbiAgeCA9IG5ldyBCdWZmZXIoeC50b0FycmF5KCkpXG4gIGlmICh4Lmxlbmd0aCA8IHEuYnl0ZUxlbmd0aCgpKSB7XG4gICAgdmFyIHplcm9zID0gbmV3IEJ1ZmZlcihxLmJ5dGVMZW5ndGgoKSAtIHgubGVuZ3RoKVxuICAgIHplcm9zLmZpbGwoMClcbiAgICB4ID0gQnVmZmVyLmNvbmNhdChbemVyb3MsIHhdKVxuICB9XG4gIHZhciBobGVuID0gaGFzaC5sZW5ndGhcbiAgdmFyIGhiaXRzID0gYml0czJvY3RldHMoaGFzaCwgcSlcbiAgdmFyIHYgPSBuZXcgQnVmZmVyKGhsZW4pXG4gIHYuZmlsbCgxKVxuICB2YXIgayA9IG5ldyBCdWZmZXIoaGxlbilcbiAgay5maWxsKDApXG4gIGsgPSBjcmVhdGVIbWFjKGFsZ28sIGspXG4gICAgLnVwZGF0ZSh2KVxuICAgIC51cGRhdGUobmV3IEJ1ZmZlcihbMF0pKVxuICAgIC51cGRhdGUoeClcbiAgICAudXBkYXRlKGhiaXRzKVxuICAgIC5kaWdlc3QoKVxuICB2ID0gY3JlYXRlSG1hYyhhbGdvLCBrKVxuICAgIC51cGRhdGUodilcbiAgICAuZGlnZXN0KClcbiAgayA9IGNyZWF0ZUhtYWMoYWxnbywgaylcbiAgICAudXBkYXRlKHYpXG4gICAgLnVwZGF0ZShuZXcgQnVmZmVyKFsxXSkpXG4gICAgLnVwZGF0ZSh4KVxuICAgIC51cGRhdGUoaGJpdHMpXG4gICAgLmRpZ2VzdCgpXG4gIHYgPSBjcmVhdGVIbWFjKGFsZ28sIGspXG4gICAgLnVwZGF0ZSh2KVxuICAgIC5kaWdlc3QoKVxuICByZXR1cm4ge1xuICAgIGs6IGssXG4gICAgdjogdlxuICB9XG59XG5cbmZ1bmN0aW9uIGJpdHMyaW50IChvYml0cywgcSkge1xuICB2YXIgYml0cyA9IG5ldyBCTihvYml0cylcbiAgdmFyIHNoaWZ0ID0gKG9iaXRzLmxlbmd0aCA8PCAzKSAtIHEuYml0TGVuZ3RoKClcbiAgaWYgKHNoaWZ0ID4gMCkge1xuICAgIGJpdHMuaXNocm4oc2hpZnQpXG4gIH1cbiAgcmV0dXJuIGJpdHNcbn1cblxuZnVuY3Rpb24gYml0czJvY3RldHMgKGJpdHMsIHEpIHtcbiAgYml0cyA9IGJpdHMyaW50KGJpdHMsIHEpXG4gIGJpdHMgPSBiaXRzLm1vZChxKVxuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihiaXRzLnRvQXJyYXkoKSlcbiAgaWYgKG91dC5sZW5ndGggPCBxLmJ5dGVMZW5ndGgoKSkge1xuICAgIHZhciB6ZXJvcyA9IG5ldyBCdWZmZXIocS5ieXRlTGVuZ3RoKCkgLSBvdXQubGVuZ3RoKVxuICAgIHplcm9zLmZpbGwoMClcbiAgICBvdXQgPSBCdWZmZXIuY29uY2F0KFt6ZXJvcywgb3V0XSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIG1ha2VLZXkgKHEsIGt2LCBhbGdvKSB7XG4gIHZhciB0LCBrXG5cbiAgZG8ge1xuICAgIHQgPSBuZXcgQnVmZmVyKCcnKVxuXG4gICAgd2hpbGUgKHQubGVuZ3RoICogOCA8IHEuYml0TGVuZ3RoKCkpIHtcbiAgICAgIGt2LnYgPSBjcmVhdGVIbWFjKGFsZ28sIGt2LmspXG4gICAgICAgIC51cGRhdGUoa3YudilcbiAgICAgICAgLmRpZ2VzdCgpXG4gICAgICB0ID0gQnVmZmVyLmNvbmNhdChbdCwga3Yudl0pXG4gICAgfVxuXG4gICAgayA9IGJpdHMyaW50KHQsIHEpXG4gICAga3YuayA9IGNyZWF0ZUhtYWMoYWxnbywga3YuaylcbiAgICAgIC51cGRhdGUoa3YudilcbiAgICAgIC51cGRhdGUobmV3IEJ1ZmZlcihbMF0pKVxuICAgICAgLmRpZ2VzdCgpXG4gICAga3YudiA9IGNyZWF0ZUhtYWMoYWxnbywga3YuaylcbiAgICAgIC51cGRhdGUoa3YudilcbiAgICAgIC5kaWdlc3QoKVxuICB9IHdoaWxlIChrLmNtcChxKSAhPT0gLTEpXG5cbiAgcmV0dXJuIGtcbn1cblxuZnVuY3Rpb24gbWFrZVIgKGcsIGssIHAsIHEpIHtcbiAgcmV0dXJuIGcudG9SZWQoQk4ubW9udChwKSkucmVkUG93KGspLmZyb21SZWQoKS5tb2QocSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzaWduXG5tb2R1bGUuZXhwb3J0cy5nZXRLZXkgPSBnZXRLZXlcbm1vZHVsZS5leHBvcnRzLm1ha2VLZXkgPSBtYWtlS2V5XG4iLCIvLyBtdWNoIG9mIHRoaXMgYmFzZWQgb24gaHR0cHM6Ly9naXRodWIuY29tL2luZHV0bnkvc2VsZi1zaWduZWQvYmxvYi9naC1wYWdlcy9saWIvcnNhLmpzXG52YXIgY3VydmVzID0gcmVxdWlyZSgnLi9jdXJ2ZXMnKVxudmFyIGVsbGlwdGljID0gcmVxdWlyZSgnZWxsaXB0aWMnKVxudmFyIHBhcnNlS2V5cyA9IHJlcXVpcmUoJ3BhcnNlLWFzbjEnKVxuXG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpXG52YXIgRUMgPSBlbGxpcHRpYy5lY1xuXG5mdW5jdGlvbiB2ZXJpZnkgKHNpZywgaGFzaCwga2V5LCBzaWduVHlwZSkge1xuICB2YXIgcHViID0gcGFyc2VLZXlzKGtleSlcbiAgaWYgKHB1Yi50eXBlID09PSAnZWMnKSB7XG4gICAgaWYgKHNpZ25UeXBlICE9PSAnZWNkc2EnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3dyb25nIHB1YmxpYyBrZXkgdHlwZScpXG4gICAgfVxuICAgIHJldHVybiBlY1ZlcmlmeShzaWcsIGhhc2gsIHB1YilcbiAgfSBlbHNlIGlmIChwdWIudHlwZSA9PT0gJ2RzYScpIHtcbiAgICBpZiAoc2lnblR5cGUgIT09ICdkc2EnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3dyb25nIHB1YmxpYyBrZXkgdHlwZScpXG4gICAgfVxuICAgIHJldHVybiBkc2FWZXJpZnkoc2lnLCBoYXNoLCBwdWIpXG4gIH0gZWxzZSB7XG4gICAgaWYgKHNpZ25UeXBlICE9PSAncnNhJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd3cm9uZyBwdWJsaWMga2V5IHR5cGUnKVxuICAgIH1cbiAgfVxuICB2YXIgbGVuID0gcHViLm1vZHVsdXMuYnl0ZUxlbmd0aCgpXG4gIHZhciBwYWQgPSBbIDEgXVxuICB2YXIgcGFkTnVtID0gMFxuICB3aGlsZSAoaGFzaC5sZW5ndGggKyBwYWQubGVuZ3RoICsgMiA8IGxlbikge1xuICAgIHBhZC5wdXNoKDB4ZmYpXG4gICAgcGFkTnVtKytcbiAgfVxuICBwYWQucHVzaCgweDAwKVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBoYXNoLmxlbmd0aCkge1xuICAgIHBhZC5wdXNoKGhhc2hbaV0pXG4gIH1cbiAgcGFkID0gbmV3IEJ1ZmZlcihwYWQpXG4gIHZhciByZWQgPSBCTi5tb250KHB1Yi5tb2R1bHVzKVxuICBzaWcgPSBuZXcgQk4oc2lnKS50b1JlZChyZWQpXG5cbiAgc2lnID0gc2lnLnJlZFBvdyhuZXcgQk4ocHViLnB1YmxpY0V4cG9uZW50KSlcblxuICBzaWcgPSBuZXcgQnVmZmVyKHNpZy5mcm9tUmVkKCkudG9BcnJheSgpKVxuICB2YXIgb3V0ID0gMFxuICBpZiAocGFkTnVtIDwgOCkge1xuICAgIG91dCA9IDFcbiAgfVxuICBsZW4gPSBNYXRoLm1pbihzaWcubGVuZ3RoLCBwYWQubGVuZ3RoKVxuICBpZiAoc2lnLmxlbmd0aCAhPT0gcGFkLmxlbmd0aCkge1xuICAgIG91dCA9IDFcbiAgfVxuXG4gIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgb3V0IHw9IChzaWdbaV0gXiBwYWRbaV0pXG4gIH1cbiAgcmV0dXJuIG91dCA9PT0gMFxufVxuXG5mdW5jdGlvbiBlY1ZlcmlmeSAoc2lnLCBoYXNoLCBwdWIpIHtcbiAgdmFyIGN1cnZlSWQgPSBjdXJ2ZXNbcHViLmRhdGEuYWxnb3JpdGhtLmN1cnZlLmpvaW4oJy4nKV1cbiAgaWYgKCFjdXJ2ZUlkKSB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gY3VydmUgJyArIHB1Yi5kYXRhLmFsZ29yaXRobS5jdXJ2ZS5qb2luKCcuJykpXG5cbiAgdmFyIGN1cnZlID0gbmV3IEVDKGN1cnZlSWQpXG4gIHZhciBwdWJrZXkgPSBwdWIuZGF0YS5zdWJqZWN0UHJpdmF0ZUtleS5kYXRhXG5cbiAgcmV0dXJuIGN1cnZlLnZlcmlmeShoYXNoLCBzaWcsIHB1YmtleSlcbn1cblxuZnVuY3Rpb24gZHNhVmVyaWZ5IChzaWcsIGhhc2gsIHB1Yikge1xuICB2YXIgcCA9IHB1Yi5kYXRhLnBcbiAgdmFyIHEgPSBwdWIuZGF0YS5xXG4gIHZhciBnID0gcHViLmRhdGEuZ1xuICB2YXIgeSA9IHB1Yi5kYXRhLnB1Yl9rZXlcbiAgdmFyIHVucGFja2VkID0gcGFyc2VLZXlzLnNpZ25hdHVyZS5kZWNvZGUoc2lnLCAnZGVyJylcbiAgdmFyIHMgPSB1bnBhY2tlZC5zXG4gIHZhciByID0gdW5wYWNrZWQuclxuICBjaGVja1ZhbHVlKHMsIHEpXG4gIGNoZWNrVmFsdWUociwgcSlcbiAgdmFyIG1vbnRwID0gQk4ubW9udChwKVxuICB2YXIgdyA9IHMuaW52bShxKVxuICB2YXIgdiA9IGcudG9SZWQobW9udHApXG4gICAgLnJlZFBvdyhuZXcgQk4oaGFzaCkubXVsKHcpLm1vZChxKSlcbiAgICAuZnJvbVJlZCgpXG4gICAgLm11bChcbiAgICAgIHkudG9SZWQobW9udHApXG4gICAgICAgIC5yZWRQb3coci5tdWwodykubW9kKHEpKVxuICAgICAgICAuZnJvbVJlZCgpXG4gICkubW9kKHApLm1vZChxKVxuICByZXR1cm4gIXYuY21wKHIpXG59XG5cbmZ1bmN0aW9uIGNoZWNrVmFsdWUgKGIsIHEpIHtcbiAgaWYgKGIuY21wbigwKSA8PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHNpZycpXG4gIH1cbiAgaWYgKGIuY21wKHEpID49IHEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgc2lnJylcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHZlcmlmeVxuIiwidmFyIGVsbGlwdGljID0gcmVxdWlyZSgnZWxsaXB0aWMnKTtcbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY3JlYXRlRUNESChjdXJ2ZSkge1xuXHRyZXR1cm4gbmV3IEVDREgoY3VydmUpO1xufTtcblxudmFyIGFsaWFzZXMgPSB7XG5cdHNlY3AyNTZrMToge1xuXHRcdG5hbWU6ICdzZWNwMjU2azEnLFxuXHRcdGJ5dGVMZW5ndGg6IDMyXG5cdH0sXG5cdHNlY3AyMjRyMToge1xuXHRcdG5hbWU6ICdwMjI0Jyxcblx0XHRieXRlTGVuZ3RoOiAyOFxuXHR9LFxuXHRwcmltZTI1NnYxOiB7XG5cdFx0bmFtZTogJ3AyNTYnLFxuXHRcdGJ5dGVMZW5ndGg6IDMyXG5cdH0sXG5cdHByaW1lMTkydjE6IHtcblx0XHRuYW1lOiAncDE5MicsXG5cdFx0Ynl0ZUxlbmd0aDogMjRcblx0fSxcblx0ZWQyNTUxOToge1xuXHRcdG5hbWU6ICdlZDI1NTE5Jyxcblx0XHRieXRlTGVuZ3RoOiAzMlxuXHR9LFxuXHRzZWNwMzg0cjE6IHtcblx0XHRuYW1lOiAncDM4NCcsXG5cdFx0Ynl0ZUxlbmd0aDogNDhcblx0fSxcblx0c2VjcDUyMXIxOiB7XG5cdFx0bmFtZTogJ3A1MjEnLFxuXHRcdGJ5dGVMZW5ndGg6IDY2XG5cdH1cbn07XG5cbmFsaWFzZXMucDIyNCA9IGFsaWFzZXMuc2VjcDIyNHIxO1xuYWxpYXNlcy5wMjU2ID0gYWxpYXNlcy5zZWNwMjU2cjEgPSBhbGlhc2VzLnByaW1lMjU2djE7XG5hbGlhc2VzLnAxOTIgPSBhbGlhc2VzLnNlY3AxOTJyMSA9IGFsaWFzZXMucHJpbWUxOTJ2MTtcbmFsaWFzZXMucDM4NCA9IGFsaWFzZXMuc2VjcDM4NHIxO1xuYWxpYXNlcy5wNTIxID0gYWxpYXNlcy5zZWNwNTIxcjE7XG5cbmZ1bmN0aW9uIEVDREgoY3VydmUpIHtcblx0dGhpcy5jdXJ2ZVR5cGUgPSBhbGlhc2VzW2N1cnZlXTtcblx0aWYgKCF0aGlzLmN1cnZlVHlwZSApIHtcblx0XHR0aGlzLmN1cnZlVHlwZSA9IHtcblx0XHRcdG5hbWU6IGN1cnZlXG5cdFx0fTtcblx0fVxuXHR0aGlzLmN1cnZlID0gbmV3IGVsbGlwdGljLmVjKHRoaXMuY3VydmVUeXBlLm5hbWUpO1xuXHR0aGlzLmtleXMgPSB2b2lkIDA7XG59XG5cbkVDREgucHJvdG90eXBlLmdlbmVyYXRlS2V5cyA9IGZ1bmN0aW9uIChlbmMsIGZvcm1hdCkge1xuXHR0aGlzLmtleXMgPSB0aGlzLmN1cnZlLmdlbktleVBhaXIoKTtcblx0cmV0dXJuIHRoaXMuZ2V0UHVibGljS2V5KGVuYywgZm9ybWF0KTtcbn07XG5cbkVDREgucHJvdG90eXBlLmNvbXB1dGVTZWNyZXQgPSBmdW5jdGlvbiAob3RoZXIsIGluZW5jLCBlbmMpIHtcblx0aW5lbmMgPSBpbmVuYyB8fCAndXRmOCc7XG5cdGlmICghQnVmZmVyLmlzQnVmZmVyKG90aGVyKSkge1xuXHRcdG90aGVyID0gbmV3IEJ1ZmZlcihvdGhlciwgaW5lbmMpO1xuXHR9XG5cdHZhciBvdGhlclB1YiA9IHRoaXMuY3VydmUua2V5RnJvbVB1YmxpYyhvdGhlcikuZ2V0UHVibGljKCk7XG5cdHZhciBvdXQgPSBvdGhlclB1Yi5tdWwodGhpcy5rZXlzLmdldFByaXZhdGUoKSkuZ2V0WCgpO1xuXHRyZXR1cm4gZm9ybWF0UmV0dXJuVmFsdWUob3V0LCBlbmMsIHRoaXMuY3VydmVUeXBlLmJ5dGVMZW5ndGgpO1xufTtcblxuRUNESC5wcm90b3R5cGUuZ2V0UHVibGljS2V5ID0gZnVuY3Rpb24gKGVuYywgZm9ybWF0KSB7XG5cdHZhciBrZXkgPSB0aGlzLmtleXMuZ2V0UHVibGljKGZvcm1hdCA9PT0gJ2NvbXByZXNzZWQnLCB0cnVlKTtcblx0aWYgKGZvcm1hdCA9PT0gJ2h5YnJpZCcpIHtcblx0XHRpZiAoa2V5W2tleS5sZW5ndGggLSAxXSAlIDIpIHtcblx0XHRcdGtleVswXSA9IDc7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGtleSBbMF0gPSA2O1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gZm9ybWF0UmV0dXJuVmFsdWUoa2V5LCBlbmMpO1xufTtcblxuRUNESC5wcm90b3R5cGUuZ2V0UHJpdmF0ZUtleSA9IGZ1bmN0aW9uIChlbmMpIHtcblx0cmV0dXJuIGZvcm1hdFJldHVyblZhbHVlKHRoaXMua2V5cy5nZXRQcml2YXRlKCksIGVuYyk7XG59O1xuXG5FQ0RILnByb3RvdHlwZS5zZXRQdWJsaWNLZXkgPSBmdW5jdGlvbiAocHViLCBlbmMpIHtcblx0ZW5jID0gZW5jIHx8ICd1dGY4Jztcblx0aWYgKCFCdWZmZXIuaXNCdWZmZXIocHViKSkge1xuXHRcdHB1YiA9IG5ldyBCdWZmZXIocHViLCBlbmMpO1xuXHR9XG5cdHRoaXMua2V5cy5faW1wb3J0UHVibGljKHB1Yik7XG5cdHJldHVybiB0aGlzO1xufTtcblxuRUNESC5wcm90b3R5cGUuc2V0UHJpdmF0ZUtleSA9IGZ1bmN0aW9uIChwcml2LCBlbmMpIHtcblx0ZW5jID0gZW5jIHx8ICd1dGY4Jztcblx0aWYgKCFCdWZmZXIuaXNCdWZmZXIocHJpdikpIHtcblx0XHRwcml2ID0gbmV3IEJ1ZmZlcihwcml2LCBlbmMpO1xuXHR9XG5cdHZhciBfcHJpdiA9IG5ldyBCTihwcml2KTtcblx0X3ByaXYgPSBfcHJpdi50b1N0cmluZygxNik7XG5cdHRoaXMua2V5cy5faW1wb3J0UHJpdmF0ZShfcHJpdik7XG5cdHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gZm9ybWF0UmV0dXJuVmFsdWUoYm4sIGVuYywgbGVuKSB7XG5cdGlmICghQXJyYXkuaXNBcnJheShibikpIHtcblx0XHRibiA9IGJuLnRvQXJyYXkoKTtcblx0fVxuXHR2YXIgYnVmID0gbmV3IEJ1ZmZlcihibik7XG5cdGlmIChsZW4gJiYgYnVmLmxlbmd0aCA8IGxlbikge1xuXHRcdHZhciB6ZXJvcyA9IG5ldyBCdWZmZXIobGVuIC0gYnVmLmxlbmd0aCk7XG5cdFx0emVyb3MuZmlsbCgwKTtcblx0XHRidWYgPSBCdWZmZXIuY29uY2F0KFt6ZXJvcywgYnVmXSk7XG5cdH1cblx0aWYgKCFlbmMpIHtcblx0XHRyZXR1cm4gYnVmO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBidWYudG9TdHJpbmcoZW5jKTtcblx0fVxufVxuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIG1kNSA9IHJlcXVpcmUoJy4vbWQ1JylcbnZhciBybWQxNjAgPSByZXF1aXJlKCdyaXBlbWQxNjAnKVxudmFyIHNoYSA9IHJlcXVpcmUoJ3NoYS5qcycpXG5cbnZhciBCYXNlID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxuXG5mdW5jdGlvbiBIYXNoTm9Db25zdHJ1Y3RvcihoYXNoKSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnZGlnZXN0JylcblxuICB0aGlzLl9oYXNoID0gaGFzaFxuICB0aGlzLmJ1ZmZlcnMgPSBbXVxufVxuXG5pbmhlcml0cyhIYXNoTm9Db25zdHJ1Y3RvciwgQmFzZSlcblxuSGFzaE5vQ29uc3RydWN0b3IucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB0aGlzLmJ1ZmZlcnMucHVzaChkYXRhKVxufVxuXG5IYXNoTm9Db25zdHJ1Y3Rvci5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICB2YXIgYnVmID0gQnVmZmVyLmNvbmNhdCh0aGlzLmJ1ZmZlcnMpXG4gIHZhciByID0gdGhpcy5faGFzaChidWYpXG4gIHRoaXMuYnVmZmVycyA9IG51bGxcblxuICByZXR1cm4gclxufVxuXG5mdW5jdGlvbiBIYXNoKGhhc2gpIHtcbiAgQmFzZS5jYWxsKHRoaXMsICdkaWdlc3QnKVxuXG4gIHRoaXMuX2hhc2ggPSBoYXNoXG59XG5cbmluaGVyaXRzKEhhc2gsIEJhc2UpXG5cbkhhc2gucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB0aGlzLl9oYXNoLnVwZGF0ZShkYXRhKVxufVxuXG5IYXNoLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLl9oYXNoLmRpZ2VzdCgpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY3JlYXRlSGFzaCAoYWxnKSB7XG4gIGFsZyA9IGFsZy50b0xvd2VyQ2FzZSgpXG4gIGlmICgnbWQ1JyA9PT0gYWxnKSByZXR1cm4gbmV3IEhhc2hOb0NvbnN0cnVjdG9yKG1kNSlcbiAgaWYgKCdybWQxNjAnID09PSBhbGcgfHwgJ3JpcGVtZDE2MCcgPT09IGFsZykgcmV0dXJuIG5ldyBIYXNoTm9Db25zdHJ1Y3RvcihybWQxNjApXG5cbiAgcmV0dXJuIG5ldyBIYXNoKHNoYShhbGcpKVxufVxuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGludFNpemUgPSA0O1xudmFyIHplcm9CdWZmZXIgPSBuZXcgQnVmZmVyKGludFNpemUpOyB6ZXJvQnVmZmVyLmZpbGwoMCk7XG52YXIgY2hyc3ogPSA4O1xuXG5mdW5jdGlvbiB0b0FycmF5KGJ1ZiwgYmlnRW5kaWFuKSB7XG4gIGlmICgoYnVmLmxlbmd0aCAlIGludFNpemUpICE9PSAwKSB7XG4gICAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGggKyAoaW50U2l6ZSAtIChidWYubGVuZ3RoICUgaW50U2l6ZSkpO1xuICAgIGJ1ZiA9IEJ1ZmZlci5jb25jYXQoW2J1ZiwgemVyb0J1ZmZlcl0sIGxlbik7XG4gIH1cblxuICB2YXIgYXJyID0gW107XG4gIHZhciBmbiA9IGJpZ0VuZGlhbiA/IGJ1Zi5yZWFkSW50MzJCRSA6IGJ1Zi5yZWFkSW50MzJMRTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBidWYubGVuZ3RoOyBpICs9IGludFNpemUpIHtcbiAgICBhcnIucHVzaChmbi5jYWxsKGJ1ZiwgaSkpO1xuICB9XG4gIHJldHVybiBhcnI7XG59XG5cbmZ1bmN0aW9uIHRvQnVmZmVyKGFyciwgc2l6ZSwgYmlnRW5kaWFuKSB7XG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKHNpemUpO1xuICB2YXIgZm4gPSBiaWdFbmRpYW4gPyBidWYud3JpdGVJbnQzMkJFIDogYnVmLndyaXRlSW50MzJMRTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICBmbi5jYWxsKGJ1ZiwgYXJyW2ldLCBpICogNCwgdHJ1ZSk7XG4gIH1cbiAgcmV0dXJuIGJ1Zjtcbn1cblxuZnVuY3Rpb24gaGFzaChidWYsIGZuLCBoYXNoU2l6ZSwgYmlnRW5kaWFuKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIGJ1ZiA9IG5ldyBCdWZmZXIoYnVmKTtcbiAgdmFyIGFyciA9IGZuKHRvQXJyYXkoYnVmLCBiaWdFbmRpYW4pLCBidWYubGVuZ3RoICogY2hyc3opO1xuICByZXR1cm4gdG9CdWZmZXIoYXJyLCBoYXNoU2l6ZSwgYmlnRW5kaWFuKTtcbn1cbmV4cG9ydHMuaGFzaCA9IGhhc2g7IiwiJ3VzZSBzdHJpY3QnO1xuLypcbiAqIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgUlNBIERhdGEgU2VjdXJpdHksIEluYy4gTUQ1IE1lc3NhZ2VcbiAqIERpZ2VzdCBBbGdvcml0aG0sIGFzIGRlZmluZWQgaW4gUkZDIDEzMjEuXG4gKiBWZXJzaW9uIDIuMSBDb3B5cmlnaHQgKEMpIFBhdWwgSm9obnN0b24gMTk5OSAtIDIwMDIuXG4gKiBPdGhlciBjb250cmlidXRvcnM6IEdyZWcgSG9sdCwgQW5kcmV3IEtlcGVydCwgWWRuYXIsIExvc3RpbmV0XG4gKiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQlNEIExpY2Vuc2VcbiAqIFNlZSBodHRwOi8vcGFqaG9tZS5vcmcudWsvY3J5cHQvbWQ1IGZvciBtb3JlIGluZm8uXG4gKi9cblxudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKTtcblxuLypcbiAqIENhbGN1bGF0ZSB0aGUgTUQ1IG9mIGFuIGFycmF5IG9mIGxpdHRsZS1lbmRpYW4gd29yZHMsIGFuZCBhIGJpdCBsZW5ndGhcbiAqL1xuZnVuY3Rpb24gY29yZV9tZDUoeCwgbGVuKVxue1xuICAvKiBhcHBlbmQgcGFkZGluZyAqL1xuICB4W2xlbiA+PiA1XSB8PSAweDgwIDw8ICgobGVuKSAlIDMyKTtcbiAgeFsoKChsZW4gKyA2NCkgPj4+IDkpIDw8IDQpICsgMTRdID0gbGVuO1xuXG4gIHZhciBhID0gIDE3MzI1ODQxOTM7XG4gIHZhciBiID0gLTI3MTczMzg3OTtcbiAgdmFyIGMgPSAtMTczMjU4NDE5NDtcbiAgdmFyIGQgPSAgMjcxNzMzODc4O1xuXG4gIGZvcih2YXIgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSArPSAxNilcbiAge1xuICAgIHZhciBvbGRhID0gYTtcbiAgICB2YXIgb2xkYiA9IGI7XG4gICAgdmFyIG9sZGMgPSBjO1xuICAgIHZhciBvbGRkID0gZDtcblxuICAgIGEgPSBtZDVfZmYoYSwgYiwgYywgZCwgeFtpKyAwXSwgNyAsIC02ODA4NzY5MzYpO1xuICAgIGQgPSBtZDVfZmYoZCwgYSwgYiwgYywgeFtpKyAxXSwgMTIsIC0zODk1NjQ1ODYpO1xuICAgIGMgPSBtZDVfZmYoYywgZCwgYSwgYiwgeFtpKyAyXSwgMTcsICA2MDYxMDU4MTkpO1xuICAgIGIgPSBtZDVfZmYoYiwgYywgZCwgYSwgeFtpKyAzXSwgMjIsIC0xMDQ0NTI1MzMwKTtcbiAgICBhID0gbWQ1X2ZmKGEsIGIsIGMsIGQsIHhbaSsgNF0sIDcgLCAtMTc2NDE4ODk3KTtcbiAgICBkID0gbWQ1X2ZmKGQsIGEsIGIsIGMsIHhbaSsgNV0sIDEyLCAgMTIwMDA4MDQyNik7XG4gICAgYyA9IG1kNV9mZihjLCBkLCBhLCBiLCB4W2krIDZdLCAxNywgLTE0NzMyMzEzNDEpO1xuICAgIGIgPSBtZDVfZmYoYiwgYywgZCwgYSwgeFtpKyA3XSwgMjIsIC00NTcwNTk4Myk7XG4gICAgYSA9IG1kNV9mZihhLCBiLCBjLCBkLCB4W2krIDhdLCA3ICwgIDE3NzAwMzU0MTYpO1xuICAgIGQgPSBtZDVfZmYoZCwgYSwgYiwgYywgeFtpKyA5XSwgMTIsIC0xOTU4NDE0NDE3KTtcbiAgICBjID0gbWQ1X2ZmKGMsIGQsIGEsIGIsIHhbaSsxMF0sIDE3LCAtNDIwNjMpO1xuICAgIGIgPSBtZDVfZmYoYiwgYywgZCwgYSwgeFtpKzExXSwgMjIsIC0xOTkwNDA0MTYyKTtcbiAgICBhID0gbWQ1X2ZmKGEsIGIsIGMsIGQsIHhbaSsxMl0sIDcgLCAgMTgwNDYwMzY4Mik7XG4gICAgZCA9IG1kNV9mZihkLCBhLCBiLCBjLCB4W2krMTNdLCAxMiwgLTQwMzQxMTAxKTtcbiAgICBjID0gbWQ1X2ZmKGMsIGQsIGEsIGIsIHhbaSsxNF0sIDE3LCAtMTUwMjAwMjI5MCk7XG4gICAgYiA9IG1kNV9mZihiLCBjLCBkLCBhLCB4W2krMTVdLCAyMiwgIDEyMzY1MzUzMjkpO1xuXG4gICAgYSA9IG1kNV9nZyhhLCBiLCBjLCBkLCB4W2krIDFdLCA1ICwgLTE2NTc5NjUxMCk7XG4gICAgZCA9IG1kNV9nZyhkLCBhLCBiLCBjLCB4W2krIDZdLCA5ICwgLTEwNjk1MDE2MzIpO1xuICAgIGMgPSBtZDVfZ2coYywgZCwgYSwgYiwgeFtpKzExXSwgMTQsICA2NDM3MTc3MTMpO1xuICAgIGIgPSBtZDVfZ2coYiwgYywgZCwgYSwgeFtpKyAwXSwgMjAsIC0zNzM4OTczMDIpO1xuICAgIGEgPSBtZDVfZ2coYSwgYiwgYywgZCwgeFtpKyA1XSwgNSAsIC03MDE1NTg2OTEpO1xuICAgIGQgPSBtZDVfZ2coZCwgYSwgYiwgYywgeFtpKzEwXSwgOSAsICAzODAxNjA4Myk7XG4gICAgYyA9IG1kNV9nZyhjLCBkLCBhLCBiLCB4W2krMTVdLCAxNCwgLTY2MDQ3ODMzNSk7XG4gICAgYiA9IG1kNV9nZyhiLCBjLCBkLCBhLCB4W2krIDRdLCAyMCwgLTQwNTUzNzg0OCk7XG4gICAgYSA9IG1kNV9nZyhhLCBiLCBjLCBkLCB4W2krIDldLCA1ICwgIDU2ODQ0NjQzOCk7XG4gICAgZCA9IG1kNV9nZyhkLCBhLCBiLCBjLCB4W2krMTRdLCA5ICwgLTEwMTk4MDM2OTApO1xuICAgIGMgPSBtZDVfZ2coYywgZCwgYSwgYiwgeFtpKyAzXSwgMTQsIC0xODczNjM5NjEpO1xuICAgIGIgPSBtZDVfZ2coYiwgYywgZCwgYSwgeFtpKyA4XSwgMjAsICAxMTYzNTMxNTAxKTtcbiAgICBhID0gbWQ1X2dnKGEsIGIsIGMsIGQsIHhbaSsxM10sIDUgLCAtMTQ0NDY4MTQ2Nyk7XG4gICAgZCA9IG1kNV9nZyhkLCBhLCBiLCBjLCB4W2krIDJdLCA5ICwgLTUxNDAzNzg0KTtcbiAgICBjID0gbWQ1X2dnKGMsIGQsIGEsIGIsIHhbaSsgN10sIDE0LCAgMTczNTMyODQ3Myk7XG4gICAgYiA9IG1kNV9nZyhiLCBjLCBkLCBhLCB4W2krMTJdLCAyMCwgLTE5MjY2MDc3MzQpO1xuXG4gICAgYSA9IG1kNV9oaChhLCBiLCBjLCBkLCB4W2krIDVdLCA0ICwgLTM3ODU1OCk7XG4gICAgZCA9IG1kNV9oaChkLCBhLCBiLCBjLCB4W2krIDhdLCAxMSwgLTIwMjI1NzQ0NjMpO1xuICAgIGMgPSBtZDVfaGgoYywgZCwgYSwgYiwgeFtpKzExXSwgMTYsICAxODM5MDMwNTYyKTtcbiAgICBiID0gbWQ1X2hoKGIsIGMsIGQsIGEsIHhbaSsxNF0sIDIzLCAtMzUzMDk1NTYpO1xuICAgIGEgPSBtZDVfaGgoYSwgYiwgYywgZCwgeFtpKyAxXSwgNCAsIC0xNTMwOTkyMDYwKTtcbiAgICBkID0gbWQ1X2hoKGQsIGEsIGIsIGMsIHhbaSsgNF0sIDExLCAgMTI3Mjg5MzM1Myk7XG4gICAgYyA9IG1kNV9oaChjLCBkLCBhLCBiLCB4W2krIDddLCAxNiwgLTE1NTQ5NzYzMik7XG4gICAgYiA9IG1kNV9oaChiLCBjLCBkLCBhLCB4W2krMTBdLCAyMywgLTEwOTQ3MzA2NDApO1xuICAgIGEgPSBtZDVfaGgoYSwgYiwgYywgZCwgeFtpKzEzXSwgNCAsICA2ODEyNzkxNzQpO1xuICAgIGQgPSBtZDVfaGgoZCwgYSwgYiwgYywgeFtpKyAwXSwgMTEsIC0zNTg1MzcyMjIpO1xuICAgIGMgPSBtZDVfaGgoYywgZCwgYSwgYiwgeFtpKyAzXSwgMTYsIC03MjI1MjE5NzkpO1xuICAgIGIgPSBtZDVfaGgoYiwgYywgZCwgYSwgeFtpKyA2XSwgMjMsICA3NjAyOTE4OSk7XG4gICAgYSA9IG1kNV9oaChhLCBiLCBjLCBkLCB4W2krIDldLCA0ICwgLTY0MDM2NDQ4Nyk7XG4gICAgZCA9IG1kNV9oaChkLCBhLCBiLCBjLCB4W2krMTJdLCAxMSwgLTQyMTgxNTgzNSk7XG4gICAgYyA9IG1kNV9oaChjLCBkLCBhLCBiLCB4W2krMTVdLCAxNiwgIDUzMDc0MjUyMCk7XG4gICAgYiA9IG1kNV9oaChiLCBjLCBkLCBhLCB4W2krIDJdLCAyMywgLTk5NTMzODY1MSk7XG5cbiAgICBhID0gbWQ1X2lpKGEsIGIsIGMsIGQsIHhbaSsgMF0sIDYgLCAtMTk4NjMwODQ0KTtcbiAgICBkID0gbWQ1X2lpKGQsIGEsIGIsIGMsIHhbaSsgN10sIDEwLCAgMTEyNjg5MTQxNSk7XG4gICAgYyA9IG1kNV9paShjLCBkLCBhLCBiLCB4W2krMTRdLCAxNSwgLTE0MTYzNTQ5MDUpO1xuICAgIGIgPSBtZDVfaWkoYiwgYywgZCwgYSwgeFtpKyA1XSwgMjEsIC01NzQzNDA1NSk7XG4gICAgYSA9IG1kNV9paShhLCBiLCBjLCBkLCB4W2krMTJdLCA2ICwgIDE3MDA0ODU1NzEpO1xuICAgIGQgPSBtZDVfaWkoZCwgYSwgYiwgYywgeFtpKyAzXSwgMTAsIC0xODk0OTg2NjA2KTtcbiAgICBjID0gbWQ1X2lpKGMsIGQsIGEsIGIsIHhbaSsxMF0sIDE1LCAtMTA1MTUyMyk7XG4gICAgYiA9IG1kNV9paShiLCBjLCBkLCBhLCB4W2krIDFdLCAyMSwgLTIwNTQ5MjI3OTkpO1xuICAgIGEgPSBtZDVfaWkoYSwgYiwgYywgZCwgeFtpKyA4XSwgNiAsICAxODczMzEzMzU5KTtcbiAgICBkID0gbWQ1X2lpKGQsIGEsIGIsIGMsIHhbaSsxNV0sIDEwLCAtMzA2MTE3NDQpO1xuICAgIGMgPSBtZDVfaWkoYywgZCwgYSwgYiwgeFtpKyA2XSwgMTUsIC0xNTYwMTk4MzgwKTtcbiAgICBiID0gbWQ1X2lpKGIsIGMsIGQsIGEsIHhbaSsxM10sIDIxLCAgMTMwOTE1MTY0OSk7XG4gICAgYSA9IG1kNV9paShhLCBiLCBjLCBkLCB4W2krIDRdLCA2ICwgLTE0NTUyMzA3MCk7XG4gICAgZCA9IG1kNV9paShkLCBhLCBiLCBjLCB4W2krMTFdLCAxMCwgLTExMjAyMTAzNzkpO1xuICAgIGMgPSBtZDVfaWkoYywgZCwgYSwgYiwgeFtpKyAyXSwgMTUsICA3MTg3ODcyNTkpO1xuICAgIGIgPSBtZDVfaWkoYiwgYywgZCwgYSwgeFtpKyA5XSwgMjEsIC0zNDM0ODU1NTEpO1xuXG4gICAgYSA9IHNhZmVfYWRkKGEsIG9sZGEpO1xuICAgIGIgPSBzYWZlX2FkZChiLCBvbGRiKTtcbiAgICBjID0gc2FmZV9hZGQoYywgb2xkYyk7XG4gICAgZCA9IHNhZmVfYWRkKGQsIG9sZGQpO1xuICB9XG4gIHJldHVybiBBcnJheShhLCBiLCBjLCBkKTtcblxufVxuXG4vKlxuICogVGhlc2UgZnVuY3Rpb25zIGltcGxlbWVudCB0aGUgZm91ciBiYXNpYyBvcGVyYXRpb25zIHRoZSBhbGdvcml0aG0gdXNlcy5cbiAqL1xuZnVuY3Rpb24gbWQ1X2NtbihxLCBhLCBiLCB4LCBzLCB0KVxue1xuICByZXR1cm4gc2FmZV9hZGQoYml0X3JvbChzYWZlX2FkZChzYWZlX2FkZChhLCBxKSwgc2FmZV9hZGQoeCwgdCkpLCBzKSxiKTtcbn1cbmZ1bmN0aW9uIG1kNV9mZihhLCBiLCBjLCBkLCB4LCBzLCB0KVxue1xuICByZXR1cm4gbWQ1X2NtbigoYiAmIGMpIHwgKCh+YikgJiBkKSwgYSwgYiwgeCwgcywgdCk7XG59XG5mdW5jdGlvbiBtZDVfZ2coYSwgYiwgYywgZCwgeCwgcywgdClcbntcbiAgcmV0dXJuIG1kNV9jbW4oKGIgJiBkKSB8IChjICYgKH5kKSksIGEsIGIsIHgsIHMsIHQpO1xufVxuZnVuY3Rpb24gbWQ1X2hoKGEsIGIsIGMsIGQsIHgsIHMsIHQpXG57XG4gIHJldHVybiBtZDVfY21uKGIgXiBjIF4gZCwgYSwgYiwgeCwgcywgdCk7XG59XG5mdW5jdGlvbiBtZDVfaWkoYSwgYiwgYywgZCwgeCwgcywgdClcbntcbiAgcmV0dXJuIG1kNV9jbW4oYyBeIChiIHwgKH5kKSksIGEsIGIsIHgsIHMsIHQpO1xufVxuXG4vKlxuICogQWRkIGludGVnZXJzLCB3cmFwcGluZyBhdCAyXjMyLiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnMgaW50ZXJuYWxseVxuICogdG8gd29yayBhcm91bmQgYnVncyBpbiBzb21lIEpTIGludGVycHJldGVycy5cbiAqL1xuZnVuY3Rpb24gc2FmZV9hZGQoeCwgeSlcbntcbiAgdmFyIGxzdyA9ICh4ICYgMHhGRkZGKSArICh5ICYgMHhGRkZGKTtcbiAgdmFyIG1zdyA9ICh4ID4+IDE2KSArICh5ID4+IDE2KSArIChsc3cgPj4gMTYpO1xuICByZXR1cm4gKG1zdyA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcbn1cblxuLypcbiAqIEJpdHdpc2Ugcm90YXRlIGEgMzItYml0IG51bWJlciB0byB0aGUgbGVmdC5cbiAqL1xuZnVuY3Rpb24gYml0X3JvbChudW0sIGNudClcbntcbiAgcmV0dXJuIChudW0gPDwgY250KSB8IChudW0gPj4+ICgzMiAtIGNudCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIG1kNShidWYpIHtcbiAgcmV0dXJuIGhlbHBlcnMuaGFzaChidWYsIGNvcmVfbWQ1LCAxNik7XG59OyIsInZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdzdHJlYW0nKS5UcmFuc2Zvcm1cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXInKS5TdHJpbmdEZWNvZGVyXG5tb2R1bGUuZXhwb3J0cyA9IENpcGhlckJhc2VcbmluaGVyaXRzKENpcGhlckJhc2UsIFRyYW5zZm9ybSlcbmZ1bmN0aW9uIENpcGhlckJhc2UgKGhhc2hNb2RlKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG4gIHRoaXMuaGFzaE1vZGUgPSB0eXBlb2YgaGFzaE1vZGUgPT09ICdzdHJpbmcnXG4gIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgdGhpc1toYXNoTW9kZV0gPSB0aGlzLl9maW5hbE9yRGlnZXN0XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5maW5hbCA9IHRoaXMuX2ZpbmFsT3JEaWdlc3RcbiAgfVxuICB0aGlzLl9kZWNvZGVyID0gbnVsbFxuICB0aGlzLl9lbmNvZGluZyA9IG51bGxcbn1cbkNpcGhlckJhc2UucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhLCBpbnB1dEVuYywgb3V0cHV0RW5jKSB7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICBkYXRhID0gbmV3IEJ1ZmZlcihkYXRhLCBpbnB1dEVuYylcbiAgfVxuICB2YXIgb3V0RGF0YSA9IHRoaXMuX3VwZGF0ZShkYXRhKVxuICBpZiAodGhpcy5oYXNoTW9kZSkge1xuICAgIHJldHVybiB0aGlzXG4gIH1cbiAgaWYgKG91dHB1dEVuYykge1xuICAgIG91dERhdGEgPSB0aGlzLl90b1N0cmluZyhvdXREYXRhLCBvdXRwdXRFbmMpXG4gIH1cbiAgcmV0dXJuIG91dERhdGFcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuc2V0QXV0b1BhZGRpbmcgPSBmdW5jdGlvbiAoKSB7fVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5nZXRBdXRoVGFnID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3RyeWluZyB0byBnZXQgYXV0aCB0YWcgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBdXRoVGFnID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3RyeWluZyB0byBzZXQgYXV0aCB0YWcgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBQUQgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIHNldCBhYWQgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24gKGRhdGEsIF8sIG5leHQpIHtcbiAgdmFyIGVyclxuICB0cnkge1xuICAgIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgICB0aGlzLl91cGRhdGUoZGF0YSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wdXNoKHRoaXMuX3VwZGF0ZShkYXRhKSlcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBlcnIgPSBlXG4gIH0gZmluYWxseSB7XG4gICAgbmV4dChlcnIpXG4gIH1cbn1cbkNpcGhlckJhc2UucHJvdG90eXBlLl9mbHVzaCA9IGZ1bmN0aW9uIChkb25lKSB7XG4gIHZhciBlcnJcbiAgdHJ5IHtcbiAgICB0aGlzLnB1c2godGhpcy5fZmluYWwoKSlcbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfSBmaW5hbGx5IHtcbiAgICBkb25lKGVycilcbiAgfVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZpbmFsT3JEaWdlc3QgPSBmdW5jdGlvbiAob3V0cHV0RW5jKSB7XG4gIHZhciBvdXREYXRhID0gdGhpcy5fZmluYWwoKSB8fCBuZXcgQnVmZmVyKCcnKVxuICBpZiAob3V0cHV0RW5jKSB7XG4gICAgb3V0RGF0YSA9IHRoaXMuX3RvU3RyaW5nKG91dERhdGEsIG91dHB1dEVuYywgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb3V0RGF0YVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fdG9TdHJpbmcgPSBmdW5jdGlvbiAodmFsdWUsIGVuYywgZmluYWwpIHtcbiAgaWYgKCF0aGlzLl9kZWNvZGVyKSB7XG4gICAgdGhpcy5fZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKGVuYylcbiAgICB0aGlzLl9lbmNvZGluZyA9IGVuY1xuICB9XG4gIGlmICh0aGlzLl9lbmNvZGluZyAhPT0gZW5jKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjYW5cXCd0IHN3aXRjaCBlbmNvZGluZ3MnKVxuICB9XG4gIHZhciBvdXQgPSB0aGlzLl9kZWNvZGVyLndyaXRlKHZhbHVlKVxuICBpZiAoZmluYWwpIHtcbiAgICBvdXQgKz0gdGhpcy5fZGVjb2Rlci5lbmQoKVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsIi8qXG5DcnlwdG9KUyB2My4xLjJcbmNvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qc1xuKGMpIDIwMDktMjAxMyBieSBKZWZmIE1vdHQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG5jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvd2lraS9MaWNlbnNlXG4qL1xuLyoqIEBwcmVzZXJ2ZVxuKGMpIDIwMTIgYnkgQ8OpZHJpYyBNZXNuaWwuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG5cblJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dCBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcblxuICAgIC0gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICAgIC0gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuXG5USElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG4vLyBjb25zdGFudHMgdGFibGVcbnZhciB6bCA9IFtcbiAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSxcbiAgNywgNCwgMTMsIDEsIDEwLCA2LCAxNSwgMywgMTIsIDAsIDksIDUsIDIsIDE0LCAxMSwgOCxcbiAgMywgMTAsIDE0LCA0LCA5LCAxNSwgOCwgMSwgMiwgNywgMCwgNiwgMTMsIDExLCA1LCAxMixcbiAgMSwgOSwgMTEsIDEwLCAwLCA4LCAxMiwgNCwgMTMsIDMsIDcsIDE1LCAxNCwgNSwgNiwgMixcbiAgNCwgMCwgNSwgOSwgNywgMTIsIDIsIDEwLCAxNCwgMSwgMywgOCwgMTEsIDYsIDE1LCAxM1xuXVxuXG52YXIgenIgPSBbXG4gIDUsIDE0LCA3LCAwLCA5LCAyLCAxMSwgNCwgMTMsIDYsIDE1LCA4LCAxLCAxMCwgMywgMTIsXG4gIDYsIDExLCAzLCA3LCAwLCAxMywgNSwgMTAsIDE0LCAxNSwgOCwgMTIsIDQsIDksIDEsIDIsXG4gIDE1LCA1LCAxLCAzLCA3LCAxNCwgNiwgOSwgMTEsIDgsIDEyLCAyLCAxMCwgMCwgNCwgMTMsXG4gIDgsIDYsIDQsIDEsIDMsIDExLCAxNSwgMCwgNSwgMTIsIDIsIDEzLCA5LCA3LCAxMCwgMTQsXG4gIDEyLCAxNSwgMTAsIDQsIDEsIDUsIDgsIDcsIDYsIDIsIDEzLCAxNCwgMCwgMywgOSwgMTFcbl1cblxudmFyIHNsID0gW1xuICAxMSwgMTQsIDE1LCAxMiwgNSwgOCwgNywgOSwgMTEsIDEzLCAxNCwgMTUsIDYsIDcsIDksIDgsXG4gIDcsIDYsIDgsIDEzLCAxMSwgOSwgNywgMTUsIDcsIDEyLCAxNSwgOSwgMTEsIDcsIDEzLCAxMixcbiAgMTEsIDEzLCA2LCA3LCAxNCwgOSwgMTMsIDE1LCAxNCwgOCwgMTMsIDYsIDUsIDEyLCA3LCA1LFxuICAxMSwgMTIsIDE0LCAxNSwgMTQsIDE1LCA5LCA4LCA5LCAxNCwgNSwgNiwgOCwgNiwgNSwgMTIsXG4gIDksIDE1LCA1LCAxMSwgNiwgOCwgMTMsIDEyLCA1LCAxMiwgMTMsIDE0LCAxMSwgOCwgNSwgNlxuXVxuXG52YXIgc3IgPSBbXG4gIDgsIDksIDksIDExLCAxMywgMTUsIDE1LCA1LCA3LCA3LCA4LCAxMSwgMTQsIDE0LCAxMiwgNixcbiAgOSwgMTMsIDE1LCA3LCAxMiwgOCwgOSwgMTEsIDcsIDcsIDEyLCA3LCA2LCAxNSwgMTMsIDExLFxuICA5LCA3LCAxNSwgMTEsIDgsIDYsIDYsIDE0LCAxMiwgMTMsIDUsIDE0LCAxMywgMTMsIDcsIDUsXG4gIDE1LCA1LCA4LCAxMSwgMTQsIDE0LCA2LCAxNCwgNiwgOSwgMTIsIDksIDEyLCA1LCAxNSwgOCxcbiAgOCwgNSwgMTIsIDksIDEyLCA1LCAxNCwgNiwgOCwgMTMsIDYsIDUsIDE1LCAxMywgMTEsIDExXG5dXG5cbnZhciBobCA9IFsweDAwMDAwMDAwLCAweDVBODI3OTk5LCAweDZFRDlFQkExLCAweDhGMUJCQ0RDLCAweEE5NTNGRDRFXVxudmFyIGhyID0gWzB4NTBBMjhCRTYsIDB4NUM0REQxMjQsIDB4NkQ3MDNFRjMsIDB4N0E2RDc2RTksIDB4MDAwMDAwMDBdXG5cbmZ1bmN0aW9uIGJ5dGVzVG9Xb3JkcyAoYnl0ZXMpIHtcbiAgdmFyIHdvcmRzID0gW11cbiAgZm9yICh2YXIgaSA9IDAsIGIgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpKyssIGIgKz0gOCkge1xuICAgIHdvcmRzW2IgPj4+IDVdIHw9IGJ5dGVzW2ldIDw8ICgyNCAtIGIgJSAzMilcbiAgfVxuICByZXR1cm4gd29yZHNcbn1cblxuZnVuY3Rpb24gd29yZHNUb0J5dGVzICh3b3Jkcykge1xuICB2YXIgYnl0ZXMgPSBbXVxuICBmb3IgKHZhciBiID0gMDsgYiA8IHdvcmRzLmxlbmd0aCAqIDMyOyBiICs9IDgpIHtcbiAgICBieXRlcy5wdXNoKCh3b3Jkc1tiID4+PiA1XSA+Pj4gKDI0IC0gYiAlIDMyKSkgJiAweEZGKVxuICB9XG4gIHJldHVybiBieXRlc1xufVxuXG5mdW5jdGlvbiBwcm9jZXNzQmxvY2sgKEgsIE0sIG9mZnNldCkge1xuICAvLyBzd2FwIGVuZGlhblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspIHtcbiAgICB2YXIgb2Zmc2V0X2kgPSBvZmZzZXQgKyBpXG4gICAgdmFyIE1fb2Zmc2V0X2kgPSBNW29mZnNldF9pXVxuXG4gICAgLy8gU3dhcFxuICAgIE1bb2Zmc2V0X2ldID0gKFxuICAgICAgKCgoTV9vZmZzZXRfaSA8PCA4KSB8IChNX29mZnNldF9pID4+PiAyNCkpICYgMHgwMGZmMDBmZikgfFxuICAgICAgKCgoTV9vZmZzZXRfaSA8PCAyNCkgfCAoTV9vZmZzZXRfaSA+Pj4gOCkpICYgMHhmZjAwZmYwMClcbiAgICApXG4gIH1cblxuICAvLyBXb3JraW5nIHZhcmlhYmxlc1xuICB2YXIgYWwsIGJsLCBjbCwgZGwsIGVsXG4gIHZhciBhciwgYnIsIGNyLCBkciwgZXJcblxuICBhciA9IGFsID0gSFswXVxuICBiciA9IGJsID0gSFsxXVxuICBjciA9IGNsID0gSFsyXVxuICBkciA9IGRsID0gSFszXVxuICBlciA9IGVsID0gSFs0XVxuXG4gIC8vIGNvbXB1dGF0aW9uXG4gIHZhciB0XG4gIGZvciAoaSA9IDA7IGkgPCA4MDsgaSArPSAxKSB7XG4gICAgdCA9IChhbCArIE1bb2Zmc2V0ICsgemxbaV1dKSB8IDBcbiAgICBpZiAoaSA8IDE2KSB7XG4gICAgICB0ICs9IGYxKGJsLCBjbCwgZGwpICsgaGxbMF1cbiAgICB9IGVsc2UgaWYgKGkgPCAzMikge1xuICAgICAgdCArPSBmMihibCwgY2wsIGRsKSArIGhsWzFdXG4gICAgfSBlbHNlIGlmIChpIDwgNDgpIHtcbiAgICAgIHQgKz0gZjMoYmwsIGNsLCBkbCkgKyBobFsyXVxuICAgIH0gZWxzZSBpZiAoaSA8IDY0KSB7XG4gICAgICB0ICs9IGY0KGJsLCBjbCwgZGwpICsgaGxbM11cbiAgICB9IGVsc2Ugey8vIGlmIChpPDgwKSB7XG4gICAgICB0ICs9IGY1KGJsLCBjbCwgZGwpICsgaGxbNF1cbiAgICB9XG4gICAgdCA9IHQgfCAwXG4gICAgdCA9IHJvdGwodCwgc2xbaV0pXG4gICAgdCA9ICh0ICsgZWwpIHwgMFxuICAgIGFsID0gZWxcbiAgICBlbCA9IGRsXG4gICAgZGwgPSByb3RsKGNsLCAxMClcbiAgICBjbCA9IGJsXG4gICAgYmwgPSB0XG5cbiAgICB0ID0gKGFyICsgTVtvZmZzZXQgKyB6cltpXV0pIHwgMFxuICAgIGlmIChpIDwgMTYpIHtcbiAgICAgIHQgKz0gZjUoYnIsIGNyLCBkcikgKyBoclswXVxuICAgIH0gZWxzZSBpZiAoaSA8IDMyKSB7XG4gICAgICB0ICs9IGY0KGJyLCBjciwgZHIpICsgaHJbMV1cbiAgICB9IGVsc2UgaWYgKGkgPCA0OCkge1xuICAgICAgdCArPSBmMyhiciwgY3IsIGRyKSArIGhyWzJdXG4gICAgfSBlbHNlIGlmIChpIDwgNjQpIHtcbiAgICAgIHQgKz0gZjIoYnIsIGNyLCBkcikgKyBoclszXVxuICAgIH0gZWxzZSB7Ly8gaWYgKGk8ODApIHtcbiAgICAgIHQgKz0gZjEoYnIsIGNyLCBkcikgKyBocls0XVxuICAgIH1cblxuICAgIHQgPSB0IHwgMFxuICAgIHQgPSByb3RsKHQsIHNyW2ldKVxuICAgIHQgPSAodCArIGVyKSB8IDBcbiAgICBhciA9IGVyXG4gICAgZXIgPSBkclxuICAgIGRyID0gcm90bChjciwgMTApXG4gICAgY3IgPSBiclxuICAgIGJyID0gdFxuICB9XG5cbiAgLy8gaW50ZXJtZWRpYXRlIGhhc2ggdmFsdWVcbiAgdCA9IChIWzFdICsgY2wgKyBkcikgfCAwXG4gIEhbMV0gPSAoSFsyXSArIGRsICsgZXIpIHwgMFxuICBIWzJdID0gKEhbM10gKyBlbCArIGFyKSB8IDBcbiAgSFszXSA9IChIWzRdICsgYWwgKyBicikgfCAwXG4gIEhbNF0gPSAoSFswXSArIGJsICsgY3IpIHwgMFxuICBIWzBdID0gdFxufVxuXG5mdW5jdGlvbiBmMSAoeCwgeSwgeikge1xuICByZXR1cm4gKCh4KSBeICh5KSBeICh6KSlcbn1cblxuZnVuY3Rpb24gZjIgKHgsIHksIHopIHtcbiAgcmV0dXJuICgoKHgpICYgKHkpKSB8ICgofngpICYgKHopKSlcbn1cblxuZnVuY3Rpb24gZjMgKHgsIHksIHopIHtcbiAgcmV0dXJuICgoKHgpIHwgKH4oeSkpKSBeICh6KSlcbn1cblxuZnVuY3Rpb24gZjQgKHgsIHksIHopIHtcbiAgcmV0dXJuICgoKHgpICYgKHopKSB8ICgoeSkgJiAofih6KSkpKVxufVxuXG5mdW5jdGlvbiBmNSAoeCwgeSwgeikge1xuICByZXR1cm4gKCh4KSBeICgoeSkgfCAofih6KSkpKVxufVxuXG5mdW5jdGlvbiByb3RsICh4LCBuKSB7XG4gIHJldHVybiAoeCA8PCBuKSB8ICh4ID4+PiAoMzIgLSBuKSlcbn1cblxuZnVuY3Rpb24gcmlwZW1kMTYwIChtZXNzYWdlKSB7XG4gIHZhciBIID0gWzB4Njc0NTIzMDEsIDB4RUZDREFCODksIDB4OThCQURDRkUsIDB4MTAzMjU0NzYsIDB4QzNEMkUxRjBdXG5cbiAgaWYgKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgIG1lc3NhZ2UgPSBuZXcgQnVmZmVyKG1lc3NhZ2UsICd1dGY4JylcbiAgfVxuXG4gIHZhciBtID0gYnl0ZXNUb1dvcmRzKG1lc3NhZ2UpXG5cbiAgdmFyIG5CaXRzTGVmdCA9IG1lc3NhZ2UubGVuZ3RoICogOFxuICB2YXIgbkJpdHNUb3RhbCA9IG1lc3NhZ2UubGVuZ3RoICogOFxuXG4gIC8vIEFkZCBwYWRkaW5nXG4gIG1bbkJpdHNMZWZ0ID4+PiA1XSB8PSAweDgwIDw8ICgyNCAtIG5CaXRzTGVmdCAlIDMyKVxuICBtWygoKG5CaXRzTGVmdCArIDY0KSA+Pj4gOSkgPDwgNCkgKyAxNF0gPSAoXG4gICAgKCgobkJpdHNUb3RhbCA8PCA4KSB8IChuQml0c1RvdGFsID4+PiAyNCkpICYgMHgwMGZmMDBmZikgfFxuICAgICgoKG5CaXRzVG90YWwgPDwgMjQpIHwgKG5CaXRzVG90YWwgPj4+IDgpKSAmIDB4ZmYwMGZmMDApXG4gIClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IG0ubGVuZ3RoOyBpICs9IDE2KSB7XG4gICAgcHJvY2Vzc0Jsb2NrKEgsIG0sIGkpXG4gIH1cblxuICAvLyBzd2FwIGVuZGlhblxuICBmb3IgKGkgPSAwOyBpIDwgNTsgaSsrKSB7XG4gICAgLy8gc2hvcnRjdXRcbiAgICB2YXIgSF9pID0gSFtpXVxuXG4gICAgLy8gU3dhcFxuICAgIEhbaV0gPSAoKChIX2kgPDwgOCkgfCAoSF9pID4+PiAyNCkpICYgMHgwMGZmMDBmZikgfFxuICAgICAgKCgoSF9pIDw8IDI0KSB8IChIX2kgPj4+IDgpKSAmIDB4ZmYwMGZmMDApXG4gIH1cblxuICB2YXIgZGlnZXN0Ynl0ZXMgPSB3b3Jkc1RvQnl0ZXMoSClcbiAgcmV0dXJuIG5ldyBCdWZmZXIoZGlnZXN0Ynl0ZXMpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gcmlwZW1kMTYwXG4iLCIvLyBwcm90b3R5cGUgY2xhc3MgZm9yIGhhc2ggZnVuY3Rpb25zXG5mdW5jdGlvbiBIYXNoIChibG9ja1NpemUsIGZpbmFsU2l6ZSkge1xuICB0aGlzLl9ibG9jayA9IG5ldyBCdWZmZXIoYmxvY2tTaXplKVxuICB0aGlzLl9maW5hbFNpemUgPSBmaW5hbFNpemVcbiAgdGhpcy5fYmxvY2tTaXplID0gYmxvY2tTaXplXG4gIHRoaXMuX2xlbiA9IDBcbiAgdGhpcy5fcyA9IDBcbn1cblxuSGFzaC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGVuYykge1xuICBpZiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jID0gZW5jIHx8ICd1dGY4J1xuICAgIGRhdGEgPSBuZXcgQnVmZmVyKGRhdGEsIGVuYylcbiAgfVxuXG4gIHZhciBsID0gdGhpcy5fbGVuICs9IGRhdGEubGVuZ3RoXG4gIHZhciBzID0gdGhpcy5fcyB8fCAwXG4gIHZhciBmID0gMFxuICB2YXIgYnVmZmVyID0gdGhpcy5fYmxvY2tcblxuICB3aGlsZSAocyA8IGwpIHtcbiAgICB2YXIgdCA9IE1hdGgubWluKGRhdGEubGVuZ3RoLCBmICsgdGhpcy5fYmxvY2tTaXplIC0gKHMgJSB0aGlzLl9ibG9ja1NpemUpKVxuICAgIHZhciBjaCA9ICh0IC0gZilcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2g7IGkrKykge1xuICAgICAgYnVmZmVyWyhzICUgdGhpcy5fYmxvY2tTaXplKSArIGldID0gZGF0YVtpICsgZl1cbiAgICB9XG5cbiAgICBzICs9IGNoXG4gICAgZiArPSBjaFxuXG4gICAgaWYgKChzICUgdGhpcy5fYmxvY2tTaXplKSA9PT0gMCkge1xuICAgICAgdGhpcy5fdXBkYXRlKGJ1ZmZlcilcbiAgICB9XG4gIH1cbiAgdGhpcy5fcyA9IHNcblxuICByZXR1cm4gdGhpc1xufVxuXG5IYXNoLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiAoZW5jKSB7XG4gIC8vIFN1cHBvc2UgdGhlIGxlbmd0aCBvZiB0aGUgbWVzc2FnZSBNLCBpbiBiaXRzLCBpcyBsXG4gIHZhciBsID0gdGhpcy5fbGVuICogOFxuXG4gIC8vIEFwcGVuZCB0aGUgYml0IDEgdG8gdGhlIGVuZCBvZiB0aGUgbWVzc2FnZVxuICB0aGlzLl9ibG9ja1t0aGlzLl9sZW4gJSB0aGlzLl9ibG9ja1NpemVdID0gMHg4MFxuXG4gIC8vIGFuZCB0aGVuIGsgemVybyBiaXRzLCB3aGVyZSBrIGlzIHRoZSBzbWFsbGVzdCBub24tbmVnYXRpdmUgc29sdXRpb24gdG8gdGhlIGVxdWF0aW9uIChsICsgMSArIGspID09PSBmaW5hbFNpemUgbW9kIGJsb2NrU2l6ZVxuICB0aGlzLl9ibG9jay5maWxsKDAsIHRoaXMuX2xlbiAlIHRoaXMuX2Jsb2NrU2l6ZSArIDEpXG5cbiAgaWYgKGwgJSAodGhpcy5fYmxvY2tTaXplICogOCkgPj0gdGhpcy5fZmluYWxTaXplICogOCkge1xuICAgIHRoaXMuX3VwZGF0ZSh0aGlzLl9ibG9jaylcbiAgICB0aGlzLl9ibG9jay5maWxsKDApXG4gIH1cblxuICAvLyB0byB0aGlzIGFwcGVuZCB0aGUgYmxvY2sgd2hpY2ggaXMgZXF1YWwgdG8gdGhlIG51bWJlciBsIHdyaXR0ZW4gaW4gYmluYXJ5XG4gIC8vIFRPRE86IGhhbmRsZSBjYXNlIHdoZXJlIGwgaXMgPiBNYXRoLnBvdygyLCAyOSlcbiAgdGhpcy5fYmxvY2sud3JpdGVJbnQzMkJFKGwsIHRoaXMuX2Jsb2NrU2l6ZSAtIDQpXG5cbiAgdmFyIGhhc2ggPSB0aGlzLl91cGRhdGUodGhpcy5fYmxvY2spIHx8IHRoaXMuX2hhc2goKVxuXG4gIHJldHVybiBlbmMgPyBoYXNoLnRvU3RyaW5nKGVuYykgOiBoYXNoXG59XG5cbkhhc2gucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcignX3VwZGF0ZSBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IHN1YmNsYXNzJylcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBIYXNoXG4iLCJ2YXIgZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gU0hBIChhbGdvcml0aG0pIHtcbiAgYWxnb3JpdGhtID0gYWxnb3JpdGhtLnRvTG93ZXJDYXNlKClcblxuICB2YXIgQWxnb3JpdGhtID0gZXhwb3J0c1thbGdvcml0aG1dXG4gIGlmICghQWxnb3JpdGhtKSB0aHJvdyBuZXcgRXJyb3IoYWxnb3JpdGhtICsgJyBpcyBub3Qgc3VwcG9ydGVkICh3ZSBhY2NlcHQgcHVsbCByZXF1ZXN0cyknKVxuXG4gIHJldHVybiBuZXcgQWxnb3JpdGhtKClcbn1cblxuZXhwb3J0cy5zaGEgPSByZXF1aXJlKCcuL3NoYScpXG5leHBvcnRzLnNoYTEgPSByZXF1aXJlKCcuL3NoYTEnKVxuZXhwb3J0cy5zaGEyMjQgPSByZXF1aXJlKCcuL3NoYTIyNCcpXG5leHBvcnRzLnNoYTI1NiA9IHJlcXVpcmUoJy4vc2hhMjU2JylcbmV4cG9ydHMuc2hhMzg0ID0gcmVxdWlyZSgnLi9zaGEzODQnKVxuZXhwb3J0cy5zaGE1MTIgPSByZXF1aXJlKCcuL3NoYTUxMicpXG4iLCIvKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0wLCBhcyBkZWZpbmVkXG4gKiBpbiBGSVBTIFBVQiAxODAtMVxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBkZXJpdmVkIGZyb20gc2hhMS5qcyBvZiB0aGUgc2FtZSByZXBvc2l0b3J5LlxuICogVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBTSEEtMCBhbmQgU0hBLTEgaXMganVzdCBhIGJpdHdpc2Ugcm90YXRlIGxlZnRcbiAqIG9wZXJhdGlvbiB3YXMgYWRkZWQuXG4gKi9cblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKVxuXG52YXIgVyA9IG5ldyBBcnJheSg4MClcblxuZnVuY3Rpb24gU2hhICgpIHtcbiAgdGhpcy5pbml0KClcbiAgdGhpcy5fdyA9IFdcblxuICBIYXNoLmNhbGwodGhpcywgNjQsIDU2KVxufVxuXG5pbmhlcml0cyhTaGEsIEhhc2gpXG5cblNoYS5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fYSA9IDB4Njc0NTIzMDEgfCAwXG4gIHRoaXMuX2IgPSAweGVmY2RhYjg5IHwgMFxuICB0aGlzLl9jID0gMHg5OGJhZGNmZSB8IDBcbiAgdGhpcy5fZCA9IDB4MTAzMjU0NzYgfCAwXG4gIHRoaXMuX2UgPSAweGMzZDJlMWYwIHwgMFxuXG4gIHJldHVybiB0aGlzXG59XG5cbi8qXG4gKiBCaXR3aXNlIHJvdGF0ZSBhIDMyLWJpdCBudW1iZXIgdG8gdGhlIGxlZnQuXG4gKi9cbmZ1bmN0aW9uIHJvbCAobnVtLCBjbnQpIHtcbiAgcmV0dXJuIChudW0gPDwgY250KSB8IChudW0gPj4+ICgzMiAtIGNudCkpXG59XG5cblNoYS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChNKSB7XG4gIHZhciBXID0gdGhpcy5fd1xuXG4gIHZhciBhID0gdGhpcy5fYVxuICB2YXIgYiA9IHRoaXMuX2JcbiAgdmFyIGMgPSB0aGlzLl9jXG4gIHZhciBkID0gdGhpcy5fZFxuICB2YXIgZSA9IHRoaXMuX2VcblxuICB2YXIgaiA9IDBcbiAgdmFyIGtcblxuICAvKlxuICAgKiBTSEEtMSBoYXMgYSBiaXR3aXNlIHJvdGF0ZSBsZWZ0IG9wZXJhdGlvbi4gQnV0LCBTSEEgaXMgbm90XG4gICAqIGZ1bmN0aW9uIGNhbGNXKCkgeyByZXR1cm4gcm9sKFdbaiAtIDNdIF4gV1tqIC0gIDhdIF4gV1tqIC0gMTRdIF4gV1tqIC0gMTZdLCAxKSB9XG4gICAqL1xuICBmdW5jdGlvbiBjYWxjVyAoKSB7IHJldHVybiBXW2ogLSAzXSBeIFdbaiAtIDhdIF4gV1tqIC0gMTRdIF4gV1tqIC0gMTZdIH1cbiAgZnVuY3Rpb24gbG9vcCAodywgZikge1xuICAgIFdbal0gPSB3XG5cbiAgICB2YXIgdCA9IHJvbChhLCA1KSArIGYgKyBlICsgdyArIGtcblxuICAgIGUgPSBkXG4gICAgZCA9IGNcbiAgICBjID0gcm9sKGIsIDMwKVxuICAgIGIgPSBhXG4gICAgYSA9IHRcbiAgICBqKytcbiAgfVxuXG4gIGsgPSAxNTE4NTAwMjQ5XG4gIHdoaWxlIChqIDwgMTYpIGxvb3AoTS5yZWFkSW50MzJCRShqICogNCksIChiICYgYykgfCAoKH5iKSAmIGQpKVxuICB3aGlsZSAoaiA8IDIwKSBsb29wKGNhbGNXKCksIChiICYgYykgfCAoKH5iKSAmIGQpKVxuICBrID0gMTg1OTc3NTM5M1xuICB3aGlsZSAoaiA8IDQwKSBsb29wKGNhbGNXKCksIGIgXiBjIF4gZClcbiAgayA9IC0xODk0MDA3NTg4XG4gIHdoaWxlIChqIDwgNjApIGxvb3AoY2FsY1coKSwgKGIgJiBjKSB8IChiICYgZCkgfCAoYyAmIGQpKVxuICBrID0gLTg5OTQ5NzUxNFxuICB3aGlsZSAoaiA8IDgwKSBsb29wKGNhbGNXKCksIGIgXiBjIF4gZClcblxuICB0aGlzLl9hID0gKGEgKyB0aGlzLl9hKSB8IDBcbiAgdGhpcy5fYiA9IChiICsgdGhpcy5fYikgfCAwXG4gIHRoaXMuX2MgPSAoYyArIHRoaXMuX2MpIHwgMFxuICB0aGlzLl9kID0gKGQgKyB0aGlzLl9kKSB8IDBcbiAgdGhpcy5fZSA9IChlICsgdGhpcy5fZSkgfCAwXG59XG5cblNoYS5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gbmV3IEJ1ZmZlcigyMClcblxuICBILndyaXRlSW50MzJCRSh0aGlzLl9hIHwgMCwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiB8IDAsIDQpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2MgfCAwLCA4KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9kIHwgMCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UgfCAwLCAxNilcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYVxuXG4iLCIvKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0xLCBhcyBkZWZpbmVkXG4gKiBpbiBGSVBTIFBVQiAxODAtMVxuICogVmVyc2lvbiAyLjFhIENvcHlyaWdodCBQYXVsIEpvaG5zdG9uIDIwMDAgLSAyMDAyLlxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxuICogRGlzdHJpYnV0ZWQgdW5kZXIgdGhlIEJTRCBMaWNlbnNlXG4gKiBTZWUgaHR0cDovL3BhamhvbWUub3JnLnVrL2NyeXB0L21kNSBmb3IgZGV0YWlscy5cbiAqL1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgSGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpXG5cbnZhciBXID0gbmV3IEFycmF5KDgwKVxuXG5mdW5jdGlvbiBTaGExICgpIHtcbiAgdGhpcy5pbml0KClcbiAgdGhpcy5fdyA9IFdcblxuICBIYXNoLmNhbGwodGhpcywgNjQsIDU2KVxufVxuXG5pbmhlcml0cyhTaGExLCBIYXNoKVxuXG5TaGExLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9hID0gMHg2NzQ1MjMwMSB8IDBcbiAgdGhpcy5fYiA9IDB4ZWZjZGFiODkgfCAwXG4gIHRoaXMuX2MgPSAweDk4YmFkY2ZlIHwgMFxuICB0aGlzLl9kID0gMHgxMDMyNTQ3NiB8IDBcbiAgdGhpcy5fZSA9IDB4YzNkMmUxZjAgfCAwXG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLypcbiAqIEJpdHdpc2Ugcm90YXRlIGEgMzItYml0IG51bWJlciB0byB0aGUgbGVmdC5cbiAqL1xuZnVuY3Rpb24gcm9sIChudW0sIGNudCkge1xuICByZXR1cm4gKG51bSA8PCBjbnQpIHwgKG51bSA+Pj4gKDMyIC0gY250KSlcbn1cblxuU2hhMS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChNKSB7XG4gIHZhciBXID0gdGhpcy5fd1xuXG4gIHZhciBhID0gdGhpcy5fYVxuICB2YXIgYiA9IHRoaXMuX2JcbiAgdmFyIGMgPSB0aGlzLl9jXG4gIHZhciBkID0gdGhpcy5fZFxuICB2YXIgZSA9IHRoaXMuX2VcblxuICB2YXIgaiA9IDBcbiAgdmFyIGtcblxuICBmdW5jdGlvbiBjYWxjVyAoKSB7IHJldHVybiByb2woV1tqIC0gM10gXiBXW2ogLSA4XSBeIFdbaiAtIDE0XSBeIFdbaiAtIDE2XSwgMSkgfVxuICBmdW5jdGlvbiBsb29wICh3LCBmKSB7XG4gICAgV1tqXSA9IHdcblxuICAgIHZhciB0ID0gcm9sKGEsIDUpICsgZiArIGUgKyB3ICsga1xuXG4gICAgZSA9IGRcbiAgICBkID0gY1xuICAgIGMgPSByb2woYiwgMzApXG4gICAgYiA9IGFcbiAgICBhID0gdFxuICAgIGorK1xuICB9XG5cbiAgayA9IDE1MTg1MDAyNDlcbiAgd2hpbGUgKGogPCAxNikgbG9vcChNLnJlYWRJbnQzMkJFKGogKiA0KSwgKGIgJiBjKSB8ICgofmIpICYgZCkpXG4gIHdoaWxlIChqIDwgMjApIGxvb3AoY2FsY1coKSwgKGIgJiBjKSB8ICgofmIpICYgZCkpXG4gIGsgPSAxODU5Nzc1MzkzXG4gIHdoaWxlIChqIDwgNDApIGxvb3AoY2FsY1coKSwgYiBeIGMgXiBkKVxuICBrID0gLTE4OTQwMDc1ODhcbiAgd2hpbGUgKGogPCA2MCkgbG9vcChjYWxjVygpLCAoYiAmIGMpIHwgKGIgJiBkKSB8IChjICYgZCkpXG4gIGsgPSAtODk5NDk3NTE0XG4gIHdoaWxlIChqIDwgODApIGxvb3AoY2FsY1coKSwgYiBeIGMgXiBkKVxuXG4gIHRoaXMuX2EgPSAoYSArIHRoaXMuX2EpIHwgMFxuICB0aGlzLl9iID0gKGIgKyB0aGlzLl9iKSB8IDBcbiAgdGhpcy5fYyA9IChjICsgdGhpcy5fYykgfCAwXG4gIHRoaXMuX2QgPSAoZCArIHRoaXMuX2QpIHwgMFxuICB0aGlzLl9lID0gKGUgKyB0aGlzLl9lKSB8IDBcbn1cblxuU2hhMS5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gbmV3IEJ1ZmZlcigyMClcblxuICBILndyaXRlSW50MzJCRSh0aGlzLl9hIHwgMCwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiB8IDAsIDQpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2MgfCAwLCA4KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9kIHwgMCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UgfCAwLCAxNilcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYTFcbiIsIi8qKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0yNTYsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgMTgwLTJcbiAqIFZlcnNpb24gMi4yLWJldGEgQ29weXJpZ2h0IEFuZ2VsIE1hcmluLCBQYXVsIEpvaG5zdG9uIDIwMDAgLSAyMDA5LlxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxuICpcbiAqL1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgU2hhMjU2ID0gcmVxdWlyZSgnLi9zaGEyNTYnKVxudmFyIEhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKVxuXG52YXIgVyA9IG5ldyBBcnJheSg2NClcblxuZnVuY3Rpb24gU2hhMjI0ICgpIHtcbiAgdGhpcy5pbml0KClcblxuICB0aGlzLl93ID0gVyAvLyBuZXcgQXJyYXkoNjQpXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDY0LCA1Nilcbn1cblxuaW5oZXJpdHMoU2hhMjI0LCBTaGEyNTYpXG5cblNoYTIyNC5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fYSA9IDB4YzEwNTllZDggfCAwXG4gIHRoaXMuX2IgPSAweDM2N2NkNTA3IHwgMFxuICB0aGlzLl9jID0gMHgzMDcwZGQxNyB8IDBcbiAgdGhpcy5fZCA9IDB4ZjcwZTU5MzkgfCAwXG4gIHRoaXMuX2UgPSAweGZmYzAwYjMxIHwgMFxuICB0aGlzLl9mID0gMHg2ODU4MTUxMSB8IDBcbiAgdGhpcy5fZyA9IDB4NjRmOThmYTcgfCAwXG4gIHRoaXMuX2ggPSAweGJlZmE0ZmE0IHwgMFxuXG4gIHJldHVybiB0aGlzXG59XG5cblNoYTIyNC5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gbmV3IEJ1ZmZlcigyOClcblxuICBILndyaXRlSW50MzJCRSh0aGlzLl9hLCAwKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9iLCA0KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9jLCA4KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9kLCAxMilcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZSwgMTYpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2YsIDIwKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9nLCAyNClcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYTIyNFxuIiwiLyoqXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFNlY3VyZSBIYXNoIEFsZ29yaXRobSwgU0hBLTI1NiwgYXMgZGVmaW5lZFxuICogaW4gRklQUyAxODAtMlxuICogVmVyc2lvbiAyLjItYmV0YSBDb3B5cmlnaHQgQW5nZWwgTWFyaW4sIFBhdWwgSm9obnN0b24gMjAwMCAtIDIwMDkuXG4gKiBPdGhlciBjb250cmlidXRvcnM6IEdyZWcgSG9sdCwgQW5kcmV3IEtlcGVydCwgWWRuYXIsIExvc3RpbmV0XG4gKlxuICovXG5cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBIYXNoID0gcmVxdWlyZSgnLi9oYXNoJylcblxudmFyIEsgPSBbXG4gIDB4NDI4QTJGOTgsIDB4NzEzNzQ0OTEsIDB4QjVDMEZCQ0YsIDB4RTlCNURCQTUsXG4gIDB4Mzk1NkMyNUIsIDB4NTlGMTExRjEsIDB4OTIzRjgyQTQsIDB4QUIxQzVFRDUsXG4gIDB4RDgwN0FBOTgsIDB4MTI4MzVCMDEsIDB4MjQzMTg1QkUsIDB4NTUwQzdEQzMsXG4gIDB4NzJCRTVENzQsIDB4ODBERUIxRkUsIDB4OUJEQzA2QTcsIDB4QzE5QkYxNzQsXG4gIDB4RTQ5QjY5QzEsIDB4RUZCRTQ3ODYsIDB4MEZDMTlEQzYsIDB4MjQwQ0ExQ0MsXG4gIDB4MkRFOTJDNkYsIDB4NEE3NDg0QUEsIDB4NUNCMEE5REMsIDB4NzZGOTg4REEsXG4gIDB4OTgzRTUxNTIsIDB4QTgzMUM2NkQsIDB4QjAwMzI3QzgsIDB4QkY1OTdGQzcsXG4gIDB4QzZFMDBCRjMsIDB4RDVBNzkxNDcsIDB4MDZDQTYzNTEsIDB4MTQyOTI5NjcsXG4gIDB4MjdCNzBBODUsIDB4MkUxQjIxMzgsIDB4NEQyQzZERkMsIDB4NTMzODBEMTMsXG4gIDB4NjUwQTczNTQsIDB4NzY2QTBBQkIsIDB4ODFDMkM5MkUsIDB4OTI3MjJDODUsXG4gIDB4QTJCRkU4QTEsIDB4QTgxQTY2NEIsIDB4QzI0QjhCNzAsIDB4Qzc2QzUxQTMsXG4gIDB4RDE5MkU4MTksIDB4RDY5OTA2MjQsIDB4RjQwRTM1ODUsIDB4MTA2QUEwNzAsXG4gIDB4MTlBNEMxMTYsIDB4MUUzNzZDMDgsIDB4Mjc0ODc3NEMsIDB4MzRCMEJDQjUsXG4gIDB4MzkxQzBDQjMsIDB4NEVEOEFBNEEsIDB4NUI5Q0NBNEYsIDB4NjgyRTZGRjMsXG4gIDB4NzQ4RjgyRUUsIDB4NzhBNTYzNkYsIDB4ODRDODc4MTQsIDB4OENDNzAyMDgsXG4gIDB4OTBCRUZGRkEsIDB4QTQ1MDZDRUIsIDB4QkVGOUEzRjcsIDB4QzY3MTc4RjJcbl1cblxudmFyIFcgPSBuZXcgQXJyYXkoNjQpXG5cbmZ1bmN0aW9uIFNoYTI1NiAoKSB7XG4gIHRoaXMuaW5pdCgpXG5cbiAgdGhpcy5fdyA9IFcgLy8gbmV3IEFycmF5KDY0KVxuXG4gIEhhc2guY2FsbCh0aGlzLCA2NCwgNTYpXG59XG5cbmluaGVyaXRzKFNoYTI1NiwgSGFzaClcblxuU2hhMjU2LnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9hID0gMHg2YTA5ZTY2NyB8IDBcbiAgdGhpcy5fYiA9IDB4YmI2N2FlODUgfCAwXG4gIHRoaXMuX2MgPSAweDNjNmVmMzcyIHwgMFxuICB0aGlzLl9kID0gMHhhNTRmZjUzYSB8IDBcbiAgdGhpcy5fZSA9IDB4NTEwZTUyN2YgfCAwXG4gIHRoaXMuX2YgPSAweDliMDU2ODhjIHwgMFxuICB0aGlzLl9nID0gMHgxZjgzZDlhYiB8IDBcbiAgdGhpcy5faCA9IDB4NWJlMGNkMTkgfCAwXG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gQ2ggKHgsIHksIHopIHtcbiAgcmV0dXJuIHogXiAoeCAmICh5IF4geikpXG59XG5cbmZ1bmN0aW9uIE1haiAoeCwgeSwgeikge1xuICByZXR1cm4gKHggJiB5KSB8ICh6ICYgKHggfCB5KSlcbn1cblxuZnVuY3Rpb24gU2lnbWEwICh4KSB7XG4gIHJldHVybiAoeCA+Pj4gMiB8IHggPDwgMzApIF4gKHggPj4+IDEzIHwgeCA8PCAxOSkgXiAoeCA+Pj4gMjIgfCB4IDw8IDEwKVxufVxuXG5mdW5jdGlvbiBTaWdtYTEgKHgpIHtcbiAgcmV0dXJuICh4ID4+PiA2IHwgeCA8PCAyNikgXiAoeCA+Pj4gMTEgfCB4IDw8IDIxKSBeICh4ID4+PiAyNSB8IHggPDwgNylcbn1cblxuZnVuY3Rpb24gR2FtbWEwICh4KSB7XG4gIHJldHVybiAoeCA+Pj4gNyB8IHggPDwgMjUpIF4gKHggPj4+IDE4IHwgeCA8PCAxNCkgXiAoeCA+Pj4gMylcbn1cblxuZnVuY3Rpb24gR2FtbWExICh4KSB7XG4gIHJldHVybiAoeCA+Pj4gMTcgfCB4IDw8IDE1KSBeICh4ID4+PiAxOSB8IHggPDwgMTMpIF4gKHggPj4+IDEwKVxufVxuXG5TaGEyNTYucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoTSkge1xuICB2YXIgVyA9IHRoaXMuX3dcblxuICB2YXIgYSA9IHRoaXMuX2EgfCAwXG4gIHZhciBiID0gdGhpcy5fYiB8IDBcbiAgdmFyIGMgPSB0aGlzLl9jIHwgMFxuICB2YXIgZCA9IHRoaXMuX2QgfCAwXG4gIHZhciBlID0gdGhpcy5fZSB8IDBcbiAgdmFyIGYgPSB0aGlzLl9mIHwgMFxuICB2YXIgZyA9IHRoaXMuX2cgfCAwXG4gIHZhciBoID0gdGhpcy5faCB8IDBcblxuICB2YXIgaiA9IDBcblxuICBmdW5jdGlvbiBjYWxjVyAoKSB7IHJldHVybiBHYW1tYTEoV1tqIC0gMl0pICsgV1tqIC0gN10gKyBHYW1tYTAoV1tqIC0gMTVdKSArIFdbaiAtIDE2XSB9XG4gIGZ1bmN0aW9uIGxvb3AgKHcpIHtcbiAgICBXW2pdID0gd1xuXG4gICAgdmFyIFQxID0gaCArIFNpZ21hMShlKSArIENoKGUsIGYsIGcpICsgS1tqXSArIHdcbiAgICB2YXIgVDIgPSBTaWdtYTAoYSkgKyBNYWooYSwgYiwgYylcblxuICAgIGggPSBnXG4gICAgZyA9IGZcbiAgICBmID0gZVxuICAgIGUgPSBkICsgVDFcbiAgICBkID0gY1xuICAgIGMgPSBiXG4gICAgYiA9IGFcbiAgICBhID0gVDEgKyBUMlxuXG4gICAgaisrXG4gIH1cblxuICB3aGlsZSAoaiA8IDE2KSBsb29wKE0ucmVhZEludDMyQkUoaiAqIDQpKVxuICB3aGlsZSAoaiA8IDY0KSBsb29wKGNhbGNXKCkpXG5cbiAgdGhpcy5fYSA9IChhICsgdGhpcy5fYSkgfCAwXG4gIHRoaXMuX2IgPSAoYiArIHRoaXMuX2IpIHwgMFxuICB0aGlzLl9jID0gKGMgKyB0aGlzLl9jKSB8IDBcbiAgdGhpcy5fZCA9IChkICsgdGhpcy5fZCkgfCAwXG4gIHRoaXMuX2UgPSAoZSArIHRoaXMuX2UpIHwgMFxuICB0aGlzLl9mID0gKGYgKyB0aGlzLl9mKSB8IDBcbiAgdGhpcy5fZyA9IChnICsgdGhpcy5fZykgfCAwXG4gIHRoaXMuX2ggPSAoaCArIHRoaXMuX2gpIHwgMFxufVxuXG5TaGEyNTYucHJvdG90eXBlLl9oYXNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgSCA9IG5ldyBCdWZmZXIoMzIpXG5cbiAgSC53cml0ZUludDMyQkUodGhpcy5fYSwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiwgNClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYywgOClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UsIDE2KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9mLCAyMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZywgMjQpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2gsIDI4KVxuXG4gIHJldHVybiBIXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2hhMjU2XG4iLCJ2YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgU0hBNTEyID0gcmVxdWlyZSgnLi9zaGE1MTInKVxudmFyIEhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKVxuXG52YXIgVyA9IG5ldyBBcnJheSgxNjApXG5cbmZ1bmN0aW9uIFNoYTM4NCAoKSB7XG4gIHRoaXMuaW5pdCgpXG4gIHRoaXMuX3cgPSBXXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDEyOCwgMTEyKVxufVxuXG5pbmhlcml0cyhTaGEzODQsIFNIQTUxMilcblxuU2hhMzg0LnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9hID0gMHhjYmJiOWQ1ZCB8IDBcbiAgdGhpcy5fYiA9IDB4NjI5YTI5MmEgfCAwXG4gIHRoaXMuX2MgPSAweDkxNTkwMTVhIHwgMFxuICB0aGlzLl9kID0gMHgxNTJmZWNkOCB8IDBcbiAgdGhpcy5fZSA9IDB4NjczMzI2NjcgfCAwXG4gIHRoaXMuX2YgPSAweDhlYjQ0YTg3IHwgMFxuICB0aGlzLl9nID0gMHhkYjBjMmUwZCB8IDBcbiAgdGhpcy5faCA9IDB4NDdiNTQ4MWQgfCAwXG5cbiAgdGhpcy5fYWwgPSAweGMxMDU5ZWQ4IHwgMFxuICB0aGlzLl9ibCA9IDB4MzY3Y2Q1MDcgfCAwXG4gIHRoaXMuX2NsID0gMHgzMDcwZGQxNyB8IDBcbiAgdGhpcy5fZGwgPSAweGY3MGU1OTM5IHwgMFxuICB0aGlzLl9lbCA9IDB4ZmZjMDBiMzEgfCAwXG4gIHRoaXMuX2ZsID0gMHg2ODU4MTUxMSB8IDBcbiAgdGhpcy5fZ2wgPSAweDY0Zjk4ZmE3IHwgMFxuICB0aGlzLl9obCA9IDB4YmVmYTRmYTQgfCAwXG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuU2hhMzg0LnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBuZXcgQnVmZmVyKDQ4KVxuXG4gIGZ1bmN0aW9uIHdyaXRlSW50NjRCRSAoaCwgbCwgb2Zmc2V0KSB7XG4gICAgSC53cml0ZUludDMyQkUoaCwgb2Zmc2V0KVxuICAgIEgud3JpdGVJbnQzMkJFKGwsIG9mZnNldCArIDQpXG4gIH1cblxuICB3cml0ZUludDY0QkUodGhpcy5fYSwgdGhpcy5fYWwsIDApXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9iLCB0aGlzLl9ibCwgOClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2MsIHRoaXMuX2NsLCAxNilcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2QsIHRoaXMuX2RsLCAyNClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2UsIHRoaXMuX2VsLCAzMilcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2YsIHRoaXMuX2ZsLCA0MClcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYTM4NFxuIiwidmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKVxuXG52YXIgSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHhkNzI4YWUyMiwgMHg3MTM3NDQ5MSwgMHgyM2VmNjVjZCxcbiAgMHhiNWMwZmJjZiwgMHhlYzRkM2IyZiwgMHhlOWI1ZGJhNSwgMHg4MTg5ZGJiYyxcbiAgMHgzOTU2YzI1YiwgMHhmMzQ4YjUzOCwgMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOSxcbiAgMHg5MjNmODJhNCwgMHhhZjE5NGY5YiwgMHhhYjFjNWVkNSwgMHhkYTZkODExOCxcbiAgMHhkODA3YWE5OCwgMHhhMzAzMDI0MiwgMHgxMjgzNWIwMSwgMHg0NTcwNmZiZSxcbiAgMHgyNDMxODViZSwgMHg0ZWU0YjI4YywgMHg1NTBjN2RjMywgMHhkNWZmYjRlMixcbiAgMHg3MmJlNWQ3NCwgMHhmMjdiODk2ZiwgMHg4MGRlYjFmZSwgMHgzYjE2OTZiMSxcbiAgMHg5YmRjMDZhNywgMHgyNWM3MTIzNSwgMHhjMTliZjE3NCwgMHhjZjY5MjY5NCxcbiAgMHhlNDliNjljMSwgMHg5ZWYxNGFkMiwgMHhlZmJlNDc4NiwgMHgzODRmMjVlMyxcbiAgMHgwZmMxOWRjNiwgMHg4YjhjZDViNSwgMHgyNDBjYTFjYywgMHg3N2FjOWM2NSxcbiAgMHgyZGU5MmM2ZiwgMHg1OTJiMDI3NSwgMHg0YTc0ODRhYSwgMHg2ZWE2ZTQ4MyxcbiAgMHg1Y2IwYTlkYywgMHhiZDQxZmJkNCwgMHg3NmY5ODhkYSwgMHg4MzExNTNiNSxcbiAgMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYiwgMHhhODMxYzY2ZCwgMHgyZGI0MzIxMCxcbiAgMHhiMDAzMjdjOCwgMHg5OGZiMjEzZiwgMHhiZjU5N2ZjNywgMHhiZWVmMGVlNCxcbiAgMHhjNmUwMGJmMywgMHgzZGE4OGZjMiwgMHhkNWE3OTE0NywgMHg5MzBhYTcyNSxcbiAgMHgwNmNhNjM1MSwgMHhlMDAzODI2ZiwgMHgxNDI5Mjk2NywgMHgwYTBlNmU3MCxcbiAgMHgyN2I3MGE4NSwgMHg0NmQyMmZmYywgMHgyZTFiMjEzOCwgMHg1YzI2YzkyNixcbiAgMHg0ZDJjNmRmYywgMHg1YWM0MmFlZCwgMHg1MzM4MGQxMywgMHg5ZDk1YjNkZixcbiAgMHg2NTBhNzM1NCwgMHg4YmFmNjNkZSwgMHg3NjZhMGFiYiwgMHgzYzc3YjJhOCxcbiAgMHg4MWMyYzkyZSwgMHg0N2VkYWVlNiwgMHg5MjcyMmM4NSwgMHgxNDgyMzUzYixcbiAgMHhhMmJmZThhMSwgMHg0Y2YxMDM2NCwgMHhhODFhNjY0YiwgMHhiYzQyMzAwMSxcbiAgMHhjMjRiOGI3MCwgMHhkMGY4OTc5MSwgMHhjNzZjNTFhMywgMHgwNjU0YmUzMCxcbiAgMHhkMTkyZTgxOSwgMHhkNmVmNTIxOCwgMHhkNjk5MDYyNCwgMHg1NTY1YTkxMCxcbiAgMHhmNDBlMzU4NSwgMHg1NzcxMjAyYSwgMHgxMDZhYTA3MCwgMHgzMmJiZDFiOCxcbiAgMHgxOWE0YzExNiwgMHhiOGQyZDBjOCwgMHgxZTM3NmMwOCwgMHg1MTQxYWI1MyxcbiAgMHgyNzQ4Nzc0YywgMHhkZjhlZWI5OSwgMHgzNGIwYmNiNSwgMHhlMTliNDhhOCxcbiAgMHgzOTFjMGNiMywgMHhjNWM5NWE2MywgMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYixcbiAgMHg1YjljY2E0ZiwgMHg3NzYzZTM3MywgMHg2ODJlNmZmMywgMHhkNmIyYjhhMyxcbiAgMHg3NDhmODJlZSwgMHg1ZGVmYjJmYywgMHg3OGE1NjM2ZiwgMHg0MzE3MmY2MCxcbiAgMHg4NGM4NzgxNCwgMHhhMWYwYWI3MiwgMHg4Y2M3MDIwOCwgMHgxYTY0MzllYyxcbiAgMHg5MGJlZmZmYSwgMHgyMzYzMWUyOCwgMHhhNDUwNmNlYiwgMHhkZTgyYmRlOSxcbiAgMHhiZWY5YTNmNywgMHhiMmM2NzkxNSwgMHhjNjcxNzhmMiwgMHhlMzcyNTMyYixcbiAgMHhjYTI3M2VjZSwgMHhlYTI2NjE5YywgMHhkMTg2YjhjNywgMHgyMWMwYzIwNyxcbiAgMHhlYWRhN2RkNiwgMHhjZGUwZWIxZSwgMHhmNTdkNGY3ZiwgMHhlZTZlZDE3OCxcbiAgMHgwNmYwNjdhYSwgMHg3MjE3NmZiYSwgMHgwYTYzN2RjNSwgMHhhMmM4OThhNixcbiAgMHgxMTNmOTgwNCwgMHhiZWY5MGRhZSwgMHgxYjcxMGIzNSwgMHgxMzFjNDcxYixcbiAgMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NCwgMHgzMmNhYWI3YiwgMHg0MGM3MjQ5MyxcbiAgMHgzYzllYmUwYSwgMHgxNWM5YmViYywgMHg0MzFkNjdjNCwgMHg5YzEwMGQ0YyxcbiAgMHg0Y2M1ZDRiZSwgMHhjYjNlNDJiNiwgMHg1OTdmMjk5YywgMHhmYzY1N2UyYSxcbiAgMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlYywgMHg2YzQ0MTk4YywgMHg0YTQ3NTgxN1xuXVxuXG52YXIgVyA9IG5ldyBBcnJheSgxNjApXG5cbmZ1bmN0aW9uIFNoYTUxMiAoKSB7XG4gIHRoaXMuaW5pdCgpXG4gIHRoaXMuX3cgPSBXXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDEyOCwgMTEyKVxufVxuXG5pbmhlcml0cyhTaGE1MTIsIEhhc2gpXG5cblNoYTUxMi5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fYSA9IDB4NmEwOWU2NjcgfCAwXG4gIHRoaXMuX2IgPSAweGJiNjdhZTg1IHwgMFxuICB0aGlzLl9jID0gMHgzYzZlZjM3MiB8IDBcbiAgdGhpcy5fZCA9IDB4YTU0ZmY1M2EgfCAwXG4gIHRoaXMuX2UgPSAweDUxMGU1MjdmIHwgMFxuICB0aGlzLl9mID0gMHg5YjA1Njg4YyB8IDBcbiAgdGhpcy5fZyA9IDB4MWY4M2Q5YWIgfCAwXG4gIHRoaXMuX2ggPSAweDViZTBjZDE5IHwgMFxuXG4gIHRoaXMuX2FsID0gMHhmM2JjYzkwOCB8IDBcbiAgdGhpcy5fYmwgPSAweDg0Y2FhNzNiIHwgMFxuICB0aGlzLl9jbCA9IDB4ZmU5NGY4MmIgfCAwXG4gIHRoaXMuX2RsID0gMHg1ZjFkMzZmMSB8IDBcbiAgdGhpcy5fZWwgPSAweGFkZTY4MmQxIHwgMFxuICB0aGlzLl9mbCA9IDB4MmIzZTZjMWYgfCAwXG4gIHRoaXMuX2dsID0gMHhmYjQxYmQ2YiB8IDBcbiAgdGhpcy5faGwgPSAweDEzN2UyMTc5IHwgMFxuXG4gIHJldHVybiB0aGlzXG59XG5cbmZ1bmN0aW9uIENoICh4LCB5LCB6KSB7XG4gIHJldHVybiB6IF4gKHggJiAoeSBeIHopKVxufVxuXG5mdW5jdGlvbiBNYWogKHgsIHksIHopIHtcbiAgcmV0dXJuICh4ICYgeSkgfCAoeiAmICh4IHwgeSkpXG59XG5cbmZ1bmN0aW9uIFNpZ21hMCAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAyOCB8IHhsIDw8IDQpIF4gKHhsID4+PiAyIHwgeCA8PCAzMCkgXiAoeGwgPj4+IDcgfCB4IDw8IDI1KVxufVxuXG5mdW5jdGlvbiBTaWdtYTEgKHgsIHhsKSB7XG4gIHJldHVybiAoeCA+Pj4gMTQgfCB4bCA8PCAxOCkgXiAoeCA+Pj4gMTggfCB4bCA8PCAxNCkgXiAoeGwgPj4+IDkgfCB4IDw8IDIzKVxufVxuXG5mdW5jdGlvbiBHYW1tYTAgKHgsIHhsKSB7XG4gIHJldHVybiAoeCA+Pj4gMSB8IHhsIDw8IDMxKSBeICh4ID4+PiA4IHwgeGwgPDwgMjQpIF4gKHggPj4+IDcpXG59XG5cbmZ1bmN0aW9uIEdhbW1hMGwgKHgsIHhsKSB7XG4gIHJldHVybiAoeCA+Pj4gMSB8IHhsIDw8IDMxKSBeICh4ID4+PiA4IHwgeGwgPDwgMjQpIF4gKHggPj4+IDcgfCB4bCA8PCAyNSlcbn1cblxuZnVuY3Rpb24gR2FtbWExICh4LCB4bCkge1xuICByZXR1cm4gKHggPj4+IDE5IHwgeGwgPDwgMTMpIF4gKHhsID4+PiAyOSB8IHggPDwgMykgXiAoeCA+Pj4gNilcbn1cblxuZnVuY3Rpb24gR2FtbWExbCAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxOSB8IHhsIDw8IDEzKSBeICh4bCA+Pj4gMjkgfCB4IDw8IDMpIF4gKHggPj4+IDYgfCB4bCA8PCAyNilcbn1cblxuU2hhNTEyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKE0pIHtcbiAgdmFyIFcgPSB0aGlzLl93XG5cbiAgdmFyIGEgPSB0aGlzLl9hIHwgMFxuICB2YXIgYiA9IHRoaXMuX2IgfCAwXG4gIHZhciBjID0gdGhpcy5fYyB8IDBcbiAgdmFyIGQgPSB0aGlzLl9kIHwgMFxuICB2YXIgZSA9IHRoaXMuX2UgfCAwXG4gIHZhciBmID0gdGhpcy5fZiB8IDBcbiAgdmFyIGcgPSB0aGlzLl9nIHwgMFxuICB2YXIgaCA9IHRoaXMuX2ggfCAwXG5cbiAgdmFyIGFsID0gdGhpcy5fYWwgfCAwXG4gIHZhciBibCA9IHRoaXMuX2JsIHwgMFxuICB2YXIgY2wgPSB0aGlzLl9jbCB8IDBcbiAgdmFyIGRsID0gdGhpcy5fZGwgfCAwXG4gIHZhciBlbCA9IHRoaXMuX2VsIHwgMFxuICB2YXIgZmwgPSB0aGlzLl9mbCB8IDBcbiAgdmFyIGdsID0gdGhpcy5fZ2wgfCAwXG4gIHZhciBobCA9IHRoaXMuX2hsIHwgMFxuXG4gIHZhciBpID0gMFxuICB2YXIgaiA9IDBcbiAgdmFyIFdpLCBXaWxcbiAgZnVuY3Rpb24gY2FsY1cgKCkge1xuICAgIHZhciB4ID0gV1tqIC0gMTUgKiAyXVxuICAgIHZhciB4bCA9IFdbaiAtIDE1ICogMiArIDFdXG4gICAgdmFyIGdhbW1hMCA9IEdhbW1hMCh4LCB4bClcbiAgICB2YXIgZ2FtbWEwbCA9IEdhbW1hMGwoeGwsIHgpXG5cbiAgICB4ID0gV1tqIC0gMiAqIDJdXG4gICAgeGwgPSBXW2ogLSAyICogMiArIDFdXG4gICAgdmFyIGdhbW1hMSA9IEdhbW1hMSh4LCB4bClcbiAgICB2YXIgZ2FtbWExbCA9IEdhbW1hMWwoeGwsIHgpXG5cbiAgICAvLyBXW2ldID0gZ2FtbWEwICsgV1tpIC0gN10gKyBnYW1tYTEgKyBXW2kgLSAxNl1cbiAgICB2YXIgV2k3ID0gV1tqIC0gNyAqIDJdXG4gICAgdmFyIFdpN2wgPSBXW2ogLSA3ICogMiArIDFdXG5cbiAgICB2YXIgV2kxNiA9IFdbaiAtIDE2ICogMl1cbiAgICB2YXIgV2kxNmwgPSBXW2ogLSAxNiAqIDIgKyAxXVxuXG4gICAgV2lsID0gZ2FtbWEwbCArIFdpN2xcbiAgICBXaSA9IGdhbW1hMCArIFdpNyArICgoV2lsID4+PiAwKSA8IChnYW1tYTBsID4+PiAwKSA/IDEgOiAwKVxuICAgIFdpbCA9IFdpbCArIGdhbW1hMWxcbiAgICBXaSA9IFdpICsgZ2FtbWExICsgKChXaWwgPj4+IDApIDwgKGdhbW1hMWwgPj4+IDApID8gMSA6IDApXG4gICAgV2lsID0gV2lsICsgV2kxNmxcbiAgICBXaSA9IFdpICsgV2kxNiArICgoV2lsID4+PiAwKSA8IChXaTE2bCA+Pj4gMCkgPyAxIDogMClcbiAgfVxuXG4gIGZ1bmN0aW9uIGxvb3AgKCkge1xuICAgIFdbal0gPSBXaVxuICAgIFdbaiArIDFdID0gV2lsXG5cbiAgICB2YXIgbWFqID0gTWFqKGEsIGIsIGMpXG4gICAgdmFyIG1hamwgPSBNYWooYWwsIGJsLCBjbClcblxuICAgIHZhciBzaWdtYTBoID0gU2lnbWEwKGEsIGFsKVxuICAgIHZhciBzaWdtYTBsID0gU2lnbWEwKGFsLCBhKVxuICAgIHZhciBzaWdtYTFoID0gU2lnbWExKGUsIGVsKVxuICAgIHZhciBzaWdtYTFsID0gU2lnbWExKGVsLCBlKVxuXG4gICAgLy8gdDEgPSBoICsgc2lnbWExICsgY2ggKyBLW2ldICsgV1tpXVxuICAgIHZhciBLaSA9IEtbal1cbiAgICB2YXIgS2lsID0gS1tqICsgMV1cblxuICAgIHZhciBjaCA9IENoKGUsIGYsIGcpXG4gICAgdmFyIGNobCA9IENoKGVsLCBmbCwgZ2wpXG5cbiAgICB2YXIgdDFsID0gaGwgKyBzaWdtYTFsXG4gICAgdmFyIHQxID0gaCArIHNpZ21hMWggKyAoKHQxbCA+Pj4gMCkgPCAoaGwgPj4+IDApID8gMSA6IDApXG4gICAgdDFsID0gdDFsICsgY2hsXG4gICAgdDEgPSB0MSArIGNoICsgKCh0MWwgPj4+IDApIDwgKGNobCA+Pj4gMCkgPyAxIDogMClcbiAgICB0MWwgPSB0MWwgKyBLaWxcbiAgICB0MSA9IHQxICsgS2kgKyAoKHQxbCA+Pj4gMCkgPCAoS2lsID4+PiAwKSA/IDEgOiAwKVxuICAgIHQxbCA9IHQxbCArIFdpbFxuICAgIHQxID0gdDEgKyBXaSArICgodDFsID4+PiAwKSA8IChXaWwgPj4+IDApID8gMSA6IDApXG5cbiAgICAvLyB0MiA9IHNpZ21hMCArIG1halxuICAgIHZhciB0MmwgPSBzaWdtYTBsICsgbWFqbFxuICAgIHZhciB0MiA9IHNpZ21hMGggKyBtYWogKyAoKHQybCA+Pj4gMCkgPCAoc2lnbWEwbCA+Pj4gMCkgPyAxIDogMClcblxuICAgIGggPSBnXG4gICAgaGwgPSBnbFxuICAgIGcgPSBmXG4gICAgZ2wgPSBmbFxuICAgIGYgPSBlXG4gICAgZmwgPSBlbFxuICAgIGVsID0gKGRsICsgdDFsKSB8IDBcbiAgICBlID0gKGQgKyB0MSArICgoZWwgPj4+IDApIDwgKGRsID4+PiAwKSA/IDEgOiAwKSkgfCAwXG4gICAgZCA9IGNcbiAgICBkbCA9IGNsXG4gICAgYyA9IGJcbiAgICBjbCA9IGJsXG4gICAgYiA9IGFcbiAgICBibCA9IGFsXG4gICAgYWwgPSAodDFsICsgdDJsKSB8IDBcbiAgICBhID0gKHQxICsgdDIgKyAoKGFsID4+PiAwKSA8ICh0MWwgPj4+IDApID8gMSA6IDApKSB8IDBcblxuICAgIGkrK1xuICAgIGogKz0gMlxuICB9XG5cbiAgd2hpbGUgKGkgPCAxNikge1xuICAgIFdpID0gTS5yZWFkSW50MzJCRShqICogNClcbiAgICBXaWwgPSBNLnJlYWRJbnQzMkJFKGogKiA0ICsgNClcblxuICAgIGxvb3AoKVxuICB9XG5cbiAgd2hpbGUgKGkgPCA4MCkge1xuICAgIGNhbGNXKClcbiAgICBsb29wKClcbiAgfVxuXG4gIHRoaXMuX2FsID0gKHRoaXMuX2FsICsgYWwpIHwgMFxuICB0aGlzLl9ibCA9ICh0aGlzLl9ibCArIGJsKSB8IDBcbiAgdGhpcy5fY2wgPSAodGhpcy5fY2wgKyBjbCkgfCAwXG4gIHRoaXMuX2RsID0gKHRoaXMuX2RsICsgZGwpIHwgMFxuICB0aGlzLl9lbCA9ICh0aGlzLl9lbCArIGVsKSB8IDBcbiAgdGhpcy5fZmwgPSAodGhpcy5fZmwgKyBmbCkgfCAwXG4gIHRoaXMuX2dsID0gKHRoaXMuX2dsICsgZ2wpIHwgMFxuICB0aGlzLl9obCA9ICh0aGlzLl9obCArIGhsKSB8IDBcblxuICB0aGlzLl9hID0gKHRoaXMuX2EgKyBhICsgKCh0aGlzLl9hbCA+Pj4gMCkgPCAoYWwgPj4+IDApID8gMSA6IDApKSB8IDBcbiAgdGhpcy5fYiA9ICh0aGlzLl9iICsgYiArICgodGhpcy5fYmwgPj4+IDApIDwgKGJsID4+PiAwKSA/IDEgOiAwKSkgfCAwXG4gIHRoaXMuX2MgPSAodGhpcy5fYyArIGMgKyAoKHRoaXMuX2NsID4+PiAwKSA8IChjbCA+Pj4gMCkgPyAxIDogMCkpIHwgMFxuICB0aGlzLl9kID0gKHRoaXMuX2QgKyBkICsgKCh0aGlzLl9kbCA+Pj4gMCkgPCAoZGwgPj4+IDApID8gMSA6IDApKSB8IDBcbiAgdGhpcy5fZSA9ICh0aGlzLl9lICsgZSArICgodGhpcy5fZWwgPj4+IDApIDwgKGVsID4+PiAwKSA/IDEgOiAwKSkgfCAwXG4gIHRoaXMuX2YgPSAodGhpcy5fZiArIGYgKyAoKHRoaXMuX2ZsID4+PiAwKSA8IChmbCA+Pj4gMCkgPyAxIDogMCkpIHwgMFxuICB0aGlzLl9nID0gKHRoaXMuX2cgKyBnICsgKCh0aGlzLl9nbCA+Pj4gMCkgPCAoZ2wgPj4+IDApID8gMSA6IDApKSB8IDBcbiAgdGhpcy5faCA9ICh0aGlzLl9oICsgaCArICgodGhpcy5faGwgPj4+IDApIDwgKGhsID4+PiAwKSA/IDEgOiAwKSkgfCAwXG59XG5cblNoYTUxMi5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gbmV3IEJ1ZmZlcig2NClcblxuICBmdW5jdGlvbiB3cml0ZUludDY0QkUgKGgsIGwsIG9mZnNldCkge1xuICAgIEgud3JpdGVJbnQzMkJFKGgsIG9mZnNldClcbiAgICBILndyaXRlSW50MzJCRShsLCBvZmZzZXQgKyA0KVxuICB9XG5cbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2EsIHRoaXMuX2FsLCAwKVxuICB3cml0ZUludDY0QkUodGhpcy5fYiwgdGhpcy5fYmwsIDgpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9jLCB0aGlzLl9jbCwgMTYpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9kLCB0aGlzLl9kbCwgMjQpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9lLCB0aGlzLl9lbCwgMzIpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9mLCB0aGlzLl9mbCwgNDApXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9nLCB0aGlzLl9nbCwgNDgpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9oLCB0aGlzLl9obCwgNTYpXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGE1MTJcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBjcmVhdGVIYXNoID0gcmVxdWlyZSgnY3JlYXRlLWhhc2gvYnJvd3NlcicpO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxuXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnc3RyZWFtJykuVHJhbnNmb3JtXG5cbnZhciBaRVJPUyA9IG5ldyBCdWZmZXIoMTI4KVxuWkVST1MuZmlsbCgwKVxuXG5mdW5jdGlvbiBIbWFjKGFsZywga2V5KSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG4gIGFsZyA9IGFsZy50b0xvd2VyQ2FzZSgpXG4gIGlmICh0eXBlb2Yga2V5ID09PSAnc3RyaW5nJykge1xuICAgIGtleSA9IG5ldyBCdWZmZXIoa2V5KVxuICB9XG5cbiAgdmFyIGJsb2Nrc2l6ZSA9IChhbGcgPT09ICdzaGE1MTInIHx8IGFsZyA9PT0gJ3NoYTM4NCcpID8gMTI4IDogNjRcblxuICB0aGlzLl9hbGcgPSBhbGdcbiAgdGhpcy5fa2V5ID0ga2V5XG5cbiAgaWYgKGtleS5sZW5ndGggPiBibG9ja3NpemUpIHtcbiAgICBrZXkgPSBjcmVhdGVIYXNoKGFsZykudXBkYXRlKGtleSkuZGlnZXN0KClcblxuICB9IGVsc2UgaWYgKGtleS5sZW5ndGggPCBibG9ja3NpemUpIHtcbiAgICBrZXkgPSBCdWZmZXIuY29uY2F0KFtrZXksIFpFUk9TXSwgYmxvY2tzaXplKVxuICB9XG5cbiAgdmFyIGlwYWQgPSB0aGlzLl9pcGFkID0gbmV3IEJ1ZmZlcihibG9ja3NpemUpXG4gIHZhciBvcGFkID0gdGhpcy5fb3BhZCA9IG5ldyBCdWZmZXIoYmxvY2tzaXplKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tzaXplOyBpKyspIHtcbiAgICBpcGFkW2ldID0ga2V5W2ldIF4gMHgzNlxuICAgIG9wYWRbaV0gPSBrZXlbaV0gXiAweDVDXG4gIH1cblxuICB0aGlzLl9oYXNoID0gY3JlYXRlSGFzaChhbGcpLnVwZGF0ZShpcGFkKVxufVxuXG5pbmhlcml0cyhIbWFjLCBUcmFuc2Zvcm0pXG5cbkhtYWMucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhLCBlbmMpIHtcbiAgdGhpcy5faGFzaC51cGRhdGUoZGF0YSwgZW5jKVxuXG4gIHJldHVybiB0aGlzXG59XG5cbkhtYWMucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoZGF0YSwgXywgbmV4dCkge1xuICB0aGlzLl9oYXNoLnVwZGF0ZShkYXRhKVxuXG4gIG5leHQoKVxufVxuXG5IbWFjLnByb3RvdHlwZS5fZmx1c2ggPSBmdW5jdGlvbiAobmV4dCkge1xuICB0aGlzLnB1c2godGhpcy5kaWdlc3QoKSlcblxuICBuZXh0KClcbn1cblxuSG1hYy5wcm90b3R5cGUuZGlnZXN0ID0gZnVuY3Rpb24gKGVuYykge1xuICB2YXIgaCA9IHRoaXMuX2hhc2guZGlnZXN0KClcblxuICByZXR1cm4gY3JlYXRlSGFzaCh0aGlzLl9hbGcpLnVwZGF0ZSh0aGlzLl9vcGFkKS51cGRhdGUoaCkuZGlnZXN0KGVuYylcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBjcmVhdGVIbWFjKGFsZywga2V5KSB7XG4gIHJldHVybiBuZXcgSG1hYyhhbGcsIGtleSlcbn1cbiIsInZhciBnZW5lcmF0ZVByaW1lID0gcmVxdWlyZSgnLi9saWIvZ2VuZXJhdGVQcmltZScpXG52YXIgcHJpbWVzID0gcmVxdWlyZSgnLi9saWIvcHJpbWVzLmpzb24nKVxuXG52YXIgREggPSByZXF1aXJlKCcuL2xpYi9kaCcpXG5cbmZ1bmN0aW9uIGdldERpZmZpZUhlbGxtYW4gKG1vZCkge1xuICB2YXIgcHJpbWUgPSBuZXcgQnVmZmVyKHByaW1lc1ttb2RdLnByaW1lLCAnaGV4JylcbiAgdmFyIGdlbiA9IG5ldyBCdWZmZXIocHJpbWVzW21vZF0uZ2VuLCAnaGV4JylcblxuICByZXR1cm4gbmV3IERIKHByaW1lLCBnZW4pXG59XG5cbnZhciBFTkNPRElOR1MgPSB7XG4gICdiaW5hcnknOiB0cnVlLCAnaGV4JzogdHJ1ZSwgJ2Jhc2U2NCc6IHRydWVcbn1cblxuZnVuY3Rpb24gY3JlYXRlRGlmZmllSGVsbG1hbiAocHJpbWUsIGVuYywgZ2VuZXJhdG9yLCBnZW5jKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoZW5jKSB8fCBFTkNPRElOR1NbZW5jXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGNyZWF0ZURpZmZpZUhlbGxtYW4ocHJpbWUsICdiaW5hcnknLCBlbmMsIGdlbmVyYXRvcilcbiAgfVxuXG4gIGVuYyA9IGVuYyB8fCAnYmluYXJ5J1xuICBnZW5jID0gZ2VuYyB8fCAnYmluYXJ5J1xuICBnZW5lcmF0b3IgPSBnZW5lcmF0b3IgfHwgbmV3IEJ1ZmZlcihbMl0pXG5cbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoZ2VuZXJhdG9yKSkge1xuICAgIGdlbmVyYXRvciA9IG5ldyBCdWZmZXIoZ2VuZXJhdG9yLCBnZW5jKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBwcmltZSA9PT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gbmV3IERIKGdlbmVyYXRlUHJpbWUocHJpbWUsIGdlbmVyYXRvciksIGdlbmVyYXRvciwgdHJ1ZSlcbiAgfVxuXG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHByaW1lKSkge1xuICAgIHByaW1lID0gbmV3IEJ1ZmZlcihwcmltZSwgZW5jKVxuICB9XG5cbiAgcmV0dXJuIG5ldyBESChwcmltZSwgZ2VuZXJhdG9yLCB0cnVlKVxufVxuXG5leHBvcnRzLkRpZmZpZUhlbGxtYW5Hcm91cCA9IGV4cG9ydHMuY3JlYXRlRGlmZmllSGVsbG1hbkdyb3VwID0gZXhwb3J0cy5nZXREaWZmaWVIZWxsbWFuID0gZ2V0RGlmZmllSGVsbG1hblxuZXhwb3J0cy5jcmVhdGVEaWZmaWVIZWxsbWFuID0gZXhwb3J0cy5EaWZmaWVIZWxsbWFuID0gY3JlYXRlRGlmZmllSGVsbG1hblxuIiwidmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciBNaWxsZXJSYWJpbiA9IHJlcXVpcmUoJ21pbGxlci1yYWJpbicpO1xudmFyIG1pbGxlclJhYmluID0gbmV3IE1pbGxlclJhYmluKCk7XG52YXIgVFdFTlRZRk9VUiA9IG5ldyBCTigyNCk7XG52YXIgRUxFVkVOID0gbmV3IEJOKDExKTtcbnZhciBURU4gPSBuZXcgQk4oMTApO1xudmFyIFRIUkVFID0gbmV3IEJOKDMpO1xudmFyIFNFVkVOID0gbmV3IEJOKDcpO1xudmFyIHByaW1lcyA9IHJlcXVpcmUoJy4vZ2VuZXJhdGVQcmltZScpO1xudmFyIHJhbmRvbUJ5dGVzID0gcmVxdWlyZSgncmFuZG9tYnl0ZXMnKTtcbm1vZHVsZS5leHBvcnRzID0gREg7XG5cbmZ1bmN0aW9uIHNldFB1YmxpY0tleShwdWIsIGVuYykge1xuICBlbmMgPSBlbmMgfHwgJ3V0ZjgnO1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihwdWIpKSB7XG4gICAgcHViID0gbmV3IEJ1ZmZlcihwdWIsIGVuYyk7XG4gIH1cbiAgdGhpcy5fcHViID0gbmV3IEJOKHB1Yik7XG4gIHJldHVybiB0aGlzO1xufVxuXG5mdW5jdGlvbiBzZXRQcml2YXRlS2V5KHByaXYsIGVuYykge1xuICBlbmMgPSBlbmMgfHwgJ3V0ZjgnO1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihwcml2KSkge1xuICAgIHByaXYgPSBuZXcgQnVmZmVyKHByaXYsIGVuYyk7XG4gIH1cbiAgdGhpcy5fcHJpdiA9IG5ldyBCTihwcml2KTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbnZhciBwcmltZUNhY2hlID0ge307XG5mdW5jdGlvbiBjaGVja1ByaW1lKHByaW1lLCBnZW5lcmF0b3IpIHtcbiAgdmFyIGdlbiA9IGdlbmVyYXRvci50b1N0cmluZygnaGV4Jyk7XG4gIHZhciBoZXggPSBbZ2VuLCBwcmltZS50b1N0cmluZygxNildLmpvaW4oJ18nKTtcbiAgaWYgKGhleCBpbiBwcmltZUNhY2hlKSB7XG4gICAgcmV0dXJuIHByaW1lQ2FjaGVbaGV4XTtcbiAgfVxuICB2YXIgZXJyb3IgPSAwO1xuXG4gIGlmIChwcmltZS5pc0V2ZW4oKSB8fFxuICAgICFwcmltZXMuc2ltcGxlU2lldmUgfHxcbiAgICAhcHJpbWVzLmZlcm1hdFRlc3QocHJpbWUpIHx8XG4gICAgIW1pbGxlclJhYmluLnRlc3QocHJpbWUpKSB7XG4gICAgLy9ub3QgYSBwcmltZSBzbyArMVxuICAgIGVycm9yICs9IDE7XG5cbiAgICBpZiAoZ2VuID09PSAnMDInIHx8IGdlbiA9PT0gJzA1Jykge1xuICAgICAgLy8gd2UnZCBiZSBhYmxlIHRvIGNoZWNrIHRoZSBnZW5lcmF0b3JcbiAgICAgIC8vIGl0IHdvdWxkIGZhaWwgc28gKzhcbiAgICAgIGVycm9yICs9IDg7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vd2Ugd291bGRuJ3QgYmUgYWJsZSB0byB0ZXN0IHRoZSBnZW5lcmF0b3JcbiAgICAgIC8vIHNvICs0XG4gICAgICBlcnJvciArPSA0O1xuICAgIH1cbiAgICBwcmltZUNhY2hlW2hleF0gPSBlcnJvcjtcbiAgICByZXR1cm4gZXJyb3I7XG4gIH1cbiAgaWYgKCFtaWxsZXJSYWJpbi50ZXN0KHByaW1lLnNocm4oMSkpKSB7XG4gICAgLy9ub3QgYSBzYWZlIHByaW1lXG4gICAgZXJyb3IgKz0gMjtcbiAgfVxuICB2YXIgcmVtO1xuICBzd2l0Y2ggKGdlbikge1xuICAgIGNhc2UgJzAyJzpcbiAgICAgIGlmIChwcmltZS5tb2QoVFdFTlRZRk9VUikuY21wKEVMRVZFTikpIHtcbiAgICAgICAgLy8gdW5zdWlkYWJsZSBnZW5lcmF0b3JcbiAgICAgICAgZXJyb3IgKz0gODtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJzA1JzpcbiAgICAgIHJlbSA9IHByaW1lLm1vZChURU4pO1xuICAgICAgaWYgKHJlbS5jbXAoVEhSRUUpICYmIHJlbS5jbXAoU0VWRU4pKSB7XG4gICAgICAgIC8vIHByaW1lIG1vZCAxMCBuZWVkcyB0byBlcXVhbCAzIG9yIDdcbiAgICAgICAgZXJyb3IgKz0gODtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBlcnJvciArPSA0O1xuICB9XG4gIHByaW1lQ2FjaGVbaGV4XSA9IGVycm9yO1xuICByZXR1cm4gZXJyb3I7XG59XG5cbmZ1bmN0aW9uIERIKHByaW1lLCBnZW5lcmF0b3IsIG1hbGxlYWJsZSkge1xuICB0aGlzLnNldEdlbmVyYXRvcihnZW5lcmF0b3IpO1xuICB0aGlzLl9fcHJpbWUgPSBuZXcgQk4ocHJpbWUpO1xuICB0aGlzLl9wcmltZSA9IEJOLm1vbnQodGhpcy5fX3ByaW1lKTtcbiAgdGhpcy5fcHJpbWVMZW4gPSBwcmltZS5sZW5ndGg7XG4gIHRoaXMuX3B1YiA9IHVuZGVmaW5lZDtcbiAgdGhpcy5fcHJpdiA9IHVuZGVmaW5lZDtcbiAgdGhpcy5fcHJpbWVDb2RlID0gdW5kZWZpbmVkO1xuICBpZiAobWFsbGVhYmxlKSB7XG4gICAgdGhpcy5zZXRQdWJsaWNLZXkgPSBzZXRQdWJsaWNLZXk7XG4gICAgdGhpcy5zZXRQcml2YXRlS2V5ID0gc2V0UHJpdmF0ZUtleTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLl9wcmltZUNvZGUgPSA4O1xuICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoREgucHJvdG90eXBlLCAndmVyaWZ5RXJyb3InLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5fcHJpbWVDb2RlICE9PSAnbnVtYmVyJykge1xuICAgICAgdGhpcy5fcHJpbWVDb2RlID0gY2hlY2tQcmltZSh0aGlzLl9fcHJpbWUsIHRoaXMuX19nZW4pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fcHJpbWVDb2RlO1xuICB9XG59KTtcbkRILnByb3RvdHlwZS5nZW5lcmF0ZUtleXMgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5fcHJpdikge1xuICAgIHRoaXMuX3ByaXYgPSBuZXcgQk4ocmFuZG9tQnl0ZXModGhpcy5fcHJpbWVMZW4pKTtcbiAgfVxuICB0aGlzLl9wdWIgPSB0aGlzLl9nZW4udG9SZWQodGhpcy5fcHJpbWUpLnJlZFBvdyh0aGlzLl9wcml2KS5mcm9tUmVkKCk7XG4gIHJldHVybiB0aGlzLmdldFB1YmxpY0tleSgpO1xufTtcblxuREgucHJvdG90eXBlLmNvbXB1dGVTZWNyZXQgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgb3RoZXIgPSBuZXcgQk4ob3RoZXIpO1xuICBvdGhlciA9IG90aGVyLnRvUmVkKHRoaXMuX3ByaW1lKTtcbiAgdmFyIHNlY3JldCA9IG90aGVyLnJlZFBvdyh0aGlzLl9wcml2KS5mcm9tUmVkKCk7XG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKHNlY3JldC50b0FycmF5KCkpO1xuICB2YXIgcHJpbWUgPSB0aGlzLmdldFByaW1lKCk7XG4gIGlmIChvdXQubGVuZ3RoIDwgcHJpbWUubGVuZ3RoKSB7XG4gICAgdmFyIGZyb250ID0gbmV3IEJ1ZmZlcihwcmltZS5sZW5ndGggLSBvdXQubGVuZ3RoKTtcbiAgICBmcm9udC5maWxsKDApO1xuICAgIG91dCA9IEJ1ZmZlci5jb25jYXQoW2Zyb250LCBvdXRdKTtcbiAgfVxuICByZXR1cm4gb3V0O1xufTtcblxuREgucHJvdG90eXBlLmdldFB1YmxpY0tleSA9IGZ1bmN0aW9uIGdldFB1YmxpY0tleShlbmMpIHtcbiAgcmV0dXJuIGZvcm1hdFJldHVyblZhbHVlKHRoaXMuX3B1YiwgZW5jKTtcbn07XG5cbkRILnByb3RvdHlwZS5nZXRQcml2YXRlS2V5ID0gZnVuY3Rpb24gZ2V0UHJpdmF0ZUtleShlbmMpIHtcbiAgcmV0dXJuIGZvcm1hdFJldHVyblZhbHVlKHRoaXMuX3ByaXYsIGVuYyk7XG59O1xuXG5ESC5wcm90b3R5cGUuZ2V0UHJpbWUgPSBmdW5jdGlvbiAoZW5jKSB7XG4gIHJldHVybiBmb3JtYXRSZXR1cm5WYWx1ZSh0aGlzLl9fcHJpbWUsIGVuYyk7XG59O1xuXG5ESC5wcm90b3R5cGUuZ2V0R2VuZXJhdG9yID0gZnVuY3Rpb24gKGVuYykge1xuICByZXR1cm4gZm9ybWF0UmV0dXJuVmFsdWUodGhpcy5fZ2VuLCBlbmMpO1xufTtcblxuREgucHJvdG90eXBlLnNldEdlbmVyYXRvciA9IGZ1bmN0aW9uIChnZW4sIGVuYykge1xuICBlbmMgPSBlbmMgfHwgJ3V0ZjgnO1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihnZW4pKSB7XG4gICAgZ2VuID0gbmV3IEJ1ZmZlcihnZW4sIGVuYyk7XG4gIH1cbiAgdGhpcy5fX2dlbiA9IGdlbjtcbiAgdGhpcy5fZ2VuID0gbmV3IEJOKGdlbik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gZm9ybWF0UmV0dXJuVmFsdWUoYm4sIGVuYykge1xuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcihibi50b0FycmF5KCkpO1xuICBpZiAoIWVuYykge1xuICAgIHJldHVybiBidWY7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJ1Zi50b1N0cmluZyhlbmMpO1xuICB9XG59XG4iLCJ2YXIgcmFuZG9tQnl0ZXMgPSByZXF1aXJlKCdyYW5kb21ieXRlcycpO1xubW9kdWxlLmV4cG9ydHMgPSBmaW5kUHJpbWU7XG5maW5kUHJpbWUuc2ltcGxlU2lldmUgPSBzaW1wbGVTaWV2ZTtcbmZpbmRQcmltZS5mZXJtYXRUZXN0ID0gZmVybWF0VGVzdDtcbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgVFdFTlRZRk9VUiA9IG5ldyBCTigyNCk7XG52YXIgTWlsbGVyUmFiaW4gPSByZXF1aXJlKCdtaWxsZXItcmFiaW4nKTtcbnZhciBtaWxsZXJSYWJpbiA9IG5ldyBNaWxsZXJSYWJpbigpO1xudmFyIE9ORSA9IG5ldyBCTigxKTtcbnZhciBUV08gPSBuZXcgQk4oMik7XG52YXIgRklWRSA9IG5ldyBCTig1KTtcbnZhciBTSVhURUVOID0gbmV3IEJOKDE2KTtcbnZhciBFSUdIVCA9IG5ldyBCTig4KTtcbnZhciBURU4gPSBuZXcgQk4oMTApO1xudmFyIFRIUkVFID0gbmV3IEJOKDMpO1xudmFyIFNFVkVOID0gbmV3IEJOKDcpO1xudmFyIEVMRVZFTiA9IG5ldyBCTigxMSk7XG52YXIgRk9VUiA9IG5ldyBCTig0KTtcbnZhciBUV0VMVkUgPSBuZXcgQk4oMTIpO1xudmFyIHByaW1lcyA9IG51bGw7XG5cbmZ1bmN0aW9uIF9nZXRQcmltZXMoKSB7XG4gIGlmIChwcmltZXMgIT09IG51bGwpXG4gICAgcmV0dXJuIHByaW1lcztcblxuICB2YXIgbGltaXQgPSAweDEwMDAwMDtcbiAgdmFyIHJlcyA9IFtdO1xuICByZXNbMF0gPSAyO1xuICBmb3IgKHZhciBpID0gMSwgayA9IDM7IGsgPCBsaW1pdDsgayArPSAyKSB7XG4gICAgdmFyIHNxcnQgPSBNYXRoLmNlaWwoTWF0aC5zcXJ0KGspKTtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IGkgJiYgcmVzW2pdIDw9IHNxcnQ7IGorKylcbiAgICAgIGlmIChrICUgcmVzW2pdID09PSAwKVxuICAgICAgICBicmVhaztcblxuICAgIGlmIChpICE9PSBqICYmIHJlc1tqXSA8PSBzcXJ0KVxuICAgICAgY29udGludWU7XG5cbiAgICByZXNbaSsrXSA9IGs7XG4gIH1cbiAgcHJpbWVzID0gcmVzO1xuICByZXR1cm4gcmVzO1xufVxuXG5mdW5jdGlvbiBzaW1wbGVTaWV2ZShwKSB7XG4gIHZhciBwcmltZXMgPSBfZ2V0UHJpbWVzKCk7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcmltZXMubGVuZ3RoOyBpKyspXG4gICAgaWYgKHAubW9kbihwcmltZXNbaV0pID09PSAwKSB7XG4gICAgICBpZiAocC5jbXBuKHByaW1lc1tpXSkgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBmZXJtYXRUZXN0KHApIHtcbiAgdmFyIHJlZCA9IEJOLm1vbnQocCk7XG4gIHJldHVybiBUV08udG9SZWQocmVkKS5yZWRQb3cocC5zdWJuKDEpKS5mcm9tUmVkKCkuY21wbigxKSA9PT0gMDtcbn1cblxuZnVuY3Rpb24gZmluZFByaW1lKGJpdHMsIGdlbikge1xuICBpZiAoYml0cyA8IDE2KSB7XG4gICAgLy8gdGhpcyBpcyB3aGF0IG9wZW5zc2wgZG9lc1xuICAgIGlmIChnZW4gPT09IDIgfHwgZ2VuID09PSA1KSB7XG4gICAgICByZXR1cm4gbmV3IEJOKFsweDhjLCAweDdiXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgQk4oWzB4OGMsIDB4MjddKTtcbiAgICB9XG4gIH1cbiAgZ2VuID0gbmV3IEJOKGdlbik7XG5cbiAgdmFyIG51bSwgbjI7XG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBudW0gPSBuZXcgQk4ocmFuZG9tQnl0ZXMoTWF0aC5jZWlsKGJpdHMgLyA4KSkpO1xuICAgIHdoaWxlIChudW0uYml0TGVuZ3RoKCkgPiBiaXRzKSB7XG4gICAgICBudW0uaXNocm4oMSk7XG4gICAgfVxuICAgIGlmIChudW0uaXNFdmVuKCkpIHtcbiAgICAgIG51bS5pYWRkKE9ORSk7XG4gICAgfVxuICAgIGlmICghbnVtLnRlc3RuKDEpKSB7XG4gICAgICBudW0uaWFkZChUV08pO1xuICAgIH1cbiAgICBpZiAoIWdlbi5jbXAoVFdPKSkge1xuICAgICAgd2hpbGUgKG51bS5tb2QoVFdFTlRZRk9VUikuY21wKEVMRVZFTikpIHtcbiAgICAgICAgbnVtLmlhZGQoRk9VUik7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghZ2VuLmNtcChGSVZFKSkge1xuICAgICAgd2hpbGUgKG51bS5tb2QoVEVOKS5jbXAoVEhSRUUpKSB7XG4gICAgICAgIG51bS5pYWRkKEZPVVIpO1xuICAgICAgfVxuICAgIH1cbiAgICBuMiA9IG51bS5zaHJuKDEpO1xuICAgIGlmIChzaW1wbGVTaWV2ZShuMikgJiYgc2ltcGxlU2lldmUobnVtKSAmJlxuICAgICAgZmVybWF0VGVzdChuMikgJiYgZmVybWF0VGVzdChudW0pICYmXG4gICAgICBtaWxsZXJSYWJpbi50ZXN0KG4yKSAmJiBtaWxsZXJSYWJpbi50ZXN0KG51bSkpIHtcbiAgICAgIHJldHVybiBudW07XG4gICAgfVxuICB9XG5cbn1cbiIsIm1vZHVsZS5leHBvcnRzPXtcbiAgICBcIm1vZHAxXCI6IHtcbiAgICAgICAgXCJnZW5cIjogXCIwMlwiLFxuICAgICAgICBcInByaW1lXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmM5MGZkYWEyMjE2OGMyMzRjNGM2NjI4YjgwZGMxY2QxMjkwMjRlMDg4YTY3Y2M3NDAyMGJiZWE2M2IxMzliMjI1MTRhMDg3OThlMzQwNGRkZWY5NTE5YjNjZDNhNDMxYjMwMmIwYTZkZjI1ZjE0Mzc0ZmUxMzU2ZDZkNTFjMjQ1ZTQ4NWI1NzY2MjVlN2VjNmY0NGM0MmU5YTYzYTM2MjBmZmZmZmZmZmZmZmZmZmZmXCJcbiAgICB9LFxuICAgIFwibW9kcDJcIjoge1xuICAgICAgICBcImdlblwiOiBcIjAyXCIsXG4gICAgICAgIFwicHJpbWVcIjogXCJmZmZmZmZmZmZmZmZmZmZmYzkwZmRhYTIyMTY4YzIzNGM0YzY2MjhiODBkYzFjZDEyOTAyNGUwODhhNjdjYzc0MDIwYmJlYTYzYjEzOWIyMjUxNGEwODc5OGUzNDA0ZGRlZjk1MTliM2NkM2E0MzFiMzAyYjBhNmRmMjVmMTQzNzRmZTEzNTZkNmQ1MWMyNDVlNDg1YjU3NjYyNWU3ZWM2ZjQ0YzQyZTlhNjM3ZWQ2YjBiZmY1Y2I2ZjQwNmI3ZWRlZTM4NmJmYjVhODk5ZmE1YWU5ZjI0MTE3YzRiMWZlNjQ5Mjg2NjUxZWNlNjUzODFmZmZmZmZmZmZmZmZmZmZmXCJcbiAgICB9LFxuICAgIFwibW9kcDVcIjoge1xuICAgICAgICBcImdlblwiOiBcIjAyXCIsXG4gICAgICAgIFwicHJpbWVcIjogXCJmZmZmZmZmZmZmZmZmZmZmYzkwZmRhYTIyMTY4YzIzNGM0YzY2MjhiODBkYzFjZDEyOTAyNGUwODhhNjdjYzc0MDIwYmJlYTYzYjEzOWIyMjUxNGEwODc5OGUzNDA0ZGRlZjk1MTliM2NkM2E0MzFiMzAyYjBhNmRmMjVmMTQzNzRmZTEzNTZkNmQ1MWMyNDVlNDg1YjU3NjYyNWU3ZWM2ZjQ0YzQyZTlhNjM3ZWQ2YjBiZmY1Y2I2ZjQwNmI3ZWRlZTM4NmJmYjVhODk5ZmE1YWU5ZjI0MTE3YzRiMWZlNjQ5Mjg2NjUxZWNlNDViM2RjMjAwN2NiOGExNjNiZjA1OThkYTQ4MzYxYzU1ZDM5YTY5MTYzZmE4ZmQyNGNmNWY4MzY1NWQyM2RjYTNhZDk2MWM2MmYzNTYyMDg1NTJiYjllZDUyOTA3NzA5Njk2NmQ2NzBjMzU0ZTRhYmM5ODA0ZjE3NDZjMDhjYTIzNzMyN2ZmZmZmZmZmZmZmZmZmZmZcIlxuICAgIH0sXG4gICAgXCJtb2RwMTRcIjoge1xuICAgICAgICBcImdlblwiOiBcIjAyXCIsXG4gICAgICAgIFwicHJpbWVcIjogXCJmZmZmZmZmZmZmZmZmZmZmYzkwZmRhYTIyMTY4YzIzNGM0YzY2MjhiODBkYzFjZDEyOTAyNGUwODhhNjdjYzc0MDIwYmJlYTYzYjEzOWIyMjUxNGEwODc5OGUzNDA0ZGRlZjk1MTliM2NkM2E0MzFiMzAyYjBhNmRmMjVmMTQzNzRmZTEzNTZkNmQ1MWMyNDVlNDg1YjU3NjYyNWU3ZWM2ZjQ0YzQyZTlhNjM3ZWQ2YjBiZmY1Y2I2ZjQwNmI3ZWRlZTM4NmJmYjVhODk5ZmE1YWU5ZjI0MTE3YzRiMWZlNjQ5Mjg2NjUxZWNlNDViM2RjMjAwN2NiOGExNjNiZjA1OThkYTQ4MzYxYzU1ZDM5YTY5MTYzZmE4ZmQyNGNmNWY4MzY1NWQyM2RjYTNhZDk2MWM2MmYzNTYyMDg1NTJiYjllZDUyOTA3NzA5Njk2NmQ2NzBjMzU0ZTRhYmM5ODA0ZjE3NDZjMDhjYTE4MjE3YzMyOTA1ZTQ2MmUzNmNlM2JlMzllNzcyYzE4MGU4NjAzOWIyNzgzYTJlYzA3YTI4ZmI1YzU1ZGYwNmY0YzUyYzlkZTJiY2JmNjk1NTgxNzE4Mzk5NTQ5N2NlYTk1NmFlNTE1ZDIyNjE4OThmYTA1MTAxNTcyOGU1YThhYWNhYTY4ZmZmZmZmZmZmZmZmZmZmZlwiXG4gICAgfSxcbiAgICBcIm1vZHAxNVwiOiB7XG4gICAgICAgIFwiZ2VuXCI6IFwiMDJcIixcbiAgICAgICAgXCJwcmltZVwiOiBcImZmZmZmZmZmZmZmZmZmZmZjOTBmZGFhMjIxNjhjMjM0YzRjNjYyOGI4MGRjMWNkMTI5MDI0ZTA4OGE2N2NjNzQwMjBiYmVhNjNiMTM5YjIyNTE0YTA4Nzk4ZTM0MDRkZGVmOTUxOWIzY2QzYTQzMWIzMDJiMGE2ZGYyNWYxNDM3NGZlMTM1NmQ2ZDUxYzI0NWU0ODViNTc2NjI1ZTdlYzZmNDRjNDJlOWE2MzdlZDZiMGJmZjVjYjZmNDA2YjdlZGVlMzg2YmZiNWE4OTlmYTVhZTlmMjQxMTdjNGIxZmU2NDkyODY2NTFlY2U0NWIzZGMyMDA3Y2I4YTE2M2JmMDU5OGRhNDgzNjFjNTVkMzlhNjkxNjNmYThmZDI0Y2Y1ZjgzNjU1ZDIzZGNhM2FkOTYxYzYyZjM1NjIwODU1MmJiOWVkNTI5MDc3MDk2OTY2ZDY3MGMzNTRlNGFiYzk4MDRmMTc0NmMwOGNhMTgyMTdjMzI5MDVlNDYyZTM2Y2UzYmUzOWU3NzJjMTgwZTg2MDM5YjI3ODNhMmVjMDdhMjhmYjVjNTVkZjA2ZjRjNTJjOWRlMmJjYmY2OTU1ODE3MTgzOTk1NDk3Y2VhOTU2YWU1MTVkMjI2MTg5OGZhMDUxMDE1NzI4ZTVhOGFhYWM0MmRhZDMzMTcwZDA0NTA3YTMzYTg1NTIxYWJkZjFjYmE2NGVjZmI4NTA0NThkYmVmMGE4YWVhNzE1NzVkMDYwYzdkYjM5NzBmODVhNmUxZTRjN2FiZjVhZThjZGIwOTMzZDcxZThjOTRlMDRhMjU2MTlkY2VlM2QyMjYxYWQyZWU2YmYxMmZmYTA2ZDk4YTA4NjRkODc2MDI3MzNlYzg2YTY0NTIxZjJiMTgxNzdiMjAwY2JiZTExNzU3N2E2MTVkNmM3NzA5ODhjMGJhZDk0NmUyMDhlMjRmYTA3NGU1YWIzMTQzZGI1YmZjZTBmZDEwOGU0YjgyZDEyMGE5M2FkMmNhZmZmZmZmZmZmZmZmZmZmZlwiXG4gICAgfSxcbiAgICBcIm1vZHAxNlwiOiB7XG4gICAgICAgIFwiZ2VuXCI6IFwiMDJcIixcbiAgICAgICAgXCJwcmltZVwiOiBcImZmZmZmZmZmZmZmZmZmZmZjOTBmZGFhMjIxNjhjMjM0YzRjNjYyOGI4MGRjMWNkMTI5MDI0ZTA4OGE2N2NjNzQwMjBiYmVhNjNiMTM5YjIyNTE0YTA4Nzk4ZTM0MDRkZGVmOTUxOWIzY2QzYTQzMWIzMDJiMGE2ZGYyNWYxNDM3NGZlMTM1NmQ2ZDUxYzI0NWU0ODViNTc2NjI1ZTdlYzZmNDRjNDJlOWE2MzdlZDZiMGJmZjVjYjZmNDA2YjdlZGVlMzg2YmZiNWE4OTlmYTVhZTlmMjQxMTdjNGIxZmU2NDkyODY2NTFlY2U0NWIzZGMyMDA3Y2I4YTE2M2JmMDU5OGRhNDgzNjFjNTVkMzlhNjkxNjNmYThmZDI0Y2Y1ZjgzNjU1ZDIzZGNhM2FkOTYxYzYyZjM1NjIwODU1MmJiOWVkNTI5MDc3MDk2OTY2ZDY3MGMzNTRlNGFiYzk4MDRmMTc0NmMwOGNhMTgyMTdjMzI5MDVlNDYyZTM2Y2UzYmUzOWU3NzJjMTgwZTg2MDM5YjI3ODNhMmVjMDdhMjhmYjVjNTVkZjA2ZjRjNTJjOWRlMmJjYmY2OTU1ODE3MTgzOTk1NDk3Y2VhOTU2YWU1MTVkMjI2MTg5OGZhMDUxMDE1NzI4ZTVhOGFhYWM0MmRhZDMzMTcwZDA0NTA3YTMzYTg1NTIxYWJkZjFjYmE2NGVjZmI4NTA0NThkYmVmMGE4YWVhNzE1NzVkMDYwYzdkYjM5NzBmODVhNmUxZTRjN2FiZjVhZThjZGIwOTMzZDcxZThjOTRlMDRhMjU2MTlkY2VlM2QyMjYxYWQyZWU2YmYxMmZmYTA2ZDk4YTA4NjRkODc2MDI3MzNlYzg2YTY0NTIxZjJiMTgxNzdiMjAwY2JiZTExNzU3N2E2MTVkNmM3NzA5ODhjMGJhZDk0NmUyMDhlMjRmYTA3NGU1YWIzMTQzZGI1YmZjZTBmZDEwOGU0YjgyZDEyMGE5MjEwODAxMWE3MjNjMTJhNzg3ZTZkNzg4NzE5YTEwYmRiYTViMjY5OWMzMjcxODZhZjRlMjNjMWE5NDY4MzRiNjE1MGJkYTI1ODNlOWNhMmFkNDRjZThkYmJiYzJkYjA0ZGU4ZWY5MmU4ZWZjMTQxZmJlY2FhNjI4N2M1OTQ3NGU2YmMwNWQ5OWIyOTY0ZmEwOTBjM2EyMjMzYmExODY1MTViZTdlZDFmNjEyOTcwY2VlMmQ3YWZiODFiZGQ3NjIxNzA0ODFjZDAwNjkxMjdkNWIwNWFhOTkzYjRlYTk4OGQ4ZmRkYzE4NmZmYjdkYzkwYTZjMDhmNGRmNDM1YzkzNDA2MzE5OWZmZmZmZmZmZmZmZmZmZmZcIlxuICAgIH0sXG4gICAgXCJtb2RwMTdcIjoge1xuICAgICAgICBcImdlblwiOiBcIjAyXCIsXG4gICAgICAgIFwicHJpbWVcIjogXCJmZmZmZmZmZmZmZmZmZmZmYzkwZmRhYTIyMTY4YzIzNGM0YzY2MjhiODBkYzFjZDEyOTAyNGUwODhhNjdjYzc0MDIwYmJlYTYzYjEzOWIyMjUxNGEwODc5OGUzNDA0ZGRlZjk1MTliM2NkM2E0MzFiMzAyYjBhNmRmMjVmMTQzNzRmZTEzNTZkNmQ1MWMyNDVlNDg1YjU3NjYyNWU3ZWM2ZjQ0YzQyZTlhNjM3ZWQ2YjBiZmY1Y2I2ZjQwNmI3ZWRlZTM4NmJmYjVhODk5ZmE1YWU5ZjI0MTE3YzRiMWZlNjQ5Mjg2NjUxZWNlNDViM2RjMjAwN2NiOGExNjNiZjA1OThkYTQ4MzYxYzU1ZDM5YTY5MTYzZmE4ZmQyNGNmNWY4MzY1NWQyM2RjYTNhZDk2MWM2MmYzNTYyMDg1NTJiYjllZDUyOTA3NzA5Njk2NmQ2NzBjMzU0ZTRhYmM5ODA0ZjE3NDZjMDhjYTE4MjE3YzMyOTA1ZTQ2MmUzNmNlM2JlMzllNzcyYzE4MGU4NjAzOWIyNzgzYTJlYzA3YTI4ZmI1YzU1ZGYwNmY0YzUyYzlkZTJiY2JmNjk1NTgxNzE4Mzk5NTQ5N2NlYTk1NmFlNTE1ZDIyNjE4OThmYTA1MTAxNTcyOGU1YThhYWFjNDJkYWQzMzE3MGQwNDUwN2EzM2E4NTUyMWFiZGYxY2JhNjRlY2ZiODUwNDU4ZGJlZjBhOGFlYTcxNTc1ZDA2MGM3ZGIzOTcwZjg1YTZlMWU0YzdhYmY1YWU4Y2RiMDkzM2Q3MWU4Yzk0ZTA0YTI1NjE5ZGNlZTNkMjI2MWFkMmVlNmJmMTJmZmEwNmQ5OGEwODY0ZDg3NjAyNzMzZWM4NmE2NDUyMWYyYjE4MTc3YjIwMGNiYmUxMTc1NzdhNjE1ZDZjNzcwOTg4YzBiYWQ5NDZlMjA4ZTI0ZmEwNzRlNWFiMzE0M2RiNWJmY2UwZmQxMDhlNGI4MmQxMjBhOTIxMDgwMTFhNzIzYzEyYTc4N2U2ZDc4ODcxOWExMGJkYmE1YjI2OTljMzI3MTg2YWY0ZTIzYzFhOTQ2ODM0YjYxNTBiZGEyNTgzZTljYTJhZDQ0Y2U4ZGJiYmMyZGIwNGRlOGVmOTJlOGVmYzE0MWZiZWNhYTYyODdjNTk0NzRlNmJjMDVkOTliMjk2NGZhMDkwYzNhMjIzM2JhMTg2NTE1YmU3ZWQxZjYxMjk3MGNlZTJkN2FmYjgxYmRkNzYyMTcwNDgxY2QwMDY5MTI3ZDViMDVhYTk5M2I0ZWE5ODhkOGZkZGMxODZmZmI3ZGM5MGE2YzA4ZjRkZjQzNWM5MzQwMjg0OTIzNmMzZmFiNGQyN2M3MDI2YzFkNGRjYjI2MDI2NDZkZWM5NzUxZTc2M2RiYTM3YmRmOGZmOTQwNmFkOWU1MzBlZTVkYjM4MmY0MTMwMDFhZWIwNmE1M2VkOTAyN2Q4MzExNzk3MjdiMDg2NWE4OTE4ZGEzZWRiZWJjZjliMTRlZDQ0Y2U2Y2JhY2VkNGJiMWJkYjdmMTQ0N2U2Y2MyNTRiMzMyMDUxNTEyYmQ3YWY0MjZmYjhmNDAxMzc4Y2QyYmY1OTgzY2EwMWM2NGI5MmVjZjAzMmVhMTVkMTcyMWQwM2Y0ODJkN2NlNmU3NGZlZjZkNTVlNzAyZjQ2OTgwYzgyYjVhODQwMzE5MDBiMWM5ZTU5ZTdjOTdmYmVjN2U4ZjMyM2E5N2E3ZTM2Y2M4OGJlMGYxZDQ1YjdmZjU4NWFjNTRiZDQwN2IyMmI0MTU0YWFjYzhmNmQ3ZWJmNDhlMWQ4MTRjYzVlZDIwZjgwMzdlMGE3OTcxNWVlZjI5YmUzMjgwNmExZDU4YmI3YzVkYTc2ZjU1MGFhM2Q4YTFmYmZmMGViMTljY2IxYTMxM2Q1NWNkYTU2YzllYzJlZjI5NjMyMzg3ZmU4ZDc2ZTNjMDQ2ODA0M2U4ZjY2M2Y0ODYwZWUxMmJmMmQ1YjBiNzQ3NGQ2ZTY5NGY5MWU2ZGNjNDAyNGZmZmZmZmZmZmZmZmZmZmZcIlxuICAgIH0sXG4gICAgXCJtb2RwMThcIjoge1xuICAgICAgICBcImdlblwiOiBcIjAyXCIsXG4gICAgICAgIFwicHJpbWVcIjogXCJmZmZmZmZmZmZmZmZmZmZmYzkwZmRhYTIyMTY4YzIzNGM0YzY2MjhiODBkYzFjZDEyOTAyNGUwODhhNjdjYzc0MDIwYmJlYTYzYjEzOWIyMjUxNGEwODc5OGUzNDA0ZGRlZjk1MTliM2NkM2E0MzFiMzAyYjBhNmRmMjVmMTQzNzRmZTEzNTZkNmQ1MWMyNDVlNDg1YjU3NjYyNWU3ZWM2ZjQ0YzQyZTlhNjM3ZWQ2YjBiZmY1Y2I2ZjQwNmI3ZWRlZTM4NmJmYjVhODk5ZmE1YWU5ZjI0MTE3YzRiMWZlNjQ5Mjg2NjUxZWNlNDViM2RjMjAwN2NiOGExNjNiZjA1OThkYTQ4MzYxYzU1ZDM5YTY5MTYzZmE4ZmQyNGNmNWY4MzY1NWQyM2RjYTNhZDk2MWM2MmYzNTYyMDg1NTJiYjllZDUyOTA3NzA5Njk2NmQ2NzBjMzU0ZTRhYmM5ODA0ZjE3NDZjMDhjYTE4MjE3YzMyOTA1ZTQ2MmUzNmNlM2JlMzllNzcyYzE4MGU4NjAzOWIyNzgzYTJlYzA3YTI4ZmI1YzU1ZGYwNmY0YzUyYzlkZTJiY2JmNjk1NTgxNzE4Mzk5NTQ5N2NlYTk1NmFlNTE1ZDIyNjE4OThmYTA1MTAxNTcyOGU1YThhYWFjNDJkYWQzMzE3MGQwNDUwN2EzM2E4NTUyMWFiZGYxY2JhNjRlY2ZiODUwNDU4ZGJlZjBhOGFlYTcxNTc1ZDA2MGM3ZGIzOTcwZjg1YTZlMWU0YzdhYmY1YWU4Y2RiMDkzM2Q3MWU4Yzk0ZTA0YTI1NjE5ZGNlZTNkMjI2MWFkMmVlNmJmMTJmZmEwNmQ5OGEwODY0ZDg3NjAyNzMzZWM4NmE2NDUyMWYyYjE4MTc3YjIwMGNiYmUxMTc1NzdhNjE1ZDZjNzcwOTg4YzBiYWQ5NDZlMjA4ZTI0ZmEwNzRlNWFiMzE0M2RiNWJmY2UwZmQxMDhlNGI4MmQxMjBhOTIxMDgwMTFhNzIzYzEyYTc4N2U2ZDc4ODcxOWExMGJkYmE1YjI2OTljMzI3MTg2YWY0ZTIzYzFhOTQ2ODM0YjYxNTBiZGEyNTgzZTljYTJhZDQ0Y2U4ZGJiYmMyZGIwNGRlOGVmOTJlOGVmYzE0MWZiZWNhYTYyODdjNTk0NzRlNmJjMDVkOTliMjk2NGZhMDkwYzNhMjIzM2JhMTg2NTE1YmU3ZWQxZjYxMjk3MGNlZTJkN2FmYjgxYmRkNzYyMTcwNDgxY2QwMDY5MTI3ZDViMDVhYTk5M2I0ZWE5ODhkOGZkZGMxODZmZmI3ZGM5MGE2YzA4ZjRkZjQzNWM5MzQwMjg0OTIzNmMzZmFiNGQyN2M3MDI2YzFkNGRjYjI2MDI2NDZkZWM5NzUxZTc2M2RiYTM3YmRmOGZmOTQwNmFkOWU1MzBlZTVkYjM4MmY0MTMwMDFhZWIwNmE1M2VkOTAyN2Q4MzExNzk3MjdiMDg2NWE4OTE4ZGEzZWRiZWJjZjliMTRlZDQ0Y2U2Y2JhY2VkNGJiMWJkYjdmMTQ0N2U2Y2MyNTRiMzMyMDUxNTEyYmQ3YWY0MjZmYjhmNDAxMzc4Y2QyYmY1OTgzY2EwMWM2NGI5MmVjZjAzMmVhMTVkMTcyMWQwM2Y0ODJkN2NlNmU3NGZlZjZkNTVlNzAyZjQ2OTgwYzgyYjVhODQwMzE5MDBiMWM5ZTU5ZTdjOTdmYmVjN2U4ZjMyM2E5N2E3ZTM2Y2M4OGJlMGYxZDQ1YjdmZjU4NWFjNTRiZDQwN2IyMmI0MTU0YWFjYzhmNmQ3ZWJmNDhlMWQ4MTRjYzVlZDIwZjgwMzdlMGE3OTcxNWVlZjI5YmUzMjgwNmExZDU4YmI3YzVkYTc2ZjU1MGFhM2Q4YTFmYmZmMGViMTljY2IxYTMxM2Q1NWNkYTU2YzllYzJlZjI5NjMyMzg3ZmU4ZDc2ZTNjMDQ2ODA0M2U4ZjY2M2Y0ODYwZWUxMmJmMmQ1YjBiNzQ3NGQ2ZTY5NGY5MWU2ZGJlMTE1OTc0YTM5MjZmMTJmZWU1ZTQzODc3N2NiNmE5MzJkZjhjZDhiZWM0ZDA3M2I5MzFiYTNiYzgzMmI2OGQ5ZGQzMDA3NDFmYTdiZjhhZmM0N2VkMjU3NmY2OTM2YmE0MjQ2NjNhYWI2MzljNWFlNGY1NjgzNDIzYjQ3NDJiZjFjOTc4MjM4ZjE2Y2JlMzlkNjUyZGUzZmRiOGJlZmM4NDhhZDkyMjIyMmUwNGE0MDM3YzA3MTNlYjU3YTgxYTIzZjBjNzM0NzNmYzY0NmNlYTMwNmI0YmNiYzg4NjJmODM4NWRkZmE5ZDRiN2ZhMmMwODdlODc5NjgzMzAzZWQ1YmRkM2EwNjJiM2NmNWIzYTI3OGE2NmQyYTEzZjgzZjQ0ZjgyZGRmMzEwZWUwNzRhYjZhMzY0NTk3ZTg5OWEwMjU1ZGMxNjRmMzFjYzUwODQ2ODUxZGY5YWI0ODE5NWRlZDdlYTFiMWQ1MTBiZDdlZTc0ZDczZmFmMzZiYzMxZWNmYTI2ODM1OTA0NmY0ZWI4NzlmOTI0MDA5NDM4YjQ4MWM2Y2Q3ODg5YTAwMmVkNWVlMzgyYmM5MTkwZGE2ZmMwMjZlNDc5NTU4ZTQ0NzU2NzdlOWFhOWUzMDUwZTI3NjU2OTRkZmM4MWY1NmU4ODBiOTZlNzE2MGM5ODBkZDk4ZWRkM2RmZmZmZmZmZmZmZmZmZmZmZlwiXG4gICAgfVxufSIsInZhciBibiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgYnJvcmFuZCA9IHJlcXVpcmUoJ2Jyb3JhbmQnKTtcblxuZnVuY3Rpb24gTWlsbGVyUmFiaW4ocmFuZCkge1xuICB0aGlzLnJhbmQgPSByYW5kIHx8IG5ldyBicm9yYW5kLlJhbmQoKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gTWlsbGVyUmFiaW47XG5cbk1pbGxlclJhYmluLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShyYW5kKSB7XG4gIHJldHVybiBuZXcgTWlsbGVyUmFiaW4ocmFuZCk7XG59O1xuXG5NaWxsZXJSYWJpbi5wcm90b3R5cGUuX3JhbmQgPSBmdW5jdGlvbiBfcmFuZChuKSB7XG4gIHZhciBsZW4gPSBuLmJpdExlbmd0aCgpO1xuICB2YXIgYnVmID0gdGhpcy5yYW5kLmdlbmVyYXRlKE1hdGguY2VpbChsZW4gLyA4KSk7XG5cbiAgLy8gU2V0IGxvdyBiaXRzXG4gIGJ1ZlswXSB8PSAzO1xuXG4gIC8vIE1hc2sgaGlnaCBiaXRzXG4gIHZhciBtYXNrID0gbGVuICYgMHg3O1xuICBpZiAobWFzayAhPT0gMClcbiAgICBidWZbYnVmLmxlbmd0aCAtIDFdID4+PSA3IC0gbWFzaztcblxuICByZXR1cm4gbmV3IGJuKGJ1Zik7XG59XG5cbk1pbGxlclJhYmluLnByb3RvdHlwZS50ZXN0ID0gZnVuY3Rpb24gdGVzdChuLCBrLCBjYikge1xuICB2YXIgbGVuID0gbi5iaXRMZW5ndGgoKTtcbiAgdmFyIHJlZCA9IGJuLm1vbnQobik7XG4gIHZhciByb25lID0gbmV3IGJuKDEpLnRvUmVkKHJlZCk7XG5cbiAgaWYgKCFrKVxuICAgIGsgPSBNYXRoLm1heCgxLCAobGVuIC8gNDgpIHwgMCk7XG5cbiAgLy8gRmluZCBkIGFuZCBzLCAobiAtIDEpID0gKDIgXiBzKSAqIGQ7XG4gIHZhciBuMSA9IG4uc3VibigxKTtcbiAgdmFyIG4yID0gbjEuc3VibigxKTtcbiAgZm9yICh2YXIgcyA9IDA7ICFuMS50ZXN0bihzKTsgcysrKSB7fVxuICB2YXIgZCA9IG4uc2hybihzKTtcblxuICB2YXIgcm4xID0gbjEudG9SZWQocmVkKTtcblxuICB2YXIgcHJpbWUgPSB0cnVlO1xuICBmb3IgKDsgayA+IDA7IGstLSkge1xuICAgIHZhciBhID0gdGhpcy5fcmFuZChuMik7XG4gICAgaWYgKGNiKVxuICAgICAgY2IoYSk7XG5cbiAgICB2YXIgeCA9IGEudG9SZWQocmVkKS5yZWRQb3coZCk7XG4gICAgaWYgKHguY21wKHJvbmUpID09PSAwIHx8IHguY21wKHJuMSkgPT09IDApXG4gICAgICBjb250aW51ZTtcblxuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgczsgaSsrKSB7XG4gICAgICB4ID0geC5yZWRTcXIoKTtcblxuICAgICAgaWYgKHguY21wKHJvbmUpID09PSAwKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICBpZiAoeC5jbXAocm4xKSA9PT0gMClcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKGkgPT09IHMpXG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gcHJpbWU7XG59O1xuXG5NaWxsZXJSYWJpbi5wcm90b3R5cGUuZ2V0RGl2aXNvciA9IGZ1bmN0aW9uIGdldERpdmlzb3Iobiwgaykge1xuICB2YXIgbGVuID0gbi5iaXRMZW5ndGgoKTtcbiAgdmFyIHJlZCA9IGJuLm1vbnQobik7XG4gIHZhciByb25lID0gbmV3IGJuKDEpLnRvUmVkKHJlZCk7XG5cbiAgaWYgKCFrKVxuICAgIGsgPSBNYXRoLm1heCgxLCAobGVuIC8gNDgpIHwgMCk7XG5cbiAgLy8gRmluZCBkIGFuZCBzLCAobiAtIDEpID0gKDIgXiBzKSAqIGQ7XG4gIHZhciBuMSA9IG4uc3VibigxKTtcbiAgdmFyIG4yID0gbjEuc3VibigxKTtcbiAgZm9yICh2YXIgcyA9IDA7ICFuMS50ZXN0bihzKTsgcysrKSB7fVxuICB2YXIgZCA9IG4uc2hybihzKTtcblxuICB2YXIgcm4xID0gbjEudG9SZWQocmVkKTtcblxuICBmb3IgKDsgayA+IDA7IGstLSkge1xuICAgIHZhciBhID0gdGhpcy5fcmFuZChuMik7XG5cbiAgICB2YXIgZyA9IG4uZ2NkKGEpO1xuICAgIGlmIChnLmNtcG4oMSkgIT09IDApXG4gICAgICByZXR1cm4gZztcblxuICAgIHZhciB4ID0gYS50b1JlZChyZWQpLnJlZFBvdyhkKTtcbiAgICBpZiAoeC5jbXAocm9uZSkgPT09IDAgfHwgeC5jbXAocm4xKSA9PT0gMClcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCBzOyBpKyspIHtcbiAgICAgIHggPSB4LnJlZFNxcigpO1xuXG4gICAgICBpZiAoeC5jbXAocm9uZSkgPT09IDApXG4gICAgICAgIHJldHVybiB4LmZyb21SZWQoKS5zdWJuKDEpLmdjZChuKTtcbiAgICAgIGlmICh4LmNtcChybjEpID09PSAwKVxuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoaSA9PT0gcykge1xuICAgICAgeCA9IHgucmVkU3FyKCk7XG4gICAgICByZXR1cm4geC5mcm9tUmVkKCkuc3VibigxKS5nY2Qobik7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufTtcbiIsInZhciBjcmVhdGVIbWFjID0gcmVxdWlyZSgnY3JlYXRlLWhtYWMnKVxudmFyIE1BWF9BTExPQyA9IE1hdGgucG93KDIsIDMwKSAtIDEgLy8gZGVmYXVsdCBpbiBpb2pzXG5cbmV4cG9ydHMucGJrZGYyID0gcGJrZGYyXG5mdW5jdGlvbiBwYmtkZjIgKHBhc3N3b3JkLCBzYWx0LCBpdGVyYXRpb25zLCBrZXlsZW4sIGRpZ2VzdCwgY2FsbGJhY2spIHtcbiAgaWYgKHR5cGVvZiBkaWdlc3QgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IGRpZ2VzdFxuICAgIGRpZ2VzdCA9IHVuZGVmaW5lZFxuICB9XG5cbiAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBFcnJvcignTm8gY2FsbGJhY2sgcHJvdmlkZWQgdG8gcGJrZGYyJylcbiAgfVxuXG4gIHZhciByZXN1bHQgPSBwYmtkZjJTeW5jKHBhc3N3b3JkLCBzYWx0LCBpdGVyYXRpb25zLCBrZXlsZW4sIGRpZ2VzdClcbiAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgY2FsbGJhY2sodW5kZWZpbmVkLCByZXN1bHQpXG4gIH0pXG59XG5cbmV4cG9ydHMucGJrZGYyU3luYyA9IHBia2RmMlN5bmNcbmZ1bmN0aW9uIHBia2RmMlN5bmMgKHBhc3N3b3JkLCBzYWx0LCBpdGVyYXRpb25zLCBrZXlsZW4sIGRpZ2VzdCkge1xuICBpZiAodHlwZW9mIGl0ZXJhdGlvbnMgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSXRlcmF0aW9ucyBub3QgYSBudW1iZXInKVxuICB9XG5cbiAgaWYgKGl0ZXJhdGlvbnMgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQmFkIGl0ZXJhdGlvbnMnKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBrZXlsZW4gIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignS2V5IGxlbmd0aCBub3QgYSBudW1iZXInKVxuICB9XG5cbiAgaWYgKGtleWxlbiA8IDAgfHwga2V5bGVuID4gTUFYX0FMTE9DKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQmFkIGtleSBsZW5ndGgnKVxuICB9XG5cbiAgZGlnZXN0ID0gZGlnZXN0IHx8ICdzaGExJ1xuXG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHBhc3N3b3JkKSkgcGFzc3dvcmQgPSBuZXcgQnVmZmVyKHBhc3N3b3JkLCAnYmluYXJ5JylcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoc2FsdCkpIHNhbHQgPSBuZXcgQnVmZmVyKHNhbHQsICdiaW5hcnknKVxuXG4gIHZhciBoTGVuXG4gIHZhciBsID0gMVxuICB2YXIgREsgPSBuZXcgQnVmZmVyKGtleWxlbilcbiAgdmFyIGJsb2NrMSA9IG5ldyBCdWZmZXIoc2FsdC5sZW5ndGggKyA0KVxuICBzYWx0LmNvcHkoYmxvY2sxLCAwLCAwLCBzYWx0Lmxlbmd0aClcblxuICB2YXIgclxuICB2YXIgVFxuXG4gIGZvciAodmFyIGkgPSAxOyBpIDw9IGw7IGkrKykge1xuICAgIGJsb2NrMS53cml0ZVVJbnQzMkJFKGksIHNhbHQubGVuZ3RoKVxuICAgIHZhciBVID0gY3JlYXRlSG1hYyhkaWdlc3QsIHBhc3N3b3JkKS51cGRhdGUoYmxvY2sxKS5kaWdlc3QoKVxuXG4gICAgaWYgKCFoTGVuKSB7XG4gICAgICBoTGVuID0gVS5sZW5ndGhcbiAgICAgIFQgPSBuZXcgQnVmZmVyKGhMZW4pXG4gICAgICBsID0gTWF0aC5jZWlsKGtleWxlbiAvIGhMZW4pXG4gICAgICByID0ga2V5bGVuIC0gKGwgLSAxKSAqIGhMZW5cbiAgICB9XG5cbiAgICBVLmNvcHkoVCwgMCwgMCwgaExlbilcblxuICAgIGZvciAodmFyIGogPSAxOyBqIDwgaXRlcmF0aW9uczsgaisrKSB7XG4gICAgICBVID0gY3JlYXRlSG1hYyhkaWdlc3QsIHBhc3N3b3JkKS51cGRhdGUoVSkuZGlnZXN0KClcblxuICAgICAgZm9yICh2YXIgayA9IDA7IGsgPCBoTGVuOyBrKyspIHtcbiAgICAgICAgVFtrXSBePSBVW2tdXG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGRlc3RQb3MgPSAoaSAtIDEpICogaExlblxuICAgIHZhciBsZW4gPSAoaSA9PT0gbCA/IHIgOiBoTGVuKVxuICAgIFQuY29weShESywgZGVzdFBvcywgMCwgbGVuKVxuICB9XG5cbiAgcmV0dXJuIERLXG59XG4iLCJleHBvcnRzLnB1YmxpY0VuY3J5cHQgPSByZXF1aXJlKCcuL3B1YmxpY0VuY3J5cHQnKTtcbmV4cG9ydHMucHJpdmF0ZURlY3J5cHQgPSByZXF1aXJlKCcuL3ByaXZhdGVEZWNyeXB0Jyk7XG5cbmV4cG9ydHMucHJpdmF0ZUVuY3J5cHQgPSBmdW5jdGlvbiBwcml2YXRlRW5jcnlwdChrZXksIGJ1Zikge1xuICByZXR1cm4gZXhwb3J0cy5wdWJsaWNFbmNyeXB0KGtleSwgYnVmLCB0cnVlKTtcbn07XG5cbmV4cG9ydHMucHVibGljRGVjcnlwdCA9IGZ1bmN0aW9uIHB1YmxpY0RlY3J5cHQoa2V5LCBidWYpIHtcbiAgcmV0dXJuIGV4cG9ydHMucHJpdmF0ZURlY3J5cHQoa2V5LCBidWYsIHRydWUpO1xufTsiLCJ2YXIgY3JlYXRlSGFzaCA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChzZWVkLCBsZW4pIHtcbiAgdmFyIHQgPSBuZXcgQnVmZmVyKCcnKTtcbiAgdmFyICBpID0gMCwgYztcbiAgd2hpbGUgKHQubGVuZ3RoIDwgbGVuKSB7XG4gICAgYyA9IGkyb3BzKGkrKyk7XG4gICAgdCA9IEJ1ZmZlci5jb25jYXQoW3QsIGNyZWF0ZUhhc2goJ3NoYTEnKS51cGRhdGUoc2VlZCkudXBkYXRlKGMpLmRpZ2VzdCgpXSk7XG4gIH1cbiAgcmV0dXJuIHQuc2xpY2UoMCwgbGVuKTtcbn07XG5cbmZ1bmN0aW9uIGkyb3BzKGMpIHtcbiAgdmFyIG91dCA9IG5ldyBCdWZmZXIoNCk7XG4gIG91dC53cml0ZVVJbnQzMkJFKGMsMCk7XG4gIHJldHVybiBvdXQ7XG59IiwidmFyIGJuID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciByYW5kb21CeXRlcyA9IHJlcXVpcmUoJ3JhbmRvbWJ5dGVzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGNydDtcbmZ1bmN0aW9uIGJsaW5kKHByaXYpIHtcbiAgdmFyIHIgPSBnZXRyKHByaXYpO1xuICB2YXIgYmxpbmRlciA9IHIudG9SZWQoYm4ubW9udChwcml2Lm1vZHVsdXMpKVxuICAucmVkUG93KG5ldyBibihwcml2LnB1YmxpY0V4cG9uZW50KSkuZnJvbVJlZCgpO1xuICByZXR1cm4ge1xuICAgIGJsaW5kZXI6IGJsaW5kZXIsXG4gICAgdW5ibGluZGVyOnIuaW52bShwcml2Lm1vZHVsdXMpXG4gIH07XG59XG5mdW5jdGlvbiBjcnQobXNnLCBwcml2KSB7XG4gIHZhciBibGluZHMgPSBibGluZChwcml2KTtcbiAgdmFyIGxlbiA9IHByaXYubW9kdWx1cy5ieXRlTGVuZ3RoKCk7XG4gIHZhciBtb2QgPSBibi5tb250KHByaXYubW9kdWx1cyk7XG4gIHZhciBibGluZGVkID0gbmV3IGJuKG1zZykubXVsKGJsaW5kcy5ibGluZGVyKS51bW9kKHByaXYubW9kdWx1cyk7XG4gIHZhciBjMSA9IGJsaW5kZWQudG9SZWQoYm4ubW9udChwcml2LnByaW1lMSkpO1xuICB2YXIgYzIgPSBibGluZGVkLnRvUmVkKGJuLm1vbnQocHJpdi5wcmltZTIpKTtcbiAgdmFyIHFpbnYgPSBwcml2LmNvZWZmaWNpZW50O1xuICB2YXIgcCA9IHByaXYucHJpbWUxO1xuICB2YXIgcSA9IHByaXYucHJpbWUyO1xuICB2YXIgbTEgPSBjMS5yZWRQb3cocHJpdi5leHBvbmVudDEpO1xuICB2YXIgbTIgPSBjMi5yZWRQb3cocHJpdi5leHBvbmVudDIpO1xuICBtMSA9IG0xLmZyb21SZWQoKTtcbiAgbTIgPSBtMi5mcm9tUmVkKCk7XG4gIHZhciBoID0gbTEuaXN1YihtMikuaW11bChxaW52KS51bW9kKHApO1xuICBoLmltdWwocSk7XG4gIG0yLmlhZGQoaCk7XG4gIHJldHVybiBuZXcgQnVmZmVyKG0yLmltdWwoYmxpbmRzLnVuYmxpbmRlcikudW1vZChwcml2Lm1vZHVsdXMpLnRvQXJyYXkoZmFsc2UsIGxlbikpO1xufVxuY3J0LmdldHIgPSBnZXRyO1xuZnVuY3Rpb24gZ2V0cihwcml2KSB7XG4gIHZhciBsZW4gPSBwcml2Lm1vZHVsdXMuYnl0ZUxlbmd0aCgpO1xuICB2YXIgciA9IG5ldyBibihyYW5kb21CeXRlcyhsZW4pKTtcbiAgd2hpbGUgKHIuY21wKHByaXYubW9kdWx1cykgPj0gIDAgfHwgIXIudW1vZChwcml2LnByaW1lMSkgfHwgIXIudW1vZChwcml2LnByaW1lMikpIHtcbiAgICByID0gbmV3IGJuKHJhbmRvbUJ5dGVzKGxlbikpO1xuICB9XG4gIHJldHVybiByO1xufVxuIiwiLy8gYWRhcHRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9hcGF0aWwvcGVtc3RyaXBcbnZhciBmaW5kUHJvYyA9IC9Qcm9jLVR5cGU6IDQsRU5DUllQVEVEXFxyP1xcbkRFSy1JbmZvOiBBRVMtKCg/OjEyOCl8KD86MTkyKXwoPzoyNTYpKS1DQkMsKFswLTlBLUhdKylcXHI/XFxuXFxyP1xcbihbMC05QS16XFxuXFxyXFwrXFwvXFw9XSspXFxyP1xcbi9tXG52YXIgc3RhcnRSZWdleCA9IC9eLS0tLS1CRUdJTiAoLiopIEtFWS0tLS0tXFxyP1xcbi9tXG52YXIgZnVsbFJlZ2V4ID0gL14tLS0tLUJFR0lOICguKikgS0VZLS0tLS1cXHI/XFxuKFswLTlBLXpcXG5cXHJcXCtcXC9cXD1dKylcXHI/XFxuLS0tLS1FTkQgXFwxIEtFWS0tLS0tJC9tXG52YXIgZXZwID0gcmVxdWlyZSgnZXZwX2J5dGVzdG9rZXknKVxudmFyIGNpcGhlcnMgPSByZXF1aXJlKCdicm93c2VyaWZ5LWFlcycpXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChva2V5LCBwYXNzd29yZCkge1xuICB2YXIga2V5ID0gb2tleS50b1N0cmluZygpXG4gIHZhciBtYXRjaCA9IGtleS5tYXRjaChmaW5kUHJvYylcbiAgdmFyIGRlY3J5cHRlZFxuICBpZiAoIW1hdGNoKSB7XG4gICAgdmFyIG1hdGNoMiA9IGtleS5tYXRjaChmdWxsUmVnZXgpXG4gICAgZGVjcnlwdGVkID0gbmV3IEJ1ZmZlcihtYXRjaDJbMl0ucmVwbGFjZSgvXFxyP1xcbi9nLCAnJyksICdiYXNlNjQnKVxuICB9IGVsc2Uge1xuICAgIHZhciBzdWl0ZSA9ICdhZXMnICsgbWF0Y2hbMV1cbiAgICB2YXIgaXYgPSBuZXcgQnVmZmVyKG1hdGNoWzJdLCAnaGV4JylcbiAgICB2YXIgY2lwaGVyVGV4dCA9IG5ldyBCdWZmZXIobWF0Y2hbM10ucmVwbGFjZSgvXFxyP1xcbi9nLCAnJyksICdiYXNlNjQnKVxuICAgIHZhciBjaXBoZXJLZXkgPSBldnAocGFzc3dvcmQsIGl2LnNsaWNlKDAsIDgpLCBwYXJzZUludChtYXRjaFsxXSwgMTApKS5rZXlcbiAgICB2YXIgb3V0ID0gW11cbiAgICB2YXIgY2lwaGVyID0gY2lwaGVycy5jcmVhdGVEZWNpcGhlcml2KHN1aXRlLCBjaXBoZXJLZXksIGl2KVxuICAgIG91dC5wdXNoKGNpcGhlci51cGRhdGUoY2lwaGVyVGV4dCkpXG4gICAgb3V0LnB1c2goY2lwaGVyLmZpbmFsKCkpXG4gICAgZGVjcnlwdGVkID0gQnVmZmVyLmNvbmNhdChvdXQpXG4gIH1cbiAgdmFyIHRhZyA9IGtleS5tYXRjaChzdGFydFJlZ2V4KVsxXSArICcgS0VZJ1xuICByZXR1cm4ge1xuICAgIHRhZzogdGFnLFxuICAgIGRhdGE6IGRlY3J5cHRlZFxuICB9XG59XG4iLCJ2YXIgYXNuMSA9IHJlcXVpcmUoJy4vYXNuMScpXG52YXIgYWVzaWQgPSByZXF1aXJlKCcuL2Flc2lkLmpzb24nKVxudmFyIGZpeFByb2MgPSByZXF1aXJlKCcuL2ZpeFByb2MnKVxudmFyIGNpcGhlcnMgPSByZXF1aXJlKCdicm93c2VyaWZ5LWFlcycpXG52YXIgY29tcGF0ID0gcmVxdWlyZSgncGJrZGYyJylcbm1vZHVsZS5leHBvcnRzID0gcGFyc2VLZXlzXG5cbmZ1bmN0aW9uIHBhcnNlS2V5cyAoYnVmZmVyKSB7XG4gIHZhciBwYXNzd29yZFxuICBpZiAodHlwZW9mIGJ1ZmZlciA9PT0gJ29iamVjdCcgJiYgIUJ1ZmZlci5pc0J1ZmZlcihidWZmZXIpKSB7XG4gICAgcGFzc3dvcmQgPSBidWZmZXIucGFzc3BocmFzZVxuICAgIGJ1ZmZlciA9IGJ1ZmZlci5rZXlcbiAgfVxuICBpZiAodHlwZW9mIGJ1ZmZlciA9PT0gJ3N0cmluZycpIHtcbiAgICBidWZmZXIgPSBuZXcgQnVmZmVyKGJ1ZmZlcilcbiAgfVxuXG4gIHZhciBzdHJpcHBlZCA9IGZpeFByb2MoYnVmZmVyLCBwYXNzd29yZClcblxuICB2YXIgdHlwZSA9IHN0cmlwcGVkLnRhZ1xuICB2YXIgZGF0YSA9IHN0cmlwcGVkLmRhdGFcbiAgdmFyIHN1YnR5cGUsIG5kYXRhXG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ1BVQkxJQyBLRVknOlxuICAgICAgbmRhdGEgPSBhc24xLlB1YmxpY0tleS5kZWNvZGUoZGF0YSwgJ2RlcicpXG4gICAgICBzdWJ0eXBlID0gbmRhdGEuYWxnb3JpdGhtLmFsZ29yaXRobS5qb2luKCcuJylcbiAgICAgIHN3aXRjaCAoc3VidHlwZSkge1xuICAgICAgICBjYXNlICcxLjIuODQwLjExMzU0OS4xLjEuMSc6XG4gICAgICAgICAgcmV0dXJuIGFzbjEuUlNBUHVibGljS2V5LmRlY29kZShuZGF0YS5zdWJqZWN0UHVibGljS2V5LmRhdGEsICdkZXInKVxuICAgICAgICBjYXNlICcxLjIuODQwLjEwMDQ1LjIuMSc6XG4gICAgICAgICAgbmRhdGEuc3ViamVjdFByaXZhdGVLZXkgPSBuZGF0YS5zdWJqZWN0UHVibGljS2V5XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdlYycsXG4gICAgICAgICAgICBkYXRhOiBuZGF0YVxuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAnMS4yLjg0MC4xMDA0MC40LjEnOlxuICAgICAgICAgIG5kYXRhLmFsZ29yaXRobS5wYXJhbXMucHViX2tleSA9IGFzbjEuRFNBcGFyYW0uZGVjb2RlKG5kYXRhLnN1YmplY3RQdWJsaWNLZXkuZGF0YSwgJ2RlcicpXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdkc2EnLFxuICAgICAgICAgICAgZGF0YTogbmRhdGEuYWxnb3JpdGhtLnBhcmFtc1xuICAgICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGtleSBpZCAnICsgc3VidHlwZSlcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBrZXkgdHlwZSAnICsgdHlwZSlcbiAgICBjYXNlICdFTkNSWVBURUQgUFJJVkFURSBLRVknOlxuICAgICAgZGF0YSA9IGFzbjEuRW5jcnlwdGVkUHJpdmF0ZUtleS5kZWNvZGUoZGF0YSwgJ2RlcicpXG4gICAgICBkYXRhID0gZGVjcnlwdChkYXRhLCBwYXNzd29yZClcbiAgICAgIC8vIGZhbGxzIHRocm91Z2hcbiAgICBjYXNlICdQUklWQVRFIEtFWSc6XG4gICAgICBuZGF0YSA9IGFzbjEuUHJpdmF0ZUtleS5kZWNvZGUoZGF0YSwgJ2RlcicpXG4gICAgICBzdWJ0eXBlID0gbmRhdGEuYWxnb3JpdGhtLmFsZ29yaXRobS5qb2luKCcuJylcbiAgICAgIHN3aXRjaCAoc3VidHlwZSkge1xuICAgICAgICBjYXNlICcxLjIuODQwLjExMzU0OS4xLjEuMSc6XG4gICAgICAgICAgcmV0dXJuIGFzbjEuUlNBUHJpdmF0ZUtleS5kZWNvZGUobmRhdGEuc3ViamVjdFByaXZhdGVLZXksICdkZXInKVxuICAgICAgICBjYXNlICcxLjIuODQwLjEwMDQ1LjIuMSc6XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGN1cnZlOiBuZGF0YS5hbGdvcml0aG0uY3VydmUsXG4gICAgICAgICAgICBwcml2YXRlS2V5OiBhc24xLkVDUHJpdmF0ZUtleS5kZWNvZGUobmRhdGEuc3ViamVjdFByaXZhdGVLZXksICdkZXInKS5wcml2YXRlS2V5XG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICcxLjIuODQwLjEwMDQwLjQuMSc6XG4gICAgICAgICAgbmRhdGEuYWxnb3JpdGhtLnBhcmFtcy5wcml2X2tleSA9IGFzbjEuRFNBcGFyYW0uZGVjb2RlKG5kYXRhLnN1YmplY3RQcml2YXRlS2V5LCAnZGVyJylcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ2RzYScsXG4gICAgICAgICAgICBwYXJhbXM6IG5kYXRhLmFsZ29yaXRobS5wYXJhbXNcbiAgICAgICAgICB9XG4gICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcigndW5rbm93biBrZXkgaWQgJyArIHN1YnR5cGUpXG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24ga2V5IHR5cGUgJyArIHR5cGUpXG4gICAgY2FzZSAnUlNBIFBVQkxJQyBLRVknOlxuICAgICAgcmV0dXJuIGFzbjEuUlNBUHVibGljS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICBjYXNlICdSU0EgUFJJVkFURSBLRVknOlxuICAgICAgcmV0dXJuIGFzbjEuUlNBUHJpdmF0ZUtleS5kZWNvZGUoZGF0YSwgJ2RlcicpXG4gICAgY2FzZSAnRFNBIFBSSVZBVEUgS0VZJzpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdkc2EnLFxuICAgICAgICBwYXJhbXM6IGFzbjEuRFNBUHJpdmF0ZUtleS5kZWNvZGUoZGF0YSwgJ2RlcicpXG4gICAgICB9XG4gICAgY2FzZSAnRUMgUFJJVkFURSBLRVknOlxuICAgICAgZGF0YSA9IGFzbjEuRUNQcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGN1cnZlOiBkYXRhLnBhcmFtZXRlcnMudmFsdWUsXG4gICAgICAgIHByaXZhdGVLZXk6IGRhdGEucHJpdmF0ZUtleVxuICAgICAgfVxuICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcigndW5rbm93biBrZXkgdHlwZSAnICsgdHlwZSlcbiAgfVxufVxucGFyc2VLZXlzLnNpZ25hdHVyZSA9IGFzbjEuc2lnbmF0dXJlXG5mdW5jdGlvbiBkZWNyeXB0IChkYXRhLCBwYXNzd29yZCkge1xuICB2YXIgc2FsdCA9IGRhdGEuYWxnb3JpdGhtLmRlY3J5cHQua2RlLmtkZXBhcmFtcy5zYWx0XG4gIHZhciBpdGVycyA9IHBhcnNlSW50KGRhdGEuYWxnb3JpdGhtLmRlY3J5cHQua2RlLmtkZXBhcmFtcy5pdGVycy50b1N0cmluZygpLCAxMClcbiAgdmFyIGFsZ28gPSBhZXNpZFtkYXRhLmFsZ29yaXRobS5kZWNyeXB0LmNpcGhlci5hbGdvLmpvaW4oJy4nKV1cbiAgdmFyIGl2ID0gZGF0YS5hbGdvcml0aG0uZGVjcnlwdC5jaXBoZXIuaXZcbiAgdmFyIGNpcGhlclRleHQgPSBkYXRhLnN1YmplY3RQcml2YXRlS2V5XG4gIHZhciBrZXlsZW4gPSBwYXJzZUludChhbGdvLnNwbGl0KCctJylbMV0sIDEwKSAvIDhcbiAgdmFyIGtleSA9IGNvbXBhdC5wYmtkZjJTeW5jKHBhc3N3b3JkLCBzYWx0LCBpdGVycywga2V5bGVuKVxuICB2YXIgY2lwaGVyID0gY2lwaGVycy5jcmVhdGVEZWNpcGhlcml2KGFsZ28sIGtleSwgaXYpXG4gIHZhciBvdXQgPSBbXVxuICBvdXQucHVzaChjaXBoZXIudXBkYXRlKGNpcGhlclRleHQpKVxuICBvdXQucHVzaChjaXBoZXIuZmluYWwoKSlcbiAgcmV0dXJuIEJ1ZmZlci5jb25jYXQob3V0KVxufVxuIiwiLy8gYmFzZWQgb24gdGhlIGFlcyBpbXBsaW1lbnRhdGlvbiBpbiB0cmlwbGUgc2VjXG4vLyBodHRwczovL2dpdGh1Yi5jb20va2V5YmFzZS90cmlwbGVzZWNcblxuLy8gd2hpY2ggaXMgaW4gdHVybiBiYXNlZCBvbiB0aGUgb25lIGZyb20gY3J5cHRvLWpzXG4vLyBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qcy9cblxudmFyIHVpbnRfbWF4ID0gTWF0aC5wb3coMiwgMzIpXG5mdW5jdGlvbiBmaXh1cF91aW50MzIgKHgpIHtcbiAgdmFyIHJldCwgeF9wb3NcbiAgcmV0ID0geCA+IHVpbnRfbWF4IHx8IHggPCAwID8gKHhfcG9zID0gTWF0aC5hYnMoeCkgJSB1aW50X21heCwgeCA8IDAgPyB1aW50X21heCAtIHhfcG9zIDogeF9wb3MpIDogeFxuICByZXR1cm4gcmV0XG59XG5mdW5jdGlvbiBzY3J1Yl92ZWMgKHYpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB2Lmxlbmd0aDsgdisrKSB7XG4gICAgdltpXSA9IDBcbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cblxuZnVuY3Rpb24gR2xvYmFsICgpIHtcbiAgdGhpcy5TQk9YID0gW11cbiAgdGhpcy5JTlZfU0JPWCA9IFtdXG4gIHRoaXMuU1VCX01JWCA9IFtbXSwgW10sIFtdLCBbXV1cbiAgdGhpcy5JTlZfU1VCX01JWCA9IFtbXSwgW10sIFtdLCBbXV1cbiAgdGhpcy5pbml0KClcbiAgdGhpcy5SQ09OID0gWzB4MDAsIDB4MDEsIDB4MDIsIDB4MDQsIDB4MDgsIDB4MTAsIDB4MjAsIDB4NDAsIDB4ODAsIDB4MWIsIDB4MzZdXG59XG5cbkdsb2JhbC5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGQsIGksIHN4LCB0LCB4LCB4MiwgeDQsIHg4LCB4aSwgX2lcbiAgZCA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIF9pLCBfcmVzdWx0c1xuICAgIF9yZXN1bHRzID0gW11cbiAgICBmb3IgKGkgPSBfaSA9IDA7IF9pIDwgMjU2OyBpID0gKytfaSkge1xuICAgICAgaWYgKGkgPCAxMjgpIHtcbiAgICAgICAgX3Jlc3VsdHMucHVzaChpIDw8IDEpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfcmVzdWx0cy5wdXNoKChpIDw8IDEpIF4gMHgxMWIpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBfcmVzdWx0c1xuICB9KSgpXG4gIHggPSAwXG4gIHhpID0gMFxuICBmb3IgKGkgPSBfaSA9IDA7IF9pIDwgMjU2OyBpID0gKytfaSkge1xuICAgIHN4ID0geGkgXiAoeGkgPDwgMSkgXiAoeGkgPDwgMikgXiAoeGkgPDwgMykgXiAoeGkgPDwgNClcbiAgICBzeCA9IChzeCA+Pj4gOCkgXiAoc3ggJiAweGZmKSBeIDB4NjNcbiAgICB0aGlzLlNCT1hbeF0gPSBzeFxuICAgIHRoaXMuSU5WX1NCT1hbc3hdID0geFxuICAgIHgyID0gZFt4XVxuICAgIHg0ID0gZFt4Ml1cbiAgICB4OCA9IGRbeDRdXG4gICAgdCA9IChkW3N4XSAqIDB4MTAxKSBeIChzeCAqIDB4MTAxMDEwMClcbiAgICB0aGlzLlNVQl9NSVhbMF1beF0gPSAodCA8PCAyNCkgfCAodCA+Pj4gOClcbiAgICB0aGlzLlNVQl9NSVhbMV1beF0gPSAodCA8PCAxNikgfCAodCA+Pj4gMTYpXG4gICAgdGhpcy5TVUJfTUlYWzJdW3hdID0gKHQgPDwgOCkgfCAodCA+Pj4gMjQpXG4gICAgdGhpcy5TVUJfTUlYWzNdW3hdID0gdFxuICAgIHQgPSAoeDggKiAweDEwMTAxMDEpIF4gKHg0ICogMHgxMDAwMSkgXiAoeDIgKiAweDEwMSkgXiAoeCAqIDB4MTAxMDEwMClcbiAgICB0aGlzLklOVl9TVUJfTUlYWzBdW3N4XSA9ICh0IDw8IDI0KSB8ICh0ID4+PiA4KVxuICAgIHRoaXMuSU5WX1NVQl9NSVhbMV1bc3hdID0gKHQgPDwgMTYpIHwgKHQgPj4+IDE2KVxuICAgIHRoaXMuSU5WX1NVQl9NSVhbMl1bc3hdID0gKHQgPDwgOCkgfCAodCA+Pj4gMjQpXG4gICAgdGhpcy5JTlZfU1VCX01JWFszXVtzeF0gPSB0XG4gICAgaWYgKHggPT09IDApIHtcbiAgICAgIHggPSB4aSA9IDFcbiAgICB9IGVsc2Uge1xuICAgICAgeCA9IHgyIF4gZFtkW2RbeDggXiB4Ml1dXVxuICAgICAgeGkgXj0gZFtkW3hpXV1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWVcbn1cblxudmFyIEcgPSBuZXcgR2xvYmFsKClcblxuQUVTLmJsb2NrU2l6ZSA9IDQgKiA0XG5cbkFFUy5wcm90b3R5cGUuYmxvY2tTaXplID0gQUVTLmJsb2NrU2l6ZVxuXG5BRVMua2V5U2l6ZSA9IDI1NiAvIDhcblxuQUVTLnByb3RvdHlwZS5rZXlTaXplID0gQUVTLmtleVNpemVcblxuZnVuY3Rpb24gYnVmZmVyVG9BcnJheSAoYnVmKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoIC8gNFxuICB2YXIgb3V0ID0gbmV3IEFycmF5KGxlbilcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgb3V0W2ldID0gYnVmLnJlYWRVSW50MzJCRShpICogNClcbiAgfVxuICByZXR1cm4gb3V0XG59XG5mdW5jdGlvbiBBRVMgKGtleSkge1xuICB0aGlzLl9rZXkgPSBidWZmZXJUb0FycmF5KGtleSlcbiAgdGhpcy5fZG9SZXNldCgpXG59XG5cbkFFUy5wcm90b3R5cGUuX2RvUmVzZXQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBpbnZLc1Jvdywga2V5U2l6ZSwga2V5V29yZHMsIGtzUm93LCBrc1Jvd3MsIHRcbiAga2V5V29yZHMgPSB0aGlzLl9rZXlcbiAga2V5U2l6ZSA9IGtleVdvcmRzLmxlbmd0aFxuICB0aGlzLl9uUm91bmRzID0ga2V5U2l6ZSArIDZcbiAga3NSb3dzID0gKHRoaXMuX25Sb3VuZHMgKyAxKSAqIDRcbiAgdGhpcy5fa2V5U2NoZWR1bGUgPSBbXVxuICBmb3IgKGtzUm93ID0gMDsga3NSb3cgPCBrc1Jvd3M7IGtzUm93KyspIHtcbiAgICB0aGlzLl9rZXlTY2hlZHVsZVtrc1Jvd10gPSBrc1JvdyA8IGtleVNpemUgPyBrZXlXb3Jkc1trc1Jvd10gOiAodCA9IHRoaXMuX2tleVNjaGVkdWxlW2tzUm93IC0gMV0sIChrc1JvdyAlIGtleVNpemUpID09PSAwID8gKHQgPSAodCA8PCA4KSB8ICh0ID4+PiAyNCksIHQgPSAoRy5TQk9YW3QgPj4+IDI0XSA8PCAyNCkgfCAoRy5TQk9YWyh0ID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoRy5TQk9YWyh0ID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgRy5TQk9YW3QgJiAweGZmXSwgdCBePSBHLlJDT05bKGtzUm93IC8ga2V5U2l6ZSkgfCAwXSA8PCAyNCkgOiBrZXlTaXplID4gNiAmJiBrc1JvdyAlIGtleVNpemUgPT09IDQgPyB0ID0gKEcuU0JPWFt0ID4+PiAyNF0gPDwgMjQpIHwgKEcuU0JPWFsodCA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKEcuU0JPWFsodCA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IEcuU0JPWFt0ICYgMHhmZl0gOiB2b2lkIDAsIHRoaXMuX2tleVNjaGVkdWxlW2tzUm93IC0ga2V5U2l6ZV0gXiB0KVxuICB9XG4gIHRoaXMuX2ludktleVNjaGVkdWxlID0gW11cbiAgZm9yIChpbnZLc1JvdyA9IDA7IGludktzUm93IDwga3NSb3dzOyBpbnZLc1JvdysrKSB7XG4gICAga3NSb3cgPSBrc1Jvd3MgLSBpbnZLc1Jvd1xuICAgIHQgPSB0aGlzLl9rZXlTY2hlZHVsZVtrc1JvdyAtIChpbnZLc1JvdyAlIDQgPyAwIDogNCldXG4gICAgdGhpcy5faW52S2V5U2NoZWR1bGVbaW52S3NSb3ddID0gaW52S3NSb3cgPCA0IHx8IGtzUm93IDw9IDQgPyB0IDogRy5JTlZfU1VCX01JWFswXVtHLlNCT1hbdCA+Pj4gMjRdXSBeIEcuSU5WX1NVQl9NSVhbMV1bRy5TQk9YWyh0ID4+PiAxNikgJiAweGZmXV0gXiBHLklOVl9TVUJfTUlYWzJdW0cuU0JPWFsodCA+Pj4gOCkgJiAweGZmXV0gXiBHLklOVl9TVUJfTUlYWzNdW0cuU0JPWFt0ICYgMHhmZl1dXG4gIH1cbiAgcmV0dXJuIHRydWVcbn1cblxuQUVTLnByb3RvdHlwZS5lbmNyeXB0QmxvY2sgPSBmdW5jdGlvbiAoTSkge1xuICBNID0gYnVmZmVyVG9BcnJheShuZXcgQnVmZmVyKE0pKVxuICB2YXIgb3V0ID0gdGhpcy5fZG9DcnlwdEJsb2NrKE0sIHRoaXMuX2tleVNjaGVkdWxlLCBHLlNVQl9NSVgsIEcuU0JPWClcbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoMTYpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFswXSwgMClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzFdLCA0KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMl0sIDgpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFszXSwgMTIpXG4gIHJldHVybiBidWZcbn1cblxuQUVTLnByb3RvdHlwZS5kZWNyeXB0QmxvY2sgPSBmdW5jdGlvbiAoTSkge1xuICBNID0gYnVmZmVyVG9BcnJheShuZXcgQnVmZmVyKE0pKVxuICB2YXIgdGVtcCA9IFtNWzNdLCBNWzFdXVxuICBNWzFdID0gdGVtcFswXVxuICBNWzNdID0gdGVtcFsxXVxuICB2YXIgb3V0ID0gdGhpcy5fZG9DcnlwdEJsb2NrKE0sIHRoaXMuX2ludktleVNjaGVkdWxlLCBHLklOVl9TVUJfTUlYLCBHLklOVl9TQk9YKVxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcigxNilcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzBdLCAwKVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbM10sIDQpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsyXSwgOClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzFdLCAxMilcbiAgcmV0dXJuIGJ1ZlxufVxuXG5BRVMucHJvdG90eXBlLnNjcnViID0gZnVuY3Rpb24gKCkge1xuICBzY3J1Yl92ZWModGhpcy5fa2V5U2NoZWR1bGUpXG4gIHNjcnViX3ZlYyh0aGlzLl9pbnZLZXlTY2hlZHVsZSlcbiAgc2NydWJfdmVjKHRoaXMuX2tleSlcbn1cblxuQUVTLnByb3RvdHlwZS5fZG9DcnlwdEJsb2NrID0gZnVuY3Rpb24gKE0sIGtleVNjaGVkdWxlLCBTVUJfTUlYLCBTQk9YKSB7XG4gIHZhciBrc1JvdywgczAsIHMxLCBzMiwgczMsIHQwLCB0MSwgdDIsIHQzXG5cbiAgczAgPSBNWzBdIF4ga2V5U2NoZWR1bGVbMF1cbiAgczEgPSBNWzFdIF4ga2V5U2NoZWR1bGVbMV1cbiAgczIgPSBNWzJdIF4ga2V5U2NoZWR1bGVbMl1cbiAgczMgPSBNWzNdIF4ga2V5U2NoZWR1bGVbM11cbiAga3NSb3cgPSA0XG4gIGZvciAodmFyIHJvdW5kID0gMTsgcm91bmQgPCB0aGlzLl9uUm91bmRzOyByb3VuZCsrKSB7XG4gICAgdDAgPSBTVUJfTUlYWzBdW3MwID4+PiAyNF0gXiBTVUJfTUlYWzFdWyhzMSA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYWzJdWyhzMiA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhbM11bczMgJiAweGZmXSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gICAgdDEgPSBTVUJfTUlYWzBdW3MxID4+PiAyNF0gXiBTVUJfTUlYWzFdWyhzMiA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYWzJdWyhzMyA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhbM11bczAgJiAweGZmXSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gICAgdDIgPSBTVUJfTUlYWzBdW3MyID4+PiAyNF0gXiBTVUJfTUlYWzFdWyhzMyA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYWzJdWyhzMCA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhbM11bczEgJiAweGZmXSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gICAgdDMgPSBTVUJfTUlYWzBdW3MzID4+PiAyNF0gXiBTVUJfTUlYWzFdWyhzMCA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYWzJdWyhzMSA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhbM11bczIgJiAweGZmXSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gICAgczAgPSB0MFxuICAgIHMxID0gdDFcbiAgICBzMiA9IHQyXG4gICAgczMgPSB0M1xuICB9XG4gIHQwID0gKChTQk9YW3MwID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMxID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczIgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MzICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgdDEgPSAoKFNCT1hbczEgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczIgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMyA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczAgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICB0MiA9ICgoU0JPWFtzMiA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMyA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMwID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMSAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gIHQzID0gKChTQk9YW3MzID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMwID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczEgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MyICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgcmV0dXJuIFtcbiAgICBmaXh1cF91aW50MzIodDApLFxuICAgIGZpeHVwX3VpbnQzMih0MSksXG4gICAgZml4dXBfdWludDMyKHQyKSxcbiAgICBmaXh1cF91aW50MzIodDMpXG4gIF1cbn1cblxuZXhwb3J0cy5BRVMgPSBBRVNcbiIsInZhciBhZXMgPSByZXF1aXJlKCcuL2FlcycpXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEdIQVNIID0gcmVxdWlyZSgnLi9naGFzaCcpXG52YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG5pbmhlcml0cyhTdHJlYW1DaXBoZXIsIFRyYW5zZm9ybSlcbm1vZHVsZS5leHBvcnRzID0gU3RyZWFtQ2lwaGVyXG5cbmZ1bmN0aW9uIFN0cmVhbUNpcGhlciAobW9kZSwga2V5LCBpdiwgZGVjcnlwdCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3RyZWFtQ2lwaGVyKSkge1xuICAgIHJldHVybiBuZXcgU3RyZWFtQ2lwaGVyKG1vZGUsIGtleSwgaXYpXG4gIH1cbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5fZmluSUQgPSBCdWZmZXIuY29uY2F0KFtpdiwgbmV3IEJ1ZmZlcihbMCwgMCwgMCwgMV0pXSlcbiAgaXYgPSBCdWZmZXIuY29uY2F0KFtpdiwgbmV3IEJ1ZmZlcihbMCwgMCwgMCwgMl0pXSlcbiAgdGhpcy5fY2lwaGVyID0gbmV3IGFlcy5BRVMoa2V5KVxuICB0aGlzLl9wcmV2ID0gbmV3IEJ1ZmZlcihpdi5sZW5ndGgpXG4gIHRoaXMuX2NhY2hlID0gbmV3IEJ1ZmZlcignJylcbiAgdGhpcy5fc2VjQ2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxuICB0aGlzLl9kZWNyeXB0ID0gZGVjcnlwdFxuICB0aGlzLl9hbGVuID0gMFxuICB0aGlzLl9sZW4gPSAwXG4gIGl2LmNvcHkodGhpcy5fcHJldilcbiAgdGhpcy5fbW9kZSA9IG1vZGVcbiAgdmFyIGggPSBuZXcgQnVmZmVyKDQpXG4gIGguZmlsbCgwKVxuICB0aGlzLl9naGFzaCA9IG5ldyBHSEFTSCh0aGlzLl9jaXBoZXIuZW5jcnlwdEJsb2NrKGgpKVxuICB0aGlzLl9hdXRoVGFnID0gbnVsbFxuICB0aGlzLl9jYWxsZWQgPSBmYWxzZVxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gIGlmICghdGhpcy5fY2FsbGVkICYmIHRoaXMuX2FsZW4pIHtcbiAgICB2YXIgcnVtcCA9IDE2IC0gKHRoaXMuX2FsZW4gJSAxNilcbiAgICBpZiAocnVtcCA8IDE2KSB7XG4gICAgICBydW1wID0gbmV3IEJ1ZmZlcihydW1wKVxuICAgICAgcnVtcC5maWxsKDApXG4gICAgICB0aGlzLl9naGFzaC51cGRhdGUocnVtcClcbiAgICB9XG4gIH1cbiAgdGhpcy5fY2FsbGVkID0gdHJ1ZVxuICB2YXIgb3V0ID0gdGhpcy5fbW9kZS5lbmNyeXB0KHRoaXMsIGNodW5rKVxuICBpZiAodGhpcy5fZGVjcnlwdCkge1xuICAgIHRoaXMuX2doYXNoLnVwZGF0ZShjaHVuaylcbiAgfSBlbHNlIHtcbiAgICB0aGlzLl9naGFzaC51cGRhdGUob3V0KVxuICB9XG4gIHRoaXMuX2xlbiArPSBjaHVuay5sZW5ndGhcbiAgcmV0dXJuIG91dFxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLl9kZWNyeXB0ICYmICF0aGlzLl9hdXRoVGFnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBzdGF0ZSBvciB1bmFibGUgdG8gYXV0aGVudGljYXRlIGRhdGEnKVxuICB9XG4gIHZhciB0YWcgPSB4b3IodGhpcy5fZ2hhc2guZmluYWwodGhpcy5fYWxlbiAqIDgsIHRoaXMuX2xlbiAqIDgpLCB0aGlzLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHRoaXMuX2ZpbklEKSlcbiAgaWYgKHRoaXMuX2RlY3J5cHQpIHtcbiAgICBpZiAoeG9yVGVzdCh0YWcsIHRoaXMuX2F1dGhUYWcpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIHN0YXRlIG9yIHVuYWJsZSB0byBhdXRoZW50aWNhdGUgZGF0YScpXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRoaXMuX2F1dGhUYWcgPSB0YWdcbiAgfVxuICB0aGlzLl9jaXBoZXIuc2NydWIoKVxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5nZXRBdXRoVGFnID0gZnVuY3Rpb24gZ2V0QXV0aFRhZyAoKSB7XG4gIGlmICghdGhpcy5fZGVjcnlwdCAmJiBCdWZmZXIuaXNCdWZmZXIodGhpcy5fYXV0aFRhZykpIHtcbiAgICByZXR1cm4gdGhpcy5fYXV0aFRhZ1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignQXR0ZW1wdGluZyB0byBnZXQgYXV0aCB0YWcgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxuICB9XG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLnNldEF1dGhUYWcgPSBmdW5jdGlvbiBzZXRBdXRoVGFnICh0YWcpIHtcbiAgaWYgKHRoaXMuX2RlY3J5cHQpIHtcbiAgICB0aGlzLl9hdXRoVGFnID0gdGFnXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIHNldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG4gIH1cbn1cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuc2V0QUFEID0gZnVuY3Rpb24gc2V0QUFEIChidWYpIHtcbiAgaWYgKCF0aGlzLl9jYWxsZWQpIHtcbiAgICB0aGlzLl9naGFzaC51cGRhdGUoYnVmKVxuICAgIHRoaXMuX2FsZW4gKz0gYnVmLmxlbmd0aFxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignQXR0ZW1wdGluZyB0byBzZXQgQUFEIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbiAgfVxufVxuZnVuY3Rpb24geG9yVGVzdCAoYSwgYikge1xuICB2YXIgb3V0ID0gMFxuICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSB7XG4gICAgb3V0KytcbiAgfVxuICB2YXIgbGVuID0gTWF0aC5taW4oYS5sZW5ndGgsIGIubGVuZ3RoKVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXQgKz0gKGFbaV0gXiBiW2ldKVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsInZhciBhZXMgPSByZXF1aXJlKCcuL2FlcycpXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIG1vZGVzID0gcmVxdWlyZSgnLi9tb2RlcycpXG52YXIgU3RyZWFtQ2lwaGVyID0gcmVxdWlyZSgnLi9zdHJlYW1DaXBoZXInKVxudmFyIEF1dGhDaXBoZXIgPSByZXF1aXJlKCcuL2F1dGhDaXBoZXInKVxudmFyIGVidGsgPSByZXF1aXJlKCdldnBfYnl0ZXN0b2tleScpXG5cbmluaGVyaXRzKERlY2lwaGVyLCBUcmFuc2Zvcm0pXG5mdW5jdGlvbiBEZWNpcGhlciAobW9kZSwga2V5LCBpdikge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgRGVjaXBoZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBEZWNpcGhlcihtb2RlLCBrZXksIGl2KVxuICB9XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG4gIHRoaXMuX2NhY2hlID0gbmV3IFNwbGl0dGVyKClcbiAgdGhpcy5fbGFzdCA9IHZvaWQgMFxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHRoaXMuX3ByZXYgPSBuZXcgQnVmZmVyKGl2Lmxlbmd0aClcbiAgaXYuY29weSh0aGlzLl9wcmV2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxuICB0aGlzLl9hdXRvcGFkZGluZyA9IHRydWVcbn1cbkRlY2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5fY2FjaGUuYWRkKGRhdGEpXG4gIHZhciBjaHVua1xuICB2YXIgdGhpbmdcbiAgdmFyIG91dCA9IFtdXG4gIHdoaWxlICgoY2h1bmsgPSB0aGlzLl9jYWNoZS5nZXQodGhpcy5fYXV0b3BhZGRpbmcpKSkge1xuICAgIHRoaW5nID0gdGhpcy5fbW9kZS5kZWNyeXB0KHRoaXMsIGNodW5rKVxuICAgIG91dC5wdXNoKHRoaW5nKVxuICB9XG4gIHJldHVybiBCdWZmZXIuY29uY2F0KG91dClcbn1cbkRlY2lwaGVyLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBjaHVuayA9IHRoaXMuX2NhY2hlLmZsdXNoKClcbiAgaWYgKHRoaXMuX2F1dG9wYWRkaW5nKSB7XG4gICAgcmV0dXJuIHVucGFkKHRoaXMuX21vZGUuZGVjcnlwdCh0aGlzLCBjaHVuaykpXG4gIH0gZWxzZSBpZiAoY2h1bmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RhdGEgbm90IG11bHRpcGxlIG9mIGJsb2NrIGxlbmd0aCcpXG4gIH1cbn1cbkRlY2lwaGVyLnByb3RvdHlwZS5zZXRBdXRvUGFkZGluZyA9IGZ1bmN0aW9uIChzZXRUbykge1xuICB0aGlzLl9hdXRvcGFkZGluZyA9ICEhc2V0VG9cbiAgcmV0dXJuIHRoaXNcbn1cbmZ1bmN0aW9uIFNwbGl0dGVyICgpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNwbGl0dGVyKSkge1xuICAgIHJldHVybiBuZXcgU3BsaXR0ZXIoKVxuICB9XG4gIHRoaXMuY2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxufVxuU3BsaXR0ZXIucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuY2FjaGUgPSBCdWZmZXIuY29uY2F0KFt0aGlzLmNhY2hlLCBkYXRhXSlcbn1cblxuU3BsaXR0ZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChhdXRvUGFkZGluZykge1xuICB2YXIgb3V0XG4gIGlmIChhdXRvUGFkZGluZykge1xuICAgIGlmICh0aGlzLmNhY2hlLmxlbmd0aCA+IDE2KSB7XG4gICAgICBvdXQgPSB0aGlzLmNhY2hlLnNsaWNlKDAsIDE2KVxuICAgICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgICByZXR1cm4gb3V0XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmICh0aGlzLmNhY2hlLmxlbmd0aCA+PSAxNikge1xuICAgICAgb3V0ID0gdGhpcy5jYWNoZS5zbGljZSgwLCAxNilcbiAgICAgIHRoaXMuY2FjaGUgPSB0aGlzLmNhY2hlLnNsaWNlKDE2KVxuICAgICAgcmV0dXJuIG91dFxuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbFxufVxuU3BsaXR0ZXIucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jYWNoZS5sZW5ndGgpIHtcbiAgICByZXR1cm4gdGhpcy5jYWNoZVxuICB9XG59XG5mdW5jdGlvbiB1bnBhZCAobGFzdCkge1xuICB2YXIgcGFkZGVkID0gbGFzdFsxNV1cbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgcGFkZGVkKSB7XG4gICAgaWYgKGxhc3RbKGkgKyAoMTYgLSBwYWRkZWQpKV0gIT09IHBhZGRlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmFibGUgdG8gZGVjcnlwdCBkYXRhJylcbiAgICB9XG4gIH1cbiAgaWYgKHBhZGRlZCA9PT0gMTYpIHtcbiAgICByZXR1cm5cbiAgfVxuICByZXR1cm4gbGFzdC5zbGljZSgwLCAxNiAtIHBhZGRlZClcbn1cblxudmFyIG1vZGVsaXN0ID0ge1xuICBFQ0I6IHJlcXVpcmUoJy4vbW9kZXMvZWNiJyksXG4gIENCQzogcmVxdWlyZSgnLi9tb2Rlcy9jYmMnKSxcbiAgQ0ZCOiByZXF1aXJlKCcuL21vZGVzL2NmYicpLFxuICBDRkI4OiByZXF1aXJlKCcuL21vZGVzL2NmYjgnKSxcbiAgQ0ZCMTogcmVxdWlyZSgnLi9tb2Rlcy9jZmIxJyksXG4gIE9GQjogcmVxdWlyZSgnLi9tb2Rlcy9vZmInKSxcbiAgQ1RSOiByZXF1aXJlKCcuL21vZGVzL2N0cicpLFxuICBHQ006IHJlcXVpcmUoJy4vbW9kZXMvY3RyJylcbn1cblxuZnVuY3Rpb24gY3JlYXRlRGVjaXBoZXJpdiAoc3VpdGUsIHBhc3N3b3JkLCBpdikge1xuICB2YXIgY29uZmlnID0gbW9kZXNbc3VpdGUudG9Mb3dlckNhc2UoKV1cbiAgaWYgKCFjb25maWcpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuICB9XG4gIGlmICh0eXBlb2YgaXYgPT09ICdzdHJpbmcnKSB7XG4gICAgaXYgPSBuZXcgQnVmZmVyKGl2KVxuICB9XG4gIGlmICh0eXBlb2YgcGFzc3dvcmQgPT09ICdzdHJpbmcnKSB7XG4gICAgcGFzc3dvcmQgPSBuZXcgQnVmZmVyKHBhc3N3b3JkKVxuICB9XG4gIGlmIChwYXNzd29yZC5sZW5ndGggIT09IGNvbmZpZy5rZXkgLyA4KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBrZXkgbGVuZ3RoICcgKyBwYXNzd29yZC5sZW5ndGgpXG4gIH1cbiAgaWYgKGl2Lmxlbmd0aCAhPT0gY29uZmlnLml2KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBpdiBsZW5ndGggJyArIGl2Lmxlbmd0aClcbiAgfVxuICBpZiAoY29uZmlnLnR5cGUgPT09ICdzdHJlYW0nKSB7XG4gICAgcmV0dXJuIG5ldyBTdHJlYW1DaXBoZXIobW9kZWxpc3RbY29uZmlnLm1vZGVdLCBwYXNzd29yZCwgaXYsIHRydWUpXG4gIH0gZWxzZSBpZiAoY29uZmlnLnR5cGUgPT09ICdhdXRoJykge1xuICAgIHJldHVybiBuZXcgQXV0aENpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdiwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gbmV3IERlY2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2KVxufVxuXG5mdW5jdGlvbiBjcmVhdGVEZWNpcGhlciAoc3VpdGUsIHBhc3N3b3JkKSB7XG4gIHZhciBjb25maWcgPSBtb2Rlc1tzdWl0ZS50b0xvd2VyQ2FzZSgpXVxuICBpZiAoIWNvbmZpZykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgdmFyIGtleXMgPSBlYnRrKHBhc3N3b3JkLCBmYWxzZSwgY29uZmlnLmtleSwgY29uZmlnLml2KVxuICByZXR1cm4gY3JlYXRlRGVjaXBoZXJpdihzdWl0ZSwga2V5cy5rZXksIGtleXMuaXYpXG59XG5leHBvcnRzLmNyZWF0ZURlY2lwaGVyID0gY3JlYXRlRGVjaXBoZXJcbmV4cG9ydHMuY3JlYXRlRGVjaXBoZXJpdiA9IGNyZWF0ZURlY2lwaGVyaXZcbiIsInZhciBhZXMgPSByZXF1aXJlKCcuL2FlcycpXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIG1vZGVzID0gcmVxdWlyZSgnLi9tb2RlcycpXG52YXIgZWJ0ayA9IHJlcXVpcmUoJ2V2cF9ieXRlc3Rva2V5JylcbnZhciBTdHJlYW1DaXBoZXIgPSByZXF1aXJlKCcuL3N0cmVhbUNpcGhlcicpXG52YXIgQXV0aENpcGhlciA9IHJlcXVpcmUoJy4vYXV0aENpcGhlcicpXG5pbmhlcml0cyhDaXBoZXIsIFRyYW5zZm9ybSlcbmZ1bmN0aW9uIENpcGhlciAobW9kZSwga2V5LCBpdikge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQ2lwaGVyKSkge1xuICAgIHJldHVybiBuZXcgQ2lwaGVyKG1vZGUsIGtleSwgaXYpXG4gIH1cbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5fY2FjaGUgPSBuZXcgU3BsaXR0ZXIoKVxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHRoaXMuX3ByZXYgPSBuZXcgQnVmZmVyKGl2Lmxlbmd0aClcbiAgaXYuY29weSh0aGlzLl9wcmV2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxuICB0aGlzLl9hdXRvcGFkZGluZyA9IHRydWVcbn1cbkNpcGhlci5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuX2NhY2hlLmFkZChkYXRhKVxuICB2YXIgY2h1bmtcbiAgdmFyIHRoaW5nXG4gIHZhciBvdXQgPSBbXVxuICB3aGlsZSAoKGNodW5rID0gdGhpcy5fY2FjaGUuZ2V0KCkpKSB7XG4gICAgdGhpbmcgPSB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmspXG4gICAgb3V0LnB1c2godGhpbmcpXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5jb25jYXQob3V0KVxufVxuQ2lwaGVyLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBjaHVuayA9IHRoaXMuX2NhY2hlLmZsdXNoKClcbiAgaWYgKHRoaXMuX2F1dG9wYWRkaW5nKSB7XG4gICAgY2h1bmsgPSB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmspXG4gICAgdGhpcy5fY2lwaGVyLnNjcnViKClcbiAgICByZXR1cm4gY2h1bmtcbiAgfSBlbHNlIGlmIChjaHVuay50b1N0cmluZygnaGV4JykgIT09ICcxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMCcpIHtcbiAgICB0aGlzLl9jaXBoZXIuc2NydWIoKVxuICAgIHRocm93IG5ldyBFcnJvcignZGF0YSBub3QgbXVsdGlwbGUgb2YgYmxvY2sgbGVuZ3RoJylcbiAgfVxufVxuQ2lwaGVyLnByb3RvdHlwZS5zZXRBdXRvUGFkZGluZyA9IGZ1bmN0aW9uIChzZXRUbykge1xuICB0aGlzLl9hdXRvcGFkZGluZyA9ICEhc2V0VG9cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gU3BsaXR0ZXIgKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3BsaXR0ZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBTcGxpdHRlcigpXG4gIH1cbiAgdGhpcy5jYWNoZSA9IG5ldyBCdWZmZXIoJycpXG59XG5TcGxpdHRlci5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIGRhdGFdKVxufVxuXG5TcGxpdHRlci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jYWNoZS5sZW5ndGggPiAxNSkge1xuICAgIHZhciBvdXQgPSB0aGlzLmNhY2hlLnNsaWNlKDAsIDE2KVxuICAgIHRoaXMuY2FjaGUgPSB0aGlzLmNhY2hlLnNsaWNlKDE2KVxuICAgIHJldHVybiBvdXRcbiAgfVxuICByZXR1cm4gbnVsbFxufVxuU3BsaXR0ZXIucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbGVuID0gMTYgLSB0aGlzLmNhY2hlLmxlbmd0aFxuICB2YXIgcGFkQnVmZiA9IG5ldyBCdWZmZXIobGVuKVxuXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIHBhZEJ1ZmYud3JpdGVVSW50OChsZW4sIGkpXG4gIH1cbiAgdmFyIG91dCA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIHBhZEJ1ZmZdKVxuICByZXR1cm4gb3V0XG59XG52YXIgbW9kZWxpc3QgPSB7XG4gIEVDQjogcmVxdWlyZSgnLi9tb2Rlcy9lY2InKSxcbiAgQ0JDOiByZXF1aXJlKCcuL21vZGVzL2NiYycpLFxuICBDRkI6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiJyksXG4gIENGQjg6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiOCcpLFxuICBDRkIxOiByZXF1aXJlKCcuL21vZGVzL2NmYjEnKSxcbiAgT0ZCOiByZXF1aXJlKCcuL21vZGVzL29mYicpLFxuICBDVFI6IHJlcXVpcmUoJy4vbW9kZXMvY3RyJyksXG4gIEdDTTogcmVxdWlyZSgnLi9tb2Rlcy9jdHInKVxufVxuXG5mdW5jdGlvbiBjcmVhdGVDaXBoZXJpdiAoc3VpdGUsIHBhc3N3b3JkLCBpdikge1xuICB2YXIgY29uZmlnID0gbW9kZXNbc3VpdGUudG9Mb3dlckNhc2UoKV1cbiAgaWYgKCFjb25maWcpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuICB9XG4gIGlmICh0eXBlb2YgaXYgPT09ICdzdHJpbmcnKSB7XG4gICAgaXYgPSBuZXcgQnVmZmVyKGl2KVxuICB9XG4gIGlmICh0eXBlb2YgcGFzc3dvcmQgPT09ICdzdHJpbmcnKSB7XG4gICAgcGFzc3dvcmQgPSBuZXcgQnVmZmVyKHBhc3N3b3JkKVxuICB9XG4gIGlmIChwYXNzd29yZC5sZW5ndGggIT09IGNvbmZpZy5rZXkgLyA4KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBrZXkgbGVuZ3RoICcgKyBwYXNzd29yZC5sZW5ndGgpXG4gIH1cbiAgaWYgKGl2Lmxlbmd0aCAhPT0gY29uZmlnLml2KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBpdiBsZW5ndGggJyArIGl2Lmxlbmd0aClcbiAgfVxuICBpZiAoY29uZmlnLnR5cGUgPT09ICdzdHJlYW0nKSB7XG4gICAgcmV0dXJuIG5ldyBTdHJlYW1DaXBoZXIobW9kZWxpc3RbY29uZmlnLm1vZGVdLCBwYXNzd29yZCwgaXYpXG4gIH0gZWxzZSBpZiAoY29uZmlnLnR5cGUgPT09ICdhdXRoJykge1xuICAgIHJldHVybiBuZXcgQXV0aENpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdilcbiAgfVxuICByZXR1cm4gbmV3IENpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdilcbn1cbmZ1bmN0aW9uIGNyZWF0ZUNpcGhlciAoc3VpdGUsIHBhc3N3b3JkKSB7XG4gIHZhciBjb25maWcgPSBtb2Rlc1tzdWl0ZS50b0xvd2VyQ2FzZSgpXVxuICBpZiAoIWNvbmZpZykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgdmFyIGtleXMgPSBlYnRrKHBhc3N3b3JkLCBmYWxzZSwgY29uZmlnLmtleSwgY29uZmlnLml2KVxuICByZXR1cm4gY3JlYXRlQ2lwaGVyaXYoc3VpdGUsIGtleXMua2V5LCBrZXlzLml2KVxufVxuXG5leHBvcnRzLmNyZWF0ZUNpcGhlcml2ID0gY3JlYXRlQ2lwaGVyaXZcbmV4cG9ydHMuY3JlYXRlQ2lwaGVyID0gY3JlYXRlQ2lwaGVyXG4iLCJ2YXIgemVyb3MgPSBuZXcgQnVmZmVyKDE2KVxuemVyb3MuZmlsbCgwKVxubW9kdWxlLmV4cG9ydHMgPSBHSEFTSFxuZnVuY3Rpb24gR0hBU0ggKGtleSkge1xuICB0aGlzLmggPSBrZXlcbiAgdGhpcy5zdGF0ZSA9IG5ldyBCdWZmZXIoMTYpXG4gIHRoaXMuc3RhdGUuZmlsbCgwKVxuICB0aGlzLmNhY2hlID0gbmV3IEJ1ZmZlcignJylcbn1cbi8vIGZyb20gaHR0cDovL2JpdHdpc2VzaGlmdGxlZnQuZ2l0aHViLmlvL3NqY2wvZG9jL3N5bWJvbHMvc3JjL2NvcmVfZ2NtLmpzLmh0bWxcbi8vIGJ5IEp1aG8gVsOkaMOkLUhlcnR0dWFcbkdIQVNILnByb3RvdHlwZS5naGFzaCA9IGZ1bmN0aW9uIChibG9jaykge1xuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBibG9jay5sZW5ndGgpIHtcbiAgICB0aGlzLnN0YXRlW2ldIF49IGJsb2NrW2ldXG4gIH1cbiAgdGhpcy5fbXVsdGlwbHkoKVxufVxuXG5HSEFTSC5wcm90b3R5cGUuX211bHRpcGx5ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgVmkgPSB0b0FycmF5KHRoaXMuaClcbiAgdmFyIFppID0gWzAsIDAsIDAsIDBdXG4gIHZhciBqLCB4aSwgbHNiX1ZpXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IDEyOCkge1xuICAgIHhpID0gKHRoaXMuc3RhdGVbfn4oaSAvIDgpXSAmICgxIDw8ICg3IC0gaSAlIDgpKSkgIT09IDBcbiAgICBpZiAoeGkpIHtcbiAgICAgIC8vIFpfaSsxID0gWl9pIF4gVl9pXG4gICAgICBaaSA9IHhvcihaaSwgVmkpXG4gICAgfVxuXG4gICAgLy8gU3RvcmUgdGhlIHZhbHVlIG9mIExTQihWX2kpXG4gICAgbHNiX1ZpID0gKFZpWzNdICYgMSkgIT09IDBcblxuICAgIC8vIFZfaSsxID0gVl9pID4+IDFcbiAgICBmb3IgKGogPSAzOyBqID4gMDsgai0tKSB7XG4gICAgICBWaVtqXSA9IChWaVtqXSA+Pj4gMSkgfCAoKFZpW2ogLSAxXSAmIDEpIDw8IDMxKVxuICAgIH1cbiAgICBWaVswXSA9IFZpWzBdID4+PiAxXG5cbiAgICAvLyBJZiBMU0IoVl9pKSBpcyAxLCBWX2krMSA9IChWX2kgPj4gMSkgXiBSXG4gICAgaWYgKGxzYl9WaSkge1xuICAgICAgVmlbMF0gPSBWaVswXSBeICgweGUxIDw8IDI0KVxuICAgIH1cbiAgfVxuICB0aGlzLnN0YXRlID0gZnJvbUFycmF5KFppKVxufVxuR0hBU0gucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChidWYpIHtcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIGJ1Zl0pXG4gIHZhciBjaHVua1xuICB3aGlsZSAodGhpcy5jYWNoZS5sZW5ndGggPj0gMTYpIHtcbiAgICBjaHVuayA9IHRoaXMuY2FjaGUuc2xpY2UoMCwgMTYpXG4gICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgdGhpcy5naGFzaChjaHVuaylcbiAgfVxufVxuR0hBU0gucHJvdG90eXBlLmZpbmFsID0gZnVuY3Rpb24gKGFibCwgYmwpIHtcbiAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoKSB7XG4gICAgdGhpcy5naGFzaChCdWZmZXIuY29uY2F0KFt0aGlzLmNhY2hlLCB6ZXJvc10sIDE2KSlcbiAgfVxuICB0aGlzLmdoYXNoKGZyb21BcnJheShbXG4gICAgMCwgYWJsLFxuICAgIDAsIGJsXG4gIF0pKVxuICByZXR1cm4gdGhpcy5zdGF0ZVxufVxuXG5mdW5jdGlvbiB0b0FycmF5IChidWYpIHtcbiAgcmV0dXJuIFtcbiAgICBidWYucmVhZFVJbnQzMkJFKDApLFxuICAgIGJ1Zi5yZWFkVUludDMyQkUoNCksXG4gICAgYnVmLnJlYWRVSW50MzJCRSg4KSxcbiAgICBidWYucmVhZFVJbnQzMkJFKDEyKVxuICBdXG59XG5mdW5jdGlvbiBmcm9tQXJyYXkgKG91dCkge1xuICBvdXQgPSBvdXQubWFwKGZpeHVwX3VpbnQzMilcbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoMTYpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFswXSwgMClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzFdLCA0KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMl0sIDgpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFszXSwgMTIpXG4gIHJldHVybiBidWZcbn1cbnZhciB1aW50X21heCA9IE1hdGgucG93KDIsIDMyKVxuZnVuY3Rpb24gZml4dXBfdWludDMyICh4KSB7XG4gIHZhciByZXQsIHhfcG9zXG4gIHJldCA9IHggPiB1aW50X21heCB8fCB4IDwgMCA/ICh4X3BvcyA9IE1hdGguYWJzKHgpICUgdWludF9tYXgsIHggPCAwID8gdWludF9tYXggLSB4X3BvcyA6IHhfcG9zKSA6IHhcbiAgcmV0dXJuIHJldFxufVxuZnVuY3Rpb24geG9yIChhLCBiKSB7XG4gIHJldHVybiBbXG4gICAgYVswXSBeIGJbMF0sXG4gICAgYVsxXSBeIGJbMV0sXG4gICAgYVsyXSBeIGJbMl0sXG4gICAgYVszXSBeIGJbM11cbiAgXVxufVxuIiwidmFyIHhvciA9IHJlcXVpcmUoJ2J1ZmZlci14b3InKVxuXG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgZGF0YSwgZGVjcnlwdCkge1xuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcignJylcbiAgdmFyIGxlblxuXG4gIHdoaWxlIChkYXRhLmxlbmd0aCkge1xuICAgIGlmIChzZWxmLl9jYWNoZS5sZW5ndGggPT09IDApIHtcbiAgICAgIHNlbGYuX2NhY2hlID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhzZWxmLl9wcmV2KVxuICAgICAgc2VsZi5fcHJldiA9IG5ldyBCdWZmZXIoJycpXG4gICAgfVxuXG4gICAgaWYgKHNlbGYuX2NhY2hlLmxlbmd0aCA8PSBkYXRhLmxlbmd0aCkge1xuICAgICAgbGVuID0gc2VsZi5fY2FjaGUubGVuZ3RoXG4gICAgICBvdXQgPSBCdWZmZXIuY29uY2F0KFtvdXQsIGVuY3J5cHRTdGFydChzZWxmLCBkYXRhLnNsaWNlKDAsIGxlbiksIGRlY3J5cHQpXSlcbiAgICAgIGRhdGEgPSBkYXRhLnNsaWNlKGxlbilcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0ID0gQnVmZmVyLmNvbmNhdChbb3V0LCBlbmNyeXB0U3RhcnQoc2VsZiwgZGF0YSwgZGVjcnlwdCldKVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gb3V0XG59XG5mdW5jdGlvbiBlbmNyeXB0U3RhcnQgKHNlbGYsIGRhdGEsIGRlY3J5cHQpIHtcbiAgdmFyIGxlbiA9IGRhdGEubGVuZ3RoXG4gIHZhciBvdXQgPSB4b3IoZGF0YSwgc2VsZi5fY2FjaGUpXG4gIHNlbGYuX2NhY2hlID0gc2VsZi5fY2FjaGUuc2xpY2UobGVuKVxuICBzZWxmLl9wcmV2ID0gQnVmZmVyLmNvbmNhdChbc2VsZi5fcHJldiwgZGVjcnlwdCA/IGRhdGEgOiBvdXRdKVxuICByZXR1cm4gb3V0XG59XG4iLCJmdW5jdGlvbiBlbmNyeXB0Qnl0ZSAoc2VsZiwgYnl0ZVBhcmFtLCBkZWNyeXB0KSB7XG4gIHZhciBwYWRcbiAgdmFyIGkgPSAtMVxuICB2YXIgbGVuID0gOFxuICB2YXIgb3V0ID0gMFxuICB2YXIgYml0LCB2YWx1ZVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgcGFkID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhzZWxmLl9wcmV2KVxuICAgIGJpdCA9IChieXRlUGFyYW0gJiAoMSA8PCAoNyAtIGkpKSkgPyAweDgwIDogMFxuICAgIHZhbHVlID0gcGFkWzBdIF4gYml0XG4gICAgb3V0ICs9ICgodmFsdWUgJiAweDgwKSA+PiAoaSAlIDgpKVxuICAgIHNlbGYuX3ByZXYgPSBzaGlmdEluKHNlbGYuX3ByZXYsIGRlY3J5cHQgPyBiaXQgOiB2YWx1ZSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgY2h1bmssIGRlY3J5cHQpIHtcbiAgdmFyIGxlbiA9IGNodW5rLmxlbmd0aFxuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihsZW4pXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dFtpXSA9IGVuY3J5cHRCeXRlKHNlbGYsIGNodW5rW2ldLCBkZWNyeXB0KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbmZ1bmN0aW9uIHNoaWZ0SW4gKGJ1ZmZlciwgdmFsdWUpIHtcbiAgdmFyIGxlbiA9IGJ1ZmZlci5sZW5ndGhcbiAgdmFyIGkgPSAtMVxuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihidWZmZXIubGVuZ3RoKVxuICBidWZmZXIgPSBCdWZmZXIuY29uY2F0KFtidWZmZXIsIG5ldyBCdWZmZXIoW3ZhbHVlXSldKVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgb3V0W2ldID0gYnVmZmVyW2ldIDw8IDEgfCBidWZmZXJbaSArIDFdID4+ICg3KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsImZ1bmN0aW9uIGVuY3J5cHRCeXRlIChzZWxmLCBieXRlUGFyYW0sIGRlY3J5cHQpIHtcbiAgdmFyIHBhZCA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soc2VsZi5fcHJldilcbiAgdmFyIG91dCA9IHBhZFswXSBeIGJ5dGVQYXJhbVxuICBzZWxmLl9wcmV2ID0gQnVmZmVyLmNvbmNhdChbc2VsZi5fcHJldi5zbGljZSgxKSwgbmV3IEJ1ZmZlcihbZGVjcnlwdCA/IGJ5dGVQYXJhbSA6IG91dF0pXSlcbiAgcmV0dXJuIG91dFxufVxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGNodW5rLCBkZWNyeXB0KSB7XG4gIHZhciBsZW4gPSBjaHVuay5sZW5ndGhcbiAgdmFyIG91dCA9IG5ldyBCdWZmZXIobGVuKVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXRbaV0gPSBlbmNyeXB0Qnl0ZShzZWxmLCBjaHVua1tpXSwgZGVjcnlwdClcbiAgfVxuICByZXR1cm4gb3V0XG59XG4iLCJ2YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG5cbmZ1bmN0aW9uIGluY3IzMiAoaXYpIHtcbiAgdmFyIGxlbiA9IGl2Lmxlbmd0aFxuICB2YXIgaXRlbVxuICB3aGlsZSAobGVuLS0pIHtcbiAgICBpdGVtID0gaXYucmVhZFVJbnQ4KGxlbilcbiAgICBpZiAoaXRlbSA9PT0gMjU1KSB7XG4gICAgICBpdi53cml0ZVVJbnQ4KDAsIGxlbilcbiAgICB9IGVsc2Uge1xuICAgICAgaXRlbSsrXG4gICAgICBpdi53cml0ZVVJbnQ4KGl0ZW0sIGxlbilcbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGdldEJsb2NrIChzZWxmKSB7XG4gIHZhciBvdXQgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gIGluY3IzMihzZWxmLl9wcmV2KVxuICByZXR1cm4gb3V0XG59XG5cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBjaHVuaykge1xuICB3aGlsZSAoc2VsZi5fY2FjaGUubGVuZ3RoIDwgY2h1bmsubGVuZ3RoKSB7XG4gICAgc2VsZi5fY2FjaGUgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9jYWNoZSwgZ2V0QmxvY2soc2VsZildKVxuICB9XG4gIHZhciBwYWQgPSBzZWxmLl9jYWNoZS5zbGljZSgwLCBjaHVuay5sZW5ndGgpXG4gIHNlbGYuX2NhY2hlID0gc2VsZi5fY2FjaGUuc2xpY2UoY2h1bmsubGVuZ3RoKVxuICByZXR1cm4geG9yKGNodW5rLCBwYWQpXG59XG4iLCJ2YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG5cbmZ1bmN0aW9uIGdldEJsb2NrIChzZWxmKSB7XG4gIHNlbGYuX3ByZXYgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gIHJldHVybiBzZWxmLl9wcmV2XG59XG5cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBjaHVuaykge1xuICB3aGlsZSAoc2VsZi5fY2FjaGUubGVuZ3RoIDwgY2h1bmsubGVuZ3RoKSB7XG4gICAgc2VsZi5fY2FjaGUgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9jYWNoZSwgZ2V0QmxvY2soc2VsZildKVxuICB9XG5cbiAgdmFyIHBhZCA9IHNlbGYuX2NhY2hlLnNsaWNlKDAsIGNodW5rLmxlbmd0aClcbiAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jYWNoZS5zbGljZShjaHVuay5sZW5ndGgpXG4gIHJldHVybiB4b3IoY2h1bmssIHBhZClcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24geG9yIChhLCBiKSB7XG4gIHZhciBsZW5ndGggPSBNYXRoLm1pbihhLmxlbmd0aCwgYi5sZW5ndGgpXG4gIHZhciBidWZmZXIgPSBuZXcgQnVmZmVyKGxlbmd0aClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgYnVmZmVyW2ldID0gYVtpXSBeIGJbaV1cbiAgfVxuXG4gIHJldHVybiBidWZmZXJcbn1cbiIsInZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdzdHJlYW0nKS5UcmFuc2Zvcm1cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXInKS5TdHJpbmdEZWNvZGVyXG5tb2R1bGUuZXhwb3J0cyA9IENpcGhlckJhc2VcbmluaGVyaXRzKENpcGhlckJhc2UsIFRyYW5zZm9ybSlcbmZ1bmN0aW9uIENpcGhlckJhc2UgKGhhc2hNb2RlKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG4gIHRoaXMuaGFzaE1vZGUgPSB0eXBlb2YgaGFzaE1vZGUgPT09ICdzdHJpbmcnXG4gIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgdGhpc1toYXNoTW9kZV0gPSB0aGlzLl9maW5hbE9yRGlnZXN0XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5maW5hbCA9IHRoaXMuX2ZpbmFsT3JEaWdlc3RcbiAgfVxuICB0aGlzLl9kZWNvZGVyID0gbnVsbFxuICB0aGlzLl9lbmNvZGluZyA9IG51bGxcbn1cbkNpcGhlckJhc2UucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhLCBpbnB1dEVuYywgb3V0cHV0RW5jKSB7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICBkYXRhID0gbmV3IEJ1ZmZlcihkYXRhLCBpbnB1dEVuYylcbiAgfVxuICB2YXIgb3V0RGF0YSA9IHRoaXMuX3VwZGF0ZShkYXRhKVxuICBpZiAodGhpcy5oYXNoTW9kZSkge1xuICAgIHJldHVybiB0aGlzXG4gIH1cbiAgaWYgKG91dHB1dEVuYykge1xuICAgIG91dERhdGEgPSB0aGlzLl90b1N0cmluZyhvdXREYXRhLCBvdXRwdXRFbmMpXG4gIH1cbiAgcmV0dXJuIG91dERhdGFcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuc2V0QXV0b1BhZGRpbmcgPSBmdW5jdGlvbiAoKSB7fVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5nZXRBdXRoVGFnID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3RyeWluZyB0byBnZXQgYXV0aCB0YWcgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBdXRoVGFnID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3RyeWluZyB0byBzZXQgYXV0aCB0YWcgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBQUQgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIHNldCBhYWQgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24gKGRhdGEsIF8sIG5leHQpIHtcbiAgdmFyIGVyclxuICB0cnkge1xuICAgIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgICB0aGlzLl91cGRhdGUoZGF0YSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wdXNoKHRoaXMuX3VwZGF0ZShkYXRhKSlcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBlcnIgPSBlXG4gIH0gZmluYWxseSB7XG4gICAgbmV4dChlcnIpXG4gIH1cbn1cbkNpcGhlckJhc2UucHJvdG90eXBlLl9mbHVzaCA9IGZ1bmN0aW9uIChkb25lKSB7XG4gIHZhciBlcnJcbiAgdHJ5IHtcbiAgICB0aGlzLnB1c2godGhpcy5fZmluYWwoKSlcbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfSBmaW5hbGx5IHtcbiAgICBkb25lKGVycilcbiAgfVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZpbmFsT3JEaWdlc3QgPSBmdW5jdGlvbiAob3V0cHV0RW5jKSB7XG4gIHZhciBvdXREYXRhID0gdGhpcy5fZmluYWwoKSB8fCBuZXcgQnVmZmVyKCcnKVxuICBpZiAob3V0cHV0RW5jKSB7XG4gICAgb3V0RGF0YSA9IHRoaXMuX3RvU3RyaW5nKG91dERhdGEsIG91dHB1dEVuYywgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb3V0RGF0YVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fdG9TdHJpbmcgPSBmdW5jdGlvbiAodmFsdWUsIGVuYywgZmluYWwpIHtcbiAgaWYgKCF0aGlzLl9kZWNvZGVyKSB7XG4gICAgdGhpcy5fZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKGVuYylcbiAgICB0aGlzLl9lbmNvZGluZyA9IGVuY1xuICB9XG4gIGlmICh0aGlzLl9lbmNvZGluZyAhPT0gZW5jKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjYW5cXCd0IHN3aXRjaCBlbmNvZGluZ3MnKVxuICB9XG4gIHZhciBvdXQgPSB0aGlzLl9kZWNvZGVyLndyaXRlKHZhbHVlKVxuICBpZiAoZmluYWwpIHtcbiAgICBvdXQgKz0gdGhpcy5fZGVjb2Rlci5lbmQoKVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsInZhciBhZXMgPSByZXF1aXJlKCcuL2FlcycpXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxuXG5pbmhlcml0cyhTdHJlYW1DaXBoZXIsIFRyYW5zZm9ybSlcbm1vZHVsZS5leHBvcnRzID0gU3RyZWFtQ2lwaGVyXG5mdW5jdGlvbiBTdHJlYW1DaXBoZXIgKG1vZGUsIGtleSwgaXYsIGRlY3J5cHQpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFN0cmVhbUNpcGhlcikpIHtcbiAgICByZXR1cm4gbmV3IFN0cmVhbUNpcGhlcihtb2RlLCBrZXksIGl2KVxuICB9XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG4gIHRoaXMuX2NpcGhlciA9IG5ldyBhZXMuQUVTKGtleSlcbiAgdGhpcy5fcHJldiA9IG5ldyBCdWZmZXIoaXYubGVuZ3RoKVxuICB0aGlzLl9jYWNoZSA9IG5ldyBCdWZmZXIoJycpXG4gIHRoaXMuX3NlY0NhY2hlID0gbmV3IEJ1ZmZlcignJylcbiAgdGhpcy5fZGVjcnlwdCA9IGRlY3J5cHRcbiAgaXYuY29weSh0aGlzLl9wcmV2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gIHJldHVybiB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmssIHRoaXMuX2RlY3J5cHQpXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fY2lwaGVyLnNjcnViKClcbn1cbiIsInZhciBtZDUgPSByZXF1aXJlKCdjcmVhdGUtaGFzaC9tZDUnKVxubW9kdWxlLmV4cG9ydHMgPSBFVlBfQnl0ZXNUb0tleVxuZnVuY3Rpb24gRVZQX0J5dGVzVG9LZXkgKHBhc3N3b3JkLCBzYWx0LCBrZXlMZW4sIGl2TGVuKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHBhc3N3b3JkKSkge1xuICAgIHBhc3N3b3JkID0gbmV3IEJ1ZmZlcihwYXNzd29yZCwgJ2JpbmFyeScpXG4gIH1cbiAgaWYgKHNhbHQgJiYgIUJ1ZmZlci5pc0J1ZmZlcihzYWx0KSkge1xuICAgIHNhbHQgPSBuZXcgQnVmZmVyKHNhbHQsICdiaW5hcnknKVxuICB9XG4gIGtleUxlbiA9IGtleUxlbiAvIDhcbiAgaXZMZW4gPSBpdkxlbiB8fCAwXG4gIHZhciBraSA9IDBcbiAgdmFyIGlpID0gMFxuICB2YXIga2V5ID0gbmV3IEJ1ZmZlcihrZXlMZW4pXG4gIHZhciBpdiA9IG5ldyBCdWZmZXIoaXZMZW4pXG4gIHZhciBhZGRtZCA9IDBcbiAgdmFyIG1kX2J1ZlxuICB2YXIgaVxuICB2YXIgYnVmcyA9IFtdXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgaWYgKGFkZG1kKysgPiAwKSB7XG4gICAgICBidWZzLnB1c2gobWRfYnVmKVxuICAgIH1cbiAgICBidWZzLnB1c2gocGFzc3dvcmQpXG4gICAgaWYgKHNhbHQpIHtcbiAgICAgIGJ1ZnMucHVzaChzYWx0KVxuICAgIH1cbiAgICBtZF9idWYgPSBtZDUoQnVmZmVyLmNvbmNhdChidWZzKSlcbiAgICBidWZzID0gW11cbiAgICBpID0gMFxuICAgIGlmIChrZXlMZW4gPiAwKSB7XG4gICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBpZiAoa2V5TGVuID09PSAwKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaSA9PT0gbWRfYnVmLmxlbmd0aCkge1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAga2V5W2tpKytdID0gbWRfYnVmW2ldXG4gICAgICAgIGtleUxlbi0tXG4gICAgICAgIGkrK1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXZMZW4gPiAwICYmIGkgIT09IG1kX2J1Zi5sZW5ndGgpIHtcbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGlmIChpdkxlbiA9PT0gMCkge1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGkgPT09IG1kX2J1Zi5sZW5ndGgpIHtcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICAgIGl2W2lpKytdID0gbWRfYnVmW2ldXG4gICAgICAgIGl2TGVuLS1cbiAgICAgICAgaSsrXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChrZXlMZW4gPT09IDAgJiYgaXZMZW4gPT09IDApIHtcbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG4gIGZvciAoaSA9IDA7IGkgPCBtZF9idWYubGVuZ3RoOyBpKyspIHtcbiAgICBtZF9idWZbaV0gPSAwXG4gIH1cbiAgcmV0dXJuIHtcbiAgICBrZXk6IGtleSxcbiAgICBpdjogaXZcbiAgfVxufVxuIiwidmFyIHBhcnNlS2V5cyA9IHJlcXVpcmUoJ3BhcnNlLWFzbjEnKTtcbnZhciBtZ2YgPSByZXF1aXJlKCcuL21nZicpO1xudmFyIHhvciA9IHJlcXVpcmUoJy4veG9yJyk7XG52YXIgYm4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIGNydCA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktcnNhJyk7XG52YXIgY3JlYXRlSGFzaCA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoJyk7XG52YXIgd2l0aFB1YmxpYyA9IHJlcXVpcmUoJy4vd2l0aFB1YmxpYycpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwcml2YXRlRGVjcnlwdChwcml2YXRlX2tleSwgZW5jLCByZXZlcnNlKSB7XG4gIHZhciBwYWRkaW5nO1xuICBpZiAocHJpdmF0ZV9rZXkucGFkZGluZykge1xuICAgIHBhZGRpbmcgPSBwcml2YXRlX2tleS5wYWRkaW5nO1xuICB9IGVsc2UgaWYgKHJldmVyc2UpIHtcbiAgICBwYWRkaW5nID0gMTtcbiAgfSBlbHNlIHtcbiAgICBwYWRkaW5nID0gNDtcbiAgfVxuICBcbiAgdmFyIGtleSA9IHBhcnNlS2V5cyhwcml2YXRlX2tleSk7XG4gIHZhciBrID0ga2V5Lm1vZHVsdXMuYnl0ZUxlbmd0aCgpO1xuICBpZiAoZW5jLmxlbmd0aCA+IGsgfHwgbmV3IGJuKGVuYykuY21wKGtleS5tb2R1bHVzKSA+PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkZWNyeXB0aW9uIGVycm9yJyk7XG4gIH1cbiAgdmFyIG1zZztcbiAgaWYgKHJldmVyc2UpIHtcbiAgICBtc2cgPSB3aXRoUHVibGljKG5ldyBibihlbmMpLCBrZXkpO1xuICB9IGVsc2Uge1xuICAgIG1zZyA9IGNydChlbmMsIGtleSk7XG4gIH1cbiAgdmFyIHpCdWZmZXIgPSBuZXcgQnVmZmVyKGsgLSBtc2cubGVuZ3RoKTtcbiAgekJ1ZmZlci5maWxsKDApO1xuICBtc2cgPSBCdWZmZXIuY29uY2F0KFt6QnVmZmVyLCBtc2ddLCBrKTtcbiAgaWYgKHBhZGRpbmcgPT09IDQpIHtcbiAgICByZXR1cm4gb2FlcChrZXksIG1zZyk7XG4gIH0gZWxzZSBpZiAocGFkZGluZyA9PT0gMSkge1xuICAgIHJldHVybiBwa2NzMShrZXksIG1zZywgcmV2ZXJzZSk7XG4gIH0gZWxzZSBpZiAocGFkZGluZyA9PT0gMykge1xuICAgIHJldHVybiBtc2c7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIHBhZGRpbmcnKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gb2FlcChrZXksIG1zZyl7XG4gIHZhciBuID0ga2V5Lm1vZHVsdXM7XG4gIHZhciBrID0ga2V5Lm1vZHVsdXMuYnl0ZUxlbmd0aCgpO1xuICB2YXIgbUxlbiA9IG1zZy5sZW5ndGg7XG4gIHZhciBpSGFzaCA9IGNyZWF0ZUhhc2goJ3NoYTEnKS51cGRhdGUobmV3IEJ1ZmZlcignJykpLmRpZ2VzdCgpO1xuICB2YXIgaExlbiA9IGlIYXNoLmxlbmd0aDtcbiAgdmFyIGhMZW4yID0gMiAqIGhMZW47XG4gIGlmIChtc2dbMF0gIT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RlY3J5cHRpb24gZXJyb3InKTtcbiAgfVxuICB2YXIgbWFza2VkU2VlZCA9IG1zZy5zbGljZSgxLCBoTGVuICsgMSk7XG4gIHZhciBtYXNrZWREYiA9ICBtc2cuc2xpY2UoaExlbiArIDEpO1xuICB2YXIgc2VlZCA9IHhvcihtYXNrZWRTZWVkLCBtZ2YobWFza2VkRGIsIGhMZW4pKTtcbiAgdmFyIGRiID0geG9yKG1hc2tlZERiLCBtZ2Yoc2VlZCwgayAtIGhMZW4gLSAxKSk7XG4gIGlmIChjb21wYXJlKGlIYXNoLCBkYi5zbGljZSgwLCBoTGVuKSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RlY3J5cHRpb24gZXJyb3InKTtcbiAgfVxuICB2YXIgaSA9IGhMZW47XG4gIHdoaWxlIChkYltpXSA9PT0gMCkge1xuICAgIGkrKztcbiAgfVxuICBpZiAoZGJbaSsrXSAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignZGVjcnlwdGlvbiBlcnJvcicpO1xuICB9XG4gIHJldHVybiBkYi5zbGljZShpKTtcbn1cblxuZnVuY3Rpb24gcGtjczEoa2V5LCBtc2csIHJldmVyc2Upe1xuICB2YXIgcDEgPSBtc2cuc2xpY2UoMCwgMik7XG4gIHZhciBpID0gMjtcbiAgdmFyIHN0YXR1cyA9IDA7XG4gIHdoaWxlIChtc2dbaSsrXSAhPT0gMCkge1xuICAgIGlmIChpID49IG1zZy5sZW5ndGgpIHtcbiAgICAgIHN0YXR1cysrO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHZhciBwcyA9IG1zZy5zbGljZSgyLCBpIC0gMSk7XG4gIHZhciBwMiA9IG1zZy5zbGljZShpIC0gMSwgaSk7XG5cbiAgaWYgKChwMS50b1N0cmluZygnaGV4JykgIT09ICcwMDAyJyAmJiAhcmV2ZXJzZSkgfHwgKHAxLnRvU3RyaW5nKCdoZXgnKSAhPT0gJzAwMDEnICYmIHJldmVyc2UpKXtcbiAgICBzdGF0dXMrKztcbiAgfVxuICBpZiAocHMubGVuZ3RoIDwgOCkge1xuICAgIHN0YXR1cysrO1xuICB9XG4gIGlmIChzdGF0dXMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RlY3J5cHRpb24gZXJyb3InKTtcbiAgfVxuICByZXR1cm4gIG1zZy5zbGljZShpKTtcbn1cbmZ1bmN0aW9uIGNvbXBhcmUoYSwgYil7XG4gIGEgPSBuZXcgQnVmZmVyKGEpO1xuICBiID0gbmV3IEJ1ZmZlcihiKTtcbiAgdmFyIGRpZiA9IDA7XG4gIHZhciBsZW4gPSBhLmxlbmd0aDtcbiAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkge1xuICAgIGRpZisrO1xuICAgIGxlbiA9IE1hdGgubWluKGEubGVuZ3RoLCBiLmxlbmd0aCk7XG4gIH1cbiAgdmFyIGkgPSAtMTtcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIGRpZiArPSAoYVtpXSBeIGJbaV0pO1xuICB9XG4gIHJldHVybiBkaWY7XG59IiwidmFyIHBhcnNlS2V5cyA9IHJlcXVpcmUoJ3BhcnNlLWFzbjEnKTtcbnZhciByYW5kb21CeXRlcyA9IHJlcXVpcmUoJ3JhbmRvbWJ5dGVzJyk7XG52YXIgY3JlYXRlSGFzaCA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoJyk7XG52YXIgbWdmID0gcmVxdWlyZSgnLi9tZ2YnKTtcbnZhciB4b3IgPSByZXF1aXJlKCcuL3hvcicpO1xudmFyIGJuID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciB3aXRoUHVibGljID0gcmVxdWlyZSgnLi93aXRoUHVibGljJyk7XG52YXIgY3J0ID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1yc2EnKTtcblxudmFyIGNvbnN0YW50cyA9IHtcbiAgUlNBX1BLQ1MxX09BRVBfUEFERElORzogNCxcbiAgUlNBX1BLQ1MxX1BBRERJTjogMSxcbiAgUlNBX05PX1BBRERJTkc6IDNcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcHVibGljRW5jcnlwdChwdWJsaWNfa2V5LCBtc2csIHJldmVyc2UpIHtcbiAgdmFyIHBhZGRpbmc7XG4gIGlmIChwdWJsaWNfa2V5LnBhZGRpbmcpIHtcbiAgICBwYWRkaW5nID0gcHVibGljX2tleS5wYWRkaW5nO1xuICB9IGVsc2UgaWYgKHJldmVyc2UpIHtcbiAgICBwYWRkaW5nID0gMTtcbiAgfSBlbHNlIHtcbiAgICBwYWRkaW5nID0gNDtcbiAgfVxuICB2YXIga2V5ID0gcGFyc2VLZXlzKHB1YmxpY19rZXkpO1xuICB2YXIgcGFkZGVkTXNnO1xuICBpZiAocGFkZGluZyA9PT0gNCkge1xuICAgIHBhZGRlZE1zZyA9IG9hZXAoa2V5LCBtc2cpO1xuICB9IGVsc2UgaWYgKHBhZGRpbmcgPT09IDEpIHtcbiAgICBwYWRkZWRNc2cgPSBwa2NzMShrZXksIG1zZywgcmV2ZXJzZSk7XG4gIH0gZWxzZSBpZiAocGFkZGluZyA9PT0gMykge1xuICAgIHBhZGRlZE1zZyA9IG5ldyBibihtc2cpO1xuICAgIGlmIChwYWRkZWRNc2cuY21wKGtleS5tb2R1bHVzKSA+PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2RhdGEgdG9vIGxvbmcgZm9yIG1vZHVsdXMnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIHBhZGRpbmcnKTtcbiAgfVxuICBpZiAocmV2ZXJzZSkge1xuICAgIHJldHVybiBjcnQocGFkZGVkTXNnLCBrZXkpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB3aXRoUHVibGljKHBhZGRlZE1zZywga2V5KTtcbiAgfVxufTtcblxuZnVuY3Rpb24gb2FlcChrZXksIG1zZyl7XG4gIHZhciBrID0ga2V5Lm1vZHVsdXMuYnl0ZUxlbmd0aCgpO1xuICB2YXIgbUxlbiA9IG1zZy5sZW5ndGg7XG4gIHZhciBpSGFzaCA9IGNyZWF0ZUhhc2goJ3NoYTEnKS51cGRhdGUobmV3IEJ1ZmZlcignJykpLmRpZ2VzdCgpO1xuICB2YXIgaExlbiA9IGlIYXNoLmxlbmd0aDtcbiAgdmFyIGhMZW4yID0gMiAqIGhMZW47XG4gIGlmIChtTGVuID4gayAtIGhMZW4yIC0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignbWVzc2FnZSB0b28gbG9uZycpO1xuICB9XG4gIHZhciBwcyA9IG5ldyBCdWZmZXIoayAtIG1MZW4gLSBoTGVuMiAtIDIpO1xuICBwcy5maWxsKDApO1xuICB2YXIgZGJsZW4gPSBrIC0gaExlbiAtIDE7XG4gIHZhciBzZWVkID0gcmFuZG9tQnl0ZXMoaExlbik7XG4gIHZhciBtYXNrZWREYiA9IHhvcihCdWZmZXIuY29uY2F0KFtpSGFzaCwgcHMsIG5ldyBCdWZmZXIoWzFdKSwgbXNnXSwgZGJsZW4pLCBtZ2Yoc2VlZCwgZGJsZW4pKTtcbiAgdmFyIG1hc2tlZFNlZWQgPSB4b3Ioc2VlZCwgbWdmKG1hc2tlZERiLCBoTGVuKSk7XG4gIHJldHVybiBuZXcgYm4oQnVmZmVyLmNvbmNhdChbbmV3IEJ1ZmZlcihbMF0pLCBtYXNrZWRTZWVkLCBtYXNrZWREYl0sIGspKTtcbn1cbmZ1bmN0aW9uIHBrY3MxKGtleSwgbXNnLCByZXZlcnNlKXtcbiAgdmFyIG1MZW4gPSBtc2cubGVuZ3RoO1xuICB2YXIgayA9IGtleS5tb2R1bHVzLmJ5dGVMZW5ndGgoKTtcbiAgaWYgKG1MZW4gPiBrIC0gMTEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ21lc3NhZ2UgdG9vIGxvbmcnKTtcbiAgfVxuICB2YXIgcHM7XG4gIGlmIChyZXZlcnNlKSB7XG4gICAgcHMgPSBuZXcgQnVmZmVyKGsgLSBtTGVuIC0gMyk7XG4gICAgcHMuZmlsbCgweGZmKTtcbiAgfSBlbHNlIHtcbiAgICBwcyA9IG5vblplcm8oayAtIG1MZW4gLSAzKTtcbiAgfVxuICByZXR1cm4gbmV3IGJuKEJ1ZmZlci5jb25jYXQoW25ldyBCdWZmZXIoWzAsIHJldmVyc2U/MToyXSksIHBzLCBuZXcgQnVmZmVyKFswXSksIG1zZ10sIGspKTtcbn1cbmZ1bmN0aW9uIG5vblplcm8obGVuLCBjcnlwdG8pIHtcbiAgdmFyIG91dCA9IG5ldyBCdWZmZXIobGVuKTtcbiAgdmFyIGkgPSAwO1xuICB2YXIgY2FjaGUgPSByYW5kb21CeXRlcyhsZW4qMik7XG4gIHZhciBjdXIgPSAwO1xuICB2YXIgbnVtO1xuICB3aGlsZSAoaSA8IGxlbikge1xuICAgIGlmIChjdXIgPT09IGNhY2hlLmxlbmd0aCkge1xuICAgICAgY2FjaGUgPSByYW5kb21CeXRlcyhsZW4qMik7XG4gICAgICBjdXIgPSAwO1xuICAgIH1cbiAgICBudW0gPSBjYWNoZVtjdXIrK107XG4gICAgaWYgKG51bSkge1xuICAgICAgb3V0W2krK10gPSBudW07XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXQ7XG59IiwidmFyIGJuID0gcmVxdWlyZSgnYm4uanMnKTtcbmZ1bmN0aW9uIHdpdGhQdWJsaWMocGFkZGVkTXNnLCBrZXkpIHtcbiAgcmV0dXJuIG5ldyBCdWZmZXIocGFkZGVkTXNnXG4gICAgLnRvUmVkKGJuLm1vbnQoa2V5Lm1vZHVsdXMpKVxuICAgIC5yZWRQb3cobmV3IGJuKGtleS5wdWJsaWNFeHBvbmVudCkpXG4gICAgLmZyb21SZWQoKVxuICAgIC50b0FycmF5KCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHdpdGhQdWJsaWM7IiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB4b3IoYSwgYikge1xuICB2YXIgbGVuID0gYS5sZW5ndGg7XG4gIHZhciBpID0gLTE7XG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBhW2ldIF49IGJbaV07XG4gIH1cbiAgcmV0dXJuIGFcbn07IiwiJ3VzZSBzdHJpY3QnXG5cbmZ1bmN0aW9uIG9sZEJyb3dzZXIgKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3NlY3VyZSByYW5kb20gbnVtYmVyIGdlbmVyYXRpb24gbm90IHN1cHBvcnRlZCBieSB0aGlzIGJyb3dzZXJcXG51c2UgY2hyb21lLCBGaXJlRm94IG9yIEludGVybmV0IEV4cGxvcmVyIDExJylcbn1cblxudmFyIGNyeXB0byA9IGdsb2JhbC5jcnlwdG8gfHwgZ2xvYmFsLm1zQ3J5cHRvXG5cbmlmIChjcnlwdG8gJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcykge1xuICBtb2R1bGUuZXhwb3J0cyA9IHJhbmRvbUJ5dGVzXG59IGVsc2Uge1xuICBtb2R1bGUuZXhwb3J0cyA9IG9sZEJyb3dzZXJcbn1cblxuZnVuY3Rpb24gcmFuZG9tQnl0ZXMgKHNpemUsIGNiKSB7XG4gIC8vIHBoYW50b21qcyBuZWVkcyB0byB0aHJvd1xuICBpZiAoc2l6ZSA+IDY1NTM2KSB0aHJvdyBuZXcgRXJyb3IoJ3JlcXVlc3RlZCB0b28gbWFueSByYW5kb20gYnl0ZXMnKVxuICAvLyBpbiBjYXNlIGJyb3dzZXJpZnkgIGlzbid0IHVzaW5nIHRoZSBVaW50OEFycmF5IHZlcnNpb25cbiAgdmFyIHJhd0J5dGVzID0gbmV3IGdsb2JhbC5VaW50OEFycmF5KHNpemUpXG5cbiAgLy8gVGhpcyB3aWxsIG5vdCB3b3JrIGluIG9sZGVyIGJyb3dzZXJzLlxuICAvLyBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL3dpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzXG4gIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMocmF3Qnl0ZXMpXG5cbiAgLy8gcGhhbnRvbWpzIGRvZXNuJ3QgbGlrZSBhIGJ1ZmZlciBiZWluZyBwYXNzZWQgaGVyZVxuICB2YXIgYnl0ZXMgPSBuZXcgQnVmZmVyKHJhd0J5dGVzLmJ1ZmZlcilcblxuICBpZiAodHlwZW9mIGNiID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgY2IobnVsbCwgYnl0ZXMpXG4gICAgfSlcbiAgfVxuXG4gIHJldHVybiBieXRlc1xufVxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgdGhpcy5fZXZlbnRzID0gdGhpcy5fZXZlbnRzIHx8IHt9O1xuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSB0aGlzLl9tYXhMaXN0ZW5lcnMgfHwgdW5kZWZpbmVkO1xufVxubW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG5FdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbihuKSB7XG4gIGlmICghaXNOdW1iZXIobikgfHwgbiA8IDAgfHwgaXNOYU4obikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCduIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBsaXN0ZW5lcnM7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAodHlwZSA9PT0gJ2Vycm9yJykge1xuICAgIGlmICghdGhpcy5fZXZlbnRzLmVycm9yIHx8XG4gICAgICAgIChpc09iamVjdCh0aGlzLl9ldmVudHMuZXJyb3IpICYmICF0aGlzLl9ldmVudHMuZXJyb3IubGVuZ3RoKSkge1xuICAgICAgZXIgPSBhcmd1bWVudHNbMV07XG4gICAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICAgIH1cbiAgICAgIHRocm93IFR5cGVFcnJvcignVW5jYXVnaHQsIHVuc3BlY2lmaWVkIFwiZXJyb3JcIiBldmVudC4nKTtcbiAgICB9XG4gIH1cblxuICBoYW5kbGVyID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc1VuZGVmaW5lZChoYW5kbGVyKSlcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKGlzRnVuY3Rpb24oaGFuZGxlcikpIHtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIC8vIHNsb3dlclxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgIGhhbmRsZXIuYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzT2JqZWN0KGhhbmRsZXIpKSB7XG4gICAgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgbGlzdGVuZXJzID0gaGFuZGxlci5zbGljZSgpO1xuICAgIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKVxuICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIG07XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXG4gIC8vIFRvIGF2b2lkIHJlY3Vyc2lvbiBpbiB0aGUgY2FzZSB0aGF0IHR5cGUgPT09IFwibmV3TGlzdGVuZXJcIiEgQmVmb3JlXG4gIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgaWYgKHRoaXMuX2V2ZW50cy5uZXdMaXN0ZW5lcilcbiAgICB0aGlzLmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICAgICAgaXNGdW5jdGlvbihsaXN0ZW5lci5saXN0ZW5lcikgP1xuICAgICAgICAgICAgICBsaXN0ZW5lci5saXN0ZW5lciA6IGxpc3RlbmVyKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgZWxzZSBpZiAoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSlcbiAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBhcnJheSwganVzdCBhcHBlbmQuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdLnB1c2gobGlzdGVuZXIpO1xuICBlbHNlXG4gICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gW3RoaXMuX2V2ZW50c1t0eXBlXSwgbGlzdGVuZXJdO1xuXG4gIC8vIENoZWNrIGZvciBsaXN0ZW5lciBsZWFrXG4gIGlmIChpc09iamVjdCh0aGlzLl9ldmVudHNbdHlwZV0pICYmICF0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkKSB7XG4gICAgaWYgKCFpc1VuZGVmaW5lZCh0aGlzLl9tYXhMaXN0ZW5lcnMpKSB7XG4gICAgICBtID0gdGhpcy5fbWF4TGlzdGVuZXJzO1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gICAgfVxuXG4gICAgaWYgKG0gJiYgbSA+IDAgJiYgdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aCA+IG0pIHtcbiAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQgPSB0cnVlO1xuICAgICAgY29uc29sZS5lcnJvcignKG5vZGUpIHdhcm5pbmc6IHBvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgJyArXG4gICAgICAgICAgICAgICAgICAgICdsZWFrIGRldGVjdGVkLiAlZCBsaXN0ZW5lcnMgYWRkZWQuICcgK1xuICAgICAgICAgICAgICAgICAgICAnVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gaW5jcmVhc2UgbGltaXQuJyxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aCk7XG4gICAgICBpZiAodHlwZW9mIGNvbnNvbGUudHJhY2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgLy8gbm90IHN1cHBvcnRlZCBpbiBJRSAxMFxuICAgICAgICBjb25zb2xlLnRyYWNlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIHZhciBmaXJlZCA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIGcoKSB7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBnKTtcblxuICAgIGlmICghZmlyZWQpIHtcbiAgICAgIGZpcmVkID0gdHJ1ZTtcbiAgICAgIGxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuICB9XG5cbiAgZy5saXN0ZW5lciA9IGxpc3RlbmVyO1xuICB0aGlzLm9uKHR5cGUsIGcpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gZW1pdHMgYSAncmVtb3ZlTGlzdGVuZXInIGV2ZW50IGlmZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWRcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICB2YXIgbGlzdCwgcG9zaXRpb24sIGxlbmd0aCwgaTtcblxuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICByZXR1cm4gdGhpcztcblxuICBsaXN0ID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuICBsZW5ndGggPSBsaXN0Lmxlbmd0aDtcbiAgcG9zaXRpb24gPSAtMTtcblxuICBpZiAobGlzdCA9PT0gbGlzdGVuZXIgfHxcbiAgICAgIChpc0Z1bmN0aW9uKGxpc3QubGlzdGVuZXIpICYmIGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSkge1xuICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgaWYgKHRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0ZW5lcik7XG5cbiAgfSBlbHNlIGlmIChpc09iamVjdChsaXN0KSkge1xuICAgIGZvciAoaSA9IGxlbmd0aDsgaS0tID4gMDspIHtcbiAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fFxuICAgICAgICAgIChsaXN0W2ldLmxpc3RlbmVyICYmIGxpc3RbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSkge1xuICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwb3NpdGlvbiA8IDApXG4gICAgICByZXR1cm4gdGhpcztcblxuICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSkge1xuICAgICAgbGlzdC5sZW5ndGggPSAwO1xuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGlzdC5zcGxpY2UocG9zaXRpb24sIDEpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIGtleSwgbGlzdGVuZXJzO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIC8vIG5vdCBsaXN0ZW5pbmcgZm9yIHJlbW92ZUxpc3RlbmVyLCBubyBuZWVkIHRvIGVtaXRcbiAgaWYgKCF0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIGVsc2UgaWYgKHRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBlbWl0IHJlbW92ZUxpc3RlbmVyIGZvciBhbGwgbGlzdGVuZXJzIG9uIGFsbCBldmVudHNcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICBmb3IgKGtleSBpbiB0aGlzLl9ldmVudHMpIHtcbiAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KTtcbiAgICB9XG4gICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgaWYgKGlzRnVuY3Rpb24obGlzdGVuZXJzKSkge1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzKTtcbiAgfSBlbHNlIGlmIChsaXN0ZW5lcnMpIHtcbiAgICAvLyBMSUZPIG9yZGVyXG4gICAgd2hpbGUgKGxpc3RlbmVycy5sZW5ndGgpXG4gICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tsaXN0ZW5lcnMubGVuZ3RoIC0gMV0pO1xuICB9XG4gIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIHJldDtcbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICByZXQgPSBbXTtcbiAgZWxzZSBpZiAoaXNGdW5jdGlvbih0aGlzLl9ldmVudHNbdHlwZV0pKVxuICAgIHJldCA9IFt0aGlzLl9ldmVudHNbdHlwZV1dO1xuICBlbHNlXG4gICAgcmV0ID0gdGhpcy5fZXZlbnRzW3R5cGVdLnNsaWNlKCk7XG4gIHJldHVybiByZXQ7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbih0eXBlKSB7XG4gIGlmICh0aGlzLl9ldmVudHMpIHtcbiAgICB2YXIgZXZsaXN0ZW5lciA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICAgIGlmIChpc0Z1bmN0aW9uKGV2bGlzdGVuZXIpKVxuICAgICAgcmV0dXJuIDE7XG4gICAgZWxzZSBpZiAoZXZsaXN0ZW5lcilcbiAgICAgIHJldHVybiBldmxpc3RlbmVyLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gMDtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICByZXR1cm4gZW1pdHRlci5saXN0ZW5lckNvdW50KHR5cGUpO1xufTtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XG59XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuIiwiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59IGVsc2Uge1xuICAvLyBvbGQgc2Nob29sIHNoaW0gZm9yIG9sZCBicm93c2Vyc1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgY3Rvci5wcm90b3R5cGUgPSBuZXcgVGVtcEN0b3IoKVxuICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICB9XG59XG4iLCIvKipcbiAqIERldGVybWluZSBpZiBhbiBvYmplY3QgaXMgQnVmZmVyXG4gKlxuICogQXV0aG9yOiAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBMaWNlbnNlOiAgTUlUXG4gKlxuICogYG5wbSBpbnN0YWxsIGlzLWJ1ZmZlcmBcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmopIHtcbiAgcmV0dXJuICEhKG9iaiAhPSBudWxsICYmXG4gICAgKG9iai5faXNCdWZmZXIgfHwgLy8gRm9yIFNhZmFyaSA1LTcgKG1pc3NpbmcgT2JqZWN0LnByb3RvdHlwZS5jb25zdHJ1Y3RvcilcbiAgICAgIChvYmouY29uc3RydWN0b3IgJiZcbiAgICAgIHR5cGVvZiBvYmouY29uc3RydWN0b3IuaXNCdWZmZXIgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlcihvYmopKVxuICAgICkpXG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFycikgPT0gJ1tvYmplY3QgQXJyYXldJztcbn07XG4iLCIvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcblxudmFyIHByb2Nlc3MgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xudmFyIHF1ZXVlID0gW107XG52YXIgZHJhaW5pbmcgPSBmYWxzZTtcbnZhciBjdXJyZW50UXVldWU7XG52YXIgcXVldWVJbmRleCA9IC0xO1xuXG5mdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBpZiAoY3VycmVudFF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICB9XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBkcmFpblF1ZXVlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB0aW1lb3V0ID0gc2V0VGltZW91dChjbGVhblVwTmV4dFRpY2spO1xuICAgIGRyYWluaW5nID0gdHJ1ZTtcblxuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB3aGlsZSAoKytxdWV1ZUluZGV4IDwgbGVuKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudFF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFF1ZXVlW3F1ZXVlSW5kZXhdLnJ1bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICAgICAgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIH1cbiAgICBjdXJyZW50UXVldWUgPSBudWxsO1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xufVxuXG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHF1ZXVlLnB1c2gobmV3IEl0ZW0oZnVuLCBhcmdzKSk7XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCA9PT0gMSAmJiAhZHJhaW5pbmcpIHtcbiAgICAgICAgc2V0VGltZW91dChkcmFpblF1ZXVlLCAwKTtcbiAgICB9XG59O1xuXG4vLyB2OCBsaWtlcyBwcmVkaWN0aWJsZSBvYmplY3RzXG5mdW5jdGlvbiBJdGVtKGZ1biwgYXJyYXkpIHtcbiAgICB0aGlzLmZ1biA9IGZ1bjtcbiAgICB0aGlzLmFycmF5ID0gYXJyYXk7XG59XG5JdGVtLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5mdW4uYXBwbHkobnVsbCwgdGhpcy5hcnJheSk7XG59O1xucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vbGliL19zdHJlYW1fZHVwbGV4LmpzXCIpXG4iLCIvLyBhIGR1cGxleCBzdHJlYW0gaXMganVzdCBhIHN0cmVhbSB0aGF0IGlzIGJvdGggcmVhZGFibGUgYW5kIHdyaXRhYmxlLlxuLy8gU2luY2UgSlMgZG9lc24ndCBoYXZlIG11bHRpcGxlIHByb3RvdHlwYWwgaW5oZXJpdGFuY2UsIHRoaXMgY2xhc3Ncbi8vIHByb3RvdHlwYWxseSBpbmhlcml0cyBmcm9tIFJlYWRhYmxlLCBhbmQgdGhlbiBwYXJhc2l0aWNhbGx5IGZyb21cbi8vIFdyaXRhYmxlLlxuXG4ndXNlIHN0cmljdCc7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgb2JqZWN0S2V5cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikga2V5cy5wdXNoKGtleSk7XG4gIHJldHVybiBrZXlzO1xufVxuLyo8L3JlcGxhY2VtZW50PiovXG5cblxubW9kdWxlLmV4cG9ydHMgPSBEdXBsZXg7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgcHJvY2Vzc05leHRUaWNrID0gcmVxdWlyZSgncHJvY2Vzcy1uZXh0aWNrLWFyZ3MnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSgnY29yZS11dGlsLWlzJyk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgUmVhZGFibGUgPSByZXF1aXJlKCcuL19zdHJlYW1fcmVhZGFibGUnKTtcbnZhciBXcml0YWJsZSA9IHJlcXVpcmUoJy4vX3N0cmVhbV93cml0YWJsZScpO1xuXG51dGlsLmluaGVyaXRzKER1cGxleCwgUmVhZGFibGUpO1xuXG52YXIga2V5cyA9IG9iamVjdEtleXMoV3JpdGFibGUucHJvdG90eXBlKTtcbmZvciAodmFyIHYgPSAwOyB2IDwga2V5cy5sZW5ndGg7IHYrKykge1xuICB2YXIgbWV0aG9kID0ga2V5c1t2XTtcbiAgaWYgKCFEdXBsZXgucHJvdG90eXBlW21ldGhvZF0pXG4gICAgRHVwbGV4LnByb3RvdHlwZVttZXRob2RdID0gV3JpdGFibGUucHJvdG90eXBlW21ldGhvZF07XG59XG5cbmZ1bmN0aW9uIER1cGxleChvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBEdXBsZXgpKVxuICAgIHJldHVybiBuZXcgRHVwbGV4KG9wdGlvbnMpO1xuXG4gIFJlYWRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG4gIFdyaXRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5yZWFkYWJsZSA9PT0gZmFsc2UpXG4gICAgdGhpcy5yZWFkYWJsZSA9IGZhbHNlO1xuXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMud3JpdGFibGUgPT09IGZhbHNlKVxuICAgIHRoaXMud3JpdGFibGUgPSBmYWxzZTtcblxuICB0aGlzLmFsbG93SGFsZk9wZW4gPSB0cnVlO1xuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmFsbG93SGFsZk9wZW4gPT09IGZhbHNlKVxuICAgIHRoaXMuYWxsb3dIYWxmT3BlbiA9IGZhbHNlO1xuXG4gIHRoaXMub25jZSgnZW5kJywgb25lbmQpO1xufVxuXG4vLyB0aGUgbm8taGFsZi1vcGVuIGVuZm9yY2VyXG5mdW5jdGlvbiBvbmVuZCgpIHtcbiAgLy8gaWYgd2UgYWxsb3cgaGFsZi1vcGVuIHN0YXRlLCBvciBpZiB0aGUgd3JpdGFibGUgc2lkZSBlbmRlZCxcbiAgLy8gdGhlbiB3ZSdyZSBvay5cbiAgaWYgKHRoaXMuYWxsb3dIYWxmT3BlbiB8fCB0aGlzLl93cml0YWJsZVN0YXRlLmVuZGVkKVxuICAgIHJldHVybjtcblxuICAvLyBubyBtb3JlIGRhdGEgY2FuIGJlIHdyaXR0ZW4uXG4gIC8vIEJ1dCBhbGxvdyBtb3JlIHdyaXRlcyB0byBoYXBwZW4gaW4gdGhpcyB0aWNrLlxuICBwcm9jZXNzTmV4dFRpY2sob25FbmROVCwgdGhpcyk7XG59XG5cbmZ1bmN0aW9uIG9uRW5kTlQoc2VsZikge1xuICBzZWxmLmVuZCgpO1xufVxuXG5mdW5jdGlvbiBmb3JFYWNoICh4cywgZikge1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHhzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGYoeHNbaV0sIGkpO1xuICB9XG59XG4iLCIvLyBhIHBhc3N0aHJvdWdoIHN0cmVhbS5cbi8vIGJhc2ljYWxseSBqdXN0IHRoZSBtb3N0IG1pbmltYWwgc29ydCBvZiBUcmFuc2Zvcm0gc3RyZWFtLlxuLy8gRXZlcnkgd3JpdHRlbiBjaHVuayBnZXRzIG91dHB1dCBhcy1pcy5cblxuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBhc3NUaHJvdWdoO1xuXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnLi9fc3RyZWFtX3RyYW5zZm9ybScpO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSByZXF1aXJlKCdjb3JlLXV0aWwtaXMnKTtcbnV0aWwuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnV0aWwuaW5oZXJpdHMoUGFzc1Rocm91Z2gsIFRyYW5zZm9ybSk7XG5cbmZ1bmN0aW9uIFBhc3NUaHJvdWdoKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFBhc3NUaHJvdWdoKSlcbiAgICByZXR1cm4gbmV3IFBhc3NUaHJvdWdoKG9wdGlvbnMpO1xuXG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xufVxuXG5QYXNzVGhyb3VnaC5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2IobnVsbCwgY2h1bmspO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFkYWJsZTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBwcm9jZXNzTmV4dFRpY2sgPSByZXF1aXJlKCdwcm9jZXNzLW5leHRpY2stYXJncycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXNhcnJheScpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuUmVhZGFibGUuUmVhZGFibGVTdGF0ZSA9IFJlYWRhYmxlU3RhdGU7XG5cbnZhciBFRSA9IHJlcXVpcmUoJ2V2ZW50cycpO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIEVFbGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJzKHR5cGUpLmxlbmd0aDtcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgU3RyZWFtO1xuKGZ1bmN0aW9uICgpe3RyeXtcbiAgU3RyZWFtID0gcmVxdWlyZSgnc3QnICsgJ3JlYW0nKTtcbn1jYXRjaChfKXt9ZmluYWxseXtcbiAgaWYgKCFTdHJlYW0pXG4gICAgU3RyZWFtID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xufX0oKSlcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSByZXF1aXJlKCdjb3JlLXV0aWwtaXMnKTtcbnV0aWwuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cblxuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGRlYnVnVXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciBkZWJ1ZztcbmlmIChkZWJ1Z1V0aWwgJiYgZGVidWdVdGlsLmRlYnVnbG9nKSB7XG4gIGRlYnVnID0gZGVidWdVdGlsLmRlYnVnbG9nKCdzdHJlYW0nKTtcbn0gZWxzZSB7XG4gIGRlYnVnID0gZnVuY3Rpb24gKCkge307XG59XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIFN0cmluZ0RlY29kZXI7XG5cbnV0aWwuaW5oZXJpdHMoUmVhZGFibGUsIFN0cmVhbSk7XG5cbnZhciBEdXBsZXg7XG5mdW5jdGlvbiBSZWFkYWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSkge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIG9iamVjdCBzdHJlYW0gZmxhZy4gVXNlZCB0byBtYWtlIHJlYWQobikgaWdub3JlIG4gYW5kIHRvXG4gIC8vIG1ha2UgYWxsIHRoZSBidWZmZXIgbWVyZ2luZyBhbmQgbGVuZ3RoIGNoZWNrcyBnbyBhd2F5XG4gIHRoaXMub2JqZWN0TW9kZSA9ICEhb3B0aW9ucy5vYmplY3RNb2RlO1xuXG4gIGlmIChzdHJlYW0gaW5zdGFuY2VvZiBEdXBsZXgpXG4gICAgdGhpcy5vYmplY3RNb2RlID0gdGhpcy5vYmplY3RNb2RlIHx8ICEhb3B0aW9ucy5yZWFkYWJsZU9iamVjdE1vZGU7XG5cbiAgLy8gdGhlIHBvaW50IGF0IHdoaWNoIGl0IHN0b3BzIGNhbGxpbmcgX3JlYWQoKSB0byBmaWxsIHRoZSBidWZmZXJcbiAgLy8gTm90ZTogMCBpcyBhIHZhbGlkIHZhbHVlLCBtZWFucyBcImRvbid0IGNhbGwgX3JlYWQgcHJlZW1wdGl2ZWx5IGV2ZXJcIlxuICB2YXIgaHdtID0gb3B0aW9ucy5oaWdoV2F0ZXJNYXJrO1xuICB2YXIgZGVmYXVsdEh3bSA9IHRoaXMub2JqZWN0TW9kZSA/IDE2IDogMTYgKiAxMDI0O1xuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSAoaHdtIHx8IGh3bSA9PT0gMCkgPyBod20gOiBkZWZhdWx0SHdtO1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gfn50aGlzLmhpZ2hXYXRlck1hcms7XG5cbiAgdGhpcy5idWZmZXIgPSBbXTtcbiAgdGhpcy5sZW5ndGggPSAwO1xuICB0aGlzLnBpcGVzID0gbnVsbDtcbiAgdGhpcy5waXBlc0NvdW50ID0gMDtcbiAgdGhpcy5mbG93aW5nID0gbnVsbDtcbiAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICB0aGlzLmVuZEVtaXR0ZWQgPSBmYWxzZTtcbiAgdGhpcy5yZWFkaW5nID0gZmFsc2U7XG5cbiAgLy8gYSBmbGFnIHRvIGJlIGFibGUgdG8gdGVsbCBpZiB0aGUgb253cml0ZSBjYiBpcyBjYWxsZWQgaW1tZWRpYXRlbHksXG4gIC8vIG9yIG9uIGEgbGF0ZXIgdGljay4gIFdlIHNldCB0aGlzIHRvIHRydWUgYXQgZmlyc3QsIGJlY2F1c2UgYW55XG4gIC8vIGFjdGlvbnMgdGhhdCBzaG91bGRuJ3QgaGFwcGVuIHVudGlsIFwibGF0ZXJcIiBzaG91bGQgZ2VuZXJhbGx5IGFsc29cbiAgLy8gbm90IGhhcHBlbiBiZWZvcmUgdGhlIGZpcnN0IHdyaXRlIGNhbGwuXG4gIHRoaXMuc3luYyA9IHRydWU7XG5cbiAgLy8gd2hlbmV2ZXIgd2UgcmV0dXJuIG51bGwsIHRoZW4gd2Ugc2V0IGEgZmxhZyB0byBzYXlcbiAgLy8gdGhhdCB3ZSdyZSBhd2FpdGluZyBhICdyZWFkYWJsZScgZXZlbnQgZW1pc3Npb24uXG4gIHRoaXMubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIHRoaXMuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gIHRoaXMucmVhZGFibGVMaXN0ZW5pbmcgPSBmYWxzZTtcblxuICAvLyBDcnlwdG8gaXMga2luZCBvZiBvbGQgYW5kIGNydXN0eS4gIEhpc3RvcmljYWxseSwgaXRzIGRlZmF1bHQgc3RyaW5nXG4gIC8vIGVuY29kaW5nIGlzICdiaW5hcnknIHNvIHdlIGhhdmUgdG8gbWFrZSB0aGlzIGNvbmZpZ3VyYWJsZS5cbiAgLy8gRXZlcnl0aGluZyBlbHNlIGluIHRoZSB1bml2ZXJzZSB1c2VzICd1dGY4JywgdGhvdWdoLlxuICB0aGlzLmRlZmF1bHRFbmNvZGluZyA9IG9wdGlvbnMuZGVmYXVsdEVuY29kaW5nIHx8ICd1dGY4JztcblxuICAvLyB3aGVuIHBpcGluZywgd2Ugb25seSBjYXJlIGFib3V0ICdyZWFkYWJsZScgZXZlbnRzIHRoYXQgaGFwcGVuXG4gIC8vIGFmdGVyIHJlYWQoKWluZyBhbGwgdGhlIGJ5dGVzIGFuZCBub3QgZ2V0dGluZyBhbnkgcHVzaGJhY2suXG4gIHRoaXMucmFuT3V0ID0gZmFsc2U7XG5cbiAgLy8gdGhlIG51bWJlciBvZiB3cml0ZXJzIHRoYXQgYXJlIGF3YWl0aW5nIGEgZHJhaW4gZXZlbnQgaW4gLnBpcGUoKXNcbiAgdGhpcy5hd2FpdERyYWluID0gMDtcblxuICAvLyBpZiB0cnVlLCBhIG1heWJlUmVhZE1vcmUgaGFzIGJlZW4gc2NoZWR1bGVkXG4gIHRoaXMucmVhZGluZ01vcmUgPSBmYWxzZTtcblxuICB0aGlzLmRlY29kZXIgPSBudWxsO1xuICB0aGlzLmVuY29kaW5nID0gbnVsbDtcbiAgaWYgKG9wdGlvbnMuZW5jb2RpbmcpIHtcbiAgICBpZiAoIVN0cmluZ0RlY29kZXIpXG4gICAgICBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXIvJykuU3RyaW5nRGVjb2RlcjtcbiAgICB0aGlzLmRlY29kZXIgPSBuZXcgU3RyaW5nRGVjb2RlcihvcHRpb25zLmVuY29kaW5nKTtcbiAgICB0aGlzLmVuY29kaW5nID0gb3B0aW9ucy5lbmNvZGluZztcbiAgfVxufVxuXG52YXIgRHVwbGV4O1xuZnVuY3Rpb24gUmVhZGFibGUob3B0aW9ucykge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBSZWFkYWJsZSkpXG4gICAgcmV0dXJuIG5ldyBSZWFkYWJsZShvcHRpb25zKTtcblxuICB0aGlzLl9yZWFkYWJsZVN0YXRlID0gbmV3IFJlYWRhYmxlU3RhdGUob3B0aW9ucywgdGhpcyk7XG5cbiAgLy8gbGVnYWN5XG4gIHRoaXMucmVhZGFibGUgPSB0cnVlO1xuXG4gIGlmIChvcHRpb25zICYmIHR5cGVvZiBvcHRpb25zLnJlYWQgPT09ICdmdW5jdGlvbicpXG4gICAgdGhpcy5fcmVhZCA9IG9wdGlvbnMucmVhZDtcblxuICBTdHJlYW0uY2FsbCh0aGlzKTtcbn1cblxuLy8gTWFudWFsbHkgc2hvdmUgc29tZXRoaW5nIGludG8gdGhlIHJlYWQoKSBidWZmZXIuXG4vLyBUaGlzIHJldHVybnMgdHJ1ZSBpZiB0aGUgaGlnaFdhdGVyTWFyayBoYXMgbm90IGJlZW4gaGl0IHlldCxcbi8vIHNpbWlsYXIgdG8gaG93IFdyaXRhYmxlLndyaXRlKCkgcmV0dXJucyB0cnVlIGlmIHlvdSBzaG91bGRcbi8vIHdyaXRlKCkgc29tZSBtb3JlLlxuUmVhZGFibGUucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcblxuICBpZiAoIXN0YXRlLm9iamVjdE1vZGUgJiYgdHlwZW9mIGNodW5rID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gZW5jb2RpbmcgfHwgc3RhdGUuZGVmYXVsdEVuY29kaW5nO1xuICAgIGlmIChlbmNvZGluZyAhPT0gc3RhdGUuZW5jb2RpbmcpIHtcbiAgICAgIGNodW5rID0gbmV3IEJ1ZmZlcihjaHVuaywgZW5jb2RpbmcpO1xuICAgICAgZW5jb2RpbmcgPSAnJztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVhZGFibGVBZGRDaHVuayh0aGlzLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBmYWxzZSk7XG59O1xuXG4vLyBVbnNoaWZ0IHNob3VsZCAqYWx3YXlzKiBiZSBzb21ldGhpbmcgZGlyZWN0bHkgb3V0IG9mIHJlYWQoKVxuUmVhZGFibGUucHJvdG90eXBlLnVuc2hpZnQgPSBmdW5jdGlvbihjaHVuaykge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICByZXR1cm4gcmVhZGFibGVBZGRDaHVuayh0aGlzLCBzdGF0ZSwgY2h1bmssICcnLCB0cnVlKTtcbn07XG5cblJlYWRhYmxlLnByb3RvdHlwZS5pc1BhdXNlZCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nID09PSBmYWxzZTtcbn07XG5cbmZ1bmN0aW9uIHJlYWRhYmxlQWRkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBhZGRUb0Zyb250KSB7XG4gIHZhciBlciA9IGNodW5rSW52YWxpZChzdGF0ZSwgY2h1bmspO1xuICBpZiAoZXIpIHtcbiAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gIH0gZWxzZSBpZiAoY2h1bmsgPT09IG51bGwpIHtcbiAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gICAgb25Fb2ZDaHVuayhzdHJlYW0sIHN0YXRlKTtcbiAgfSBlbHNlIGlmIChzdGF0ZS5vYmplY3RNb2RlIHx8IGNodW5rICYmIGNodW5rLmxlbmd0aCA+IDApIHtcbiAgICBpZiAoc3RhdGUuZW5kZWQgJiYgIWFkZFRvRnJvbnQpIHtcbiAgICAgIHZhciBlID0gbmV3IEVycm9yKCdzdHJlYW0ucHVzaCgpIGFmdGVyIEVPRicpO1xuICAgICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZSk7XG4gICAgfSBlbHNlIGlmIChzdGF0ZS5lbmRFbWl0dGVkICYmIGFkZFRvRnJvbnQpIHtcbiAgICAgIHZhciBlID0gbmV3IEVycm9yKCdzdHJlYW0udW5zaGlmdCgpIGFmdGVyIGVuZCBldmVudCcpO1xuICAgICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzdGF0ZS5kZWNvZGVyICYmICFhZGRUb0Zyb250ICYmICFlbmNvZGluZylcbiAgICAgICAgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLndyaXRlKGNodW5rKTtcblxuICAgICAgaWYgKCFhZGRUb0Zyb250KVxuICAgICAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG5cbiAgICAgIC8vIGlmIHdlIHdhbnQgdGhlIGRhdGEgbm93LCBqdXN0IGVtaXQgaXQuXG4gICAgICBpZiAoc3RhdGUuZmxvd2luZyAmJiBzdGF0ZS5sZW5ndGggPT09IDAgJiYgIXN0YXRlLnN5bmMpIHtcbiAgICAgICAgc3RyZWFtLmVtaXQoJ2RhdGEnLCBjaHVuayk7XG4gICAgICAgIHN0cmVhbS5yZWFkKDApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gdXBkYXRlIHRoZSBidWZmZXIgaW5mby5cbiAgICAgICAgc3RhdGUubGVuZ3RoICs9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuICAgICAgICBpZiAoYWRkVG9Gcm9udClcbiAgICAgICAgICBzdGF0ZS5idWZmZXIudW5zaGlmdChjaHVuayk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBzdGF0ZS5idWZmZXIucHVzaChjaHVuayk7XG5cbiAgICAgICAgaWYgKHN0YXRlLm5lZWRSZWFkYWJsZSlcbiAgICAgICAgICBlbWl0UmVhZGFibGUoc3RyZWFtKTtcbiAgICAgIH1cblxuICAgICAgbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIWFkZFRvRnJvbnQpIHtcbiAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gbmVlZE1vcmVEYXRhKHN0YXRlKTtcbn1cblxuXG4vLyBpZiBpdCdzIHBhc3QgdGhlIGhpZ2ggd2F0ZXIgbWFyaywgd2UgY2FuIHB1c2ggaW4gc29tZSBtb3JlLlxuLy8gQWxzbywgaWYgd2UgaGF2ZSBubyBkYXRhIHlldCwgd2UgY2FuIHN0YW5kIHNvbWVcbi8vIG1vcmUgYnl0ZXMuICBUaGlzIGlzIHRvIHdvcmsgYXJvdW5kIGNhc2VzIHdoZXJlIGh3bT0wLFxuLy8gc3VjaCBhcyB0aGUgcmVwbC4gIEFsc28sIGlmIHRoZSBwdXNoKCkgdHJpZ2dlcmVkIGFcbi8vIHJlYWRhYmxlIGV2ZW50LCBhbmQgdGhlIHVzZXIgY2FsbGVkIHJlYWQobGFyZ2VOdW1iZXIpIHN1Y2ggdGhhdFxuLy8gbmVlZFJlYWRhYmxlIHdhcyBzZXQsIHRoZW4gd2Ugb3VnaHQgdG8gcHVzaCBtb3JlLCBzbyB0aGF0IGFub3RoZXJcbi8vICdyZWFkYWJsZScgZXZlbnQgd2lsbCBiZSB0cmlnZ2VyZWQuXG5mdW5jdGlvbiBuZWVkTW9yZURhdGEoc3RhdGUpIHtcbiAgcmV0dXJuICFzdGF0ZS5lbmRlZCAmJlxuICAgICAgICAgKHN0YXRlLm5lZWRSZWFkYWJsZSB8fFxuICAgICAgICAgIHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcmsgfHxcbiAgICAgICAgICBzdGF0ZS5sZW5ndGggPT09IDApO1xufVxuXG4vLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cblJlYWRhYmxlLnByb3RvdHlwZS5zZXRFbmNvZGluZyA9IGZ1bmN0aW9uKGVuYykge1xuICBpZiAoIVN0cmluZ0RlY29kZXIpXG4gICAgU3RyaW5nRGVjb2RlciA9IHJlcXVpcmUoJ3N0cmluZ19kZWNvZGVyLycpLlN0cmluZ0RlY29kZXI7XG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKGVuYyk7XG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUuZW5jb2RpbmcgPSBlbmM7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gRG9uJ3QgcmFpc2UgdGhlIGh3bSA+IDhNQlxudmFyIE1BWF9IV00gPSAweDgwMDAwMDtcbmZ1bmN0aW9uIGNvbXB1dGVOZXdIaWdoV2F0ZXJNYXJrKG4pIHtcbiAgaWYgKG4gPj0gTUFYX0hXTSkge1xuICAgIG4gPSBNQVhfSFdNO1xuICB9IGVsc2Uge1xuICAgIC8vIEdldCB0aGUgbmV4dCBoaWdoZXN0IHBvd2VyIG9mIDJcbiAgICBuLS07XG4gICAgbiB8PSBuID4+PiAxO1xuICAgIG4gfD0gbiA+Pj4gMjtcbiAgICBuIHw9IG4gPj4+IDQ7XG4gICAgbiB8PSBuID4+PiA4O1xuICAgIG4gfD0gbiA+Pj4gMTY7XG4gICAgbisrO1xuICB9XG4gIHJldHVybiBuO1xufVxuXG5mdW5jdGlvbiBob3dNdWNoVG9SZWFkKG4sIHN0YXRlKSB7XG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuZW5kZWQpXG4gICAgcmV0dXJuIDA7XG5cbiAgaWYgKHN0YXRlLm9iamVjdE1vZGUpXG4gICAgcmV0dXJuIG4gPT09IDAgPyAwIDogMTtcblxuICBpZiAobiA9PT0gbnVsbCB8fCBpc05hTihuKSkge1xuICAgIC8vIG9ubHkgZmxvdyBvbmUgYnVmZmVyIGF0IGEgdGltZVxuICAgIGlmIChzdGF0ZS5mbG93aW5nICYmIHN0YXRlLmJ1ZmZlci5sZW5ndGgpXG4gICAgICByZXR1cm4gc3RhdGUuYnVmZmVyWzBdLmxlbmd0aDtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gc3RhdGUubGVuZ3RoO1xuICB9XG5cbiAgaWYgKG4gPD0gMClcbiAgICByZXR1cm4gMDtcblxuICAvLyBJZiB3ZSdyZSBhc2tpbmcgZm9yIG1vcmUgdGhhbiB0aGUgdGFyZ2V0IGJ1ZmZlciBsZXZlbCxcbiAgLy8gdGhlbiByYWlzZSB0aGUgd2F0ZXIgbWFyay4gIEJ1bXAgdXAgdG8gdGhlIG5leHQgaGlnaGVzdFxuICAvLyBwb3dlciBvZiAyLCB0byBwcmV2ZW50IGluY3JlYXNpbmcgaXQgZXhjZXNzaXZlbHkgaW4gdGlueVxuICAvLyBhbW91bnRzLlxuICBpZiAobiA+IHN0YXRlLmhpZ2hXYXRlck1hcmspXG4gICAgc3RhdGUuaGlnaFdhdGVyTWFyayA9IGNvbXB1dGVOZXdIaWdoV2F0ZXJNYXJrKG4pO1xuXG4gIC8vIGRvbid0IGhhdmUgdGhhdCBtdWNoLiAgcmV0dXJuIG51bGwsIHVubGVzcyB3ZSd2ZSBlbmRlZC5cbiAgaWYgKG4gPiBzdGF0ZS5sZW5ndGgpIHtcbiAgICBpZiAoIXN0YXRlLmVuZGVkKSB7XG4gICAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzdGF0ZS5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG47XG59XG5cbi8vIHlvdSBjYW4gb3ZlcnJpZGUgZWl0aGVyIHRoaXMgbWV0aG9kLCBvciB0aGUgYXN5bmMgX3JlYWQobikgYmVsb3cuXG5SZWFkYWJsZS5wcm90b3R5cGUucmVhZCA9IGZ1bmN0aW9uKG4pIHtcbiAgZGVidWcoJ3JlYWQnLCBuKTtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIG5PcmlnID0gbjtcblxuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPiAwKVxuICAgIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuXG4gIC8vIGlmIHdlJ3JlIGRvaW5nIHJlYWQoMCkgdG8gdHJpZ2dlciBhIHJlYWRhYmxlIGV2ZW50LCBidXQgd2VcbiAgLy8gYWxyZWFkeSBoYXZlIGEgYnVuY2ggb2YgZGF0YSBpbiB0aGUgYnVmZmVyLCB0aGVuIGp1c3QgdHJpZ2dlclxuICAvLyB0aGUgJ3JlYWRhYmxlJyBldmVudCBhbmQgbW92ZSBvbi5cbiAgaWYgKG4gPT09IDAgJiZcbiAgICAgIHN0YXRlLm5lZWRSZWFkYWJsZSAmJlxuICAgICAgKHN0YXRlLmxlbmd0aCA+PSBzdGF0ZS5oaWdoV2F0ZXJNYXJrIHx8IHN0YXRlLmVuZGVkKSkge1xuICAgIGRlYnVnKCdyZWFkOiBlbWl0UmVhZGFibGUnLCBzdGF0ZS5sZW5ndGgsIHN0YXRlLmVuZGVkKTtcbiAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLmVuZGVkKVxuICAgICAgZW5kUmVhZGFibGUodGhpcyk7XG4gICAgZWxzZVxuICAgICAgZW1pdFJlYWRhYmxlKHRoaXMpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgbiA9IGhvd011Y2hUb1JlYWQobiwgc3RhdGUpO1xuXG4gIC8vIGlmIHdlJ3ZlIGVuZGVkLCBhbmQgd2UncmUgbm93IGNsZWFyLCB0aGVuIGZpbmlzaCBpdCB1cC5cbiAgaWYgKG4gPT09IDAgJiYgc3RhdGUuZW5kZWQpIHtcbiAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwKVxuICAgICAgZW5kUmVhZGFibGUodGhpcyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBBbGwgdGhlIGFjdHVhbCBjaHVuayBnZW5lcmF0aW9uIGxvZ2ljIG5lZWRzIHRvIGJlXG4gIC8vICpiZWxvdyogdGhlIGNhbGwgdG8gX3JlYWQuICBUaGUgcmVhc29uIGlzIHRoYXQgaW4gY2VydGFpblxuICAvLyBzeW50aGV0aWMgc3RyZWFtIGNhc2VzLCBzdWNoIGFzIHBhc3N0aHJvdWdoIHN0cmVhbXMsIF9yZWFkXG4gIC8vIG1heSBiZSBhIGNvbXBsZXRlbHkgc3luY2hyb25vdXMgb3BlcmF0aW9uIHdoaWNoIG1heSBjaGFuZ2VcbiAgLy8gdGhlIHN0YXRlIG9mIHRoZSByZWFkIGJ1ZmZlciwgcHJvdmlkaW5nIGVub3VnaCBkYXRhIHdoZW5cbiAgLy8gYmVmb3JlIHRoZXJlIHdhcyAqbm90KiBlbm91Z2guXG4gIC8vXG4gIC8vIFNvLCB0aGUgc3RlcHMgYXJlOlxuICAvLyAxLiBGaWd1cmUgb3V0IHdoYXQgdGhlIHN0YXRlIG9mIHRoaW5ncyB3aWxsIGJlIGFmdGVyIHdlIGRvXG4gIC8vIGEgcmVhZCBmcm9tIHRoZSBidWZmZXIuXG4gIC8vXG4gIC8vIDIuIElmIHRoYXQgcmVzdWx0aW5nIHN0YXRlIHdpbGwgdHJpZ2dlciBhIF9yZWFkLCB0aGVuIGNhbGwgX3JlYWQuXG4gIC8vIE5vdGUgdGhhdCB0aGlzIG1heSBiZSBhc3luY2hyb25vdXMsIG9yIHN5bmNocm9ub3VzLiAgWWVzLCBpdCBpc1xuICAvLyBkZWVwbHkgdWdseSB0byB3cml0ZSBBUElzIHRoaXMgd2F5LCBidXQgdGhhdCBzdGlsbCBkb2Vzbid0IG1lYW5cbiAgLy8gdGhhdCB0aGUgUmVhZGFibGUgY2xhc3Mgc2hvdWxkIGJlaGF2ZSBpbXByb3Blcmx5LCBhcyBzdHJlYW1zIGFyZVxuICAvLyBkZXNpZ25lZCB0byBiZSBzeW5jL2FzeW5jIGFnbm9zdGljLlxuICAvLyBUYWtlIG5vdGUgaWYgdGhlIF9yZWFkIGNhbGwgaXMgc3luYyBvciBhc3luYyAoaWUsIGlmIHRoZSByZWFkIGNhbGxcbiAgLy8gaGFzIHJldHVybmVkIHlldCksIHNvIHRoYXQgd2Uga25vdyB3aGV0aGVyIG9yIG5vdCBpdCdzIHNhZmUgdG8gZW1pdFxuICAvLyAncmVhZGFibGUnIGV0Yy5cbiAgLy9cbiAgLy8gMy4gQWN0dWFsbHkgcHVsbCB0aGUgcmVxdWVzdGVkIGNodW5rcyBvdXQgb2YgdGhlIGJ1ZmZlciBhbmQgcmV0dXJuLlxuXG4gIC8vIGlmIHdlIG5lZWQgYSByZWFkYWJsZSBldmVudCwgdGhlbiB3ZSBuZWVkIHRvIGRvIHNvbWUgcmVhZGluZy5cbiAgdmFyIGRvUmVhZCA9IHN0YXRlLm5lZWRSZWFkYWJsZTtcbiAgZGVidWcoJ25lZWQgcmVhZGFibGUnLCBkb1JlYWQpO1xuXG4gIC8vIGlmIHdlIGN1cnJlbnRseSBoYXZlIGxlc3MgdGhhbiB0aGUgaGlnaFdhdGVyTWFyaywgdGhlbiBhbHNvIHJlYWQgc29tZVxuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwIHx8IHN0YXRlLmxlbmd0aCAtIG4gPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgZG9SZWFkID0gdHJ1ZTtcbiAgICBkZWJ1ZygnbGVuZ3RoIGxlc3MgdGhhbiB3YXRlcm1hcmsnLCBkb1JlYWQpO1xuICB9XG5cbiAgLy8gaG93ZXZlciwgaWYgd2UndmUgZW5kZWQsIHRoZW4gdGhlcmUncyBubyBwb2ludCwgYW5kIGlmIHdlJ3JlIGFscmVhZHlcbiAgLy8gcmVhZGluZywgdGhlbiBpdCdzIHVubmVjZXNzYXJ5LlxuICBpZiAoc3RhdGUuZW5kZWQgfHwgc3RhdGUucmVhZGluZykge1xuICAgIGRvUmVhZCA9IGZhbHNlO1xuICAgIGRlYnVnKCdyZWFkaW5nIG9yIGVuZGVkJywgZG9SZWFkKTtcbiAgfVxuXG4gIGlmIChkb1JlYWQpIHtcbiAgICBkZWJ1ZygnZG8gcmVhZCcpO1xuICAgIHN0YXRlLnJlYWRpbmcgPSB0cnVlO1xuICAgIHN0YXRlLnN5bmMgPSB0cnVlO1xuICAgIC8vIGlmIHRoZSBsZW5ndGggaXMgY3VycmVudGx5IHplcm8sIHRoZW4gd2UgKm5lZWQqIGEgcmVhZGFibGUgZXZlbnQuXG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMClcbiAgICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgLy8gY2FsbCBpbnRlcm5hbCByZWFkIG1ldGhvZFxuICAgIHRoaXMuX3JlYWQoc3RhdGUuaGlnaFdhdGVyTWFyayk7XG4gICAgc3RhdGUuc3luYyA9IGZhbHNlO1xuICB9XG5cbiAgLy8gSWYgX3JlYWQgcHVzaGVkIGRhdGEgc3luY2hyb25vdXNseSwgdGhlbiBgcmVhZGluZ2Agd2lsbCBiZSBmYWxzZSxcbiAgLy8gYW5kIHdlIG5lZWQgdG8gcmUtZXZhbHVhdGUgaG93IG11Y2ggZGF0YSB3ZSBjYW4gcmV0dXJuIHRvIHRoZSB1c2VyLlxuICBpZiAoZG9SZWFkICYmICFzdGF0ZS5yZWFkaW5nKVxuICAgIG4gPSBob3dNdWNoVG9SZWFkKG5PcmlnLCBzdGF0ZSk7XG5cbiAgdmFyIHJldDtcbiAgaWYgKG4gPiAwKVxuICAgIHJldCA9IGZyb21MaXN0KG4sIHN0YXRlKTtcbiAgZWxzZVxuICAgIHJldCA9IG51bGw7XG5cbiAgaWYgKHJldCA9PT0gbnVsbCkge1xuICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgbiA9IDA7XG4gIH1cblxuICBzdGF0ZS5sZW5ndGggLT0gbjtcblxuICAvLyBJZiB3ZSBoYXZlIG5vdGhpbmcgaW4gdGhlIGJ1ZmZlciwgdGhlbiB3ZSB3YW50IHRvIGtub3dcbiAgLy8gYXMgc29vbiBhcyB3ZSAqZG8qIGdldCBzb21ldGhpbmcgaW50byB0aGUgYnVmZmVyLlxuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmICFzdGF0ZS5lbmRlZClcbiAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuXG4gIC8vIElmIHdlIHRyaWVkIHRvIHJlYWQoKSBwYXN0IHRoZSBFT0YsIHRoZW4gZW1pdCBlbmQgb24gdGhlIG5leHQgdGljay5cbiAgaWYgKG5PcmlnICE9PSBuICYmIHN0YXRlLmVuZGVkICYmIHN0YXRlLmxlbmd0aCA9PT0gMClcbiAgICBlbmRSZWFkYWJsZSh0aGlzKTtcblxuICBpZiAocmV0ICE9PSBudWxsKVxuICAgIHRoaXMuZW1pdCgnZGF0YScsIHJldCk7XG5cbiAgcmV0dXJuIHJldDtcbn07XG5cbmZ1bmN0aW9uIGNodW5rSW52YWxpZChzdGF0ZSwgY2h1bmspIHtcbiAgdmFyIGVyID0gbnVsbDtcbiAgaWYgKCEoQnVmZmVyLmlzQnVmZmVyKGNodW5rKSkgJiZcbiAgICAgIHR5cGVvZiBjaHVuayAhPT0gJ3N0cmluZycgJiZcbiAgICAgIGNodW5rICE9PSBudWxsICYmXG4gICAgICBjaHVuayAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAhc3RhdGUub2JqZWN0TW9kZSkge1xuICAgIGVyID0gbmV3IFR5cGVFcnJvcignSW52YWxpZCBub24tc3RyaW5nL2J1ZmZlciBjaHVuaycpO1xuICB9XG4gIHJldHVybiBlcjtcbn1cblxuXG5mdW5jdGlvbiBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmVuZGVkKSByZXR1cm47XG4gIGlmIChzdGF0ZS5kZWNvZGVyKSB7XG4gICAgdmFyIGNodW5rID0gc3RhdGUuZGVjb2Rlci5lbmQoKTtcbiAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKSB7XG4gICAgICBzdGF0ZS5idWZmZXIucHVzaChjaHVuayk7XG4gICAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgfVxuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcblxuICAvLyBlbWl0ICdyZWFkYWJsZScgbm93IHRvIG1ha2Ugc3VyZSBpdCBnZXRzIHBpY2tlZCB1cC5cbiAgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG59XG5cbi8vIERvbid0IGVtaXQgcmVhZGFibGUgcmlnaHQgYXdheSBpbiBzeW5jIG1vZGUsIGJlY2F1c2UgdGhpcyBjYW4gdHJpZ2dlclxuLy8gYW5vdGhlciByZWFkKCkgY2FsbCA9PiBzdGFjayBvdmVyZmxvdy4gIFRoaXMgd2F5LCBpdCBtaWdodCB0cmlnZ2VyXG4vLyBhIG5leHRUaWNrIHJlY3Vyc2lvbiB3YXJuaW5nLCBidXQgdGhhdCdzIG5vdCBzbyBiYWQuXG5mdW5jdGlvbiBlbWl0UmVhZGFibGUoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgc3RhdGUubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIGlmICghc3RhdGUuZW1pdHRlZFJlYWRhYmxlKSB7XG4gICAgZGVidWcoJ2VtaXRSZWFkYWJsZScsIHN0YXRlLmZsb3dpbmcpO1xuICAgIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgaWYgKHN0YXRlLnN5bmMpXG4gICAgICBwcm9jZXNzTmV4dFRpY2soZW1pdFJlYWRhYmxlXywgc3RyZWFtKTtcbiAgICBlbHNlXG4gICAgICBlbWl0UmVhZGFibGVfKHN0cmVhbSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW1pdFJlYWRhYmxlXyhzdHJlYW0pIHtcbiAgZGVidWcoJ2VtaXQgcmVhZGFibGUnKTtcbiAgc3RyZWFtLmVtaXQoJ3JlYWRhYmxlJyk7XG4gIGZsb3coc3RyZWFtKTtcbn1cblxuXG4vLyBhdCB0aGlzIHBvaW50LCB0aGUgdXNlciBoYXMgcHJlc3VtYWJseSBzZWVuIHRoZSAncmVhZGFibGUnIGV2ZW50LFxuLy8gYW5kIGNhbGxlZCByZWFkKCkgdG8gY29uc3VtZSBzb21lIGRhdGEuICB0aGF0IG1heSBoYXZlIHRyaWdnZXJlZFxuLy8gaW4gdHVybiBhbm90aGVyIF9yZWFkKG4pIGNhbGwsIGluIHdoaWNoIGNhc2UgcmVhZGluZyA9IHRydWUgaWZcbi8vIGl0J3MgaW4gcHJvZ3Jlc3MuXG4vLyBIb3dldmVyLCBpZiB3ZSdyZSBub3QgZW5kZWQsIG9yIHJlYWRpbmcsIGFuZCB0aGUgbGVuZ3RoIDwgaHdtLFxuLy8gdGhlbiBnbyBhaGVhZCBhbmQgdHJ5IHRvIHJlYWQgc29tZSBtb3JlIHByZWVtcHRpdmVseS5cbmZ1bmN0aW9uIG1heWJlUmVhZE1vcmUoc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnJlYWRpbmdNb3JlKSB7XG4gICAgc3RhdGUucmVhZGluZ01vcmUgPSB0cnVlO1xuICAgIHByb2Nlc3NOZXh0VGljayhtYXliZVJlYWRNb3JlXywgc3RyZWFtLCBzdGF0ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZV8oc3RyZWFtLCBzdGF0ZSkge1xuICB2YXIgbGVuID0gc3RhdGUubGVuZ3RoO1xuICB3aGlsZSAoIXN0YXRlLnJlYWRpbmcgJiYgIXN0YXRlLmZsb3dpbmcgJiYgIXN0YXRlLmVuZGVkICYmXG4gICAgICAgICBzdGF0ZS5sZW5ndGggPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgZGVidWcoJ21heWJlUmVhZE1vcmUgcmVhZCAwJyk7XG4gICAgc3RyZWFtLnJlYWQoMCk7XG4gICAgaWYgKGxlbiA9PT0gc3RhdGUubGVuZ3RoKVxuICAgICAgLy8gZGlkbid0IGdldCBhbnkgZGF0YSwgc3RvcCBzcGlubmluZy5cbiAgICAgIGJyZWFrO1xuICAgIGVsc2VcbiAgICAgIGxlbiA9IHN0YXRlLmxlbmd0aDtcbiAgfVxuICBzdGF0ZS5yZWFkaW5nTW9yZSA9IGZhbHNlO1xufVxuXG4vLyBhYnN0cmFjdCBtZXRob2QuICB0byBiZSBvdmVycmlkZGVuIGluIHNwZWNpZmljIGltcGxlbWVudGF0aW9uIGNsYXNzZXMuXG4vLyBjYWxsIGNiKGVyLCBkYXRhKSB3aGVyZSBkYXRhIGlzIDw9IG4gaW4gbGVuZ3RoLlxuLy8gZm9yIHZpcnR1YWwgKG5vbi1zdHJpbmcsIG5vbi1idWZmZXIpIHN0cmVhbXMsIFwibGVuZ3RoXCIgaXMgc29tZXdoYXRcbi8vIGFyYml0cmFyeSwgYW5kIHBlcmhhcHMgbm90IHZlcnkgbWVhbmluZ2Z1bC5cblJlYWRhYmxlLnByb3RvdHlwZS5fcmVhZCA9IGZ1bmN0aW9uKG4pIHtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJykpO1xufTtcblxuUmVhZGFibGUucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbihkZXN0LCBwaXBlT3B0cykge1xuICB2YXIgc3JjID0gdGhpcztcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcblxuICBzd2l0Y2ggKHN0YXRlLnBpcGVzQ291bnQpIHtcbiAgICBjYXNlIDA6XG4gICAgICBzdGF0ZS5waXBlcyA9IGRlc3Q7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDE6XG4gICAgICBzdGF0ZS5waXBlcyA9IFtzdGF0ZS5waXBlcywgZGVzdF07XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgc3RhdGUucGlwZXMucHVzaChkZXN0KTtcbiAgICAgIGJyZWFrO1xuICB9XG4gIHN0YXRlLnBpcGVzQ291bnQgKz0gMTtcbiAgZGVidWcoJ3BpcGUgY291bnQ9JWQgb3B0cz0laicsIHN0YXRlLnBpcGVzQ291bnQsIHBpcGVPcHRzKTtcblxuICB2YXIgZG9FbmQgPSAoIXBpcGVPcHRzIHx8IHBpcGVPcHRzLmVuZCAhPT0gZmFsc2UpICYmXG4gICAgICAgICAgICAgIGRlc3QgIT09IHByb2Nlc3Muc3Rkb3V0ICYmXG4gICAgICAgICAgICAgIGRlc3QgIT09IHByb2Nlc3Muc3RkZXJyO1xuXG4gIHZhciBlbmRGbiA9IGRvRW5kID8gb25lbmQgOiBjbGVhbnVwO1xuICBpZiAoc3RhdGUuZW5kRW1pdHRlZClcbiAgICBwcm9jZXNzTmV4dFRpY2soZW5kRm4pO1xuICBlbHNlXG4gICAgc3JjLm9uY2UoJ2VuZCcsIGVuZEZuKTtcblxuICBkZXN0Lm9uKCd1bnBpcGUnLCBvbnVucGlwZSk7XG4gIGZ1bmN0aW9uIG9udW5waXBlKHJlYWRhYmxlKSB7XG4gICAgZGVidWcoJ29udW5waXBlJyk7XG4gICAgaWYgKHJlYWRhYmxlID09PSBzcmMpIHtcbiAgICAgIGNsZWFudXAoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBvbmVuZCgpIHtcbiAgICBkZWJ1Zygnb25lbmQnKTtcbiAgICBkZXN0LmVuZCgpO1xuICB9XG5cbiAgLy8gd2hlbiB0aGUgZGVzdCBkcmFpbnMsIGl0IHJlZHVjZXMgdGhlIGF3YWl0RHJhaW4gY291bnRlclxuICAvLyBvbiB0aGUgc291cmNlLiAgVGhpcyB3b3VsZCBiZSBtb3JlIGVsZWdhbnQgd2l0aCBhIC5vbmNlKClcbiAgLy8gaGFuZGxlciBpbiBmbG93KCksIGJ1dCBhZGRpbmcgYW5kIHJlbW92aW5nIHJlcGVhdGVkbHkgaXNcbiAgLy8gdG9vIHNsb3cuXG4gIHZhciBvbmRyYWluID0gcGlwZU9uRHJhaW4oc3JjKTtcbiAgZGVzdC5vbignZHJhaW4nLCBvbmRyYWluKTtcblxuICB2YXIgY2xlYW5lZFVwID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG4gICAgZGVidWcoJ2NsZWFudXAnKTtcbiAgICAvLyBjbGVhbnVwIGV2ZW50IGhhbmRsZXJzIG9uY2UgdGhlIHBpcGUgaXMgYnJva2VuXG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZHJhaW4nLCBvbmRyYWluKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ3VucGlwZScsIG9udW5waXBlKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIGNsZWFudXApO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZGF0YScsIG9uZGF0YSk7XG5cbiAgICBjbGVhbmVkVXAgPSB0cnVlO1xuXG4gICAgLy8gaWYgdGhlIHJlYWRlciBpcyB3YWl0aW5nIGZvciBhIGRyYWluIGV2ZW50IGZyb20gdGhpc1xuICAgIC8vIHNwZWNpZmljIHdyaXRlciwgdGhlbiBpdCB3b3VsZCBjYXVzZSBpdCB0byBuZXZlciBzdGFydFxuICAgIC8vIGZsb3dpbmcgYWdhaW4uXG4gICAgLy8gU28sIGlmIHRoaXMgaXMgYXdhaXRpbmcgYSBkcmFpbiwgdGhlbiB3ZSBqdXN0IGNhbGwgaXQgbm93LlxuICAgIC8vIElmIHdlIGRvbid0IGtub3csIHRoZW4gYXNzdW1lIHRoYXQgd2UgYXJlIHdhaXRpbmcgZm9yIG9uZS5cbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbiAmJlxuICAgICAgICAoIWRlc3QuX3dyaXRhYmxlU3RhdGUgfHwgZGVzdC5fd3JpdGFibGVTdGF0ZS5uZWVkRHJhaW4pKVxuICAgICAgb25kcmFpbigpO1xuICB9XG5cbiAgc3JjLm9uKCdkYXRhJywgb25kYXRhKTtcbiAgZnVuY3Rpb24gb25kYXRhKGNodW5rKSB7XG4gICAgZGVidWcoJ29uZGF0YScpO1xuICAgIHZhciByZXQgPSBkZXN0LndyaXRlKGNodW5rKTtcbiAgICBpZiAoZmFsc2UgPT09IHJldCkge1xuICAgICAgLy8gSWYgdGhlIHVzZXIgdW5waXBlZCBkdXJpbmcgYGRlc3Qud3JpdGUoKWAsIGl0IGlzIHBvc3NpYmxlXG4gICAgICAvLyB0byBnZXQgc3R1Y2sgaW4gYSBwZXJtYW5lbnRseSBwYXVzZWQgc3RhdGUgaWYgdGhhdCB3cml0ZVxuICAgICAgLy8gYWxzbyByZXR1cm5lZCBmYWxzZS5cbiAgICAgIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAxICYmXG4gICAgICAgICAgc3RhdGUucGlwZXNbMF0gPT09IGRlc3QgJiZcbiAgICAgICAgICBzcmMubGlzdGVuZXJDb3VudCgnZGF0YScpID09PSAxICYmXG4gICAgICAgICAgIWNsZWFuZWRVcCkge1xuICAgICAgICBkZWJ1ZygnZmFsc2Ugd3JpdGUgcmVzcG9uc2UsIHBhdXNlJywgc3JjLl9yZWFkYWJsZVN0YXRlLmF3YWl0RHJhaW4pO1xuICAgICAgICBzcmMuX3JlYWRhYmxlU3RhdGUuYXdhaXREcmFpbisrO1xuICAgICAgfVxuICAgICAgc3JjLnBhdXNlKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgdGhlIGRlc3QgaGFzIGFuIGVycm9yLCB0aGVuIHN0b3AgcGlwaW5nIGludG8gaXQuXG4gIC8vIGhvd2V2ZXIsIGRvbid0IHN1cHByZXNzIHRoZSB0aHJvd2luZyBiZWhhdmlvciBmb3IgdGhpcy5cbiAgZnVuY3Rpb24gb25lcnJvcihlcikge1xuICAgIGRlYnVnKCdvbmVycm9yJywgZXIpO1xuICAgIHVucGlwZSgpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgaWYgKEVFbGlzdGVuZXJDb3VudChkZXN0LCAnZXJyb3InKSA9PT0gMClcbiAgICAgIGRlc3QuZW1pdCgnZXJyb3InLCBlcik7XG4gIH1cbiAgLy8gVGhpcyBpcyBhIGJydXRhbGx5IHVnbHkgaGFjayB0byBtYWtlIHN1cmUgdGhhdCBvdXIgZXJyb3IgaGFuZGxlclxuICAvLyBpcyBhdHRhY2hlZCBiZWZvcmUgYW55IHVzZXJsYW5kIG9uZXMuICBORVZFUiBETyBUSElTLlxuICBpZiAoIWRlc3QuX2V2ZW50cyB8fCAhZGVzdC5fZXZlbnRzLmVycm9yKVxuICAgIGRlc3Qub24oJ2Vycm9yJywgb25lcnJvcik7XG4gIGVsc2UgaWYgKGlzQXJyYXkoZGVzdC5fZXZlbnRzLmVycm9yKSlcbiAgICBkZXN0Ll9ldmVudHMuZXJyb3IudW5zaGlmdChvbmVycm9yKTtcbiAgZWxzZVxuICAgIGRlc3QuX2V2ZW50cy5lcnJvciA9IFtvbmVycm9yLCBkZXN0Ll9ldmVudHMuZXJyb3JdO1xuXG5cbiAgLy8gQm90aCBjbG9zZSBhbmQgZmluaXNoIHNob3VsZCB0cmlnZ2VyIHVucGlwZSwgYnV0IG9ubHkgb25jZS5cbiAgZnVuY3Rpb24gb25jbG9zZSgpIHtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgdW5waXBlKCk7XG4gIH1cbiAgZGVzdC5vbmNlKCdjbG9zZScsIG9uY2xvc2UpO1xuICBmdW5jdGlvbiBvbmZpbmlzaCgpIHtcbiAgICBkZWJ1Zygnb25maW5pc2gnKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIHVucGlwZSgpO1xuICB9XG4gIGRlc3Qub25jZSgnZmluaXNoJywgb25maW5pc2gpO1xuXG4gIGZ1bmN0aW9uIHVucGlwZSgpIHtcbiAgICBkZWJ1ZygndW5waXBlJyk7XG4gICAgc3JjLnVucGlwZShkZXN0KTtcbiAgfVxuXG4gIC8vIHRlbGwgdGhlIGRlc3QgdGhhdCBpdCdzIGJlaW5nIHBpcGVkIHRvXG4gIGRlc3QuZW1pdCgncGlwZScsIHNyYyk7XG5cbiAgLy8gc3RhcnQgdGhlIGZsb3cgaWYgaXQgaGFzbid0IGJlZW4gc3RhcnRlZCBhbHJlYWR5LlxuICBpZiAoIXN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncGlwZSByZXN1bWUnKTtcbiAgICBzcmMucmVzdW1lKCk7XG4gIH1cblxuICByZXR1cm4gZGVzdDtcbn07XG5cbmZ1bmN0aW9uIHBpcGVPbkRyYWluKHNyYykge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHN0YXRlID0gc3JjLl9yZWFkYWJsZVN0YXRlO1xuICAgIGRlYnVnKCdwaXBlT25EcmFpbicsIHN0YXRlLmF3YWl0RHJhaW4pO1xuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluKVxuICAgICAgc3RhdGUuYXdhaXREcmFpbi0tO1xuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluID09PSAwICYmIEVFbGlzdGVuZXJDb3VudChzcmMsICdkYXRhJykpIHtcbiAgICAgIHN0YXRlLmZsb3dpbmcgPSB0cnVlO1xuICAgICAgZmxvdyhzcmMpO1xuICAgIH1cbiAgfTtcbn1cblxuXG5SZWFkYWJsZS5wcm90b3R5cGUudW5waXBlID0gZnVuY3Rpb24oZGVzdCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuXG4gIC8vIGlmIHdlJ3JlIG5vdCBwaXBpbmcgYW55d2hlcmUsIHRoZW4gZG8gbm90aGluZy5cbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDApXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8ganVzdCBvbmUgZGVzdGluYXRpb24uICBtb3N0IGNvbW1vbiBjYXNlLlxuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMSkge1xuICAgIC8vIHBhc3NlZCBpbiBvbmUsIGJ1dCBpdCdzIG5vdCB0aGUgcmlnaHQgb25lLlxuICAgIGlmIChkZXN0ICYmIGRlc3QgIT09IHN0YXRlLnBpcGVzKVxuICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAoIWRlc3QpXG4gICAgICBkZXN0ID0gc3RhdGUucGlwZXM7XG5cbiAgICAvLyBnb3QgYSBtYXRjaC5cbiAgICBzdGF0ZS5waXBlcyA9IG51bGw7XG4gICAgc3RhdGUucGlwZXNDb3VudCA9IDA7XG4gICAgc3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuICAgIGlmIChkZXN0KVxuICAgICAgZGVzdC5lbWl0KCd1bnBpcGUnLCB0aGlzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHNsb3cgY2FzZS4gbXVsdGlwbGUgcGlwZSBkZXN0aW5hdGlvbnMuXG5cbiAgaWYgKCFkZXN0KSB7XG4gICAgLy8gcmVtb3ZlIGFsbC5cbiAgICB2YXIgZGVzdHMgPSBzdGF0ZS5waXBlcztcbiAgICB2YXIgbGVuID0gc3RhdGUucGlwZXNDb3VudDtcbiAgICBzdGF0ZS5waXBlcyA9IG51bGw7XG4gICAgc3RhdGUucGlwZXNDb3VudCA9IDA7XG4gICAgc3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgIGRlc3RzW2ldLmVtaXQoJ3VucGlwZScsIHRoaXMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gdHJ5IHRvIGZpbmQgdGhlIHJpZ2h0IG9uZS5cbiAgdmFyIGkgPSBpbmRleE9mKHN0YXRlLnBpcGVzLCBkZXN0KTtcbiAgaWYgKGkgPT09IC0xKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIHN0YXRlLnBpcGVzLnNwbGljZShpLCAxKTtcbiAgc3RhdGUucGlwZXNDb3VudCAtPSAxO1xuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMSlcbiAgICBzdGF0ZS5waXBlcyA9IHN0YXRlLnBpcGVzWzBdO1xuXG4gIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBzZXQgdXAgZGF0YSBldmVudHMgaWYgdGhleSBhcmUgYXNrZWQgZm9yXG4vLyBFbnN1cmUgcmVhZGFibGUgbGlzdGVuZXJzIGV2ZW50dWFsbHkgZ2V0IHNvbWV0aGluZ1xuUmVhZGFibGUucHJvdG90eXBlLm9uID0gZnVuY3Rpb24oZXYsIGZuKSB7XG4gIHZhciByZXMgPSBTdHJlYW0ucHJvdG90eXBlLm9uLmNhbGwodGhpcywgZXYsIGZuKTtcblxuICAvLyBJZiBsaXN0ZW5pbmcgdG8gZGF0YSwgYW5kIGl0IGhhcyBub3QgZXhwbGljaXRseSBiZWVuIHBhdXNlZCxcbiAgLy8gdGhlbiBjYWxsIHJlc3VtZSB0byBzdGFydCB0aGUgZmxvdyBvZiBkYXRhIG9uIHRoZSBuZXh0IHRpY2suXG4gIGlmIChldiA9PT0gJ2RhdGEnICYmIGZhbHNlICE9PSB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcpIHtcbiAgICB0aGlzLnJlc3VtZSgpO1xuICB9XG5cbiAgaWYgKGV2ID09PSAncmVhZGFibGUnICYmIHRoaXMucmVhZGFibGUpIHtcbiAgICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICAgIGlmICghc3RhdGUucmVhZGFibGVMaXN0ZW5pbmcpIHtcbiAgICAgIHN0YXRlLnJlYWRhYmxlTGlzdGVuaW5nID0gdHJ1ZTtcbiAgICAgIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuICAgICAgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICAgIGlmICghc3RhdGUucmVhZGluZykge1xuICAgICAgICBwcm9jZXNzTmV4dFRpY2soblJlYWRpbmdOZXh0VGljaywgdGhpcyk7XG4gICAgICB9IGVsc2UgaWYgKHN0YXRlLmxlbmd0aCkge1xuICAgICAgICBlbWl0UmVhZGFibGUodGhpcywgc3RhdGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXM7XG59O1xuUmVhZGFibGUucHJvdG90eXBlLmFkZExpc3RlbmVyID0gUmVhZGFibGUucHJvdG90eXBlLm9uO1xuXG5mdW5jdGlvbiBuUmVhZGluZ05leHRUaWNrKHNlbGYpIHtcbiAgZGVidWcoJ3JlYWRhYmxlIG5leHR0aWNrIHJlYWQgMCcpO1xuICBzZWxmLnJlYWQoMCk7XG59XG5cbi8vIHBhdXNlKCkgYW5kIHJlc3VtZSgpIGFyZSByZW1uYW50cyBvZiB0aGUgbGVnYWN5IHJlYWRhYmxlIHN0cmVhbSBBUElcbi8vIElmIHRoZSB1c2VyIHVzZXMgdGhlbSwgdGhlbiBzd2l0Y2ggaW50byBvbGQgbW9kZS5cblJlYWRhYmxlLnByb3RvdHlwZS5yZXN1bWUgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgaWYgKCFzdGF0ZS5mbG93aW5nKSB7XG4gICAgZGVidWcoJ3Jlc3VtZScpO1xuICAgIHN0YXRlLmZsb3dpbmcgPSB0cnVlO1xuICAgIHJlc3VtZSh0aGlzLCBzdGF0ZSk7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiByZXN1bWUoc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnJlc3VtZVNjaGVkdWxlZCkge1xuICAgIHN0YXRlLnJlc3VtZVNjaGVkdWxlZCA9IHRydWU7XG4gICAgcHJvY2Vzc05leHRUaWNrKHJlc3VtZV8sIHN0cmVhbSwgc3RhdGUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc3VtZV8oc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnJlYWRpbmcpIHtcbiAgICBkZWJ1ZygncmVzdW1lIHJlYWQgMCcpO1xuICAgIHN0cmVhbS5yZWFkKDApO1xuICB9XG5cbiAgc3RhdGUucmVzdW1lU2NoZWR1bGVkID0gZmFsc2U7XG4gIHN0cmVhbS5lbWl0KCdyZXN1bWUnKTtcbiAgZmxvdyhzdHJlYW0pO1xuICBpZiAoc3RhdGUuZmxvd2luZyAmJiAhc3RhdGUucmVhZGluZylcbiAgICBzdHJlYW0ucmVhZCgwKTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gIGRlYnVnKCdjYWxsIHBhdXNlIGZsb3dpbmc9JWonLCB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcpO1xuICBpZiAoZmFsc2UgIT09IHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZykge1xuICAgIGRlYnVnKCdwYXVzZScpO1xuICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuICAgIHRoaXMuZW1pdCgncGF1c2UnKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIGZsb3coc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgZGVidWcoJ2Zsb3cnLCBzdGF0ZS5mbG93aW5nKTtcbiAgaWYgKHN0YXRlLmZsb3dpbmcpIHtcbiAgICBkbyB7XG4gICAgICB2YXIgY2h1bmsgPSBzdHJlYW0ucmVhZCgpO1xuICAgIH0gd2hpbGUgKG51bGwgIT09IGNodW5rICYmIHN0YXRlLmZsb3dpbmcpO1xuICB9XG59XG5cbi8vIHdyYXAgYW4gb2xkLXN0eWxlIHN0cmVhbSBhcyB0aGUgYXN5bmMgZGF0YSBzb3VyY2UuXG4vLyBUaGlzIGlzICpub3QqIHBhcnQgb2YgdGhlIHJlYWRhYmxlIHN0cmVhbSBpbnRlcmZhY2UuXG4vLyBJdCBpcyBhbiB1Z2x5IHVuZm9ydHVuYXRlIG1lc3Mgb2YgaGlzdG9yeS5cblJlYWRhYmxlLnByb3RvdHlwZS53cmFwID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciBwYXVzZWQgPSBmYWxzZTtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHN0cmVhbS5vbignZW5kJywgZnVuY3Rpb24oKSB7XG4gICAgZGVidWcoJ3dyYXBwZWQgZW5kJyk7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIgJiYgIXN0YXRlLmVuZGVkKSB7XG4gICAgICB2YXIgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLmVuZCgpO1xuICAgICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aClcbiAgICAgICAgc2VsZi5wdXNoKGNodW5rKTtcbiAgICB9XG5cbiAgICBzZWxmLnB1c2gobnVsbCk7XG4gIH0pO1xuXG4gIHN0cmVhbS5vbignZGF0YScsIGZ1bmN0aW9uKGNodW5rKSB7XG4gICAgZGVidWcoJ3dyYXBwZWQgZGF0YScpO1xuICAgIGlmIChzdGF0ZS5kZWNvZGVyKVxuICAgICAgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLndyaXRlKGNodW5rKTtcblxuICAgIC8vIGRvbid0IHNraXAgb3ZlciBmYWxzeSB2YWx1ZXMgaW4gb2JqZWN0TW9kZVxuICAgIGlmIChzdGF0ZS5vYmplY3RNb2RlICYmIChjaHVuayA9PT0gbnVsbCB8fCBjaHVuayA9PT0gdW5kZWZpbmVkKSlcbiAgICAgIHJldHVybjtcbiAgICBlbHNlIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJiAoIWNodW5rIHx8ICFjaHVuay5sZW5ndGgpKVxuICAgICAgcmV0dXJuO1xuXG4gICAgdmFyIHJldCA9IHNlbGYucHVzaChjaHVuayk7XG4gICAgaWYgKCFyZXQpIHtcbiAgICAgIHBhdXNlZCA9IHRydWU7XG4gICAgICBzdHJlYW0ucGF1c2UoKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHByb3h5IGFsbCB0aGUgb3RoZXIgbWV0aG9kcy5cbiAgLy8gaW1wb3J0YW50IHdoZW4gd3JhcHBpbmcgZmlsdGVycyBhbmQgZHVwbGV4ZXMuXG4gIGZvciAodmFyIGkgaW4gc3RyZWFtKSB7XG4gICAgaWYgKHRoaXNbaV0gPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygc3RyZWFtW2ldID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzW2ldID0gZnVuY3Rpb24obWV0aG9kKSB7IHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHN0cmVhbVttZXRob2RdLmFwcGx5KHN0cmVhbSwgYXJndW1lbnRzKTtcbiAgICAgIH07IH0oaSk7XG4gICAgfVxuICB9XG5cbiAgLy8gcHJveHkgY2VydGFpbiBpbXBvcnRhbnQgZXZlbnRzLlxuICB2YXIgZXZlbnRzID0gWydlcnJvcicsICdjbG9zZScsICdkZXN0cm95JywgJ3BhdXNlJywgJ3Jlc3VtZSddO1xuICBmb3JFYWNoKGV2ZW50cywgZnVuY3Rpb24oZXYpIHtcbiAgICBzdHJlYW0ub24oZXYsIHNlbGYuZW1pdC5iaW5kKHNlbGYsIGV2KSk7XG4gIH0pO1xuXG4gIC8vIHdoZW4gd2UgdHJ5IHRvIGNvbnN1bWUgc29tZSBtb3JlIGJ5dGVzLCBzaW1wbHkgdW5wYXVzZSB0aGVcbiAgLy8gdW5kZXJseWluZyBzdHJlYW0uXG4gIHNlbGYuX3JlYWQgPSBmdW5jdGlvbihuKSB7XG4gICAgZGVidWcoJ3dyYXBwZWQgX3JlYWQnLCBuKTtcbiAgICBpZiAocGF1c2VkKSB7XG4gICAgICBwYXVzZWQgPSBmYWxzZTtcbiAgICAgIHN0cmVhbS5yZXN1bWUoKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHNlbGY7XG59O1xuXG5cbi8vIGV4cG9zZWQgZm9yIHRlc3RpbmcgcHVycG9zZXMgb25seS5cblJlYWRhYmxlLl9mcm9tTGlzdCA9IGZyb21MaXN0O1xuXG4vLyBQbHVjayBvZmYgbiBieXRlcyBmcm9tIGFuIGFycmF5IG9mIGJ1ZmZlcnMuXG4vLyBMZW5ndGggaXMgdGhlIGNvbWJpbmVkIGxlbmd0aHMgb2YgYWxsIHRoZSBidWZmZXJzIGluIHRoZSBsaXN0LlxuZnVuY3Rpb24gZnJvbUxpc3Qobiwgc3RhdGUpIHtcbiAgdmFyIGxpc3QgPSBzdGF0ZS5idWZmZXI7XG4gIHZhciBsZW5ndGggPSBzdGF0ZS5sZW5ndGg7XG4gIHZhciBzdHJpbmdNb2RlID0gISFzdGF0ZS5kZWNvZGVyO1xuICB2YXIgb2JqZWN0TW9kZSA9ICEhc3RhdGUub2JqZWN0TW9kZTtcbiAgdmFyIHJldDtcblxuICAvLyBub3RoaW5nIGluIHRoZSBsaXN0LCBkZWZpbml0ZWx5IGVtcHR5LlxuICBpZiAobGlzdC5sZW5ndGggPT09IDApXG4gICAgcmV0dXJuIG51bGw7XG5cbiAgaWYgKGxlbmd0aCA9PT0gMClcbiAgICByZXQgPSBudWxsO1xuICBlbHNlIGlmIChvYmplY3RNb2RlKVxuICAgIHJldCA9IGxpc3Quc2hpZnQoKTtcbiAgZWxzZSBpZiAoIW4gfHwgbiA+PSBsZW5ndGgpIHtcbiAgICAvLyByZWFkIGl0IGFsbCwgdHJ1bmNhdGUgdGhlIGFycmF5LlxuICAgIGlmIChzdHJpbmdNb2RlKVxuICAgICAgcmV0ID0gbGlzdC5qb2luKCcnKTtcbiAgICBlbHNlIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgIHJldCA9IGxpc3RbMF07XG4gICAgZWxzZVxuICAgICAgcmV0ID0gQnVmZmVyLmNvbmNhdChsaXN0LCBsZW5ndGgpO1xuICAgIGxpc3QubGVuZ3RoID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyByZWFkIGp1c3Qgc29tZSBvZiBpdC5cbiAgICBpZiAobiA8IGxpc3RbMF0ubGVuZ3RoKSB7XG4gICAgICAvLyBqdXN0IHRha2UgYSBwYXJ0IG9mIHRoZSBmaXJzdCBsaXN0IGl0ZW0uXG4gICAgICAvLyBzbGljZSBpcyB0aGUgc2FtZSBmb3IgYnVmZmVycyBhbmQgc3RyaW5ncy5cbiAgICAgIHZhciBidWYgPSBsaXN0WzBdO1xuICAgICAgcmV0ID0gYnVmLnNsaWNlKDAsIG4pO1xuICAgICAgbGlzdFswXSA9IGJ1Zi5zbGljZShuKTtcbiAgICB9IGVsc2UgaWYgKG4gPT09IGxpc3RbMF0ubGVuZ3RoKSB7XG4gICAgICAvLyBmaXJzdCBsaXN0IGlzIGEgcGVyZmVjdCBtYXRjaFxuICAgICAgcmV0ID0gbGlzdC5zaGlmdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBjb21wbGV4IGNhc2UuXG4gICAgICAvLyB3ZSBoYXZlIGVub3VnaCB0byBjb3ZlciBpdCwgYnV0IGl0IHNwYW5zIHBhc3QgdGhlIGZpcnN0IGJ1ZmZlci5cbiAgICAgIGlmIChzdHJpbmdNb2RlKVxuICAgICAgICByZXQgPSAnJztcbiAgICAgIGVsc2VcbiAgICAgICAgcmV0ID0gbmV3IEJ1ZmZlcihuKTtcblxuICAgICAgdmFyIGMgPSAwO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBsaXN0Lmxlbmd0aDsgaSA8IGwgJiYgYyA8IG47IGkrKykge1xuICAgICAgICB2YXIgYnVmID0gbGlzdFswXTtcbiAgICAgICAgdmFyIGNweSA9IE1hdGgubWluKG4gLSBjLCBidWYubGVuZ3RoKTtcblxuICAgICAgICBpZiAoc3RyaW5nTW9kZSlcbiAgICAgICAgICByZXQgKz0gYnVmLnNsaWNlKDAsIGNweSk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBidWYuY29weShyZXQsIGMsIDAsIGNweSk7XG5cbiAgICAgICAgaWYgKGNweSA8IGJ1Zi5sZW5ndGgpXG4gICAgICAgICAgbGlzdFswXSA9IGJ1Zi5zbGljZShjcHkpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgbGlzdC5zaGlmdCgpO1xuXG4gICAgICAgIGMgKz0gY3B5O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGVuZFJlYWRhYmxlKHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG5cbiAgLy8gSWYgd2UgZ2V0IGhlcmUgYmVmb3JlIGNvbnN1bWluZyBhbGwgdGhlIGJ5dGVzLCB0aGVuIHRoYXQgaXMgYVxuICAvLyBidWcgaW4gbm9kZS4gIFNob3VsZCBuZXZlciBoYXBwZW4uXG4gIGlmIChzdGF0ZS5sZW5ndGggPiAwKVxuICAgIHRocm93IG5ldyBFcnJvcignZW5kUmVhZGFibGUgY2FsbGVkIG9uIG5vbi1lbXB0eSBzdHJlYW0nKTtcblxuICBpZiAoIXN0YXRlLmVuZEVtaXR0ZWQpIHtcbiAgICBzdGF0ZS5lbmRlZCA9IHRydWU7XG4gICAgcHJvY2Vzc05leHRUaWNrKGVuZFJlYWRhYmxlTlQsIHN0YXRlLCBzdHJlYW0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVuZFJlYWRhYmxlTlQoc3RhdGUsIHN0cmVhbSkge1xuICAvLyBDaGVjayB0aGF0IHdlIGRpZG4ndCBnZXQgb25lIGxhc3QgdW5zaGlmdC5cbiAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkICYmIHN0YXRlLmxlbmd0aCA9PT0gMCkge1xuICAgIHN0YXRlLmVuZEVtaXR0ZWQgPSB0cnVlO1xuICAgIHN0cmVhbS5yZWFkYWJsZSA9IGZhbHNlO1xuICAgIHN0cmVhbS5lbWl0KCdlbmQnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBmb3JFYWNoICh4cywgZikge1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHhzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGYoeHNbaV0sIGkpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YgKHhzLCB4KSB7XG4gIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgaWYgKHhzW2ldID09PSB4KSByZXR1cm4gaTtcbiAgfVxuICByZXR1cm4gLTE7XG59XG4iLCIvLyBhIHRyYW5zZm9ybSBzdHJlYW0gaXMgYSByZWFkYWJsZS93cml0YWJsZSBzdHJlYW0gd2hlcmUgeW91IGRvXG4vLyBzb21ldGhpbmcgd2l0aCB0aGUgZGF0YS4gIFNvbWV0aW1lcyBpdCdzIGNhbGxlZCBhIFwiZmlsdGVyXCIsXG4vLyBidXQgdGhhdCdzIG5vdCBhIGdyZWF0IG5hbWUgZm9yIGl0LCBzaW5jZSB0aGF0IGltcGxpZXMgYSB0aGluZyB3aGVyZVxuLy8gc29tZSBiaXRzIHBhc3MgdGhyb3VnaCwgYW5kIG90aGVycyBhcmUgc2ltcGx5IGlnbm9yZWQuICAoVGhhdCB3b3VsZFxuLy8gYmUgYSB2YWxpZCBleGFtcGxlIG9mIGEgdHJhbnNmb3JtLCBvZiBjb3Vyc2UuKVxuLy9cbi8vIFdoaWxlIHRoZSBvdXRwdXQgaXMgY2F1c2FsbHkgcmVsYXRlZCB0byB0aGUgaW5wdXQsIGl0J3Mgbm90IGFcbi8vIG5lY2Vzc2FyaWx5IHN5bW1ldHJpYyBvciBzeW5jaHJvbm91cyB0cmFuc2Zvcm1hdGlvbi4gIEZvciBleGFtcGxlLFxuLy8gYSB6bGliIHN0cmVhbSBtaWdodCB0YWtlIG11bHRpcGxlIHBsYWluLXRleHQgd3JpdGVzKCksIGFuZCB0aGVuXG4vLyBlbWl0IGEgc2luZ2xlIGNvbXByZXNzZWQgY2h1bmsgc29tZSB0aW1lIGluIHRoZSBmdXR1cmUuXG4vL1xuLy8gSGVyZSdzIGhvdyB0aGlzIHdvcmtzOlxuLy9cbi8vIFRoZSBUcmFuc2Zvcm0gc3RyZWFtIGhhcyBhbGwgdGhlIGFzcGVjdHMgb2YgdGhlIHJlYWRhYmxlIGFuZCB3cml0YWJsZVxuLy8gc3RyZWFtIGNsYXNzZXMuICBXaGVuIHlvdSB3cml0ZShjaHVuayksIHRoYXQgY2FsbHMgX3dyaXRlKGNodW5rLGNiKVxuLy8gaW50ZXJuYWxseSwgYW5kIHJldHVybnMgZmFsc2UgaWYgdGhlcmUncyBhIGxvdCBvZiBwZW5kaW5nIHdyaXRlc1xuLy8gYnVmZmVyZWQgdXAuICBXaGVuIHlvdSBjYWxsIHJlYWQoKSwgdGhhdCBjYWxscyBfcmVhZChuKSB1bnRpbFxuLy8gdGhlcmUncyBlbm91Z2ggcGVuZGluZyByZWFkYWJsZSBkYXRhIGJ1ZmZlcmVkIHVwLlxuLy9cbi8vIEluIGEgdHJhbnNmb3JtIHN0cmVhbSwgdGhlIHdyaXR0ZW4gZGF0YSBpcyBwbGFjZWQgaW4gYSBidWZmZXIuICBXaGVuXG4vLyBfcmVhZChuKSBpcyBjYWxsZWQsIGl0IHRyYW5zZm9ybXMgdGhlIHF1ZXVlZCB1cCBkYXRhLCBjYWxsaW5nIHRoZVxuLy8gYnVmZmVyZWQgX3dyaXRlIGNiJ3MgYXMgaXQgY29uc3VtZXMgY2h1bmtzLiAgSWYgY29uc3VtaW5nIGEgc2luZ2xlXG4vLyB3cml0dGVuIGNodW5rIHdvdWxkIHJlc3VsdCBpbiBtdWx0aXBsZSBvdXRwdXQgY2h1bmtzLCB0aGVuIHRoZSBmaXJzdFxuLy8gb3V0cHV0dGVkIGJpdCBjYWxscyB0aGUgcmVhZGNiLCBhbmQgc3Vic2VxdWVudCBjaHVua3MganVzdCBnbyBpbnRvXG4vLyB0aGUgcmVhZCBidWZmZXIsIGFuZCB3aWxsIGNhdXNlIGl0IHRvIGVtaXQgJ3JlYWRhYmxlJyBpZiBuZWNlc3NhcnkuXG4vL1xuLy8gVGhpcyB3YXksIGJhY2stcHJlc3N1cmUgaXMgYWN0dWFsbHkgZGV0ZXJtaW5lZCBieSB0aGUgcmVhZGluZyBzaWRlLFxuLy8gc2luY2UgX3JlYWQgaGFzIHRvIGJlIGNhbGxlZCB0byBzdGFydCBwcm9jZXNzaW5nIGEgbmV3IGNodW5rLiAgSG93ZXZlcixcbi8vIGEgcGF0aG9sb2dpY2FsIGluZmxhdGUgdHlwZSBvZiB0cmFuc2Zvcm0gY2FuIGNhdXNlIGV4Y2Vzc2l2ZSBidWZmZXJpbmdcbi8vIGhlcmUuICBGb3IgZXhhbXBsZSwgaW1hZ2luZSBhIHN0cmVhbSB3aGVyZSBldmVyeSBieXRlIG9mIGlucHV0IGlzXG4vLyBpbnRlcnByZXRlZCBhcyBhbiBpbnRlZ2VyIGZyb20gMC0yNTUsIGFuZCB0aGVuIHJlc3VsdHMgaW4gdGhhdCBtYW55XG4vLyBieXRlcyBvZiBvdXRwdXQuICBXcml0aW5nIHRoZSA0IGJ5dGVzIHtmZixmZixmZixmZn0gd291bGQgcmVzdWx0IGluXG4vLyAxa2Igb2YgZGF0YSBiZWluZyBvdXRwdXQuICBJbiB0aGlzIGNhc2UsIHlvdSBjb3VsZCB3cml0ZSBhIHZlcnkgc21hbGxcbi8vIGFtb3VudCBvZiBpbnB1dCwgYW5kIGVuZCB1cCB3aXRoIGEgdmVyeSBsYXJnZSBhbW91bnQgb2Ygb3V0cHV0LiAgSW5cbi8vIHN1Y2ggYSBwYXRob2xvZ2ljYWwgaW5mbGF0aW5nIG1lY2hhbmlzbSwgdGhlcmUnZCBiZSBubyB3YXkgdG8gdGVsbFxuLy8gdGhlIHN5c3RlbSB0byBzdG9wIGRvaW5nIHRoZSB0cmFuc2Zvcm0uICBBIHNpbmdsZSA0TUIgd3JpdGUgY291bGRcbi8vIGNhdXNlIHRoZSBzeXN0ZW0gdG8gcnVuIG91dCBvZiBtZW1vcnkuXG4vL1xuLy8gSG93ZXZlciwgZXZlbiBpbiBzdWNoIGEgcGF0aG9sb2dpY2FsIGNhc2UsIG9ubHkgYSBzaW5nbGUgd3JpdHRlbiBjaHVua1xuLy8gd291bGQgYmUgY29uc3VtZWQsIGFuZCB0aGVuIHRoZSByZXN0IHdvdWxkIHdhaXQgKHVuLXRyYW5zZm9ybWVkKSB1bnRpbFxuLy8gdGhlIHJlc3VsdHMgb2YgdGhlIHByZXZpb3VzIHRyYW5zZm9ybWVkIGNodW5rIHdlcmUgY29uc3VtZWQuXG5cbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBUcmFuc2Zvcm07XG5cbnZhciBEdXBsZXggPSByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudXRpbC5pbmhlcml0cyhUcmFuc2Zvcm0sIER1cGxleCk7XG5cblxuZnVuY3Rpb24gVHJhbnNmb3JtU3RhdGUoc3RyZWFtKSB7XG4gIHRoaXMuYWZ0ZXJUcmFuc2Zvcm0gPSBmdW5jdGlvbihlciwgZGF0YSkge1xuICAgIHJldHVybiBhZnRlclRyYW5zZm9ybShzdHJlYW0sIGVyLCBkYXRhKTtcbiAgfTtcblxuICB0aGlzLm5lZWRUcmFuc2Zvcm0gPSBmYWxzZTtcbiAgdGhpcy50cmFuc2Zvcm1pbmcgPSBmYWxzZTtcbiAgdGhpcy53cml0ZWNiID0gbnVsbDtcbiAgdGhpcy53cml0ZWNodW5rID0gbnVsbDtcbn1cblxuZnVuY3Rpb24gYWZ0ZXJUcmFuc2Zvcm0oc3RyZWFtLCBlciwgZGF0YSkge1xuICB2YXIgdHMgPSBzdHJlYW0uX3RyYW5zZm9ybVN0YXRlO1xuICB0cy50cmFuc2Zvcm1pbmcgPSBmYWxzZTtcblxuICB2YXIgY2IgPSB0cy53cml0ZWNiO1xuXG4gIGlmICghY2IpXG4gICAgcmV0dXJuIHN0cmVhbS5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignbm8gd3JpdGVjYiBpbiBUcmFuc2Zvcm0gY2xhc3MnKSk7XG5cbiAgdHMud3JpdGVjaHVuayA9IG51bGw7XG4gIHRzLndyaXRlY2IgPSBudWxsO1xuXG4gIGlmIChkYXRhICE9PSBudWxsICYmIGRhdGEgIT09IHVuZGVmaW5lZClcbiAgICBzdHJlYW0ucHVzaChkYXRhKTtcblxuICBpZiAoY2IpXG4gICAgY2IoZXIpO1xuXG4gIHZhciBycyA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgcnMucmVhZGluZyA9IGZhbHNlO1xuICBpZiAocnMubmVlZFJlYWRhYmxlIHx8IHJzLmxlbmd0aCA8IHJzLmhpZ2hXYXRlck1hcmspIHtcbiAgICBzdHJlYW0uX3JlYWQocnMuaGlnaFdhdGVyTWFyayk7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBUcmFuc2Zvcm0ob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVHJhbnNmb3JtKSlcbiAgICByZXR1cm4gbmV3IFRyYW5zZm9ybShvcHRpb25zKTtcblxuICBEdXBsZXguY2FsbCh0aGlzLCBvcHRpb25zKTtcblxuICB0aGlzLl90cmFuc2Zvcm1TdGF0ZSA9IG5ldyBUcmFuc2Zvcm1TdGF0ZSh0aGlzKTtcblxuICAvLyB3aGVuIHRoZSB3cml0YWJsZSBzaWRlIGZpbmlzaGVzLCB0aGVuIGZsdXNoIG91dCBhbnl0aGluZyByZW1haW5pbmcuXG4gIHZhciBzdHJlYW0gPSB0aGlzO1xuXG4gIC8vIHN0YXJ0IG91dCBhc2tpbmcgZm9yIGEgcmVhZGFibGUgZXZlbnQgb25jZSBkYXRhIGlzIHRyYW5zZm9ybWVkLlxuICB0aGlzLl9yZWFkYWJsZVN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG5cbiAgLy8gd2UgaGF2ZSBpbXBsZW1lbnRlZCB0aGUgX3JlYWQgbWV0aG9kLCBhbmQgZG9uZSB0aGUgb3RoZXIgdGhpbmdzXG4gIC8vIHRoYXQgUmVhZGFibGUgd2FudHMgYmVmb3JlIHRoZSBmaXJzdCBfcmVhZCBjYWxsLCBzbyB1bnNldCB0aGVcbiAgLy8gc3luYyBndWFyZCBmbGFnLlxuICB0aGlzLl9yZWFkYWJsZVN0YXRlLnN5bmMgPSBmYWxzZTtcblxuICBpZiAob3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy50cmFuc2Zvcm0gPT09ICdmdW5jdGlvbicpXG4gICAgICB0aGlzLl90cmFuc2Zvcm0gPSBvcHRpb25zLnRyYW5zZm9ybTtcblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5mbHVzaCA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgIHRoaXMuX2ZsdXNoID0gb3B0aW9ucy5mbHVzaDtcbiAgfVxuXG4gIHRoaXMub25jZSgncHJlZmluaXNoJywgZnVuY3Rpb24oKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLl9mbHVzaCA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgIHRoaXMuX2ZsdXNoKGZ1bmN0aW9uKGVyKSB7XG4gICAgICAgIGRvbmUoc3RyZWFtLCBlcik7XG4gICAgICB9KTtcbiAgICBlbHNlXG4gICAgICBkb25lKHN0cmVhbSk7XG4gIH0pO1xufVxuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcpIHtcbiAgdGhpcy5fdHJhbnNmb3JtU3RhdGUubmVlZFRyYW5zZm9ybSA9IGZhbHNlO1xuICByZXR1cm4gRHVwbGV4LnByb3RvdHlwZS5wdXNoLmNhbGwodGhpcywgY2h1bmssIGVuY29kaW5nKTtcbn07XG5cbi8vIFRoaXMgaXMgdGhlIHBhcnQgd2hlcmUgeW91IGRvIHN0dWZmIVxuLy8gb3ZlcnJpZGUgdGhpcyBmdW5jdGlvbiBpbiBpbXBsZW1lbnRhdGlvbiBjbGFzc2VzLlxuLy8gJ2NodW5rJyBpcyBhbiBpbnB1dCBjaHVuay5cbi8vXG4vLyBDYWxsIGBwdXNoKG5ld0NodW5rKWAgdG8gcGFzcyBhbG9uZyB0cmFuc2Zvcm1lZCBvdXRwdXRcbi8vIHRvIHRoZSByZWFkYWJsZSBzaWRlLiAgWW91IG1heSBjYWxsICdwdXNoJyB6ZXJvIG9yIG1vcmUgdGltZXMuXG4vL1xuLy8gQ2FsbCBgY2IoZXJyKWAgd2hlbiB5b3UgYXJlIGRvbmUgd2l0aCB0aGlzIGNodW5rLiAgSWYgeW91IHBhc3Ncbi8vIGFuIGVycm9yLCB0aGVuIHRoYXQnbGwgcHV0IHRoZSBodXJ0IG9uIHRoZSB3aG9sZSBvcGVyYXRpb24uICBJZiB5b3Vcbi8vIG5ldmVyIGNhbGwgY2IoKSwgdGhlbiB5b3UnbGwgbmV2ZXIgZ2V0IGFub3RoZXIgY2h1bmsuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHRocm93IG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJyk7XG59O1xuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHRzID0gdGhpcy5fdHJhbnNmb3JtU3RhdGU7XG4gIHRzLndyaXRlY2IgPSBjYjtcbiAgdHMud3JpdGVjaHVuayA9IGNodW5rO1xuICB0cy53cml0ZWVuY29kaW5nID0gZW5jb2Rpbmc7XG4gIGlmICghdHMudHJhbnNmb3JtaW5nKSB7XG4gICAgdmFyIHJzID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgICBpZiAodHMubmVlZFRyYW5zZm9ybSB8fFxuICAgICAgICBycy5uZWVkUmVhZGFibGUgfHxcbiAgICAgICAgcnMubGVuZ3RoIDwgcnMuaGlnaFdhdGVyTWFyaylcbiAgICAgIHRoaXMuX3JlYWQocnMuaGlnaFdhdGVyTWFyayk7XG4gIH1cbn07XG5cbi8vIERvZXNuJ3QgbWF0dGVyIHdoYXQgdGhlIGFyZ3MgYXJlIGhlcmUuXG4vLyBfdHJhbnNmb3JtIGRvZXMgYWxsIHRoZSB3b3JrLlxuLy8gVGhhdCB3ZSBnb3QgaGVyZSBtZWFucyB0aGF0IHRoZSByZWFkYWJsZSBzaWRlIHdhbnRzIG1vcmUgZGF0YS5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbihuKSB7XG4gIHZhciB0cyA9IHRoaXMuX3RyYW5zZm9ybVN0YXRlO1xuXG4gIGlmICh0cy53cml0ZWNodW5rICE9PSBudWxsICYmIHRzLndyaXRlY2IgJiYgIXRzLnRyYW5zZm9ybWluZykge1xuICAgIHRzLnRyYW5zZm9ybWluZyA9IHRydWU7XG4gICAgdGhpcy5fdHJhbnNmb3JtKHRzLndyaXRlY2h1bmssIHRzLndyaXRlZW5jb2RpbmcsIHRzLmFmdGVyVHJhbnNmb3JtKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBtYXJrIHRoYXQgd2UgbmVlZCBhIHRyYW5zZm9ybSwgc28gdGhhdCBhbnkgZGF0YSB0aGF0IGNvbWVzIGluXG4gICAgLy8gd2lsbCBnZXQgcHJvY2Vzc2VkLCBub3cgdGhhdCB3ZSd2ZSBhc2tlZCBmb3IgaXQuXG4gICAgdHMubmVlZFRyYW5zZm9ybSA9IHRydWU7XG4gIH1cbn07XG5cblxuZnVuY3Rpb24gZG9uZShzdHJlYW0sIGVyKSB7XG4gIGlmIChlcilcbiAgICByZXR1cm4gc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuXG4gIC8vIGlmIHRoZXJlJ3Mgbm90aGluZyBpbiB0aGUgd3JpdGUgYnVmZmVyLCB0aGVuIHRoYXQgbWVhbnNcbiAgLy8gdGhhdCBub3RoaW5nIG1vcmUgd2lsbCBldmVyIGJlIHByb3ZpZGVkXG4gIHZhciB3cyA9IHN0cmVhbS5fd3JpdGFibGVTdGF0ZTtcbiAgdmFyIHRzID0gc3RyZWFtLl90cmFuc2Zvcm1TdGF0ZTtcblxuICBpZiAod3MubGVuZ3RoKVxuICAgIHRocm93IG5ldyBFcnJvcignY2FsbGluZyB0cmFuc2Zvcm0gZG9uZSB3aGVuIHdzLmxlbmd0aCAhPSAwJyk7XG5cbiAgaWYgKHRzLnRyYW5zZm9ybWluZylcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NhbGxpbmcgdHJhbnNmb3JtIGRvbmUgd2hlbiBzdGlsbCB0cmFuc2Zvcm1pbmcnKTtcblxuICByZXR1cm4gc3RyZWFtLnB1c2gobnVsbCk7XG59XG4iLCIvLyBBIGJpdCBzaW1wbGVyIHRoYW4gcmVhZGFibGUgc3RyZWFtcy5cbi8vIEltcGxlbWVudCBhbiBhc3luYyAuX3dyaXRlKGNodW5rLCBlbmNvZGluZywgY2IpLCBhbmQgaXQnbGwgaGFuZGxlIGFsbFxuLy8gdGhlIGRyYWluIGV2ZW50IGVtaXNzaW9uIGFuZCBidWZmZXJpbmcuXG5cbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBXcml0YWJsZTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBwcm9jZXNzTmV4dFRpY2sgPSByZXF1aXJlKCdwcm9jZXNzLW5leHRpY2stYXJncycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuV3JpdGFibGUuV3JpdGFibGVTdGF0ZSA9IFdyaXRhYmxlU3RhdGU7XG5cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSgnY29yZS11dGlsLWlzJyk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgaW50ZXJuYWxVdGlsID0ge1xuICBkZXByZWNhdGU6IHJlcXVpcmUoJ3V0aWwtZGVwcmVjYXRlJylcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgU3RyZWFtO1xuKGZ1bmN0aW9uICgpe3RyeXtcbiAgU3RyZWFtID0gcmVxdWlyZSgnc3QnICsgJ3JlYW0nKTtcbn1jYXRjaChfKXt9ZmluYWxseXtcbiAgaWYgKCFTdHJlYW0pXG4gICAgU3RyZWFtID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xufX0oKSlcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuXG51dGlsLmluaGVyaXRzKFdyaXRhYmxlLCBTdHJlYW0pO1xuXG5mdW5jdGlvbiBub3AoKSB7fVxuXG5mdW5jdGlvbiBXcml0ZVJlcShjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHRoaXMuY2h1bmsgPSBjaHVuaztcbiAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nO1xuICB0aGlzLmNhbGxiYWNrID0gY2I7XG4gIHRoaXMubmV4dCA9IG51bGw7XG59XG5cbnZhciBEdXBsZXg7XG5mdW5jdGlvbiBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSkge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIG9iamVjdCBzdHJlYW0gZmxhZyB0byBpbmRpY2F0ZSB3aGV0aGVyIG9yIG5vdCB0aGlzIHN0cmVhbVxuICAvLyBjb250YWlucyBidWZmZXJzIG9yIG9iamVjdHMuXG4gIHRoaXMub2JqZWN0TW9kZSA9ICEhb3B0aW9ucy5vYmplY3RNb2RlO1xuXG4gIGlmIChzdHJlYW0gaW5zdGFuY2VvZiBEdXBsZXgpXG4gICAgdGhpcy5vYmplY3RNb2RlID0gdGhpcy5vYmplY3RNb2RlIHx8ICEhb3B0aW9ucy53cml0YWJsZU9iamVjdE1vZGU7XG5cbiAgLy8gdGhlIHBvaW50IGF0IHdoaWNoIHdyaXRlKCkgc3RhcnRzIHJldHVybmluZyBmYWxzZVxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIHRoYXQgd2UgYWx3YXlzIHJldHVybiBmYWxzZSBpZlxuICAvLyB0aGUgZW50aXJlIGJ1ZmZlciBpcyBub3QgZmx1c2hlZCBpbW1lZGlhdGVseSBvbiB3cml0ZSgpXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHZhciBkZWZhdWx0SHdtID0gdGhpcy5vYmplY3RNb2RlID8gMTYgOiAxNiAqIDEwMjQ7XG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IChod20gfHwgaHdtID09PSAwKSA/IGh3bSA6IGRlZmF1bHRId207XG5cbiAgLy8gY2FzdCB0byBpbnRzLlxuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSB+fnRoaXMuaGlnaFdhdGVyTWFyaztcblxuICB0aGlzLm5lZWREcmFpbiA9IGZhbHNlO1xuICAvLyBhdCB0aGUgc3RhcnQgb2YgY2FsbGluZyBlbmQoKVxuICB0aGlzLmVuZGluZyA9IGZhbHNlO1xuICAvLyB3aGVuIGVuZCgpIGhhcyBiZWVuIGNhbGxlZCwgYW5kIHJldHVybmVkXG4gIHRoaXMuZW5kZWQgPSBmYWxzZTtcbiAgLy8gd2hlbiAnZmluaXNoJyBpcyBlbWl0dGVkXG4gIHRoaXMuZmluaXNoZWQgPSBmYWxzZTtcblxuICAvLyBzaG91bGQgd2UgZGVjb2RlIHN0cmluZ3MgaW50byBidWZmZXJzIGJlZm9yZSBwYXNzaW5nIHRvIF93cml0ZT9cbiAgLy8gdGhpcyBpcyBoZXJlIHNvIHRoYXQgc29tZSBub2RlLWNvcmUgc3RyZWFtcyBjYW4gb3B0aW1pemUgc3RyaW5nXG4gIC8vIGhhbmRsaW5nIGF0IGEgbG93ZXIgbGV2ZWwuXG4gIHZhciBub0RlY29kZSA9IG9wdGlvbnMuZGVjb2RlU3RyaW5ncyA9PT0gZmFsc2U7XG4gIHRoaXMuZGVjb2RlU3RyaW5ncyA9ICFub0RlY29kZTtcblxuICAvLyBDcnlwdG8gaXMga2luZCBvZiBvbGQgYW5kIGNydXN0eS4gIEhpc3RvcmljYWxseSwgaXRzIGRlZmF1bHQgc3RyaW5nXG4gIC8vIGVuY29kaW5nIGlzICdiaW5hcnknIHNvIHdlIGhhdmUgdG8gbWFrZSB0aGlzIGNvbmZpZ3VyYWJsZS5cbiAgLy8gRXZlcnl0aGluZyBlbHNlIGluIHRoZSB1bml2ZXJzZSB1c2VzICd1dGY4JywgdGhvdWdoLlxuICB0aGlzLmRlZmF1bHRFbmNvZGluZyA9IG9wdGlvbnMuZGVmYXVsdEVuY29kaW5nIHx8ICd1dGY4JztcblxuICAvLyBub3QgYW4gYWN0dWFsIGJ1ZmZlciB3ZSBrZWVwIHRyYWNrIG9mLCBidXQgYSBtZWFzdXJlbWVudFxuICAvLyBvZiBob3cgbXVjaCB3ZSdyZSB3YWl0aW5nIHRvIGdldCBwdXNoZWQgdG8gc29tZSB1bmRlcmx5aW5nXG4gIC8vIHNvY2tldCBvciBmaWxlLlxuICB0aGlzLmxlbmd0aCA9IDA7XG5cbiAgLy8gYSBmbGFnIHRvIHNlZSB3aGVuIHdlJ3JlIGluIHRoZSBtaWRkbGUgb2YgYSB3cml0ZS5cbiAgdGhpcy53cml0aW5nID0gZmFsc2U7XG5cbiAgLy8gd2hlbiB0cnVlIGFsbCB3cml0ZXMgd2lsbCBiZSBidWZmZXJlZCB1bnRpbCAudW5jb3JrKCkgY2FsbFxuICB0aGlzLmNvcmtlZCA9IDA7XG5cbiAgLy8gYSBmbGFnIHRvIGJlIGFibGUgdG8gdGVsbCBpZiB0aGUgb253cml0ZSBjYiBpcyBjYWxsZWQgaW1tZWRpYXRlbHksXG4gIC8vIG9yIG9uIGEgbGF0ZXIgdGljay4gIFdlIHNldCB0aGlzIHRvIHRydWUgYXQgZmlyc3QsIGJlY2F1c2UgYW55XG4gIC8vIGFjdGlvbnMgdGhhdCBzaG91bGRuJ3QgaGFwcGVuIHVudGlsIFwibGF0ZXJcIiBzaG91bGQgZ2VuZXJhbGx5IGFsc29cbiAgLy8gbm90IGhhcHBlbiBiZWZvcmUgdGhlIGZpcnN0IHdyaXRlIGNhbGwuXG4gIHRoaXMuc3luYyA9IHRydWU7XG5cbiAgLy8gYSBmbGFnIHRvIGtub3cgaWYgd2UncmUgcHJvY2Vzc2luZyBwcmV2aW91c2x5IGJ1ZmZlcmVkIGl0ZW1zLCB3aGljaFxuICAvLyBtYXkgY2FsbCB0aGUgX3dyaXRlKCkgY2FsbGJhY2sgaW4gdGhlIHNhbWUgdGljaywgc28gdGhhdCB3ZSBkb24ndFxuICAvLyBlbmQgdXAgaW4gYW4gb3ZlcmxhcHBlZCBvbndyaXRlIHNpdHVhdGlvbi5cbiAgdGhpcy5idWZmZXJQcm9jZXNzaW5nID0gZmFsc2U7XG5cbiAgLy8gdGhlIGNhbGxiYWNrIHRoYXQncyBwYXNzZWQgdG8gX3dyaXRlKGNodW5rLGNiKVxuICB0aGlzLm9ud3JpdGUgPSBmdW5jdGlvbihlcikge1xuICAgIG9ud3JpdGUoc3RyZWFtLCBlcik7XG4gIH07XG5cbiAgLy8gdGhlIGNhbGxiYWNrIHRoYXQgdGhlIHVzZXIgc3VwcGxpZXMgdG8gd3JpdGUoY2h1bmssZW5jb2RpbmcsY2IpXG4gIHRoaXMud3JpdGVjYiA9IG51bGw7XG5cbiAgLy8gdGhlIGFtb3VudCB0aGF0IGlzIGJlaW5nIHdyaXR0ZW4gd2hlbiBfd3JpdGUgaXMgY2FsbGVkLlxuICB0aGlzLndyaXRlbGVuID0gMDtcblxuICB0aGlzLmJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gIHRoaXMubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG5cbiAgLy8gbnVtYmVyIG9mIHBlbmRpbmcgdXNlci1zdXBwbGllZCB3cml0ZSBjYWxsYmFja3NcbiAgLy8gdGhpcyBtdXN0IGJlIDAgYmVmb3JlICdmaW5pc2gnIGNhbiBiZSBlbWl0dGVkXG4gIHRoaXMucGVuZGluZ2NiID0gMDtcblxuICAvLyBlbWl0IHByZWZpbmlzaCBpZiB0aGUgb25seSB0aGluZyB3ZSdyZSB3YWl0aW5nIGZvciBpcyBfd3JpdGUgY2JzXG4gIC8vIFRoaXMgaXMgcmVsZXZhbnQgZm9yIHN5bmNocm9ub3VzIFRyYW5zZm9ybSBzdHJlYW1zXG4gIHRoaXMucHJlZmluaXNoZWQgPSBmYWxzZTtcblxuICAvLyBUcnVlIGlmIHRoZSBlcnJvciB3YXMgYWxyZWFkeSBlbWl0dGVkIGFuZCBzaG91bGQgbm90IGJlIHRocm93biBhZ2FpblxuICB0aGlzLmVycm9yRW1pdHRlZCA9IGZhbHNlO1xufVxuXG5Xcml0YWJsZVN0YXRlLnByb3RvdHlwZS5nZXRCdWZmZXIgPSBmdW5jdGlvbiB3cml0YWJsZVN0YXRlR2V0QnVmZmVyKCkge1xuICB2YXIgY3VycmVudCA9IHRoaXMuYnVmZmVyZWRSZXF1ZXN0O1xuICB2YXIgb3V0ID0gW107XG4gIHdoaWxlIChjdXJyZW50KSB7XG4gICAgb3V0LnB1c2goY3VycmVudCk7XG4gICAgY3VycmVudCA9IGN1cnJlbnQubmV4dDtcbiAgfVxuICByZXR1cm4gb3V0O1xufTtcblxuKGZ1bmN0aW9uICgpe3RyeSB7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGVTdGF0ZS5wcm90b3R5cGUsICdidWZmZXInLCB7XG4gIGdldDogaW50ZXJuYWxVdGlsLmRlcHJlY2F0ZShmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRCdWZmZXIoKTtcbiAgfSwgJ193cml0YWJsZVN0YXRlLmJ1ZmZlciBpcyBkZXByZWNhdGVkLiBVc2UgX3dyaXRhYmxlU3RhdGUuZ2V0QnVmZmVyICcgK1xuICAgICAnaW5zdGVhZC4nKVxufSk7XG59Y2F0Y2goXyl7fX0oKSk7XG5cblxudmFyIER1cGxleDtcbmZ1bmN0aW9uIFdyaXRhYmxlKG9wdGlvbnMpIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuICAvLyBXcml0YWJsZSBjdG9yIGlzIGFwcGxpZWQgdG8gRHVwbGV4ZXMsIHRob3VnaCB0aGV5J3JlIG5vdFxuICAvLyBpbnN0YW5jZW9mIFdyaXRhYmxlLCB0aGV5J3JlIGluc3RhbmNlb2YgUmVhZGFibGUuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBXcml0YWJsZSkgJiYgISh0aGlzIGluc3RhbmNlb2YgRHVwbGV4KSlcbiAgICByZXR1cm4gbmV3IFdyaXRhYmxlKG9wdGlvbnMpO1xuXG4gIHRoaXMuX3dyaXRhYmxlU3RhdGUgPSBuZXcgV3JpdGFibGVTdGF0ZShvcHRpb25zLCB0aGlzKTtcblxuICAvLyBsZWdhY3kuXG4gIHRoaXMud3JpdGFibGUgPSB0cnVlO1xuXG4gIGlmIChvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLndyaXRlID09PSAnZnVuY3Rpb24nKVxuICAgICAgdGhpcy5fd3JpdGUgPSBvcHRpb25zLndyaXRlO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLndyaXRldiA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgIHRoaXMuX3dyaXRldiA9IG9wdGlvbnMud3JpdGV2O1xuICB9XG5cbiAgU3RyZWFtLmNhbGwodGhpcyk7XG59XG5cbi8vIE90aGVyd2lzZSBwZW9wbGUgY2FuIHBpcGUgV3JpdGFibGUgc3RyZWFtcywgd2hpY2ggaXMganVzdCB3cm9uZy5cbldyaXRhYmxlLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ0Nhbm5vdCBwaXBlLiBOb3QgcmVhZGFibGUuJykpO1xufTtcblxuXG5mdW5jdGlvbiB3cml0ZUFmdGVyRW5kKHN0cmVhbSwgY2IpIHtcbiAgdmFyIGVyID0gbmV3IEVycm9yKCd3cml0ZSBhZnRlciBlbmQnKTtcbiAgLy8gVE9ETzogZGVmZXIgZXJyb3IgZXZlbnRzIGNvbnNpc3RlbnRseSBldmVyeXdoZXJlLCBub3QganVzdCB0aGUgY2JcbiAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICBwcm9jZXNzTmV4dFRpY2soY2IsIGVyKTtcbn1cblxuLy8gSWYgd2UgZ2V0IHNvbWV0aGluZyB0aGF0IGlzIG5vdCBhIGJ1ZmZlciwgc3RyaW5nLCBudWxsLCBvciB1bmRlZmluZWQsXG4vLyBhbmQgd2UncmUgbm90IGluIG9iamVjdE1vZGUsIHRoZW4gdGhhdCdzIGFuIGVycm9yLlxuLy8gT3RoZXJ3aXNlIHN0cmVhbSBjaHVua3MgYXJlIGFsbCBjb25zaWRlcmVkIHRvIGJlIG9mIGxlbmd0aD0xLCBhbmQgdGhlXG4vLyB3YXRlcm1hcmtzIGRldGVybWluZSBob3cgbWFueSBvYmplY3RzIHRvIGtlZXAgaW4gdGhlIGJ1ZmZlciwgcmF0aGVyIHRoYW5cbi8vIGhvdyBtYW55IGJ5dGVzIG9yIGNoYXJhY3RlcnMuXG5mdW5jdGlvbiB2YWxpZENodW5rKHN0cmVhbSwgc3RhdGUsIGNodW5rLCBjYikge1xuICB2YXIgdmFsaWQgPSB0cnVlO1xuXG4gIGlmICghKEJ1ZmZlci5pc0J1ZmZlcihjaHVuaykpICYmXG4gICAgICB0eXBlb2YgY2h1bmsgIT09ICdzdHJpbmcnICYmXG4gICAgICBjaHVuayAhPT0gbnVsbCAmJlxuICAgICAgY2h1bmsgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgIXN0YXRlLm9iamVjdE1vZGUpIHtcbiAgICB2YXIgZXIgPSBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rJyk7XG4gICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICAgIHByb2Nlc3NOZXh0VGljayhjYiwgZXIpO1xuICAgIHZhbGlkID0gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHZhbGlkO1xufVxuXG5Xcml0YWJsZS5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG4gIHZhciByZXQgPSBmYWxzZTtcblxuICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBlbmNvZGluZztcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH1cblxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKGNodW5rKSlcbiAgICBlbmNvZGluZyA9ICdidWZmZXInO1xuICBlbHNlIGlmICghZW5jb2RpbmcpXG4gICAgZW5jb2RpbmcgPSBzdGF0ZS5kZWZhdWx0RW5jb2Rpbmc7XG5cbiAgaWYgKHR5cGVvZiBjYiAhPT0gJ2Z1bmN0aW9uJylcbiAgICBjYiA9IG5vcDtcblxuICBpZiAoc3RhdGUuZW5kZWQpXG4gICAgd3JpdGVBZnRlckVuZCh0aGlzLCBjYik7XG4gIGVsc2UgaWYgKHZhbGlkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCBjYikpIHtcbiAgICBzdGF0ZS5wZW5kaW5nY2IrKztcbiAgICByZXQgPSB3cml0ZU9yQnVmZmVyKHRoaXMsIHN0YXRlLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuY29yayA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuXG4gIHN0YXRlLmNvcmtlZCsrO1xufTtcblxuV3JpdGFibGUucHJvdG90eXBlLnVuY29yayA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuXG4gIGlmIChzdGF0ZS5jb3JrZWQpIHtcbiAgICBzdGF0ZS5jb3JrZWQtLTtcblxuICAgIGlmICghc3RhdGUud3JpdGluZyAmJlxuICAgICAgICAhc3RhdGUuY29ya2VkICYmXG4gICAgICAgICFzdGF0ZS5maW5pc2hlZCAmJlxuICAgICAgICAhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyAmJlxuICAgICAgICBzdGF0ZS5idWZmZXJlZFJlcXVlc3QpXG4gICAgICBjbGVhckJ1ZmZlcih0aGlzLCBzdGF0ZSk7XG4gIH1cbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5zZXREZWZhdWx0RW5jb2RpbmcgPSBmdW5jdGlvbiBzZXREZWZhdWx0RW5jb2RpbmcoZW5jb2RpbmcpIHtcbiAgLy8gbm9kZTo6UGFyc2VFbmNvZGluZygpIHJlcXVpcmVzIGxvd2VyIGNhc2UuXG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnKVxuICAgIGVuY29kaW5nID0gZW5jb2RpbmcudG9Mb3dlckNhc2UoKTtcbiAgaWYgKCEoWydoZXgnLCAndXRmOCcsICd1dGYtOCcsICdhc2NpaScsICdiaW5hcnknLCAnYmFzZTY0Jyxcbid1Y3MyJywgJ3Vjcy0yJywndXRmMTZsZScsICd1dGYtMTZsZScsICdyYXcnXVxuLmluZGV4T2YoKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKCkpID4gLTEpKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZyk7XG4gIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVmYXVsdEVuY29kaW5nID0gZW5jb2Rpbmc7XG59O1xuXG5mdW5jdGlvbiBkZWNvZGVDaHVuayhzdGF0ZSwgY2h1bmssIGVuY29kaW5nKSB7XG4gIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJlxuICAgICAgc3RhdGUuZGVjb2RlU3RyaW5ncyAhPT0gZmFsc2UgJiZcbiAgICAgIHR5cGVvZiBjaHVuayA9PT0gJ3N0cmluZycpIHtcbiAgICBjaHVuayA9IG5ldyBCdWZmZXIoY2h1bmssIGVuY29kaW5nKTtcbiAgfVxuICByZXR1cm4gY2h1bms7XG59XG5cbi8vIGlmIHdlJ3JlIGFscmVhZHkgd3JpdGluZyBzb21ldGhpbmcsIHRoZW4ganVzdCBwdXQgdGhpc1xuLy8gaW4gdGhlIHF1ZXVlLCBhbmQgd2FpdCBvdXIgdHVybi4gIE90aGVyd2lzZSwgY2FsbCBfd3JpdGVcbi8vIElmIHdlIHJldHVybiBmYWxzZSwgdGhlbiB3ZSBuZWVkIGEgZHJhaW4gZXZlbnQsIHNvIHNldCB0aGF0IGZsYWcuXG5mdW5jdGlvbiB3cml0ZU9yQnVmZmVyKHN0cmVhbSwgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2h1bmsgPSBkZWNvZGVDaHVuayhzdGF0ZSwgY2h1bmssIGVuY29kaW5nKTtcblxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKGNodW5rKSlcbiAgICBlbmNvZGluZyA9ICdidWZmZXInO1xuICB2YXIgbGVuID0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG5cbiAgc3RhdGUubGVuZ3RoICs9IGxlbjtcblxuICB2YXIgcmV0ID0gc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgLy8gd2UgbXVzdCBlbnN1cmUgdGhhdCBwcmV2aW91cyBuZWVkRHJhaW4gd2lsbCBub3QgYmUgcmVzZXQgdG8gZmFsc2UuXG4gIGlmICghcmV0KVxuICAgIHN0YXRlLm5lZWREcmFpbiA9IHRydWU7XG5cbiAgaWYgKHN0YXRlLndyaXRpbmcgfHwgc3RhdGUuY29ya2VkKSB7XG4gICAgdmFyIGxhc3QgPSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0O1xuICAgIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBuZXcgV3JpdGVSZXEoY2h1bmssIGVuY29kaW5nLCBjYik7XG4gICAgaWYgKGxhc3QpIHtcbiAgICAgIGxhc3QubmV4dCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmFsc2UsIGxlbiwgY2h1bmssIGVuY29kaW5nLCBjYik7XG4gIH1cblxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIHdyaXRldiwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHN0YXRlLndyaXRlbGVuID0gbGVuO1xuICBzdGF0ZS53cml0ZWNiID0gY2I7XG4gIHN0YXRlLndyaXRpbmcgPSB0cnVlO1xuICBzdGF0ZS5zeW5jID0gdHJ1ZTtcbiAgaWYgKHdyaXRldilcbiAgICBzdHJlYW0uX3dyaXRldihjaHVuaywgc3RhdGUub253cml0ZSk7XG4gIGVsc2VcbiAgICBzdHJlYW0uX3dyaXRlKGNodW5rLCBlbmNvZGluZywgc3RhdGUub253cml0ZSk7XG4gIHN0YXRlLnN5bmMgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gb253cml0ZUVycm9yKHN0cmVhbSwgc3RhdGUsIHN5bmMsIGVyLCBjYikge1xuICAtLXN0YXRlLnBlbmRpbmdjYjtcbiAgaWYgKHN5bmMpXG4gICAgcHJvY2Vzc05leHRUaWNrKGNiLCBlcik7XG4gIGVsc2VcbiAgICBjYihlcik7XG5cbiAgc3RyZWFtLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCA9IHRydWU7XG4gIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbn1cblxuZnVuY3Rpb24gb253cml0ZVN0YXRlVXBkYXRlKHN0YXRlKSB7XG4gIHN0YXRlLndyaXRpbmcgPSBmYWxzZTtcbiAgc3RhdGUud3JpdGVjYiA9IG51bGw7XG4gIHN0YXRlLmxlbmd0aCAtPSBzdGF0ZS53cml0ZWxlbjtcbiAgc3RhdGUud3JpdGVsZW4gPSAwO1xufVxuXG5mdW5jdGlvbiBvbndyaXRlKHN0cmVhbSwgZXIpIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl93cml0YWJsZVN0YXRlO1xuICB2YXIgc3luYyA9IHN0YXRlLnN5bmM7XG4gIHZhciBjYiA9IHN0YXRlLndyaXRlY2I7XG5cbiAgb253cml0ZVN0YXRlVXBkYXRlKHN0YXRlKTtcblxuICBpZiAoZXIpXG4gICAgb253cml0ZUVycm9yKHN0cmVhbSwgc3RhdGUsIHN5bmMsIGVyLCBjYik7XG4gIGVsc2Uge1xuICAgIC8vIENoZWNrIGlmIHdlJ3JlIGFjdHVhbGx5IHJlYWR5IHRvIGZpbmlzaCwgYnV0IGRvbid0IGVtaXQgeWV0XG4gICAgdmFyIGZpbmlzaGVkID0gbmVlZEZpbmlzaChzdGF0ZSk7XG5cbiAgICBpZiAoIWZpbmlzaGVkICYmXG4gICAgICAgICFzdGF0ZS5jb3JrZWQgJiZcbiAgICAgICAgIXN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgJiZcbiAgICAgICAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0KSB7XG4gICAgICBjbGVhckJ1ZmZlcihzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG5cbiAgICBpZiAoc3luYykge1xuICAgICAgcHJvY2Vzc05leHRUaWNrKGFmdGVyV3JpdGUsIHN0cmVhbSwgc3RhdGUsIGZpbmlzaGVkLCBjYik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFmdGVyV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpIHtcbiAgaWYgKCFmaW5pc2hlZClcbiAgICBvbndyaXRlRHJhaW4oc3RyZWFtLCBzdGF0ZSk7XG4gIHN0YXRlLnBlbmRpbmdjYi0tO1xuICBjYigpO1xuICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbn1cblxuLy8gTXVzdCBmb3JjZSBjYWxsYmFjayB0byBiZSBjYWxsZWQgb24gbmV4dFRpY2ssIHNvIHRoYXQgd2UgZG9uJ3Rcbi8vIGVtaXQgJ2RyYWluJyBiZWZvcmUgdGhlIHdyaXRlKCkgY29uc3VtZXIgZ2V0cyB0aGUgJ2ZhbHNlJyByZXR1cm5cbi8vIHZhbHVlLCBhbmQgaGFzIGEgY2hhbmNlIHRvIGF0dGFjaCBhICdkcmFpbicgbGlzdGVuZXIuXG5mdW5jdGlvbiBvbndyaXRlRHJhaW4oc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLm5lZWREcmFpbikge1xuICAgIHN0YXRlLm5lZWREcmFpbiA9IGZhbHNlO1xuICAgIHN0cmVhbS5lbWl0KCdkcmFpbicpO1xuICB9XG59XG5cblxuLy8gaWYgdGhlcmUncyBzb21ldGhpbmcgaW4gdGhlIGJ1ZmZlciB3YWl0aW5nLCB0aGVuIHByb2Nlc3MgaXRcbmZ1bmN0aW9uIGNsZWFyQnVmZmVyKHN0cmVhbSwgc3RhdGUpIHtcbiAgc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyA9IHRydWU7XG4gIHZhciBlbnRyeSA9IHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdDtcblxuICBpZiAoc3RyZWFtLl93cml0ZXYgJiYgZW50cnkgJiYgZW50cnkubmV4dCkge1xuICAgIC8vIEZhc3QgY2FzZSwgd3JpdGUgZXZlcnl0aGluZyB1c2luZyBfd3JpdGV2KClcbiAgICB2YXIgYnVmZmVyID0gW107XG4gICAgdmFyIGNicyA9IFtdO1xuICAgIHdoaWxlIChlbnRyeSkge1xuICAgICAgY2JzLnB1c2goZW50cnkuY2FsbGJhY2spO1xuICAgICAgYnVmZmVyLnB1c2goZW50cnkpO1xuICAgICAgZW50cnkgPSBlbnRyeS5uZXh0O1xuICAgIH1cblxuICAgIC8vIGNvdW50IHRoZSBvbmUgd2UgYXJlIGFkZGluZywgYXMgd2VsbC5cbiAgICAvLyBUT0RPKGlzYWFjcykgY2xlYW4gdGhpcyB1cFxuICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgdHJ1ZSwgc3RhdGUubGVuZ3RoLCBidWZmZXIsICcnLCBmdW5jdGlvbihlcnIpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2JzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHN0YXRlLnBlbmRpbmdjYi0tO1xuICAgICAgICBjYnNbaV0oZXJyKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIENsZWFyIGJ1ZmZlclxuICB9IGVsc2Uge1xuICAgIC8vIFNsb3cgY2FzZSwgd3JpdGUgY2h1bmtzIG9uZS1ieS1vbmVcbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIHZhciBjaHVuayA9IGVudHJ5LmNodW5rO1xuICAgICAgdmFyIGVuY29kaW5nID0gZW50cnkuZW5jb2Rpbmc7XG4gICAgICB2YXIgY2IgPSBlbnRyeS5jYWxsYmFjaztcbiAgICAgIHZhciBsZW4gPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcblxuICAgICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBmYWxzZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgICAgIGVudHJ5ID0gZW50cnkubmV4dDtcbiAgICAgIC8vIGlmIHdlIGRpZG4ndCBjYWxsIHRoZSBvbndyaXRlIGltbWVkaWF0ZWx5LCB0aGVuXG4gICAgICAvLyBpdCBtZWFucyB0aGF0IHdlIG5lZWQgdG8gd2FpdCB1bnRpbCBpdCBkb2VzLlxuICAgICAgLy8gYWxzbywgdGhhdCBtZWFucyB0aGF0IHRoZSBjaHVuayBhbmQgY2IgYXJlIGN1cnJlbnRseVxuICAgICAgLy8gYmVpbmcgcHJvY2Vzc2VkLCBzbyBtb3ZlIHRoZSBidWZmZXIgY291bnRlciBwYXN0IHRoZW0uXG4gICAgICBpZiAoc3RhdGUud3JpdGluZykge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZW50cnkgPT09IG51bGwpXG4gICAgICBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcbiAgfVxuICBzdGF0ZS5idWZmZXJlZFJlcXVlc3QgPSBlbnRyeTtcbiAgc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyA9IGZhbHNlO1xufVxuXG5Xcml0YWJsZS5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjYihuZXcgRXJyb3IoJ25vdCBpbXBsZW1lbnRlZCcpKTtcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGV2ID0gbnVsbDtcblxuV3JpdGFibGUucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBpZiAodHlwZW9mIGNodW5rID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBjaHVuaztcbiAgICBjaHVuayA9IG51bGw7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9XG5cbiAgaWYgKGNodW5rICE9PSBudWxsICYmIGNodW5rICE9PSB1bmRlZmluZWQpXG4gICAgdGhpcy53cml0ZShjaHVuaywgZW5jb2RpbmcpO1xuXG4gIC8vIC5lbmQoKSBmdWxseSB1bmNvcmtzXG4gIGlmIChzdGF0ZS5jb3JrZWQpIHtcbiAgICBzdGF0ZS5jb3JrZWQgPSAxO1xuICAgIHRoaXMudW5jb3JrKCk7XG4gIH1cblxuICAvLyBpZ25vcmUgdW5uZWNlc3NhcnkgZW5kKCkgY2FsbHMuXG4gIGlmICghc3RhdGUuZW5kaW5nICYmICFzdGF0ZS5maW5pc2hlZClcbiAgICBlbmRXcml0YWJsZSh0aGlzLCBzdGF0ZSwgY2IpO1xufTtcblxuXG5mdW5jdGlvbiBuZWVkRmluaXNoKHN0YXRlKSB7XG4gIHJldHVybiAoc3RhdGUuZW5kaW5nICYmXG4gICAgICAgICAgc3RhdGUubGVuZ3RoID09PSAwICYmXG4gICAgICAgICAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0ID09PSBudWxsICYmXG4gICAgICAgICAgIXN0YXRlLmZpbmlzaGVkICYmXG4gICAgICAgICAgIXN0YXRlLndyaXRpbmcpO1xufVxuXG5mdW5jdGlvbiBwcmVmaW5pc2goc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnByZWZpbmlzaGVkKSB7XG4gICAgc3RhdGUucHJlZmluaXNoZWQgPSB0cnVlO1xuICAgIHN0cmVhbS5lbWl0KCdwcmVmaW5pc2gnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKSB7XG4gIHZhciBuZWVkID0gbmVlZEZpbmlzaChzdGF0ZSk7XG4gIGlmIChuZWVkKSB7XG4gICAgaWYgKHN0YXRlLnBlbmRpbmdjYiA9PT0gMCkge1xuICAgICAgcHJlZmluaXNoKHN0cmVhbSwgc3RhdGUpO1xuICAgICAgc3RhdGUuZmluaXNoZWQgPSB0cnVlO1xuICAgICAgc3RyZWFtLmVtaXQoJ2ZpbmlzaCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcmVmaW5pc2goc3RyZWFtLCBzdGF0ZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBuZWVkO1xufVxuXG5mdW5jdGlvbiBlbmRXcml0YWJsZShzdHJlYW0sIHN0YXRlLCBjYikge1xuICBzdGF0ZS5lbmRpbmcgPSB0cnVlO1xuICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbiAgaWYgKGNiKSB7XG4gICAgaWYgKHN0YXRlLmZpbmlzaGVkKVxuICAgICAgcHJvY2Vzc05leHRUaWNrKGNiKTtcbiAgICBlbHNlXG4gICAgICBzdHJlYW0ub25jZSgnZmluaXNoJywgY2IpO1xuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbn1cbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBOT1RFOiBUaGVzZSB0eXBlIGNoZWNraW5nIGZ1bmN0aW9ucyBpbnRlbnRpb25hbGx5IGRvbid0IHVzZSBgaW5zdGFuY2VvZmBcbi8vIGJlY2F1c2UgaXQgaXMgZnJhZ2lsZSBhbmQgY2FuIGJlIGVhc2lseSBmYWtlZCB3aXRoIGBPYmplY3QuY3JlYXRlKClgLlxuXG5mdW5jdGlvbiBpc0FycmF5KGFyZykge1xuICBpZiAoQXJyYXkuaXNBcnJheSkge1xuICAgIHJldHVybiBBcnJheS5pc0FycmF5KGFyZyk7XG4gIH1cbiAgcmV0dXJuIG9iamVjdFRvU3RyaW5nKGFyZykgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59XG5leHBvcnRzLmlzQXJyYXkgPSBpc0FycmF5O1xuXG5mdW5jdGlvbiBpc0Jvb2xlYW4oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnYm9vbGVhbic7XG59XG5leHBvcnRzLmlzQm9vbGVhbiA9IGlzQm9vbGVhbjtcblxuZnVuY3Rpb24gaXNOdWxsKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGwgPSBpc051bGw7XG5cbmZ1bmN0aW9uIGlzTnVsbE9yVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbE9yVW5kZWZpbmVkID0gaXNOdWxsT3JVbmRlZmluZWQ7XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XG59XG5leHBvcnRzLmlzTnVtYmVyID0gaXNOdW1iZXI7XG5cbmZ1bmN0aW9uIGlzU3RyaW5nKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ3N0cmluZyc7XG59XG5leHBvcnRzLmlzU3RyaW5nID0gaXNTdHJpbmc7XG5cbmZ1bmN0aW9uIGlzU3ltYm9sKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCc7XG59XG5leHBvcnRzLmlzU3ltYm9sID0gaXNTeW1ib2w7XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09PSB2b2lkIDA7XG59XG5leHBvcnRzLmlzVW5kZWZpbmVkID0gaXNVbmRlZmluZWQ7XG5cbmZ1bmN0aW9uIGlzUmVnRXhwKHJlKSB7XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhyZSkgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xufVxuZXhwb3J0cy5pc1JlZ0V4cCA9IGlzUmVnRXhwO1xuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNPYmplY3QgPSBpc09iamVjdDtcblxuZnVuY3Rpb24gaXNEYXRlKGQpIHtcbiAgcmV0dXJuIG9iamVjdFRvU3RyaW5nKGQpID09PSAnW29iamVjdCBEYXRlXSc7XG59XG5leHBvcnRzLmlzRGF0ZSA9IGlzRGF0ZTtcblxuZnVuY3Rpb24gaXNFcnJvcihlKSB7XG4gIHJldHVybiAob2JqZWN0VG9TdHJpbmcoZSkgPT09ICdbb2JqZWN0IEVycm9yXScgfHwgZSBpbnN0YW5jZW9mIEVycm9yKTtcbn1cbmV4cG9ydHMuaXNFcnJvciA9IGlzRXJyb3I7XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuZXhwb3J0cy5pc0Z1bmN0aW9uID0gaXNGdW5jdGlvbjtcblxuZnVuY3Rpb24gaXNQcmltaXRpdmUoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGwgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ251bWJlcicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3ltYm9sJyB8fCAgLy8gRVM2IHN5bWJvbFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3VuZGVmaW5lZCc7XG59XG5leHBvcnRzLmlzUHJpbWl0aXZlID0gaXNQcmltaXRpdmU7XG5cbmV4cG9ydHMuaXNCdWZmZXIgPSBCdWZmZXIuaXNCdWZmZXI7XG5cbmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKG8pIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuaWYgKCFwcm9jZXNzLnZlcnNpb24gfHxcbiAgICBwcm9jZXNzLnZlcnNpb24uaW5kZXhPZigndjAuJykgPT09IDAgfHxcbiAgICBwcm9jZXNzLnZlcnNpb24uaW5kZXhPZigndjEuJykgPT09IDAgJiYgcHJvY2Vzcy52ZXJzaW9uLmluZGV4T2YoJ3YxLjguJykgIT09IDApIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBuZXh0VGljaztcbn0gZWxzZSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcHJvY2Vzcy5uZXh0VGljaztcbn1cblxuZnVuY3Rpb24gbmV4dFRpY2soZm4pIHtcbiAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICB2YXIgaSA9IDA7XG4gIHdoaWxlIChpIDwgYXJncy5sZW5ndGgpIHtcbiAgICBhcmdzW2krK10gPSBhcmd1bWVudHNbaV07XG4gIH1cbiAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2soKSB7XG4gICAgZm4uYXBwbHkobnVsbCwgYXJncyk7XG4gIH0pO1xufVxuIiwiXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZGVwcmVjYXRlO1xuXG4vKipcbiAqIE1hcmsgdGhhdCBhIG1ldGhvZCBzaG91bGQgbm90IGJlIHVzZWQuXG4gKiBSZXR1cm5zIGEgbW9kaWZpZWQgZnVuY3Rpb24gd2hpY2ggd2FybnMgb25jZSBieSBkZWZhdWx0LlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2Uubm9EZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBpdCBpcyBhIG5vLW9wLlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2UudGhyb3dEZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBkZXByZWNhdGVkIGZ1bmN0aW9uc1xuICogd2lsbCB0aHJvdyBhbiBFcnJvciB3aGVuIGludm9rZWQuXG4gKlxuICogSWYgYGxvY2FsU3RvcmFnZS50cmFjZURlcHJlY2F0aW9uID0gdHJ1ZWAgaXMgc2V0LCB0aGVuIGRlcHJlY2F0ZWQgZnVuY3Rpb25zXG4gKiB3aWxsIGludm9rZSBgY29uc29sZS50cmFjZSgpYCBpbnN0ZWFkIG9mIGBjb25zb2xlLmVycm9yKClgLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHRvIGRlcHJlY2F0ZVxuICogQHBhcmFtIHtTdHJpbmd9IG1zZyAtIHRoZSBzdHJpbmcgdG8gcHJpbnQgdG8gdGhlIGNvbnNvbGUgd2hlbiBgZm5gIGlzIGludm9rZWRcbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gYSBuZXcgXCJkZXByZWNhdGVkXCIgdmVyc2lvbiBvZiBgZm5gXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGRlcHJlY2F0ZSAoZm4sIG1zZykge1xuICBpZiAoY29uZmlnKCdub0RlcHJlY2F0aW9uJykpIHtcbiAgICByZXR1cm4gZm47XG4gIH1cblxuICB2YXIgd2FybmVkID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGRlcHJlY2F0ZWQoKSB7XG4gICAgaWYgKCF3YXJuZWQpIHtcbiAgICAgIGlmIChjb25maWcoJ3Rocm93RGVwcmVjYXRpb24nKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgIH0gZWxzZSBpZiAoY29uZmlnKCd0cmFjZURlcHJlY2F0aW9uJykpIHtcbiAgICAgICAgY29uc29sZS50cmFjZShtc2cpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS53YXJuKG1zZyk7XG4gICAgICB9XG4gICAgICB3YXJuZWQgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHJldHVybiBkZXByZWNhdGVkO1xufVxuXG4vKipcbiAqIENoZWNrcyBgbG9jYWxTdG9yYWdlYCBmb3IgYm9vbGVhbiB2YWx1ZXMgZm9yIHRoZSBnaXZlbiBgbmFtZWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEByZXR1cm5zIHtCb29sZWFufVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gY29uZmlnIChuYW1lKSB7XG4gIC8vIGFjY2Vzc2luZyBnbG9iYWwubG9jYWxTdG9yYWdlIGNhbiB0cmlnZ2VyIGEgRE9NRXhjZXB0aW9uIGluIHNhbmRib3hlZCBpZnJhbWVzXG4gIHRyeSB7XG4gICAgaWYgKCFnbG9iYWwubG9jYWxTdG9yYWdlKSByZXR1cm4gZmFsc2U7XG4gIH0gY2F0Y2ggKF8pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHZhbCA9IGdsb2JhbC5sb2NhbFN0b3JhZ2VbbmFtZV07XG4gIGlmIChudWxsID09IHZhbCkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gU3RyaW5nKHZhbCkudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnO1xufVxuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qc1wiKVxuIiwidmFyIFN0cmVhbSA9IChmdW5jdGlvbiAoKXtcbiAgdHJ5IHtcbiAgICByZXR1cm4gcmVxdWlyZSgnc3QnICsgJ3JlYW0nKTsgLy8gaGFjayB0byBmaXggYSBjaXJjdWxhciBkZXBlbmRlbmN5IGlzc3VlIHdoZW4gdXNlZCB3aXRoIGJyb3dzZXJpZnlcbiAgfSBjYXRjaChfKXt9XG59KCkpO1xuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV9yZWFkYWJsZS5qcycpO1xuZXhwb3J0cy5TdHJlYW0gPSBTdHJlYW0gfHwgZXhwb3J0cztcbmV4cG9ydHMuUmVhZGFibGUgPSBleHBvcnRzO1xuZXhwb3J0cy5Xcml0YWJsZSA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fd3JpdGFibGUuanMnKTtcbmV4cG9ydHMuRHVwbGV4ID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV9kdXBsZXguanMnKTtcbmV4cG9ydHMuVHJhbnNmb3JtID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV90cmFuc2Zvcm0uanMnKTtcbmV4cG9ydHMuUGFzc1Rocm91Z2ggPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX3Bhc3N0aHJvdWdoLmpzJyk7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qc1wiKVxuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi9saWIvX3N0cmVhbV93cml0YWJsZS5qc1wiKVxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbm1vZHVsZS5leHBvcnRzID0gU3RyZWFtO1xuXG52YXIgRUUgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG5pbmhlcml0cyhTdHJlYW0sIEVFKTtcblN0cmVhbS5SZWFkYWJsZSA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbS9yZWFkYWJsZS5qcycpO1xuU3RyZWFtLldyaXRhYmxlID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL3dyaXRhYmxlLmpzJyk7XG5TdHJlYW0uRHVwbGV4ID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL2R1cGxleC5qcycpO1xuU3RyZWFtLlRyYW5zZm9ybSA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbS90cmFuc2Zvcm0uanMnKTtcblN0cmVhbS5QYXNzVGhyb3VnaCA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbS9wYXNzdGhyb3VnaC5qcycpO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjQueFxuU3RyZWFtLlN0cmVhbSA9IFN0cmVhbTtcblxuXG5cbi8vIG9sZC1zdHlsZSBzdHJlYW1zLiAgTm90ZSB0aGF0IHRoZSBwaXBlIG1ldGhvZCAodGhlIG9ubHkgcmVsZXZhbnRcbi8vIHBhcnQgb2YgdGhpcyBjbGFzcykgaXMgb3ZlcnJpZGRlbiBpbiB0aGUgUmVhZGFibGUgY2xhc3MuXG5cbmZ1bmN0aW9uIFN0cmVhbSgpIHtcbiAgRUUuY2FsbCh0aGlzKTtcbn1cblxuU3RyZWFtLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24oZGVzdCwgb3B0aW9ucykge1xuICB2YXIgc291cmNlID0gdGhpcztcblxuICBmdW5jdGlvbiBvbmRhdGEoY2h1bmspIHtcbiAgICBpZiAoZGVzdC53cml0YWJsZSkge1xuICAgICAgaWYgKGZhbHNlID09PSBkZXN0LndyaXRlKGNodW5rKSAmJiBzb3VyY2UucGF1c2UpIHtcbiAgICAgICAgc291cmNlLnBhdXNlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc291cmNlLm9uKCdkYXRhJywgb25kYXRhKTtcblxuICBmdW5jdGlvbiBvbmRyYWluKCkge1xuICAgIGlmIChzb3VyY2UucmVhZGFibGUgJiYgc291cmNlLnJlc3VtZSkge1xuICAgICAgc291cmNlLnJlc3VtZSgpO1xuICAgIH1cbiAgfVxuXG4gIGRlc3Qub24oJ2RyYWluJywgb25kcmFpbik7XG5cbiAgLy8gSWYgdGhlICdlbmQnIG9wdGlvbiBpcyBub3Qgc3VwcGxpZWQsIGRlc3QuZW5kKCkgd2lsbCBiZSBjYWxsZWQgd2hlblxuICAvLyBzb3VyY2UgZ2V0cyB0aGUgJ2VuZCcgb3IgJ2Nsb3NlJyBldmVudHMuICBPbmx5IGRlc3QuZW5kKCkgb25jZS5cbiAgaWYgKCFkZXN0Ll9pc1N0ZGlvICYmICghb3B0aW9ucyB8fCBvcHRpb25zLmVuZCAhPT0gZmFsc2UpKSB7XG4gICAgc291cmNlLm9uKCdlbmQnLCBvbmVuZCk7XG4gICAgc291cmNlLm9uKCdjbG9zZScsIG9uY2xvc2UpO1xuICB9XG5cbiAgdmFyIGRpZE9uRW5kID0gZmFsc2U7XG4gIGZ1bmN0aW9uIG9uZW5kKCkge1xuICAgIGlmIChkaWRPbkVuZCkgcmV0dXJuO1xuICAgIGRpZE9uRW5kID0gdHJ1ZTtcblxuICAgIGRlc3QuZW5kKCk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIG9uY2xvc2UoKSB7XG4gICAgaWYgKGRpZE9uRW5kKSByZXR1cm47XG4gICAgZGlkT25FbmQgPSB0cnVlO1xuXG4gICAgaWYgKHR5cGVvZiBkZXN0LmRlc3Ryb3kgPT09ICdmdW5jdGlvbicpIGRlc3QuZGVzdHJveSgpO1xuICB9XG5cbiAgLy8gZG9uJ3QgbGVhdmUgZGFuZ2xpbmcgcGlwZXMgd2hlbiB0aGVyZSBhcmUgZXJyb3JzLlxuICBmdW5jdGlvbiBvbmVycm9yKGVyKSB7XG4gICAgY2xlYW51cCgpO1xuICAgIGlmIChFRS5saXN0ZW5lckNvdW50KHRoaXMsICdlcnJvcicpID09PSAwKSB7XG4gICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkIHN0cmVhbSBlcnJvciBpbiBwaXBlLlxuICAgIH1cbiAgfVxuXG4gIHNvdXJjZS5vbignZXJyb3InLCBvbmVycm9yKTtcbiAgZGVzdC5vbignZXJyb3InLCBvbmVycm9yKTtcblxuICAvLyByZW1vdmUgYWxsIHRoZSBldmVudCBsaXN0ZW5lcnMgdGhhdCB3ZXJlIGFkZGVkLlxuICBmdW5jdGlvbiBjbGVhbnVwKCkge1xuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZGF0YScsIG9uZGF0YSk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZHJhaW4nLCBvbmRyYWluKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25lbmQpO1xuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuXG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBjbGVhbnVwKTtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgY2xlYW51cCk7XG5cbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIGNsZWFudXApO1xuICB9XG5cbiAgc291cmNlLm9uKCdlbmQnLCBjbGVhbnVwKTtcbiAgc291cmNlLm9uKCdjbG9zZScsIGNsZWFudXApO1xuXG4gIGRlc3Qub24oJ2Nsb3NlJywgY2xlYW51cCk7XG5cbiAgZGVzdC5lbWl0KCdwaXBlJywgc291cmNlKTtcblxuICAvLyBBbGxvdyBmb3IgdW5peC1saWtlIHVzYWdlOiBBLnBpcGUoQikucGlwZShDKVxuICByZXR1cm4gZGVzdDtcbn07XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcblxudmFyIGlzQnVmZmVyRW5jb2RpbmcgPSBCdWZmZXIuaXNFbmNvZGluZ1xuICB8fCBmdW5jdGlvbihlbmNvZGluZykge1xuICAgICAgIHN3aXRjaCAoZW5jb2RpbmcgJiYgZW5jb2RpbmcudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgY2FzZSAnaGV4JzogY2FzZSAndXRmOCc6IGNhc2UgJ3V0Zi04JzogY2FzZSAnYXNjaWknOiBjYXNlICdiaW5hcnknOiBjYXNlICdiYXNlNjQnOiBjYXNlICd1Y3MyJzogY2FzZSAndWNzLTInOiBjYXNlICd1dGYxNmxlJzogY2FzZSAndXRmLTE2bGUnOiBjYXNlICdyYXcnOiByZXR1cm4gdHJ1ZTtcbiAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBmYWxzZTtcbiAgICAgICB9XG4gICAgIH1cblxuXG5mdW5jdGlvbiBhc3NlcnRFbmNvZGluZyhlbmNvZGluZykge1xuICBpZiAoZW5jb2RpbmcgJiYgIWlzQnVmZmVyRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpO1xuICB9XG59XG5cbi8vIFN0cmluZ0RlY29kZXIgcHJvdmlkZXMgYW4gaW50ZXJmYWNlIGZvciBlZmZpY2llbnRseSBzcGxpdHRpbmcgYSBzZXJpZXMgb2Zcbi8vIGJ1ZmZlcnMgaW50byBhIHNlcmllcyBvZiBKUyBzdHJpbmdzIHdpdGhvdXQgYnJlYWtpbmcgYXBhcnQgbXVsdGktYnl0ZVxuLy8gY2hhcmFjdGVycy4gQ0VTVS04IGlzIGhhbmRsZWQgYXMgcGFydCBvZiB0aGUgVVRGLTggZW5jb2RpbmcuXG4vL1xuLy8gQFRPRE8gSGFuZGxpbmcgYWxsIGVuY29kaW5ncyBpbnNpZGUgYSBzaW5nbGUgb2JqZWN0IG1ha2VzIGl0IHZlcnkgZGlmZmljdWx0XG4vLyB0byByZWFzb24gYWJvdXQgdGhpcyBjb2RlLCBzbyBpdCBzaG91bGQgYmUgc3BsaXQgdXAgaW4gdGhlIGZ1dHVyZS5cbi8vIEBUT0RPIFRoZXJlIHNob3VsZCBiZSBhIHV0Zjgtc3RyaWN0IGVuY29kaW5nIHRoYXQgcmVqZWN0cyBpbnZhbGlkIFVURi04IGNvZGVcbi8vIHBvaW50cyBhcyB1c2VkIGJ5IENFU1UtOC5cbnZhciBTdHJpbmdEZWNvZGVyID0gZXhwb3J0cy5TdHJpbmdEZWNvZGVyID0gZnVuY3Rpb24oZW5jb2RpbmcpIHtcbiAgdGhpcy5lbmNvZGluZyA9IChlbmNvZGluZyB8fCAndXRmOCcpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvWy1fXS8sICcnKTtcbiAgYXNzZXJ0RW5jb2RpbmcoZW5jb2RpbmcpO1xuICBzd2l0Y2ggKHRoaXMuZW5jb2RpbmcpIHtcbiAgICBjYXNlICd1dGY4JzpcbiAgICAgIC8vIENFU1UtOCByZXByZXNlbnRzIGVhY2ggb2YgU3Vycm9nYXRlIFBhaXIgYnkgMy1ieXRlc1xuICAgICAgdGhpcy5zdXJyb2dhdGVTaXplID0gMztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgLy8gVVRGLTE2IHJlcHJlc2VudHMgZWFjaCBvZiBTdXJyb2dhdGUgUGFpciBieSAyLWJ5dGVzXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAyO1xuICAgICAgdGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IHV0ZjE2RGV0ZWN0SW5jb21wbGV0ZUNoYXI7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgLy8gQmFzZS02NCBzdG9yZXMgMyBieXRlcyBpbiA0IGNoYXJzLCBhbmQgcGFkcyB0aGUgcmVtYWluZGVyLlxuICAgICAgdGhpcy5zdXJyb2dhdGVTaXplID0gMztcbiAgICAgIHRoaXMuZGV0ZWN0SW5jb21wbGV0ZUNoYXIgPSBiYXNlNjREZXRlY3RJbmNvbXBsZXRlQ2hhcjtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aGlzLndyaXRlID0gcGFzc1Rocm91Z2hXcml0ZTtcbiAgICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEVub3VnaCBzcGFjZSB0byBzdG9yZSBhbGwgYnl0ZXMgb2YgYSBzaW5nbGUgY2hhcmFjdGVyLiBVVEYtOCBuZWVkcyA0XG4gIC8vIGJ5dGVzLCBidXQgQ0VTVS04IG1heSByZXF1aXJlIHVwIHRvIDYgKDMgYnl0ZXMgcGVyIHN1cnJvZ2F0ZSkuXG4gIHRoaXMuY2hhckJ1ZmZlciA9IG5ldyBCdWZmZXIoNik7XG4gIC8vIE51bWJlciBvZiBieXRlcyByZWNlaXZlZCBmb3IgdGhlIGN1cnJlbnQgaW5jb21wbGV0ZSBtdWx0aS1ieXRlIGNoYXJhY3Rlci5cbiAgdGhpcy5jaGFyUmVjZWl2ZWQgPSAwO1xuICAvLyBOdW1iZXIgb2YgYnl0ZXMgZXhwZWN0ZWQgZm9yIHRoZSBjdXJyZW50IGluY29tcGxldGUgbXVsdGktYnl0ZSBjaGFyYWN0ZXIuXG4gIHRoaXMuY2hhckxlbmd0aCA9IDA7XG59O1xuXG5cbi8vIHdyaXRlIGRlY29kZXMgdGhlIGdpdmVuIGJ1ZmZlciBhbmQgcmV0dXJucyBpdCBhcyBKUyBzdHJpbmcgdGhhdCBpc1xuLy8gZ3VhcmFudGVlZCB0byBub3QgY29udGFpbiBhbnkgcGFydGlhbCBtdWx0aS1ieXRlIGNoYXJhY3RlcnMuIEFueSBwYXJ0aWFsXG4vLyBjaGFyYWN0ZXIgZm91bmQgYXQgdGhlIGVuZCBvZiB0aGUgYnVmZmVyIGlzIGJ1ZmZlcmVkIHVwLCBhbmQgd2lsbCBiZVxuLy8gcmV0dXJuZWQgd2hlbiBjYWxsaW5nIHdyaXRlIGFnYWluIHdpdGggdGhlIHJlbWFpbmluZyBieXRlcy5cbi8vXG4vLyBOb3RlOiBDb252ZXJ0aW5nIGEgQnVmZmVyIGNvbnRhaW5pbmcgYW4gb3JwaGFuIHN1cnJvZ2F0ZSB0byBhIFN0cmluZ1xuLy8gY3VycmVudGx5IHdvcmtzLCBidXQgY29udmVydGluZyBhIFN0cmluZyB0byBhIEJ1ZmZlciAodmlhIGBuZXcgQnVmZmVyYCwgb3Jcbi8vIEJ1ZmZlciN3cml0ZSkgd2lsbCByZXBsYWNlIGluY29tcGxldGUgc3Vycm9nYXRlcyB3aXRoIHRoZSB1bmljb2RlXG4vLyByZXBsYWNlbWVudCBjaGFyYWN0ZXIuIFNlZSBodHRwczovL2NvZGVyZXZpZXcuY2hyb21pdW0ub3JnLzEyMTE3MzAwOS8gLlxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgdmFyIGNoYXJTdHIgPSAnJztcbiAgLy8gaWYgb3VyIGxhc3Qgd3JpdGUgZW5kZWQgd2l0aCBhbiBpbmNvbXBsZXRlIG11bHRpYnl0ZSBjaGFyYWN0ZXJcbiAgd2hpbGUgKHRoaXMuY2hhckxlbmd0aCkge1xuICAgIC8vIGRldGVybWluZSBob3cgbWFueSByZW1haW5pbmcgYnl0ZXMgdGhpcyBidWZmZXIgaGFzIHRvIG9mZmVyIGZvciB0aGlzIGNoYXJcbiAgICB2YXIgYXZhaWxhYmxlID0gKGJ1ZmZlci5sZW5ndGggPj0gdGhpcy5jaGFyTGVuZ3RoIC0gdGhpcy5jaGFyUmVjZWl2ZWQpID9cbiAgICAgICAgdGhpcy5jaGFyTGVuZ3RoIC0gdGhpcy5jaGFyUmVjZWl2ZWQgOlxuICAgICAgICBidWZmZXIubGVuZ3RoO1xuXG4gICAgLy8gYWRkIHRoZSBuZXcgYnl0ZXMgdG8gdGhlIGNoYXIgYnVmZmVyXG4gICAgYnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCB0aGlzLmNoYXJSZWNlaXZlZCwgMCwgYXZhaWxhYmxlKTtcbiAgICB0aGlzLmNoYXJSZWNlaXZlZCArPSBhdmFpbGFibGU7XG5cbiAgICBpZiAodGhpcy5jaGFyUmVjZWl2ZWQgPCB0aGlzLmNoYXJMZW5ndGgpIHtcbiAgICAgIC8vIHN0aWxsIG5vdCBlbm91Z2ggY2hhcnMgaW4gdGhpcyBidWZmZXI/IHdhaXQgZm9yIG1vcmUgLi4uXG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgLy8gcmVtb3ZlIGJ5dGVzIGJlbG9uZ2luZyB0byB0aGUgY3VycmVudCBjaGFyYWN0ZXIgZnJvbSB0aGUgYnVmZmVyXG4gICAgYnVmZmVyID0gYnVmZmVyLnNsaWNlKGF2YWlsYWJsZSwgYnVmZmVyLmxlbmd0aCk7XG5cbiAgICAvLyBnZXQgdGhlIGNoYXJhY3RlciB0aGF0IHdhcyBzcGxpdFxuICAgIGNoYXJTdHIgPSB0aGlzLmNoYXJCdWZmZXIuc2xpY2UoMCwgdGhpcy5jaGFyTGVuZ3RoKS50b1N0cmluZyh0aGlzLmVuY29kaW5nKTtcblxuICAgIC8vIENFU1UtODogbGVhZCBzdXJyb2dhdGUgKEQ4MDAtREJGRikgaXMgYWxzbyB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXJcbiAgICB2YXIgY2hhckNvZGUgPSBjaGFyU3RyLmNoYXJDb2RlQXQoY2hhclN0ci5sZW5ndGggLSAxKTtcbiAgICBpZiAoY2hhckNvZGUgPj0gMHhEODAwICYmIGNoYXJDb2RlIDw9IDB4REJGRikge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoICs9IHRoaXMuc3Vycm9nYXRlU2l6ZTtcbiAgICAgIGNoYXJTdHIgPSAnJztcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB0aGlzLmNoYXJSZWNlaXZlZCA9IHRoaXMuY2hhckxlbmd0aCA9IDA7XG5cbiAgICAvLyBpZiB0aGVyZSBhcmUgbm8gbW9yZSBieXRlcyBpbiB0aGlzIGJ1ZmZlciwganVzdCBlbWl0IG91ciBjaGFyXG4gICAgaWYgKGJ1ZmZlci5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBjaGFyU3RyO1xuICAgIH1cbiAgICBicmVhaztcbiAgfVxuXG4gIC8vIGRldGVybWluZSBhbmQgc2V0IGNoYXJMZW5ndGggLyBjaGFyUmVjZWl2ZWRcbiAgdGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhcihidWZmZXIpO1xuXG4gIHZhciBlbmQgPSBidWZmZXIubGVuZ3RoO1xuICBpZiAodGhpcy5jaGFyTGVuZ3RoKSB7XG4gICAgLy8gYnVmZmVyIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlciBieXRlcyB3ZSBnb3RcbiAgICBidWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsIDAsIGJ1ZmZlci5sZW5ndGggLSB0aGlzLmNoYXJSZWNlaXZlZCwgZW5kKTtcbiAgICBlbmQgLT0gdGhpcy5jaGFyUmVjZWl2ZWQ7XG4gIH1cblxuICBjaGFyU3RyICs9IGJ1ZmZlci50b1N0cmluZyh0aGlzLmVuY29kaW5nLCAwLCBlbmQpO1xuXG4gIHZhciBlbmQgPSBjaGFyU3RyLmxlbmd0aCAtIDE7XG4gIHZhciBjaGFyQ29kZSA9IGNoYXJTdHIuY2hhckNvZGVBdChlbmQpO1xuICAvLyBDRVNVLTg6IGxlYWQgc3Vycm9nYXRlIChEODAwLURCRkYpIGlzIGFsc28gdGhlIGluY29tcGxldGUgY2hhcmFjdGVyXG4gIGlmIChjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGKSB7XG4gICAgdmFyIHNpemUgPSB0aGlzLnN1cnJvZ2F0ZVNpemU7XG4gICAgdGhpcy5jaGFyTGVuZ3RoICs9IHNpemU7XG4gICAgdGhpcy5jaGFyUmVjZWl2ZWQgKz0gc2l6ZTtcbiAgICB0aGlzLmNoYXJCdWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsIHNpemUsIDAsIHNpemUpO1xuICAgIGJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgMCwgMCwgc2l6ZSk7XG4gICAgcmV0dXJuIGNoYXJTdHIuc3Vic3RyaW5nKDAsIGVuZCk7XG4gIH1cblxuICAvLyBvciBqdXN0IGVtaXQgdGhlIGNoYXJTdHJcbiAgcmV0dXJuIGNoYXJTdHI7XG59O1xuXG4vLyBkZXRlY3RJbmNvbXBsZXRlQ2hhciBkZXRlcm1pbmVzIGlmIHRoZXJlIGlzIGFuIGluY29tcGxldGUgVVRGLTggY2hhcmFjdGVyIGF0XG4vLyB0aGUgZW5kIG9mIHRoZSBnaXZlbiBidWZmZXIuIElmIHNvLCBpdCBzZXRzIHRoaXMuY2hhckxlbmd0aCB0byB0aGUgYnl0ZVxuLy8gbGVuZ3RoIHRoYXQgY2hhcmFjdGVyLCBhbmQgc2V0cyB0aGlzLmNoYXJSZWNlaXZlZCB0byB0aGUgbnVtYmVyIG9mIGJ5dGVzXG4vLyB0aGF0IGFyZSBhdmFpbGFibGUgZm9yIHRoaXMgY2hhcmFjdGVyLlxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZGV0ZWN0SW5jb21wbGV0ZUNoYXIgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgLy8gZGV0ZXJtaW5lIGhvdyBtYW55IGJ5dGVzIHdlIGhhdmUgdG8gY2hlY2sgYXQgdGhlIGVuZCBvZiB0aGlzIGJ1ZmZlclxuICB2YXIgaSA9IChidWZmZXIubGVuZ3RoID49IDMpID8gMyA6IGJ1ZmZlci5sZW5ndGg7XG5cbiAgLy8gRmlndXJlIG91dCBpZiBvbmUgb2YgdGhlIGxhc3QgaSBieXRlcyBvZiBvdXIgYnVmZmVyIGFubm91bmNlcyBhblxuICAvLyBpbmNvbXBsZXRlIGNoYXIuXG4gIGZvciAoOyBpID4gMDsgaS0tKSB7XG4gICAgdmFyIGMgPSBidWZmZXJbYnVmZmVyLmxlbmd0aCAtIGldO1xuXG4gICAgLy8gU2VlIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvVVRGLTgjRGVzY3JpcHRpb25cblxuICAgIC8vIDExMFhYWFhYXG4gICAgaWYgKGkgPT0gMSAmJiBjID4+IDUgPT0gMHgwNikge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoID0gMjtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIDExMTBYWFhYXG4gICAgaWYgKGkgPD0gMiAmJiBjID4+IDQgPT0gMHgwRSkge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoID0gMztcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIDExMTEwWFhYXG4gICAgaWYgKGkgPD0gMyAmJiBjID4+IDMgPT0gMHgxRSkge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoID0gNDtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICB0aGlzLmNoYXJSZWNlaXZlZCA9IGk7XG59O1xuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBpZiAoYnVmZmVyICYmIGJ1ZmZlci5sZW5ndGgpXG4gICAgcmVzID0gdGhpcy53cml0ZShidWZmZXIpO1xuXG4gIGlmICh0aGlzLmNoYXJSZWNlaXZlZCkge1xuICAgIHZhciBjciA9IHRoaXMuY2hhclJlY2VpdmVkO1xuICAgIHZhciBidWYgPSB0aGlzLmNoYXJCdWZmZXI7XG4gICAgdmFyIGVuYyA9IHRoaXMuZW5jb2Rpbmc7XG4gICAgcmVzICs9IGJ1Zi5zbGljZSgwLCBjcikudG9TdHJpbmcoZW5jKTtcbiAgfVxuXG4gIHJldHVybiByZXM7XG59O1xuXG5mdW5jdGlvbiBwYXNzVGhyb3VnaFdyaXRlKGJ1ZmZlcikge1xuICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpO1xufVxuXG5mdW5jdGlvbiB1dGYxNkRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcikge1xuICB0aGlzLmNoYXJSZWNlaXZlZCA9IGJ1ZmZlci5sZW5ndGggJSAyO1xuICB0aGlzLmNoYXJMZW5ndGggPSB0aGlzLmNoYXJSZWNlaXZlZCA/IDIgOiAwO1xufVxuXG5mdW5jdGlvbiBiYXNlNjREZXRlY3RJbmNvbXBsZXRlQ2hhcihidWZmZXIpIHtcbiAgdGhpcy5jaGFyUmVjZWl2ZWQgPSBidWZmZXIubGVuZ3RoICUgMztcbiAgdGhpcy5jaGFyTGVuZ3RoID0gdGhpcy5jaGFyUmVjZWl2ZWQgPyAzIDogMDtcbn1cbiIsInZhciBpbmRleE9mID0gcmVxdWlyZSgnaW5kZXhvZicpO1xuXG52YXIgT2JqZWN0X2tleXMgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgaWYgKE9iamVjdC5rZXlzKSByZXR1cm4gT2JqZWN0LmtleXMob2JqKVxuICAgIGVsc2Uge1xuICAgICAgICB2YXIgcmVzID0gW107XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBvYmopIHJlcy5wdXNoKGtleSlcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG59O1xuXG52YXIgZm9yRWFjaCA9IGZ1bmN0aW9uICh4cywgZm4pIHtcbiAgICBpZiAoeHMuZm9yRWFjaCkgcmV0dXJuIHhzLmZvckVhY2goZm4pXG4gICAgZWxzZSBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGZuKHhzW2ldLCBpLCB4cyk7XG4gICAgfVxufTtcblxudmFyIGRlZmluZVByb3AgPSAoZnVuY3Rpb24oKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAnXycsIHt9KTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iaiwgbmFtZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIG5hbWUsIHtcbiAgICAgICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlXG4gICAgICAgICAgICB9KVxuICAgICAgICB9O1xuICAgIH0gY2F0Y2goZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24ob2JqLCBuYW1lLCB2YWx1ZSkge1xuICAgICAgICAgICAgb2JqW25hbWVdID0gdmFsdWU7XG4gICAgICAgIH07XG4gICAgfVxufSgpKTtcblxudmFyIGdsb2JhbHMgPSBbJ0FycmF5JywgJ0Jvb2xlYW4nLCAnRGF0ZScsICdFcnJvcicsICdFdmFsRXJyb3InLCAnRnVuY3Rpb24nLFxuJ0luZmluaXR5JywgJ0pTT04nLCAnTWF0aCcsICdOYU4nLCAnTnVtYmVyJywgJ09iamVjdCcsICdSYW5nZUVycm9yJyxcbidSZWZlcmVuY2VFcnJvcicsICdSZWdFeHAnLCAnU3RyaW5nJywgJ1N5bnRheEVycm9yJywgJ1R5cGVFcnJvcicsICdVUklFcnJvcicsXG4nZGVjb2RlVVJJJywgJ2RlY29kZVVSSUNvbXBvbmVudCcsICdlbmNvZGVVUkknLCAnZW5jb2RlVVJJQ29tcG9uZW50JywgJ2VzY2FwZScsXG4nZXZhbCcsICdpc0Zpbml0ZScsICdpc05hTicsICdwYXJzZUZsb2F0JywgJ3BhcnNlSW50JywgJ3VuZGVmaW5lZCcsICd1bmVzY2FwZSddO1xuXG5mdW5jdGlvbiBDb250ZXh0KCkge31cbkNvbnRleHQucHJvdG90eXBlID0ge307XG5cbnZhciBTY3JpcHQgPSBleHBvcnRzLlNjcmlwdCA9IGZ1bmN0aW9uIE5vZGVTY3JpcHQgKGNvZGUpIHtcbiAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU2NyaXB0KSkgcmV0dXJuIG5ldyBTY3JpcHQoY29kZSk7XG4gICAgdGhpcy5jb2RlID0gY29kZTtcbn07XG5cblNjcmlwdC5wcm90b3R5cGUucnVuSW5Db250ZXh0ID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICBpZiAoIShjb250ZXh0IGluc3RhbmNlb2YgQ29udGV4dCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIm5lZWRzIGEgJ2NvbnRleHQnIGFyZ3VtZW50LlwiKTtcbiAgICB9XG4gICAgXG4gICAgdmFyIGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lmcmFtZScpO1xuICAgIGlmICghaWZyYW1lLnN0eWxlKSBpZnJhbWUuc3R5bGUgPSB7fTtcbiAgICBpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICBcbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGlmcmFtZSk7XG4gICAgXG4gICAgdmFyIHdpbiA9IGlmcmFtZS5jb250ZW50V2luZG93O1xuICAgIHZhciB3RXZhbCA9IHdpbi5ldmFsLCB3RXhlY1NjcmlwdCA9IHdpbi5leGVjU2NyaXB0O1xuXG4gICAgaWYgKCF3RXZhbCAmJiB3RXhlY1NjcmlwdCkge1xuICAgICAgICAvLyB3aW4uZXZhbCgpIG1hZ2ljYWxseSBhcHBlYXJzIHdoZW4gdGhpcyBpcyBjYWxsZWQgaW4gSUU6XG4gICAgICAgIHdFeGVjU2NyaXB0LmNhbGwod2luLCAnbnVsbCcpO1xuICAgICAgICB3RXZhbCA9IHdpbi5ldmFsO1xuICAgIH1cbiAgICBcbiAgICBmb3JFYWNoKE9iamVjdF9rZXlzKGNvbnRleHQpLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIHdpbltrZXldID0gY29udGV4dFtrZXldO1xuICAgIH0pO1xuICAgIGZvckVhY2goZ2xvYmFscywgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBpZiAoY29udGV4dFtrZXldKSB7XG4gICAgICAgICAgICB3aW5ba2V5XSA9IGNvbnRleHRba2V5XTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIFxuICAgIHZhciB3aW5LZXlzID0gT2JqZWN0X2tleXMod2luKTtcblxuICAgIHZhciByZXMgPSB3RXZhbC5jYWxsKHdpbiwgdGhpcy5jb2RlKTtcbiAgICBcbiAgICBmb3JFYWNoKE9iamVjdF9rZXlzKHdpbiksIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgLy8gQXZvaWQgY29weWluZyBjaXJjdWxhciBvYmplY3RzIGxpa2UgYHRvcGAgYW5kIGB3aW5kb3dgIGJ5IG9ubHlcbiAgICAgICAgLy8gdXBkYXRpbmcgZXhpc3RpbmcgY29udGV4dCBwcm9wZXJ0aWVzIG9yIG5ldyBwcm9wZXJ0aWVzIGluIHRoZSBgd2luYFxuICAgICAgICAvLyB0aGF0IHdhcyBvbmx5IGludHJvZHVjZWQgYWZ0ZXIgdGhlIGV2YWwuXG4gICAgICAgIGlmIChrZXkgaW4gY29udGV4dCB8fCBpbmRleE9mKHdpbktleXMsIGtleSkgPT09IC0xKSB7XG4gICAgICAgICAgICBjb250ZXh0W2tleV0gPSB3aW5ba2V5XTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgZm9yRWFjaChnbG9iYWxzLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIGlmICghKGtleSBpbiBjb250ZXh0KSkge1xuICAgICAgICAgICAgZGVmaW5lUHJvcChjb250ZXh0LCBrZXksIHdpbltrZXldKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIFxuICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcbiAgICBcbiAgICByZXR1cm4gcmVzO1xufTtcblxuU2NyaXB0LnByb3RvdHlwZS5ydW5JblRoaXNDb250ZXh0ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBldmFsKHRoaXMuY29kZSk7IC8vIG1heWJlLi4uXG59O1xuXG5TY3JpcHQucHJvdG90eXBlLnJ1bkluTmV3Q29udGV4dCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgdmFyIGN0eCA9IFNjcmlwdC5jcmVhdGVDb250ZXh0KGNvbnRleHQpO1xuICAgIHZhciByZXMgPSB0aGlzLnJ1bkluQ29udGV4dChjdHgpO1xuXG4gICAgZm9yRWFjaChPYmplY3Rfa2V5cyhjdHgpLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIGNvbnRleHRba2V5XSA9IGN0eFtrZXldO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJlcztcbn07XG5cbmZvckVhY2goT2JqZWN0X2tleXMoU2NyaXB0LnByb3RvdHlwZSksIGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgZXhwb3J0c1tuYW1lXSA9IFNjcmlwdFtuYW1lXSA9IGZ1bmN0aW9uIChjb2RlKSB7XG4gICAgICAgIHZhciBzID0gU2NyaXB0KGNvZGUpO1xuICAgICAgICByZXR1cm4gc1tuYW1lXS5hcHBseShzLCBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpO1xuICAgIH07XG59KTtcblxuZXhwb3J0cy5jcmVhdGVTY3JpcHQgPSBmdW5jdGlvbiAoY29kZSkge1xuICAgIHJldHVybiBleHBvcnRzLlNjcmlwdChjb2RlKTtcbn07XG5cbmV4cG9ydHMuY3JlYXRlQ29udGV4dCA9IFNjcmlwdC5jcmVhdGVDb250ZXh0ID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICB2YXIgY29weSA9IG5ldyBDb250ZXh0KCk7XG4gICAgaWYodHlwZW9mIGNvbnRleHQgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGZvckVhY2goT2JqZWN0X2tleXMoY29udGV4dCksIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgIGNvcHlba2V5XSA9IGNvbnRleHRba2V5XTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBjb3B5O1xufTtcbiIsIlxudmFyIGluZGV4T2YgPSBbXS5pbmRleE9mO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGFyciwgb2JqKXtcbiAgaWYgKGluZGV4T2YpIHJldHVybiBhcnIuaW5kZXhPZihvYmopO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7ICsraSkge1xuICAgIGlmIChhcnJbaV0gPT09IG9iaikgcmV0dXJuIGk7XG4gIH1cbiAgcmV0dXJuIC0xO1xufTsiLCIvKipcbiAqICBDb3B5cmlnaHQgKGMpIDIwMTQtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqICBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqICBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqICBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqICBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqL1xuXG4oZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuICB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKSA6XG4gIHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShmYWN0b3J5KSA6XG4gIGdsb2JhbC5JbW11dGFibGUgPSBmYWN0b3J5KCk7XG59KHRoaXMsIGZ1bmN0aW9uICgpIHsgJ3VzZSBzdHJpY3QnO3ZhciBTTElDRSQwID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xuXG4gIGZ1bmN0aW9uIGNyZWF0ZUNsYXNzKGN0b3IsIHN1cGVyQ2xhc3MpIHtcbiAgICBpZiAoc3VwZXJDbGFzcykge1xuICAgICAgY3Rvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MucHJvdG90eXBlKTtcbiAgICB9XG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yO1xuICB9XG5cbiAgZnVuY3Rpb24gSXRlcmFibGUodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc0l0ZXJhYmxlKHZhbHVlKSA/IHZhbHVlIDogU2VxKHZhbHVlKTtcbiAgICB9XG5cblxuICBjcmVhdGVDbGFzcyhLZXllZEl0ZXJhYmxlLCBJdGVyYWJsZSk7XG4gICAgZnVuY3Rpb24gS2V5ZWRJdGVyYWJsZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzS2V5ZWQodmFsdWUpID8gdmFsdWUgOiBLZXllZFNlcSh2YWx1ZSk7XG4gICAgfVxuXG5cbiAgY3JlYXRlQ2xhc3MoSW5kZXhlZEl0ZXJhYmxlLCBJdGVyYWJsZSk7XG4gICAgZnVuY3Rpb24gSW5kZXhlZEl0ZXJhYmxlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNJbmRleGVkKHZhbHVlKSA/IHZhbHVlIDogSW5kZXhlZFNlcSh2YWx1ZSk7XG4gICAgfVxuXG5cbiAgY3JlYXRlQ2xhc3MoU2V0SXRlcmFibGUsIEl0ZXJhYmxlKTtcbiAgICBmdW5jdGlvbiBTZXRJdGVyYWJsZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzSXRlcmFibGUodmFsdWUpICYmICFpc0Fzc29jaWF0aXZlKHZhbHVlKSA/IHZhbHVlIDogU2V0U2VxKHZhbHVlKTtcbiAgICB9XG5cblxuXG4gIGZ1bmN0aW9uIGlzSXRlcmFibGUobWF5YmVJdGVyYWJsZSkge1xuICAgIHJldHVybiAhIShtYXliZUl0ZXJhYmxlICYmIG1heWJlSXRlcmFibGVbSVNfSVRFUkFCTEVfU0VOVElORUxdKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzS2V5ZWQobWF5YmVLZXllZCkge1xuICAgIHJldHVybiAhIShtYXliZUtleWVkICYmIG1heWJlS2V5ZWRbSVNfS0VZRURfU0VOVElORUxdKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzSW5kZXhlZChtYXliZUluZGV4ZWQpIHtcbiAgICByZXR1cm4gISEobWF5YmVJbmRleGVkICYmIG1heWJlSW5kZXhlZFtJU19JTkRFWEVEX1NFTlRJTkVMXSk7XG4gIH1cblxuICBmdW5jdGlvbiBpc0Fzc29jaWF0aXZlKG1heWJlQXNzb2NpYXRpdmUpIHtcbiAgICByZXR1cm4gaXNLZXllZChtYXliZUFzc29jaWF0aXZlKSB8fCBpc0luZGV4ZWQobWF5YmVBc3NvY2lhdGl2ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBpc09yZGVyZWQobWF5YmVPcmRlcmVkKSB7XG4gICAgcmV0dXJuICEhKG1heWJlT3JkZXJlZCAmJiBtYXliZU9yZGVyZWRbSVNfT1JERVJFRF9TRU5USU5FTF0pO1xuICB9XG5cbiAgSXRlcmFibGUuaXNJdGVyYWJsZSA9IGlzSXRlcmFibGU7XG4gIEl0ZXJhYmxlLmlzS2V5ZWQgPSBpc0tleWVkO1xuICBJdGVyYWJsZS5pc0luZGV4ZWQgPSBpc0luZGV4ZWQ7XG4gIEl0ZXJhYmxlLmlzQXNzb2NpYXRpdmUgPSBpc0Fzc29jaWF0aXZlO1xuICBJdGVyYWJsZS5pc09yZGVyZWQgPSBpc09yZGVyZWQ7XG5cbiAgSXRlcmFibGUuS2V5ZWQgPSBLZXllZEl0ZXJhYmxlO1xuICBJdGVyYWJsZS5JbmRleGVkID0gSW5kZXhlZEl0ZXJhYmxlO1xuICBJdGVyYWJsZS5TZXQgPSBTZXRJdGVyYWJsZTtcblxuXG4gIHZhciBJU19JVEVSQUJMRV9TRU5USU5FTCA9ICdAQF9fSU1NVVRBQkxFX0lURVJBQkxFX19AQCc7XG4gIHZhciBJU19LRVlFRF9TRU5USU5FTCA9ICdAQF9fSU1NVVRBQkxFX0tFWUVEX19AQCc7XG4gIHZhciBJU19JTkRFWEVEX1NFTlRJTkVMID0gJ0BAX19JTU1VVEFCTEVfSU5ERVhFRF9fQEAnO1xuICB2YXIgSVNfT1JERVJFRF9TRU5USU5FTCA9ICdAQF9fSU1NVVRBQkxFX09SREVSRURfX0BAJztcblxuICAvLyBVc2VkIGZvciBzZXR0aW5nIHByb3RvdHlwZSBtZXRob2RzIHRoYXQgSUU4IGNob2tlcyBvbi5cbiAgdmFyIERFTEVURSA9ICdkZWxldGUnO1xuXG4gIC8vIENvbnN0YW50cyBkZXNjcmliaW5nIHRoZSBzaXplIG9mIHRyaWUgbm9kZXMuXG4gIHZhciBTSElGVCA9IDU7IC8vIFJlc3VsdGVkIGluIGJlc3QgcGVyZm9ybWFuY2UgYWZ0ZXIgX19fX19fP1xuICB2YXIgU0laRSA9IDEgPDwgU0hJRlQ7XG4gIHZhciBNQVNLID0gU0laRSAtIDE7XG5cbiAgLy8gQSBjb25zaXN0ZW50IHNoYXJlZCB2YWx1ZSByZXByZXNlbnRpbmcgXCJub3Qgc2V0XCIgd2hpY2ggZXF1YWxzIG5vdGhpbmcgb3RoZXJcbiAgLy8gdGhhbiBpdHNlbGYsIGFuZCBub3RoaW5nIHRoYXQgY291bGQgYmUgcHJvdmlkZWQgZXh0ZXJuYWxseS5cbiAgdmFyIE5PVF9TRVQgPSB7fTtcblxuICAvLyBCb29sZWFuIHJlZmVyZW5jZXMsIFJvdWdoIGVxdWl2YWxlbnQgb2YgYGJvb2wgJmAuXG4gIHZhciBDSEFOR0VfTEVOR1RIID0geyB2YWx1ZTogZmFsc2UgfTtcbiAgdmFyIERJRF9BTFRFUiA9IHsgdmFsdWU6IGZhbHNlIH07XG5cbiAgZnVuY3Rpb24gTWFrZVJlZihyZWYpIHtcbiAgICByZWYudmFsdWUgPSBmYWxzZTtcbiAgICByZXR1cm4gcmVmO1xuICB9XG5cbiAgZnVuY3Rpb24gU2V0UmVmKHJlZikge1xuICAgIHJlZiAmJiAocmVmLnZhbHVlID0gdHJ1ZSk7XG4gIH1cblxuICAvLyBBIGZ1bmN0aW9uIHdoaWNoIHJldHVybnMgYSB2YWx1ZSByZXByZXNlbnRpbmcgYW4gXCJvd25lclwiIGZvciB0cmFuc2llbnQgd3JpdGVzXG4gIC8vIHRvIHRyaWVzLiBUaGUgcmV0dXJuIHZhbHVlIHdpbGwgb25seSBldmVyIGVxdWFsIGl0c2VsZiwgYW5kIHdpbGwgbm90IGVxdWFsXG4gIC8vIHRoZSByZXR1cm4gb2YgYW55IHN1YnNlcXVlbnQgY2FsbCBvZiB0aGlzIGZ1bmN0aW9uLlxuICBmdW5jdGlvbiBPd25lcklEKCkge31cblxuICAvLyBodHRwOi8vanNwZXJmLmNvbS9jb3B5LWFycmF5LWlubGluZVxuICBmdW5jdGlvbiBhcnJDb3B5KGFyciwgb2Zmc2V0KSB7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHx8IDA7XG4gICAgdmFyIGxlbiA9IE1hdGgubWF4KDAsIGFyci5sZW5ndGggLSBvZmZzZXQpO1xuICAgIHZhciBuZXdBcnIgPSBuZXcgQXJyYXkobGVuKTtcbiAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgbGVuOyBpaSsrKSB7XG4gICAgICBuZXdBcnJbaWldID0gYXJyW2lpICsgb2Zmc2V0XTtcbiAgICB9XG4gICAgcmV0dXJuIG5ld0FycjtcbiAgfVxuXG4gIGZ1bmN0aW9uIGVuc3VyZVNpemUoaXRlcikge1xuICAgIGlmIChpdGVyLnNpemUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgaXRlci5zaXplID0gaXRlci5fX2l0ZXJhdGUocmV0dXJuVHJ1ZSk7XG4gICAgfVxuICAgIHJldHVybiBpdGVyLnNpemU7XG4gIH1cblxuICBmdW5jdGlvbiB3cmFwSW5kZXgoaXRlciwgaW5kZXgpIHtcbiAgICAvLyBUaGlzIGltcGxlbWVudHMgXCJpcyBhcnJheSBpbmRleFwiIHdoaWNoIHRoZSBFQ01BU3RyaW5nIHNwZWMgZGVmaW5lcyBhczpcbiAgICAvL1xuICAgIC8vICAgICBBIFN0cmluZyBwcm9wZXJ0eSBuYW1lIFAgaXMgYW4gYXJyYXkgaW5kZXggaWYgYW5kIG9ubHkgaWZcbiAgICAvLyAgICAgVG9TdHJpbmcoVG9VaW50MzIoUCkpIGlzIGVxdWFsIHRvIFAgYW5kIFRvVWludDMyKFApIGlzIG5vdCBlcXVhbFxuICAgIC8vICAgICB0byAyXjMy4oiSMS5cbiAgICAvL1xuICAgIC8vIGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1hcnJheS1leG90aWMtb2JqZWN0c1xuICAgIGlmICh0eXBlb2YgaW5kZXggIT09ICdudW1iZXInKSB7XG4gICAgICB2YXIgdWludDMySW5kZXggPSBpbmRleCA+Pj4gMDsgLy8gTiA+Pj4gMCBpcyBzaG9ydGhhbmQgZm9yIFRvVWludDMyXG4gICAgICBpZiAoJycgKyB1aW50MzJJbmRleCAhPT0gaW5kZXggfHwgdWludDMySW5kZXggPT09IDQyOTQ5NjcyOTUpIHtcbiAgICAgICAgcmV0dXJuIE5hTjtcbiAgICAgIH1cbiAgICAgIGluZGV4ID0gdWludDMySW5kZXg7XG4gICAgfVxuICAgIHJldHVybiBpbmRleCA8IDAgPyBlbnN1cmVTaXplKGl0ZXIpICsgaW5kZXggOiBpbmRleDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJldHVyblRydWUoKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBmdW5jdGlvbiB3aG9sZVNsaWNlKGJlZ2luLCBlbmQsIHNpemUpIHtcbiAgICByZXR1cm4gKGJlZ2luID09PSAwIHx8IChzaXplICE9PSB1bmRlZmluZWQgJiYgYmVnaW4gPD0gLXNpemUpKSAmJlxuICAgICAgKGVuZCA9PT0gdW5kZWZpbmVkIHx8IChzaXplICE9PSB1bmRlZmluZWQgJiYgZW5kID49IHNpemUpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc29sdmVCZWdpbihiZWdpbiwgc2l6ZSkge1xuICAgIHJldHVybiByZXNvbHZlSW5kZXgoYmVnaW4sIHNpemUsIDApO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzb2x2ZUVuZChlbmQsIHNpemUpIHtcbiAgICByZXR1cm4gcmVzb2x2ZUluZGV4KGVuZCwgc2l6ZSwgc2l6ZSk7XG4gIH1cblxuICBmdW5jdGlvbiByZXNvbHZlSW5kZXgoaW5kZXgsIHNpemUsIGRlZmF1bHRJbmRleCkge1xuICAgIHJldHVybiBpbmRleCA9PT0gdW5kZWZpbmVkID9cbiAgICAgIGRlZmF1bHRJbmRleCA6XG4gICAgICBpbmRleCA8IDAgP1xuICAgICAgICBNYXRoLm1heCgwLCBzaXplICsgaW5kZXgpIDpcbiAgICAgICAgc2l6ZSA9PT0gdW5kZWZpbmVkID9cbiAgICAgICAgICBpbmRleCA6XG4gICAgICAgICAgTWF0aC5taW4oc2l6ZSwgaW5kZXgpO1xuICB9XG5cbiAgLyogZ2xvYmFsIFN5bWJvbCAqL1xuXG4gIHZhciBJVEVSQVRFX0tFWVMgPSAwO1xuICB2YXIgSVRFUkFURV9WQUxVRVMgPSAxO1xuICB2YXIgSVRFUkFURV9FTlRSSUVTID0gMjtcblxuICB2YXIgUkVBTF9JVEVSQVRPUl9TWU1CT0wgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIFN5bWJvbC5pdGVyYXRvcjtcbiAgdmFyIEZBVVhfSVRFUkFUT1JfU1lNQk9MID0gJ0BAaXRlcmF0b3InO1xuXG4gIHZhciBJVEVSQVRPUl9TWU1CT0wgPSBSRUFMX0lURVJBVE9SX1NZTUJPTCB8fCBGQVVYX0lURVJBVE9SX1NZTUJPTDtcblxuXG4gIGZ1bmN0aW9uIEl0ZXJhdG9yKG5leHQpIHtcbiAgICAgIHRoaXMubmV4dCA9IG5leHQ7XG4gICAgfVxuXG4gICAgSXRlcmF0b3IucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gJ1tJdGVyYXRvcl0nO1xuICAgIH07XG5cblxuICBJdGVyYXRvci5LRVlTID0gSVRFUkFURV9LRVlTO1xuICBJdGVyYXRvci5WQUxVRVMgPSBJVEVSQVRFX1ZBTFVFUztcbiAgSXRlcmF0b3IuRU5UUklFUyA9IElURVJBVEVfRU5UUklFUztcblxuICBJdGVyYXRvci5wcm90b3R5cGUuaW5zcGVjdCA9XG4gIEl0ZXJhdG9yLnByb3RvdHlwZS50b1NvdXJjZSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMudG9TdHJpbmcoKTsgfVxuICBJdGVyYXRvci5wcm90b3R5cGVbSVRFUkFUT1JfU1lNQk9MXSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuXG4gIGZ1bmN0aW9uIGl0ZXJhdG9yVmFsdWUodHlwZSwgaywgdiwgaXRlcmF0b3JSZXN1bHQpIHtcbiAgICB2YXIgdmFsdWUgPSB0eXBlID09PSAwID8gayA6IHR5cGUgPT09IDEgPyB2IDogW2ssIHZdO1xuICAgIGl0ZXJhdG9yUmVzdWx0ID8gKGl0ZXJhdG9yUmVzdWx0LnZhbHVlID0gdmFsdWUpIDogKGl0ZXJhdG9yUmVzdWx0ID0ge1xuICAgICAgdmFsdWU6IHZhbHVlLCBkb25lOiBmYWxzZVxuICAgIH0pO1xuICAgIHJldHVybiBpdGVyYXRvclJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGl0ZXJhdG9yRG9uZSgpIHtcbiAgICByZXR1cm4geyB2YWx1ZTogdW5kZWZpbmVkLCBkb25lOiB0cnVlIH07XG4gIH1cblxuICBmdW5jdGlvbiBoYXNJdGVyYXRvcihtYXliZUl0ZXJhYmxlKSB7XG4gICAgcmV0dXJuICEhZ2V0SXRlcmF0b3JGbihtYXliZUl0ZXJhYmxlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzSXRlcmF0b3IobWF5YmVJdGVyYXRvcikge1xuICAgIHJldHVybiBtYXliZUl0ZXJhdG9yICYmIHR5cGVvZiBtYXliZUl0ZXJhdG9yLm5leHQgPT09ICdmdW5jdGlvbic7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRJdGVyYXRvcihpdGVyYWJsZSkge1xuICAgIHZhciBpdGVyYXRvckZuID0gZ2V0SXRlcmF0b3JGbihpdGVyYWJsZSk7XG4gICAgcmV0dXJuIGl0ZXJhdG9yRm4gJiYgaXRlcmF0b3JGbi5jYWxsKGl0ZXJhYmxlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldEl0ZXJhdG9yRm4oaXRlcmFibGUpIHtcbiAgICB2YXIgaXRlcmF0b3JGbiA9IGl0ZXJhYmxlICYmIChcbiAgICAgIChSRUFMX0lURVJBVE9SX1NZTUJPTCAmJiBpdGVyYWJsZVtSRUFMX0lURVJBVE9SX1NZTUJPTF0pIHx8XG4gICAgICBpdGVyYWJsZVtGQVVYX0lURVJBVE9SX1NZTUJPTF1cbiAgICApO1xuICAgIGlmICh0eXBlb2YgaXRlcmF0b3JGbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIGl0ZXJhdG9yRm47XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaXNBcnJheUxpa2UodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgJiYgdHlwZW9mIHZhbHVlLmxlbmd0aCA9PT0gJ251bWJlcic7XG4gIH1cblxuICBjcmVhdGVDbGFzcyhTZXEsIEl0ZXJhYmxlKTtcbiAgICBmdW5jdGlvbiBTZXEodmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gZW1wdHlTZXF1ZW5jZSgpIDpcbiAgICAgICAgaXNJdGVyYWJsZSh2YWx1ZSkgPyB2YWx1ZS50b1NlcSgpIDogc2VxRnJvbVZhbHVlKHZhbHVlKTtcbiAgICB9XG5cbiAgICBTZXEub2YgPSBmdW5jdGlvbigvKi4uLnZhbHVlcyovKSB7XG4gICAgICByZXR1cm4gU2VxKGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIFNlcS5wcm90b3R5cGUudG9TZXEgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBTZXEucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fX3RvU3RyaW5nKCdTZXEgeycsICd9Jyk7XG4gICAgfTtcblxuICAgIFNlcS5wcm90b3R5cGUuY2FjaGVSZXN1bHQgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICghdGhpcy5fY2FjaGUgJiYgdGhpcy5fX2l0ZXJhdGVVbmNhY2hlZCkge1xuICAgICAgICB0aGlzLl9jYWNoZSA9IHRoaXMuZW50cnlTZXEoKS50b0FycmF5KCk7XG4gICAgICAgIHRoaXMuc2l6ZSA9IHRoaXMuX2NhY2hlLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvLyBhYnN0cmFjdCBfX2l0ZXJhdGVVbmNhY2hlZChmbiwgcmV2ZXJzZSlcblxuICAgIFNlcS5wcm90b3R5cGUuX19pdGVyYXRlID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHtcbiAgICAgIHJldHVybiBzZXFJdGVyYXRlKHRoaXMsIGZuLCByZXZlcnNlLCB0cnVlKTtcbiAgICB9O1xuXG4gICAgLy8gYWJzdHJhY3QgX19pdGVyYXRvclVuY2FjaGVkKHR5cGUsIHJldmVyc2UpXG5cbiAgICBTZXEucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICByZXR1cm4gc2VxSXRlcmF0b3IodGhpcywgdHlwZSwgcmV2ZXJzZSwgdHJ1ZSk7XG4gICAgfTtcblxuXG5cbiAgY3JlYXRlQ2xhc3MoS2V5ZWRTZXEsIFNlcSk7XG4gICAgZnVuY3Rpb24gS2V5ZWRTZXEodmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkID9cbiAgICAgICAgZW1wdHlTZXF1ZW5jZSgpLnRvS2V5ZWRTZXEoKSA6XG4gICAgICAgIGlzSXRlcmFibGUodmFsdWUpID9cbiAgICAgICAgICAoaXNLZXllZCh2YWx1ZSkgPyB2YWx1ZS50b1NlcSgpIDogdmFsdWUuZnJvbUVudHJ5U2VxKCkpIDpcbiAgICAgICAgICBrZXllZFNlcUZyb21WYWx1ZSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgS2V5ZWRTZXEucHJvdG90eXBlLnRvS2V5ZWRTZXEgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cblxuXG4gIGNyZWF0ZUNsYXNzKEluZGV4ZWRTZXEsIFNlcSk7XG4gICAgZnVuY3Rpb24gSW5kZXhlZFNlcSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgPyBlbXB0eVNlcXVlbmNlKCkgOlxuICAgICAgICAhaXNJdGVyYWJsZSh2YWx1ZSkgPyBpbmRleGVkU2VxRnJvbVZhbHVlKHZhbHVlKSA6XG4gICAgICAgIGlzS2V5ZWQodmFsdWUpID8gdmFsdWUuZW50cnlTZXEoKSA6IHZhbHVlLnRvSW5kZXhlZFNlcSgpO1xuICAgIH1cblxuICAgIEluZGV4ZWRTZXEub2YgPSBmdW5jdGlvbigvKi4uLnZhbHVlcyovKSB7XG4gICAgICByZXR1cm4gSW5kZXhlZFNlcShhcmd1bWVudHMpO1xuICAgIH07XG5cbiAgICBJbmRleGVkU2VxLnByb3RvdHlwZS50b0luZGV4ZWRTZXEgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBJbmRleGVkU2VxLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX190b1N0cmluZygnU2VxIFsnLCAnXScpO1xuICAgIH07XG5cbiAgICBJbmRleGVkU2VxLnByb3RvdHlwZS5fX2l0ZXJhdGUgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge1xuICAgICAgcmV0dXJuIHNlcUl0ZXJhdGUodGhpcywgZm4sIHJldmVyc2UsIGZhbHNlKTtcbiAgICB9O1xuXG4gICAgSW5kZXhlZFNlcS5wcm90b3R5cGUuX19pdGVyYXRvciA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIHJldHVybiBzZXFJdGVyYXRvcih0aGlzLCB0eXBlLCByZXZlcnNlLCBmYWxzZSk7XG4gICAgfTtcblxuXG5cbiAgY3JlYXRlQ2xhc3MoU2V0U2VxLCBTZXEpO1xuICAgIGZ1bmN0aW9uIFNldFNlcSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCA/IGVtcHR5U2VxdWVuY2UoKSA6XG4gICAgICAgICFpc0l0ZXJhYmxlKHZhbHVlKSA/IGluZGV4ZWRTZXFGcm9tVmFsdWUodmFsdWUpIDpcbiAgICAgICAgaXNLZXllZCh2YWx1ZSkgPyB2YWx1ZS5lbnRyeVNlcSgpIDogdmFsdWVcbiAgICAgICkudG9TZXRTZXEoKTtcbiAgICB9XG5cbiAgICBTZXRTZXEub2YgPSBmdW5jdGlvbigvKi4uLnZhbHVlcyovKSB7XG4gICAgICByZXR1cm4gU2V0U2VxKGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIFNldFNlcS5wcm90b3R5cGUudG9TZXRTZXEgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cblxuXG4gIFNlcS5pc1NlcSA9IGlzU2VxO1xuICBTZXEuS2V5ZWQgPSBLZXllZFNlcTtcbiAgU2VxLlNldCA9IFNldFNlcTtcbiAgU2VxLkluZGV4ZWQgPSBJbmRleGVkU2VxO1xuXG4gIHZhciBJU19TRVFfU0VOVElORUwgPSAnQEBfX0lNTVVUQUJMRV9TRVFfX0BAJztcblxuICBTZXEucHJvdG90eXBlW0lTX1NFUV9TRU5USU5FTF0gPSB0cnVlO1xuXG5cblxuICBjcmVhdGVDbGFzcyhBcnJheVNlcSwgSW5kZXhlZFNlcSk7XG4gICAgZnVuY3Rpb24gQXJyYXlTZXEoYXJyYXkpIHtcbiAgICAgIHRoaXMuX2FycmF5ID0gYXJyYXk7XG4gICAgICB0aGlzLnNpemUgPSBhcnJheS5sZW5ndGg7XG4gICAgfVxuXG4gICAgQXJyYXlTZXEucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKGluZGV4LCBub3RTZXRWYWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuaGFzKGluZGV4KSA/IHRoaXMuX2FycmF5W3dyYXBJbmRleCh0aGlzLCBpbmRleCldIDogbm90U2V0VmFsdWU7XG4gICAgfTtcblxuICAgIEFycmF5U2VxLnByb3RvdHlwZS5fX2l0ZXJhdGUgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge1xuICAgICAgdmFyIGFycmF5ID0gdGhpcy5fYXJyYXk7XG4gICAgICB2YXIgbWF4SW5kZXggPSBhcnJheS5sZW5ndGggLSAxO1xuICAgICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8PSBtYXhJbmRleDsgaWkrKykge1xuICAgICAgICBpZiAoZm4oYXJyYXlbcmV2ZXJzZSA/IG1heEluZGV4IC0gaWkgOiBpaV0sIGlpLCB0aGlzKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICByZXR1cm4gaWkgKyAxO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gaWk7XG4gICAgfTtcblxuICAgIEFycmF5U2VxLnByb3RvdHlwZS5fX2l0ZXJhdG9yID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgdmFyIGFycmF5ID0gdGhpcy5fYXJyYXk7XG4gICAgICB2YXIgbWF4SW5kZXggPSBhcnJheS5sZW5ndGggLSAxO1xuICAgICAgdmFyIGlpID0gMDtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSBcbiAgICAgICAge3JldHVybiBpaSA+IG1heEluZGV4ID9cbiAgICAgICAgICBpdGVyYXRvckRvbmUoKSA6XG4gICAgICAgICAgaXRlcmF0b3JWYWx1ZSh0eXBlLCBpaSwgYXJyYXlbcmV2ZXJzZSA/IG1heEluZGV4IC0gaWkrKyA6IGlpKytdKX1cbiAgICAgICk7XG4gICAgfTtcblxuXG5cbiAgY3JlYXRlQ2xhc3MoT2JqZWN0U2VxLCBLZXllZFNlcSk7XG4gICAgZnVuY3Rpb24gT2JqZWN0U2VxKG9iamVjdCkge1xuICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuICAgICAgdGhpcy5fb2JqZWN0ID0gb2JqZWN0O1xuICAgICAgdGhpcy5fa2V5cyA9IGtleXM7XG4gICAgICB0aGlzLnNpemUgPSBrZXlzLmxlbmd0aDtcbiAgICB9XG5cbiAgICBPYmplY3RTZXEucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKGtleSwgbm90U2V0VmFsdWUpIHtcbiAgICAgIGlmIChub3RTZXRWYWx1ZSAhPT0gdW5kZWZpbmVkICYmICF0aGlzLmhhcyhrZXkpKSB7XG4gICAgICAgIHJldHVybiBub3RTZXRWYWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLl9vYmplY3Rba2V5XTtcbiAgICB9O1xuXG4gICAgT2JqZWN0U2VxLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9vYmplY3QuaGFzT3duUHJvcGVydHkoa2V5KTtcbiAgICB9O1xuXG4gICAgT2JqZWN0U2VxLnByb3RvdHlwZS5fX2l0ZXJhdGUgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge1xuICAgICAgdmFyIG9iamVjdCA9IHRoaXMuX29iamVjdDtcbiAgICAgIHZhciBrZXlzID0gdGhpcy5fa2V5cztcbiAgICAgIHZhciBtYXhJbmRleCA9IGtleXMubGVuZ3RoIC0gMTtcbiAgICAgIGZvciAodmFyIGlpID0gMDsgaWkgPD0gbWF4SW5kZXg7IGlpKyspIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXNbcmV2ZXJzZSA/IG1heEluZGV4IC0gaWkgOiBpaV07XG4gICAgICAgIGlmIChmbihvYmplY3Rba2V5XSwga2V5LCB0aGlzKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICByZXR1cm4gaWkgKyAxO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gaWk7XG4gICAgfTtcblxuICAgIE9iamVjdFNlcS5wcm90b3R5cGUuX19pdGVyYXRvciA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIHZhciBvYmplY3QgPSB0aGlzLl9vYmplY3Q7XG4gICAgICB2YXIga2V5cyA9IHRoaXMuX2tleXM7XG4gICAgICB2YXIgbWF4SW5kZXggPSBrZXlzLmxlbmd0aCAtIDE7XG4gICAgICB2YXIgaWkgPSAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHZhciBrZXkgPSBrZXlzW3JldmVyc2UgPyBtYXhJbmRleCAtIGlpIDogaWldO1xuICAgICAgICByZXR1cm4gaWkrKyA+IG1heEluZGV4ID9cbiAgICAgICAgICBpdGVyYXRvckRvbmUoKSA6XG4gICAgICAgICAgaXRlcmF0b3JWYWx1ZSh0eXBlLCBrZXksIG9iamVjdFtrZXldKTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgT2JqZWN0U2VxLnByb3RvdHlwZVtJU19PUkRFUkVEX1NFTlRJTkVMXSA9IHRydWU7XG5cblxuICBjcmVhdGVDbGFzcyhJdGVyYWJsZVNlcSwgSW5kZXhlZFNlcSk7XG4gICAgZnVuY3Rpb24gSXRlcmFibGVTZXEoaXRlcmFibGUpIHtcbiAgICAgIHRoaXMuX2l0ZXJhYmxlID0gaXRlcmFibGU7XG4gICAgICB0aGlzLnNpemUgPSBpdGVyYWJsZS5sZW5ndGggfHwgaXRlcmFibGUuc2l6ZTtcbiAgICB9XG5cbiAgICBJdGVyYWJsZVNlcS5wcm90b3R5cGUuX19pdGVyYXRlVW5jYWNoZWQgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge1xuICAgICAgaWYgKHJldmVyc2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FjaGVSZXN1bHQoKS5fX2l0ZXJhdGUoZm4sIHJldmVyc2UpO1xuICAgICAgfVxuICAgICAgdmFyIGl0ZXJhYmxlID0gdGhpcy5faXRlcmFibGU7XG4gICAgICB2YXIgaXRlcmF0b3IgPSBnZXRJdGVyYXRvcihpdGVyYWJsZSk7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICBpZiAoaXNJdGVyYXRvcihpdGVyYXRvcikpIHtcbiAgICAgICAgdmFyIHN0ZXA7XG4gICAgICAgIHdoaWxlICghKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmUpIHtcbiAgICAgICAgICBpZiAoZm4oc3RlcC52YWx1ZSwgaXRlcmF0aW9ucysrLCB0aGlzKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGl0ZXJhdGlvbnM7XG4gICAgfTtcblxuICAgIEl0ZXJhYmxlU2VxLnByb3RvdHlwZS5fX2l0ZXJhdG9yVW5jYWNoZWQgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZVJlc3VsdCgpLl9faXRlcmF0b3IodHlwZSwgcmV2ZXJzZSk7XG4gICAgICB9XG4gICAgICB2YXIgaXRlcmFibGUgPSB0aGlzLl9pdGVyYWJsZTtcbiAgICAgIHZhciBpdGVyYXRvciA9IGdldEl0ZXJhdG9yKGl0ZXJhYmxlKTtcbiAgICAgIGlmICghaXNJdGVyYXRvcihpdGVyYXRvcikpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihpdGVyYXRvckRvbmUpO1xuICAgICAgfVxuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHZhciBzdGVwID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICByZXR1cm4gc3RlcC5kb25lID8gc3RlcCA6IGl0ZXJhdG9yVmFsdWUodHlwZSwgaXRlcmF0aW9ucysrLCBzdGVwLnZhbHVlKTtcbiAgICAgIH0pO1xuICAgIH07XG5cblxuXG4gIGNyZWF0ZUNsYXNzKEl0ZXJhdG9yU2VxLCBJbmRleGVkU2VxKTtcbiAgICBmdW5jdGlvbiBJdGVyYXRvclNlcShpdGVyYXRvcikge1xuICAgICAgdGhpcy5faXRlcmF0b3IgPSBpdGVyYXRvcjtcbiAgICAgIHRoaXMuX2l0ZXJhdG9yQ2FjaGUgPSBbXTtcbiAgICB9XG5cbiAgICBJdGVyYXRvclNlcS5wcm90b3R5cGUuX19pdGVyYXRlVW5jYWNoZWQgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge1xuICAgICAgaWYgKHJldmVyc2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FjaGVSZXN1bHQoKS5fX2l0ZXJhdGUoZm4sIHJldmVyc2UpO1xuICAgICAgfVxuICAgICAgdmFyIGl0ZXJhdG9yID0gdGhpcy5faXRlcmF0b3I7XG4gICAgICB2YXIgY2FjaGUgPSB0aGlzLl9pdGVyYXRvckNhY2hlO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgd2hpbGUgKGl0ZXJhdGlvbnMgPCBjYWNoZS5sZW5ndGgpIHtcbiAgICAgICAgaWYgKGZuKGNhY2hlW2l0ZXJhdGlvbnNdLCBpdGVyYXRpb25zKyssIHRoaXMpID09PSBmYWxzZSkge1xuICAgICAgICAgIHJldHVybiBpdGVyYXRpb25zO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB2YXIgc3RlcDtcbiAgICAgIHdoaWxlICghKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmUpIHtcbiAgICAgICAgdmFyIHZhbCA9IHN0ZXAudmFsdWU7XG4gICAgICAgIGNhY2hlW2l0ZXJhdGlvbnNdID0gdmFsO1xuICAgICAgICBpZiAoZm4odmFsLCBpdGVyYXRpb25zKyssIHRoaXMpID09PSBmYWxzZSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gaXRlcmF0aW9ucztcbiAgICB9O1xuXG4gICAgSXRlcmF0b3JTZXEucHJvdG90eXBlLl9faXRlcmF0b3JVbmNhY2hlZCA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlUmVzdWx0KCkuX19pdGVyYXRvcih0eXBlLCByZXZlcnNlKTtcbiAgICAgIH1cbiAgICAgIHZhciBpdGVyYXRvciA9IHRoaXMuX2l0ZXJhdG9yO1xuICAgICAgdmFyIGNhY2hlID0gdGhpcy5faXRlcmF0b3JDYWNoZTtcbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSAge1xuICAgICAgICBpZiAoaXRlcmF0aW9ucyA+PSBjYWNoZS5sZW5ndGgpIHtcbiAgICAgICAgICB2YXIgc3RlcCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgICBpZiAoc3RlcC5kb25lKSB7XG4gICAgICAgICAgICByZXR1cm4gc3RlcDtcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FjaGVbaXRlcmF0aW9uc10gPSBzdGVwLnZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpdGVyYXRvclZhbHVlKHR5cGUsIGl0ZXJhdGlvbnMsIGNhY2hlW2l0ZXJhdGlvbnMrK10pO1xuICAgICAgfSk7XG4gICAgfTtcblxuXG5cblxuICAvLyAjIHByYWdtYSBIZWxwZXIgZnVuY3Rpb25zXG5cbiAgZnVuY3Rpb24gaXNTZXEobWF5YmVTZXEpIHtcbiAgICByZXR1cm4gISEobWF5YmVTZXEgJiYgbWF5YmVTZXFbSVNfU0VRX1NFTlRJTkVMXSk7XG4gIH1cblxuICB2YXIgRU1QVFlfU0VRO1xuXG4gIGZ1bmN0aW9uIGVtcHR5U2VxdWVuY2UoKSB7XG4gICAgcmV0dXJuIEVNUFRZX1NFUSB8fCAoRU1QVFlfU0VRID0gbmV3IEFycmF5U2VxKFtdKSk7XG4gIH1cblxuICBmdW5jdGlvbiBrZXllZFNlcUZyb21WYWx1ZSh2YWx1ZSkge1xuICAgIHZhciBzZXEgPVxuICAgICAgQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyBuZXcgQXJyYXlTZXEodmFsdWUpLmZyb21FbnRyeVNlcSgpIDpcbiAgICAgIGlzSXRlcmF0b3IodmFsdWUpID8gbmV3IEl0ZXJhdG9yU2VxKHZhbHVlKS5mcm9tRW50cnlTZXEoKSA6XG4gICAgICBoYXNJdGVyYXRvcih2YWx1ZSkgPyBuZXcgSXRlcmFibGVTZXEodmFsdWUpLmZyb21FbnRyeVNlcSgpIDpcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgPyBuZXcgT2JqZWN0U2VxKHZhbHVlKSA6XG4gICAgICB1bmRlZmluZWQ7XG4gICAgaWYgKCFzZXEpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICdFeHBlY3RlZCBBcnJheSBvciBpdGVyYWJsZSBvYmplY3Qgb2YgW2ssIHZdIGVudHJpZXMsICcrXG4gICAgICAgICdvciBrZXllZCBvYmplY3Q6ICcgKyB2YWx1ZVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHNlcTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluZGV4ZWRTZXFGcm9tVmFsdWUodmFsdWUpIHtcbiAgICB2YXIgc2VxID0gbWF5YmVJbmRleGVkU2VxRnJvbVZhbHVlKHZhbHVlKTtcbiAgICBpZiAoIXNlcSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgJ0V4cGVjdGVkIEFycmF5IG9yIGl0ZXJhYmxlIG9iamVjdCBvZiB2YWx1ZXM6ICcgKyB2YWx1ZVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHNlcTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNlcUZyb21WYWx1ZSh2YWx1ZSkge1xuICAgIHZhciBzZXEgPSBtYXliZUluZGV4ZWRTZXFGcm9tVmFsdWUodmFsdWUpIHx8XG4gICAgICAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiBuZXcgT2JqZWN0U2VxKHZhbHVlKSk7XG4gICAgaWYgKCFzZXEpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICdFeHBlY3RlZCBBcnJheSBvciBpdGVyYWJsZSBvYmplY3Qgb2YgdmFsdWVzLCBvciBrZXllZCBvYmplY3Q6ICcgKyB2YWx1ZVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHNlcTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1heWJlSW5kZXhlZFNlcUZyb21WYWx1ZSh2YWx1ZSkge1xuICAgIHJldHVybiAoXG4gICAgICBpc0FycmF5TGlrZSh2YWx1ZSkgPyBuZXcgQXJyYXlTZXEodmFsdWUpIDpcbiAgICAgIGlzSXRlcmF0b3IodmFsdWUpID8gbmV3IEl0ZXJhdG9yU2VxKHZhbHVlKSA6XG4gICAgICBoYXNJdGVyYXRvcih2YWx1ZSkgPyBuZXcgSXRlcmFibGVTZXEodmFsdWUpIDpcbiAgICAgIHVuZGVmaW5lZFxuICAgICk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXFJdGVyYXRlKHNlcSwgZm4sIHJldmVyc2UsIHVzZUtleXMpIHtcbiAgICB2YXIgY2FjaGUgPSBzZXEuX2NhY2hlO1xuICAgIGlmIChjYWNoZSkge1xuICAgICAgdmFyIG1heEluZGV4ID0gY2FjaGUubGVuZ3RoIC0gMTtcbiAgICAgIGZvciAodmFyIGlpID0gMDsgaWkgPD0gbWF4SW5kZXg7IGlpKyspIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gY2FjaGVbcmV2ZXJzZSA/IG1heEluZGV4IC0gaWkgOiBpaV07XG4gICAgICAgIGlmIChmbihlbnRyeVsxXSwgdXNlS2V5cyA/IGVudHJ5WzBdIDogaWksIHNlcSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgcmV0dXJuIGlpICsgMTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGlpO1xuICAgIH1cbiAgICByZXR1cm4gc2VxLl9faXRlcmF0ZVVuY2FjaGVkKGZuLCByZXZlcnNlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNlcUl0ZXJhdG9yKHNlcSwgdHlwZSwgcmV2ZXJzZSwgdXNlS2V5cykge1xuICAgIHZhciBjYWNoZSA9IHNlcS5fY2FjaGU7XG4gICAgaWYgKGNhY2hlKSB7XG4gICAgICB2YXIgbWF4SW5kZXggPSBjYWNoZS5sZW5ndGggLSAxO1xuICAgICAgdmFyIGlpID0gMDtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSAge1xuICAgICAgICB2YXIgZW50cnkgPSBjYWNoZVtyZXZlcnNlID8gbWF4SW5kZXggLSBpaSA6IGlpXTtcbiAgICAgICAgcmV0dXJuIGlpKysgPiBtYXhJbmRleCA/XG4gICAgICAgICAgaXRlcmF0b3JEb25lKCkgOlxuICAgICAgICAgIGl0ZXJhdG9yVmFsdWUodHlwZSwgdXNlS2V5cyA/IGVudHJ5WzBdIDogaWkgLSAxLCBlbnRyeVsxXSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHNlcS5fX2l0ZXJhdG9yVW5jYWNoZWQodHlwZSwgcmV2ZXJzZSk7XG4gIH1cblxuICBmdW5jdGlvbiBmcm9tSlMoanNvbiwgY29udmVydGVyKSB7XG4gICAgcmV0dXJuIGNvbnZlcnRlciA/XG4gICAgICBmcm9tSlNXaXRoKGNvbnZlcnRlciwganNvbiwgJycsIHsnJzoganNvbn0pIDpcbiAgICAgIGZyb21KU0RlZmF1bHQoanNvbik7XG4gIH1cblxuICBmdW5jdGlvbiBmcm9tSlNXaXRoKGNvbnZlcnRlciwganNvbiwga2V5LCBwYXJlbnRKU09OKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoanNvbikpIHtcbiAgICAgIHJldHVybiBjb252ZXJ0ZXIuY2FsbChwYXJlbnRKU09OLCBrZXksIEluZGV4ZWRTZXEoanNvbikubWFwKGZ1bmN0aW9uKHYsIGspICB7cmV0dXJuIGZyb21KU1dpdGgoY29udmVydGVyLCB2LCBrLCBqc29uKX0pKTtcbiAgICB9XG4gICAgaWYgKGlzUGxhaW5PYmooanNvbikpIHtcbiAgICAgIHJldHVybiBjb252ZXJ0ZXIuY2FsbChwYXJlbnRKU09OLCBrZXksIEtleWVkU2VxKGpzb24pLm1hcChmdW5jdGlvbih2LCBrKSAge3JldHVybiBmcm9tSlNXaXRoKGNvbnZlcnRlciwgdiwgaywganNvbil9KSk7XG4gICAgfVxuICAgIHJldHVybiBqc29uO1xuICB9XG5cbiAgZnVuY3Rpb24gZnJvbUpTRGVmYXVsdChqc29uKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoanNvbikpIHtcbiAgICAgIHJldHVybiBJbmRleGVkU2VxKGpzb24pLm1hcChmcm9tSlNEZWZhdWx0KS50b0xpc3QoKTtcbiAgICB9XG4gICAgaWYgKGlzUGxhaW5PYmooanNvbikpIHtcbiAgICAgIHJldHVybiBLZXllZFNlcShqc29uKS5tYXAoZnJvbUpTRGVmYXVsdCkudG9NYXAoKTtcbiAgICB9XG4gICAgcmV0dXJuIGpzb247XG4gIH1cblxuICBmdW5jdGlvbiBpc1BsYWluT2JqKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlICYmICh2YWx1ZS5jb25zdHJ1Y3RvciA9PT0gT2JqZWN0IHx8IHZhbHVlLmNvbnN0cnVjdG9yID09PSB1bmRlZmluZWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFuIGV4dGVuc2lvbiBvZiB0aGUgXCJzYW1lLXZhbHVlXCIgYWxnb3JpdGhtIGFzIFtkZXNjcmliZWQgZm9yIHVzZSBieSBFUzYgTWFwXG4gICAqIGFuZCBTZXRdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL01hcCNLZXlfZXF1YWxpdHkpXG4gICAqXG4gICAqIE5hTiBpcyBjb25zaWRlcmVkIHRoZSBzYW1lIGFzIE5hTiwgaG93ZXZlciAtMCBhbmQgMCBhcmUgY29uc2lkZXJlZCB0aGUgc2FtZVxuICAgKiB2YWx1ZSwgd2hpY2ggaXMgZGlmZmVyZW50IGZyb20gdGhlIGFsZ29yaXRobSBkZXNjcmliZWQgYnlcbiAgICogW2BPYmplY3QuaXNgXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9PYmplY3QvaXMpLlxuICAgKlxuICAgKiBUaGlzIGlzIGV4dGVuZGVkIGZ1cnRoZXIgdG8gYWxsb3cgT2JqZWN0cyB0byBkZXNjcmliZSB0aGUgdmFsdWVzIHRoZXlcbiAgICogcmVwcmVzZW50LCBieSB3YXkgb2YgYHZhbHVlT2ZgIG9yIGBlcXVhbHNgIChhbmQgYGhhc2hDb2RlYCkuXG4gICAqXG4gICAqIE5vdGU6IGJlY2F1c2Ugb2YgdGhpcyBleHRlbnNpb24sIHRoZSBrZXkgZXF1YWxpdHkgb2YgSW1tdXRhYmxlLk1hcCBhbmQgdGhlXG4gICAqIHZhbHVlIGVxdWFsaXR5IG9mIEltbXV0YWJsZS5TZXQgd2lsbCBkaWZmZXIgZnJvbSBFUzYgTWFwIGFuZCBTZXQuXG4gICAqXG4gICAqICMjIyBEZWZpbmluZyBjdXN0b20gdmFsdWVzXG4gICAqXG4gICAqIFRoZSBlYXNpZXN0IHdheSB0byBkZXNjcmliZSB0aGUgdmFsdWUgYW4gb2JqZWN0IHJlcHJlc2VudHMgaXMgYnkgaW1wbGVtZW50aW5nXG4gICAqIGB2YWx1ZU9mYC4gRm9yIGV4YW1wbGUsIGBEYXRlYCByZXByZXNlbnRzIGEgdmFsdWUgYnkgcmV0dXJuaW5nIGEgdW5peFxuICAgKiB0aW1lc3RhbXAgZm9yIGB2YWx1ZU9mYDpcbiAgICpcbiAgICogICAgIHZhciBkYXRlMSA9IG5ldyBEYXRlKDEyMzQ1Njc4OTAwMDApOyAvLyBGcmkgRmViIDEzIDIwMDkgLi4uXG4gICAqICAgICB2YXIgZGF0ZTIgPSBuZXcgRGF0ZSgxMjM0NTY3ODkwMDAwKTtcbiAgICogICAgIGRhdGUxLnZhbHVlT2YoKTsgLy8gMTIzNDU2Nzg5MDAwMFxuICAgKiAgICAgYXNzZXJ0KCBkYXRlMSAhPT0gZGF0ZTIgKTtcbiAgICogICAgIGFzc2VydCggSW1tdXRhYmxlLmlzKCBkYXRlMSwgZGF0ZTIgKSApO1xuICAgKlxuICAgKiBOb3RlOiBvdmVycmlkaW5nIGB2YWx1ZU9mYCBtYXkgaGF2ZSBvdGhlciBpbXBsaWNhdGlvbnMgaWYgeW91IHVzZSB0aGlzIG9iamVjdFxuICAgKiB3aGVyZSBKYXZhU2NyaXB0IGV4cGVjdHMgYSBwcmltaXRpdmUsIHN1Y2ggYXMgaW1wbGljaXQgc3RyaW5nIGNvZXJjaW9uLlxuICAgKlxuICAgKiBGb3IgbW9yZSBjb21wbGV4IHR5cGVzLCBlc3BlY2lhbGx5IGNvbGxlY3Rpb25zLCBpbXBsZW1lbnRpbmcgYHZhbHVlT2ZgIG1heVxuICAgKiBub3QgYmUgcGVyZm9ybWFudC4gQW4gYWx0ZXJuYXRpdmUgaXMgdG8gaW1wbGVtZW50IGBlcXVhbHNgIGFuZCBgaGFzaENvZGVgLlxuICAgKlxuICAgKiBgZXF1YWxzYCB0YWtlcyBhbm90aGVyIG9iamVjdCwgcHJlc3VtYWJseSBvZiBzaW1pbGFyIHR5cGUsIGFuZCByZXR1cm5zIHRydWVcbiAgICogaWYgdGhlIGl0IGlzIGVxdWFsLiBFcXVhbGl0eSBpcyBzeW1tZXRyaWNhbCwgc28gdGhlIHNhbWUgcmVzdWx0IHNob3VsZCBiZVxuICAgKiByZXR1cm5lZCBpZiB0aGlzIGFuZCB0aGUgYXJndW1lbnQgYXJlIGZsaXBwZWQuXG4gICAqXG4gICAqICAgICBhc3NlcnQoIGEuZXF1YWxzKGIpID09PSBiLmVxdWFscyhhKSApO1xuICAgKlxuICAgKiBgaGFzaENvZGVgIHJldHVybnMgYSAzMmJpdCBpbnRlZ2VyIG51bWJlciByZXByZXNlbnRpbmcgdGhlIG9iamVjdCB3aGljaCB3aWxsXG4gICAqIGJlIHVzZWQgdG8gZGV0ZXJtaW5lIGhvdyB0byBzdG9yZSB0aGUgdmFsdWUgb2JqZWN0IGluIGEgTWFwIG9yIFNldC4gWW91IG11c3RcbiAgICogcHJvdmlkZSBib3RoIG9yIG5laXRoZXIgbWV0aG9kcywgb25lIG11c3Qgbm90IGV4aXN0IHdpdGhvdXQgdGhlIG90aGVyLlxuICAgKlxuICAgKiBBbHNvLCBhbiBpbXBvcnRhbnQgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlc2UgbWV0aG9kcyBtdXN0IGJlIHVwaGVsZDogaWYgdHdvXG4gICAqIHZhbHVlcyBhcmUgZXF1YWwsIHRoZXkgKm11c3QqIHJldHVybiB0aGUgc2FtZSBoYXNoQ29kZS4gSWYgdGhlIHZhbHVlcyBhcmUgbm90XG4gICAqIGVxdWFsLCB0aGV5IG1pZ2h0IGhhdmUgdGhlIHNhbWUgaGFzaENvZGU7IHRoaXMgaXMgY2FsbGVkIGEgaGFzaCBjb2xsaXNpb24sXG4gICAqIGFuZCB3aGlsZSB1bmRlc2lyYWJsZSBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucywgaXQgaXMgYWNjZXB0YWJsZS5cbiAgICpcbiAgICogICAgIGlmIChhLmVxdWFscyhiKSkge1xuICAgKiAgICAgICBhc3NlcnQoIGEuaGFzaENvZGUoKSA9PT0gYi5oYXNoQ29kZSgpICk7XG4gICAqICAgICB9XG4gICAqXG4gICAqIEFsbCBJbW11dGFibGUgY29sbGVjdGlvbnMgaW1wbGVtZW50IGBlcXVhbHNgIGFuZCBgaGFzaENvZGVgLlxuICAgKlxuICAgKi9cbiAgZnVuY3Rpb24gaXModmFsdWVBLCB2YWx1ZUIpIHtcbiAgICBpZiAodmFsdWVBID09PSB2YWx1ZUIgfHwgKHZhbHVlQSAhPT0gdmFsdWVBICYmIHZhbHVlQiAhPT0gdmFsdWVCKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmICghdmFsdWVBIHx8ICF2YWx1ZUIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB2YWx1ZUEudmFsdWVPZiA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgICB0eXBlb2YgdmFsdWVCLnZhbHVlT2YgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhbHVlQSA9IHZhbHVlQS52YWx1ZU9mKCk7XG4gICAgICB2YWx1ZUIgPSB2YWx1ZUIudmFsdWVPZigpO1xuICAgICAgaWYgKHZhbHVlQSA9PT0gdmFsdWVCIHx8ICh2YWx1ZUEgIT09IHZhbHVlQSAmJiB2YWx1ZUIgIT09IHZhbHVlQikpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBpZiAoIXZhbHVlQSB8fCAhdmFsdWVCKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHR5cGVvZiB2YWx1ZUEuZXF1YWxzID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgIHR5cGVvZiB2YWx1ZUIuZXF1YWxzID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgIHZhbHVlQS5lcXVhbHModmFsdWVCKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlZXBFcXVhbChhLCBiKSB7XG4gICAgaWYgKGEgPT09IGIpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgICFpc0l0ZXJhYmxlKGIpIHx8XG4gICAgICBhLnNpemUgIT09IHVuZGVmaW5lZCAmJiBiLnNpemUgIT09IHVuZGVmaW5lZCAmJiBhLnNpemUgIT09IGIuc2l6ZSB8fFxuICAgICAgYS5fX2hhc2ggIT09IHVuZGVmaW5lZCAmJiBiLl9faGFzaCAhPT0gdW5kZWZpbmVkICYmIGEuX19oYXNoICE9PSBiLl9faGFzaCB8fFxuICAgICAgaXNLZXllZChhKSAhPT0gaXNLZXllZChiKSB8fFxuICAgICAgaXNJbmRleGVkKGEpICE9PSBpc0luZGV4ZWQoYikgfHxcbiAgICAgIGlzT3JkZXJlZChhKSAhPT0gaXNPcmRlcmVkKGIpXG4gICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKGEuc2l6ZSA9PT0gMCAmJiBiLnNpemUgPT09IDApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHZhciBub3RBc3NvY2lhdGl2ZSA9ICFpc0Fzc29jaWF0aXZlKGEpO1xuXG4gICAgaWYgKGlzT3JkZXJlZChhKSkge1xuICAgICAgdmFyIGVudHJpZXMgPSBhLmVudHJpZXMoKTtcbiAgICAgIHJldHVybiBiLmV2ZXJ5KGZ1bmN0aW9uKHYsIGspICB7XG4gICAgICAgIHZhciBlbnRyeSA9IGVudHJpZXMubmV4dCgpLnZhbHVlO1xuICAgICAgICByZXR1cm4gZW50cnkgJiYgaXMoZW50cnlbMV0sIHYpICYmIChub3RBc3NvY2lhdGl2ZSB8fCBpcyhlbnRyeVswXSwgaykpO1xuICAgICAgfSkgJiYgZW50cmllcy5uZXh0KCkuZG9uZTtcbiAgICB9XG5cbiAgICB2YXIgZmxpcHBlZCA9IGZhbHNlO1xuXG4gICAgaWYgKGEuc2l6ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoYi5zaXplID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBhLmNhY2hlUmVzdWx0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgYS5jYWNoZVJlc3VsdCgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmbGlwcGVkID0gdHJ1ZTtcbiAgICAgICAgdmFyIF8gPSBhO1xuICAgICAgICBhID0gYjtcbiAgICAgICAgYiA9IF87XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGFsbEVxdWFsID0gdHJ1ZTtcbiAgICB2YXIgYlNpemUgPSBiLl9faXRlcmF0ZShmdW5jdGlvbih2LCBrKSAge1xuICAgICAgaWYgKG5vdEFzc29jaWF0aXZlID8gIWEuaGFzKHYpIDpcbiAgICAgICAgICBmbGlwcGVkID8gIWlzKHYsIGEuZ2V0KGssIE5PVF9TRVQpKSA6ICFpcyhhLmdldChrLCBOT1RfU0VUKSwgdikpIHtcbiAgICAgICAgYWxsRXF1YWwgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGFsbEVxdWFsICYmIGEuc2l6ZSA9PT0gYlNpemU7XG4gIH1cblxuICBjcmVhdGVDbGFzcyhSZXBlYXQsIEluZGV4ZWRTZXEpO1xuXG4gICAgZnVuY3Rpb24gUmVwZWF0KHZhbHVlLCB0aW1lcykge1xuICAgICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJlcGVhdCkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXBlYXQodmFsdWUsIHRpbWVzKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX3ZhbHVlID0gdmFsdWU7XG4gICAgICB0aGlzLnNpemUgPSB0aW1lcyA9PT0gdW5kZWZpbmVkID8gSW5maW5pdHkgOiBNYXRoLm1heCgwLCB0aW1lcyk7XG4gICAgICBpZiAodGhpcy5zaXplID09PSAwKSB7XG4gICAgICAgIGlmIChFTVBUWV9SRVBFQVQpIHtcbiAgICAgICAgICByZXR1cm4gRU1QVFlfUkVQRUFUO1xuICAgICAgICB9XG4gICAgICAgIEVNUFRZX1JFUEVBVCA9IHRoaXM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgUmVwZWF0LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuc2l6ZSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gJ1JlcGVhdCBbXSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gJ1JlcGVhdCBbICcgKyB0aGlzLl92YWx1ZSArICcgJyArIHRoaXMuc2l6ZSArICcgdGltZXMgXSc7XG4gICAgfTtcblxuICAgIFJlcGVhdC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oaW5kZXgsIG5vdFNldFZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5oYXMoaW5kZXgpID8gdGhpcy5fdmFsdWUgOiBub3RTZXRWYWx1ZTtcbiAgICB9O1xuXG4gICAgUmVwZWF0LnByb3RvdHlwZS5pbmNsdWRlcyA9IGZ1bmN0aW9uKHNlYXJjaFZhbHVlKSB7XG4gICAgICByZXR1cm4gaXModGhpcy5fdmFsdWUsIHNlYXJjaFZhbHVlKTtcbiAgICB9O1xuXG4gICAgUmVwZWF0LnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcbiAgICAgIHZhciBzaXplID0gdGhpcy5zaXplO1xuICAgICAgcmV0dXJuIHdob2xlU2xpY2UoYmVnaW4sIGVuZCwgc2l6ZSkgPyB0aGlzIDpcbiAgICAgICAgbmV3IFJlcGVhdCh0aGlzLl92YWx1ZSwgcmVzb2x2ZUVuZChlbmQsIHNpemUpIC0gcmVzb2x2ZUJlZ2luKGJlZ2luLCBzaXplKSk7XG4gICAgfTtcblxuICAgIFJlcGVhdC5wcm90b3R5cGUucmV2ZXJzZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFJlcGVhdC5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uKHNlYXJjaFZhbHVlKSB7XG4gICAgICBpZiAoaXModGhpcy5fdmFsdWUsIHNlYXJjaFZhbHVlKSkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIHJldHVybiAtMTtcbiAgICB9O1xuXG4gICAgUmVwZWF0LnByb3RvdHlwZS5sYXN0SW5kZXhPZiA9IGZ1bmN0aW9uKHNlYXJjaFZhbHVlKSB7XG4gICAgICBpZiAoaXModGhpcy5fdmFsdWUsIHNlYXJjaFZhbHVlKSkge1xuICAgICAgICByZXR1cm4gdGhpcy5zaXplO1xuICAgICAgfVxuICAgICAgcmV0dXJuIC0xO1xuICAgIH07XG5cbiAgICBSZXBlYXQucHJvdG90eXBlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7XG4gICAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgdGhpcy5zaXplOyBpaSsrKSB7XG4gICAgICAgIGlmIChmbih0aGlzLl92YWx1ZSwgaWksIHRoaXMpID09PSBmYWxzZSkge1xuICAgICAgICAgIHJldHVybiBpaSArIDE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBpaTtcbiAgICB9O1xuXG4gICAgUmVwZWF0LnByb3RvdHlwZS5fX2l0ZXJhdG9yID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgdmFyIGlpID0gMDtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSBcbiAgICAgICAge3JldHVybiBpaSA8IHRoaXMkMC5zaXplID8gaXRlcmF0b3JWYWx1ZSh0eXBlLCBpaSsrLCB0aGlzJDAuX3ZhbHVlKSA6IGl0ZXJhdG9yRG9uZSgpfVxuICAgICAgKTtcbiAgICB9O1xuXG4gICAgUmVwZWF0LnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbihvdGhlcikge1xuICAgICAgcmV0dXJuIG90aGVyIGluc3RhbmNlb2YgUmVwZWF0ID9cbiAgICAgICAgaXModGhpcy5fdmFsdWUsIG90aGVyLl92YWx1ZSkgOlxuICAgICAgICBkZWVwRXF1YWwob3RoZXIpO1xuICAgIH07XG5cblxuICB2YXIgRU1QVFlfUkVQRUFUO1xuXG4gIGZ1bmN0aW9uIGludmFyaWFudChjb25kaXRpb24sIGVycm9yKSB7XG4gICAgaWYgKCFjb25kaXRpb24pIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG4gIH1cblxuICBjcmVhdGVDbGFzcyhSYW5nZSwgSW5kZXhlZFNlcSk7XG5cbiAgICBmdW5jdGlvbiBSYW5nZShzdGFydCwgZW5kLCBzdGVwKSB7XG4gICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUmFuZ2UpKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmFuZ2Uoc3RhcnQsIGVuZCwgc3RlcCk7XG4gICAgICB9XG4gICAgICBpbnZhcmlhbnQoc3RlcCAhPT0gMCwgJ0Nhbm5vdCBzdGVwIGEgUmFuZ2UgYnkgMCcpO1xuICAgICAgc3RhcnQgPSBzdGFydCB8fCAwO1xuICAgICAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGVuZCA9IEluZmluaXR5O1xuICAgICAgfVxuICAgICAgc3RlcCA9IHN0ZXAgPT09IHVuZGVmaW5lZCA/IDEgOiBNYXRoLmFicyhzdGVwKTtcbiAgICAgIGlmIChlbmQgPCBzdGFydCkge1xuICAgICAgICBzdGVwID0gLXN0ZXA7XG4gICAgICB9XG4gICAgICB0aGlzLl9zdGFydCA9IHN0YXJ0O1xuICAgICAgdGhpcy5fZW5kID0gZW5kO1xuICAgICAgdGhpcy5fc3RlcCA9IHN0ZXA7XG4gICAgICB0aGlzLnNpemUgPSBNYXRoLm1heCgwLCBNYXRoLmNlaWwoKGVuZCAtIHN0YXJ0KSAvIHN0ZXAgLSAxKSArIDEpO1xuICAgICAgaWYgKHRoaXMuc2l6ZSA9PT0gMCkge1xuICAgICAgICBpZiAoRU1QVFlfUkFOR0UpIHtcbiAgICAgICAgICByZXR1cm4gRU1QVFlfUkFOR0U7XG4gICAgICAgIH1cbiAgICAgICAgRU1QVFlfUkFOR0UgPSB0aGlzO1xuICAgICAgfVxuICAgIH1cblxuICAgIFJhbmdlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuc2l6ZSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gJ1JhbmdlIFtdJztcbiAgICAgIH1cbiAgICAgIHJldHVybiAnUmFuZ2UgWyAnICtcbiAgICAgICAgdGhpcy5fc3RhcnQgKyAnLi4uJyArIHRoaXMuX2VuZCArXG4gICAgICAgICh0aGlzLl9zdGVwID4gMSA/ICcgYnkgJyArIHRoaXMuX3N0ZXAgOiAnJykgK1xuICAgICAgJyBdJztcbiAgICB9O1xuXG4gICAgUmFuZ2UucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKGluZGV4LCBub3RTZXRWYWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuaGFzKGluZGV4KSA/XG4gICAgICAgIHRoaXMuX3N0YXJ0ICsgd3JhcEluZGV4KHRoaXMsIGluZGV4KSAqIHRoaXMuX3N0ZXAgOlxuICAgICAgICBub3RTZXRWYWx1ZTtcbiAgICB9O1xuXG4gICAgUmFuZ2UucHJvdG90eXBlLmluY2x1ZGVzID0gZnVuY3Rpb24oc2VhcmNoVmFsdWUpIHtcbiAgICAgIHZhciBwb3NzaWJsZUluZGV4ID0gKHNlYXJjaFZhbHVlIC0gdGhpcy5fc3RhcnQpIC8gdGhpcy5fc3RlcDtcbiAgICAgIHJldHVybiBwb3NzaWJsZUluZGV4ID49IDAgJiZcbiAgICAgICAgcG9zc2libGVJbmRleCA8IHRoaXMuc2l6ZSAmJlxuICAgICAgICBwb3NzaWJsZUluZGV4ID09PSBNYXRoLmZsb29yKHBvc3NpYmxlSW5kZXgpO1xuICAgIH07XG5cbiAgICBSYW5nZS5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XG4gICAgICBpZiAod2hvbGVTbGljZShiZWdpbiwgZW5kLCB0aGlzLnNpemUpKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgYmVnaW4gPSByZXNvbHZlQmVnaW4oYmVnaW4sIHRoaXMuc2l6ZSk7XG4gICAgICBlbmQgPSByZXNvbHZlRW5kKGVuZCwgdGhpcy5zaXplKTtcbiAgICAgIGlmIChlbmQgPD0gYmVnaW4pIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSYW5nZSgwLCAwKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgUmFuZ2UodGhpcy5nZXQoYmVnaW4sIHRoaXMuX2VuZCksIHRoaXMuZ2V0KGVuZCwgdGhpcy5fZW5kKSwgdGhpcy5fc3RlcCk7XG4gICAgfTtcblxuICAgIFJhbmdlLnByb3RvdHlwZS5pbmRleE9mID0gZnVuY3Rpb24oc2VhcmNoVmFsdWUpIHtcbiAgICAgIHZhciBvZmZzZXRWYWx1ZSA9IHNlYXJjaFZhbHVlIC0gdGhpcy5fc3RhcnQ7XG4gICAgICBpZiAob2Zmc2V0VmFsdWUgJSB0aGlzLl9zdGVwID09PSAwKSB7XG4gICAgICAgIHZhciBpbmRleCA9IG9mZnNldFZhbHVlIC8gdGhpcy5fc3RlcDtcbiAgICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCB0aGlzLnNpemUpIHtcbiAgICAgICAgICByZXR1cm4gaW5kZXhcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIC0xO1xuICAgIH07XG5cbiAgICBSYW5nZS5wcm90b3R5cGUubGFzdEluZGV4T2YgPSBmdW5jdGlvbihzZWFyY2hWYWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuaW5kZXhPZihzZWFyY2hWYWx1ZSk7XG4gICAgfTtcblxuICAgIFJhbmdlLnByb3RvdHlwZS5fX2l0ZXJhdGUgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge1xuICAgICAgdmFyIG1heEluZGV4ID0gdGhpcy5zaXplIC0gMTtcbiAgICAgIHZhciBzdGVwID0gdGhpcy5fc3RlcDtcbiAgICAgIHZhciB2YWx1ZSA9IHJldmVyc2UgPyB0aGlzLl9zdGFydCArIG1heEluZGV4ICogc3RlcCA6IHRoaXMuX3N0YXJ0O1xuICAgICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8PSBtYXhJbmRleDsgaWkrKykge1xuICAgICAgICBpZiAoZm4odmFsdWUsIGlpLCB0aGlzKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICByZXR1cm4gaWkgKyAxO1xuICAgICAgICB9XG4gICAgICAgIHZhbHVlICs9IHJldmVyc2UgPyAtc3RlcCA6IHN0ZXA7XG4gICAgICB9XG4gICAgICByZXR1cm4gaWk7XG4gICAgfTtcblxuICAgIFJhbmdlLnByb3RvdHlwZS5fX2l0ZXJhdG9yID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgdmFyIG1heEluZGV4ID0gdGhpcy5zaXplIC0gMTtcbiAgICAgIHZhciBzdGVwID0gdGhpcy5fc3RlcDtcbiAgICAgIHZhciB2YWx1ZSA9IHJldmVyc2UgPyB0aGlzLl9zdGFydCArIG1heEluZGV4ICogc3RlcCA6IHRoaXMuX3N0YXJ0O1xuICAgICAgdmFyIGlpID0gMDtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSAge1xuICAgICAgICB2YXIgdiA9IHZhbHVlO1xuICAgICAgICB2YWx1ZSArPSByZXZlcnNlID8gLXN0ZXAgOiBzdGVwO1xuICAgICAgICByZXR1cm4gaWkgPiBtYXhJbmRleCA/IGl0ZXJhdG9yRG9uZSgpIDogaXRlcmF0b3JWYWx1ZSh0eXBlLCBpaSsrLCB2KTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBSYW5nZS5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24ob3RoZXIpIHtcbiAgICAgIHJldHVybiBvdGhlciBpbnN0YW5jZW9mIFJhbmdlID9cbiAgICAgICAgdGhpcy5fc3RhcnQgPT09IG90aGVyLl9zdGFydCAmJlxuICAgICAgICB0aGlzLl9lbmQgPT09IG90aGVyLl9lbmQgJiZcbiAgICAgICAgdGhpcy5fc3RlcCA9PT0gb3RoZXIuX3N0ZXAgOlxuICAgICAgICBkZWVwRXF1YWwodGhpcywgb3RoZXIpO1xuICAgIH07XG5cblxuICB2YXIgRU1QVFlfUkFOR0U7XG5cbiAgY3JlYXRlQ2xhc3MoQ29sbGVjdGlvbiwgSXRlcmFibGUpO1xuICAgIGZ1bmN0aW9uIENvbGxlY3Rpb24oKSB7XG4gICAgICB0aHJvdyBUeXBlRXJyb3IoJ0Fic3RyYWN0Jyk7XG4gICAgfVxuXG5cbiAgY3JlYXRlQ2xhc3MoS2V5ZWRDb2xsZWN0aW9uLCBDb2xsZWN0aW9uKTtmdW5jdGlvbiBLZXllZENvbGxlY3Rpb24oKSB7fVxuXG4gIGNyZWF0ZUNsYXNzKEluZGV4ZWRDb2xsZWN0aW9uLCBDb2xsZWN0aW9uKTtmdW5jdGlvbiBJbmRleGVkQ29sbGVjdGlvbigpIHt9XG5cbiAgY3JlYXRlQ2xhc3MoU2V0Q29sbGVjdGlvbiwgQ29sbGVjdGlvbik7ZnVuY3Rpb24gU2V0Q29sbGVjdGlvbigpIHt9XG5cblxuICBDb2xsZWN0aW9uLktleWVkID0gS2V5ZWRDb2xsZWN0aW9uO1xuICBDb2xsZWN0aW9uLkluZGV4ZWQgPSBJbmRleGVkQ29sbGVjdGlvbjtcbiAgQ29sbGVjdGlvbi5TZXQgPSBTZXRDb2xsZWN0aW9uO1xuXG4gIHZhciBpbXVsID1cbiAgICB0eXBlb2YgTWF0aC5pbXVsID09PSAnZnVuY3Rpb24nICYmIE1hdGguaW11bCgweGZmZmZmZmZmLCAyKSA9PT0gLTIgP1xuICAgIE1hdGguaW11bCA6XG4gICAgZnVuY3Rpb24gaW11bChhLCBiKSB7XG4gICAgICBhID0gYSB8IDA7IC8vIGludFxuICAgICAgYiA9IGIgfCAwOyAvLyBpbnRcbiAgICAgIHZhciBjID0gYSAmIDB4ZmZmZjtcbiAgICAgIHZhciBkID0gYiAmIDB4ZmZmZjtcbiAgICAgIC8vIFNoaWZ0IGJ5IDAgZml4ZXMgdGhlIHNpZ24gb24gdGhlIGhpZ2ggcGFydC5cbiAgICAgIHJldHVybiAoYyAqIGQpICsgKCgoKGEgPj4+IDE2KSAqIGQgKyBjICogKGIgPj4+IDE2KSkgPDwgMTYpID4+PiAwKSB8IDA7IC8vIGludFxuICAgIH07XG5cbiAgLy8gdjggaGFzIGFuIG9wdGltaXphdGlvbiBmb3Igc3RvcmluZyAzMS1iaXQgc2lnbmVkIG51bWJlcnMuXG4gIC8vIFZhbHVlcyB3aGljaCBoYXZlIGVpdGhlciAwMCBvciAxMSBhcyB0aGUgaGlnaCBvcmRlciBiaXRzIHF1YWxpZnkuXG4gIC8vIFRoaXMgZnVuY3Rpb24gZHJvcHMgdGhlIGhpZ2hlc3Qgb3JkZXIgYml0IGluIGEgc2lnbmVkIG51bWJlciwgbWFpbnRhaW5pbmdcbiAgLy8gdGhlIHNpZ24gYml0LlxuICBmdW5jdGlvbiBzbWkoaTMyKSB7XG4gICAgcmV0dXJuICgoaTMyID4+PiAxKSAmIDB4NDAwMDAwMDApIHwgKGkzMiAmIDB4QkZGRkZGRkYpO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFzaChvKSB7XG4gICAgaWYgKG8gPT09IGZhbHNlIHx8IG8gPT09IG51bGwgfHwgbyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBvLnZhbHVlT2YgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIG8gPSBvLnZhbHVlT2YoKTtcbiAgICAgIGlmIChvID09PSBmYWxzZSB8fCBvID09PSBudWxsIHx8IG8gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKG8gPT09IHRydWUpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgICB2YXIgdHlwZSA9IHR5cGVvZiBvO1xuICAgIGlmICh0eXBlID09PSAnbnVtYmVyJykge1xuICAgICAgdmFyIGggPSBvIHwgMDtcbiAgICAgIGlmIChoICE9PSBvKSB7XG4gICAgICAgIGggXj0gbyAqIDB4RkZGRkZGRkY7XG4gICAgICB9XG4gICAgICB3aGlsZSAobyA+IDB4RkZGRkZGRkYpIHtcbiAgICAgICAgbyAvPSAweEZGRkZGRkZGO1xuICAgICAgICBoIF49IG87XG4gICAgICB9XG4gICAgICByZXR1cm4gc21pKGgpO1xuICAgIH1cbiAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBvLmxlbmd0aCA+IFNUUklOR19IQVNIX0NBQ0hFX01JTl9TVFJMRU4gPyBjYWNoZWRIYXNoU3RyaW5nKG8pIDogaGFzaFN0cmluZyhvKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBvLmhhc2hDb2RlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gby5oYXNoQ29kZSgpO1xuICAgIH1cbiAgICBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHJldHVybiBoYXNoSlNPYmoobyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygby50b1N0cmluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIGhhc2hTdHJpbmcoby50b1N0cmluZygpKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKCdWYWx1ZSB0eXBlICcgKyB0eXBlICsgJyBjYW5ub3QgYmUgaGFzaGVkLicpO1xuICB9XG5cbiAgZnVuY3Rpb24gY2FjaGVkSGFzaFN0cmluZyhzdHJpbmcpIHtcbiAgICB2YXIgaGFzaCA9IHN0cmluZ0hhc2hDYWNoZVtzdHJpbmddO1xuICAgIGlmIChoYXNoID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGhhc2ggPSBoYXNoU3RyaW5nKHN0cmluZyk7XG4gICAgICBpZiAoU1RSSU5HX0hBU0hfQ0FDSEVfU0laRSA9PT0gU1RSSU5HX0hBU0hfQ0FDSEVfTUFYX1NJWkUpIHtcbiAgICAgICAgU1RSSU5HX0hBU0hfQ0FDSEVfU0laRSA9IDA7XG4gICAgICAgIHN0cmluZ0hhc2hDYWNoZSA9IHt9O1xuICAgICAgfVxuICAgICAgU1RSSU5HX0hBU0hfQ0FDSEVfU0laRSsrO1xuICAgICAgc3RyaW5nSGFzaENhY2hlW3N0cmluZ10gPSBoYXNoO1xuICAgIH1cbiAgICByZXR1cm4gaGFzaDtcbiAgfVxuXG4gIC8vIGh0dHA6Ly9qc3BlcmYuY29tL2hhc2hpbmctc3RyaW5nc1xuICBmdW5jdGlvbiBoYXNoU3RyaW5nKHN0cmluZykge1xuICAgIC8vIFRoaXMgaXMgdGhlIGhhc2ggZnJvbSBKVk1cbiAgICAvLyBUaGUgaGFzaCBjb2RlIGZvciBhIHN0cmluZyBpcyBjb21wdXRlZCBhc1xuICAgIC8vIHNbMF0gKiAzMSBeIChuIC0gMSkgKyBzWzFdICogMzEgXiAobiAtIDIpICsgLi4uICsgc1tuIC0gMV0sXG4gICAgLy8gd2hlcmUgc1tpXSBpcyB0aGUgaXRoIGNoYXJhY3RlciBvZiB0aGUgc3RyaW5nIGFuZCBuIGlzIHRoZSBsZW5ndGggb2ZcbiAgICAvLyB0aGUgc3RyaW5nLiBXZSBcIm1vZFwiIHRoZSByZXN1bHQgdG8gbWFrZSBpdCBiZXR3ZWVuIDAgKGluY2x1c2l2ZSkgYW5kIDJeMzFcbiAgICAvLyAoZXhjbHVzaXZlKSBieSBkcm9wcGluZyBoaWdoIGJpdHMuXG4gICAgdmFyIGhhc2ggPSAwO1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCBzdHJpbmcubGVuZ3RoOyBpaSsrKSB7XG4gICAgICBoYXNoID0gMzEgKiBoYXNoICsgc3RyaW5nLmNoYXJDb2RlQXQoaWkpIHwgMDtcbiAgICB9XG4gICAgcmV0dXJuIHNtaShoYXNoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhc2hKU09iaihvYmopIHtcbiAgICB2YXIgaGFzaDtcbiAgICBpZiAodXNpbmdXZWFrTWFwKSB7XG4gICAgICBoYXNoID0gd2Vha01hcC5nZXQob2JqKTtcbiAgICAgIGlmIChoYXNoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGhhc2g7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaGFzaCA9IG9ialtVSURfSEFTSF9LRVldO1xuICAgIGlmIChoYXNoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBoYXNoO1xuICAgIH1cblxuICAgIGlmICghY2FuRGVmaW5lUHJvcGVydHkpIHtcbiAgICAgIGhhc2ggPSBvYmoucHJvcGVydHlJc0VudW1lcmFibGUgJiYgb2JqLnByb3BlcnR5SXNFbnVtZXJhYmxlW1VJRF9IQVNIX0tFWV07XG4gICAgICBpZiAoaGFzaCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBoYXNoO1xuICAgICAgfVxuXG4gICAgICBoYXNoID0gZ2V0SUVOb2RlSGFzaChvYmopO1xuICAgICAgaWYgKGhhc2ggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gaGFzaDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBoYXNoID0gKytvYmpIYXNoVUlEO1xuICAgIGlmIChvYmpIYXNoVUlEICYgMHg0MDAwMDAwMCkge1xuICAgICAgb2JqSGFzaFVJRCA9IDA7XG4gICAgfVxuXG4gICAgaWYgKHVzaW5nV2Vha01hcCkge1xuICAgICAgd2Vha01hcC5zZXQob2JqLCBoYXNoKTtcbiAgICB9IGVsc2UgaWYgKGlzRXh0ZW5zaWJsZSAhPT0gdW5kZWZpbmVkICYmIGlzRXh0ZW5zaWJsZShvYmopID09PSBmYWxzZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb24tZXh0ZW5zaWJsZSBvYmplY3RzIGFyZSBub3QgYWxsb3dlZCBhcyBrZXlzLicpO1xuICAgIH0gZWxzZSBpZiAoY2FuRGVmaW5lUHJvcGVydHkpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIFVJRF9IQVNIX0tFWSwge1xuICAgICAgICAnZW51bWVyYWJsZSc6IGZhbHNlLFxuICAgICAgICAnY29uZmlndXJhYmxlJzogZmFsc2UsXG4gICAgICAgICd3cml0YWJsZSc6IGZhbHNlLFxuICAgICAgICAndmFsdWUnOiBoYXNoXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKG9iai5wcm9wZXJ0eUlzRW51bWVyYWJsZSAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICAgICBvYmoucHJvcGVydHlJc0VudW1lcmFibGUgPT09IG9iai5jb25zdHJ1Y3Rvci5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUpIHtcbiAgICAgIC8vIFNpbmNlIHdlIGNhbid0IGRlZmluZSBhIG5vbi1lbnVtZXJhYmxlIHByb3BlcnR5IG9uIHRoZSBvYmplY3RcbiAgICAgIC8vIHdlJ2xsIGhpamFjayBvbmUgb2YgdGhlIGxlc3MtdXNlZCBub24tZW51bWVyYWJsZSBwcm9wZXJ0aWVzIHRvXG4gICAgICAvLyBzYXZlIG91ciBoYXNoIG9uIGl0LiBTaW5jZSB0aGlzIGlzIGEgZnVuY3Rpb24gaXQgd2lsbCBub3Qgc2hvdyB1cCBpblxuICAgICAgLy8gYEpTT04uc3RyaW5naWZ5YCB3aGljaCBpcyB3aGF0IHdlIHdhbnQuXG4gICAgICBvYmoucHJvcGVydHlJc0VudW1lcmFibGUgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgICAgb2JqLnByb3BlcnR5SXNFbnVtZXJhYmxlW1VJRF9IQVNIX0tFWV0gPSBoYXNoO1xuICAgIH0gZWxzZSBpZiAob2JqLm5vZGVUeXBlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIEF0IHRoaXMgcG9pbnQgd2UgY291bGRuJ3QgZ2V0IHRoZSBJRSBgdW5pcXVlSURgIHRvIHVzZSBhcyBhIGhhc2hcbiAgICAgIC8vIGFuZCB3ZSBjb3VsZG4ndCB1c2UgYSBub24tZW51bWVyYWJsZSBwcm9wZXJ0eSB0byBleHBsb2l0IHRoZVxuICAgICAgLy8gZG9udEVudW0gYnVnIHNvIHdlIHNpbXBseSBhZGQgdGhlIGBVSURfSEFTSF9LRVlgIG9uIHRoZSBub2RlXG4gICAgICAvLyBpdHNlbGYuXG4gICAgICBvYmpbVUlEX0hBU0hfS0VZXSA9IGhhc2g7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIHNldCBhIG5vbi1lbnVtZXJhYmxlIHByb3BlcnR5IG9uIG9iamVjdC4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gaGFzaDtcbiAgfVxuXG4gIC8vIEdldCByZWZlcmVuY2VzIHRvIEVTNSBvYmplY3QgbWV0aG9kcy5cbiAgdmFyIGlzRXh0ZW5zaWJsZSA9IE9iamVjdC5pc0V4dGVuc2libGU7XG5cbiAgLy8gVHJ1ZSBpZiBPYmplY3QuZGVmaW5lUHJvcGVydHkgd29ya3MgYXMgZXhwZWN0ZWQuIElFOCBmYWlscyB0aGlzIHRlc3QuXG4gIHZhciBjYW5EZWZpbmVQcm9wZXJ0eSA9IChmdW5jdGlvbigpIHtcbiAgICB0cnkge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAnQCcsIHt9KTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH0oKSk7XG5cbiAgLy8gSUUgaGFzIGEgYHVuaXF1ZUlEYCBwcm9wZXJ0eSBvbiBET00gbm9kZXMuIFdlIGNhbiBjb25zdHJ1Y3QgdGhlIGhhc2ggZnJvbSBpdFxuICAvLyBhbmQgYXZvaWQgbWVtb3J5IGxlYWtzIGZyb20gdGhlIElFIGNsb25lTm9kZSBidWcuXG4gIGZ1bmN0aW9uIGdldElFTm9kZUhhc2gobm9kZSkge1xuICAgIGlmIChub2RlICYmIG5vZGUubm9kZVR5cGUgPiAwKSB7XG4gICAgICBzd2l0Y2ggKG5vZGUubm9kZVR5cGUpIHtcbiAgICAgICAgY2FzZSAxOiAvLyBFbGVtZW50XG4gICAgICAgICAgcmV0dXJuIG5vZGUudW5pcXVlSUQ7XG4gICAgICAgIGNhc2UgOTogLy8gRG9jdW1lbnRcbiAgICAgICAgICByZXR1cm4gbm9kZS5kb2N1bWVudEVsZW1lbnQgJiYgbm9kZS5kb2N1bWVudEVsZW1lbnQudW5pcXVlSUQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gSWYgcG9zc2libGUsIHVzZSBhIFdlYWtNYXAuXG4gIHZhciB1c2luZ1dlYWtNYXAgPSB0eXBlb2YgV2Vha01hcCA9PT0gJ2Z1bmN0aW9uJztcbiAgdmFyIHdlYWtNYXA7XG4gIGlmICh1c2luZ1dlYWtNYXApIHtcbiAgICB3ZWFrTWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgfVxuXG4gIHZhciBvYmpIYXNoVUlEID0gMDtcblxuICB2YXIgVUlEX0hBU0hfS0VZID0gJ19faW1tdXRhYmxlaGFzaF9fJztcbiAgaWYgKHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicpIHtcbiAgICBVSURfSEFTSF9LRVkgPSBTeW1ib2woVUlEX0hBU0hfS0VZKTtcbiAgfVxuXG4gIHZhciBTVFJJTkdfSEFTSF9DQUNIRV9NSU5fU1RSTEVOID0gMTY7XG4gIHZhciBTVFJJTkdfSEFTSF9DQUNIRV9NQVhfU0laRSA9IDI1NTtcbiAgdmFyIFNUUklOR19IQVNIX0NBQ0hFX1NJWkUgPSAwO1xuICB2YXIgc3RyaW5nSGFzaENhY2hlID0ge307XG5cbiAgZnVuY3Rpb24gYXNzZXJ0Tm90SW5maW5pdGUoc2l6ZSkge1xuICAgIGludmFyaWFudChcbiAgICAgIHNpemUgIT09IEluZmluaXR5LFxuICAgICAgJ0Nhbm5vdCBwZXJmb3JtIHRoaXMgYWN0aW9uIHdpdGggYW4gaW5maW5pdGUgc2l6ZS4nXG4gICAgKTtcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKE1hcCwgS2V5ZWRDb2xsZWN0aW9uKTtcblxuICAgIC8vIEBwcmFnbWEgQ29uc3RydWN0aW9uXG5cbiAgICBmdW5jdGlvbiBNYXAodmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gZW1wdHlNYXAoKSA6XG4gICAgICAgIGlzTWFwKHZhbHVlKSAmJiAhaXNPcmRlcmVkKHZhbHVlKSA/IHZhbHVlIDpcbiAgICAgICAgZW1wdHlNYXAoKS53aXRoTXV0YXRpb25zKGZ1bmN0aW9uKG1hcCApIHtcbiAgICAgICAgICB2YXIgaXRlciA9IEtleWVkSXRlcmFibGUodmFsdWUpO1xuICAgICAgICAgIGFzc2VydE5vdEluZmluaXRlKGl0ZXIuc2l6ZSk7XG4gICAgICAgICAgaXRlci5mb3JFYWNoKGZ1bmN0aW9uKHYsIGspICB7cmV0dXJuIG1hcC5zZXQoaywgdil9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgTWFwLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX190b1N0cmluZygnTWFwIHsnLCAnfScpO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIEFjY2Vzc1xuXG4gICAgTWFwLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihrLCBub3RTZXRWYWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX3Jvb3QgP1xuICAgICAgICB0aGlzLl9yb290LmdldCgwLCB1bmRlZmluZWQsIGssIG5vdFNldFZhbHVlKSA6XG4gICAgICAgIG5vdFNldFZhbHVlO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIE1vZGlmaWNhdGlvblxuXG4gICAgTWFwLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbihrLCB2KSB7XG4gICAgICByZXR1cm4gdXBkYXRlTWFwKHRoaXMsIGssIHYpO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLnNldEluID0gZnVuY3Rpb24oa2V5UGF0aCwgdikge1xuICAgICAgcmV0dXJuIHRoaXMudXBkYXRlSW4oa2V5UGF0aCwgTk9UX1NFVCwgZnVuY3Rpb24oKSAge3JldHVybiB2fSk7XG4gICAgfTtcblxuICAgIE1hcC5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24oaykge1xuICAgICAgcmV0dXJuIHVwZGF0ZU1hcCh0aGlzLCBrLCBOT1RfU0VUKTtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5kZWxldGVJbiA9IGZ1bmN0aW9uKGtleVBhdGgpIHtcbiAgICAgIHJldHVybiB0aGlzLnVwZGF0ZUluKGtleVBhdGgsIGZ1bmN0aW9uKCkgIHtyZXR1cm4gTk9UX1NFVH0pO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKGssIG5vdFNldFZhbHVlLCB1cGRhdGVyKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/XG4gICAgICAgIGsodGhpcykgOlxuICAgICAgICB0aGlzLnVwZGF0ZUluKFtrXSwgbm90U2V0VmFsdWUsIHVwZGF0ZXIpO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLnVwZGF0ZUluID0gZnVuY3Rpb24oa2V5UGF0aCwgbm90U2V0VmFsdWUsIHVwZGF0ZXIpIHtcbiAgICAgIGlmICghdXBkYXRlcikge1xuICAgICAgICB1cGRhdGVyID0gbm90U2V0VmFsdWU7XG4gICAgICAgIG5vdFNldFZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgdmFyIHVwZGF0ZWRWYWx1ZSA9IHVwZGF0ZUluRGVlcE1hcChcbiAgICAgICAgdGhpcyxcbiAgICAgICAgZm9yY2VJdGVyYXRvcihrZXlQYXRoKSxcbiAgICAgICAgbm90U2V0VmFsdWUsXG4gICAgICAgIHVwZGF0ZXJcbiAgICAgICk7XG4gICAgICByZXR1cm4gdXBkYXRlZFZhbHVlID09PSBOT1RfU0VUID8gdW5kZWZpbmVkIDogdXBkYXRlZFZhbHVlO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5zaXplID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuX19vd25lcklEKSB7XG4gICAgICAgIHRoaXMuc2l6ZSA9IDA7XG4gICAgICAgIHRoaXMuX3Jvb3QgPSBudWxsO1xuICAgICAgICB0aGlzLl9faGFzaCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fX2FsdGVyZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBlbXB0eU1hcCgpO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIENvbXBvc2l0aW9uXG5cbiAgICBNYXAucHJvdG90eXBlLm1lcmdlID0gZnVuY3Rpb24oLyouLi5pdGVycyovKSB7XG4gICAgICByZXR1cm4gbWVyZ2VJbnRvTWFwV2l0aCh0aGlzLCB1bmRlZmluZWQsIGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIE1hcC5wcm90b3R5cGUubWVyZ2VXaXRoID0gZnVuY3Rpb24obWVyZ2VyKSB7dmFyIGl0ZXJzID0gU0xJQ0UkMC5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICByZXR1cm4gbWVyZ2VJbnRvTWFwV2l0aCh0aGlzLCBtZXJnZXIsIGl0ZXJzKTtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5tZXJnZUluID0gZnVuY3Rpb24oa2V5UGF0aCkge3ZhciBpdGVycyA9IFNMSUNFJDAuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgcmV0dXJuIHRoaXMudXBkYXRlSW4oXG4gICAgICAgIGtleVBhdGgsXG4gICAgICAgIGVtcHR5TWFwKCksXG4gICAgICAgIGZ1bmN0aW9uKG0gKSB7cmV0dXJuIHR5cGVvZiBtLm1lcmdlID09PSAnZnVuY3Rpb24nID9cbiAgICAgICAgICBtLm1lcmdlLmFwcGx5KG0sIGl0ZXJzKSA6XG4gICAgICAgICAgaXRlcnNbaXRlcnMubGVuZ3RoIC0gMV19XG4gICAgICApO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLm1lcmdlRGVlcCA9IGZ1bmN0aW9uKC8qLi4uaXRlcnMqLykge1xuICAgICAgcmV0dXJuIG1lcmdlSW50b01hcFdpdGgodGhpcywgZGVlcE1lcmdlciwgYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5tZXJnZURlZXBXaXRoID0gZnVuY3Rpb24obWVyZ2VyKSB7dmFyIGl0ZXJzID0gU0xJQ0UkMC5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICByZXR1cm4gbWVyZ2VJbnRvTWFwV2l0aCh0aGlzLCBkZWVwTWVyZ2VyV2l0aChtZXJnZXIpLCBpdGVycyk7XG4gICAgfTtcblxuICAgIE1hcC5wcm90b3R5cGUubWVyZ2VEZWVwSW4gPSBmdW5jdGlvbihrZXlQYXRoKSB7dmFyIGl0ZXJzID0gU0xJQ0UkMC5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICByZXR1cm4gdGhpcy51cGRhdGVJbihcbiAgICAgICAga2V5UGF0aCxcbiAgICAgICAgZW1wdHlNYXAoKSxcbiAgICAgICAgZnVuY3Rpb24obSApIHtyZXR1cm4gdHlwZW9mIG0ubWVyZ2VEZWVwID09PSAnZnVuY3Rpb24nID9cbiAgICAgICAgICBtLm1lcmdlRGVlcC5hcHBseShtLCBpdGVycykgOlxuICAgICAgICAgIGl0ZXJzW2l0ZXJzLmxlbmd0aCAtIDFdfVxuICAgICAgKTtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5zb3J0ID0gZnVuY3Rpb24oY29tcGFyYXRvcikge1xuICAgICAgLy8gTGF0ZSBiaW5kaW5nXG4gICAgICByZXR1cm4gT3JkZXJlZE1hcChzb3J0RmFjdG9yeSh0aGlzLCBjb21wYXJhdG9yKSk7XG4gICAgfTtcblxuICAgIE1hcC5wcm90b3R5cGUuc29ydEJ5ID0gZnVuY3Rpb24obWFwcGVyLCBjb21wYXJhdG9yKSB7XG4gICAgICAvLyBMYXRlIGJpbmRpbmdcbiAgICAgIHJldHVybiBPcmRlcmVkTWFwKHNvcnRGYWN0b3J5KHRoaXMsIGNvbXBhcmF0b3IsIG1hcHBlcikpO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIE11dGFiaWxpdHlcblxuICAgIE1hcC5wcm90b3R5cGUud2l0aE11dGF0aW9ucyA9IGZ1bmN0aW9uKGZuKSB7XG4gICAgICB2YXIgbXV0YWJsZSA9IHRoaXMuYXNNdXRhYmxlKCk7XG4gICAgICBmbihtdXRhYmxlKTtcbiAgICAgIHJldHVybiBtdXRhYmxlLndhc0FsdGVyZWQoKSA/IG11dGFibGUuX19lbnN1cmVPd25lcih0aGlzLl9fb3duZXJJRCkgOiB0aGlzO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLmFzTXV0YWJsZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX19vd25lcklEID8gdGhpcyA6IHRoaXMuX19lbnN1cmVPd25lcihuZXcgT3duZXJJRCgpKTtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5hc0ltbXV0YWJsZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX19lbnN1cmVPd25lcigpO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLndhc0FsdGVyZWQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fYWx0ZXJlZDtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5fX2l0ZXJhdG9yID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgcmV0dXJuIG5ldyBNYXBJdGVyYXRvcih0aGlzLCB0eXBlLCByZXZlcnNlKTtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5fX2l0ZXJhdGUgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgdGhpcy5fcm9vdCAmJiB0aGlzLl9yb290Lml0ZXJhdGUoZnVuY3Rpb24oZW50cnkgKSB7XG4gICAgICAgIGl0ZXJhdGlvbnMrKztcbiAgICAgICAgcmV0dXJuIGZuKGVudHJ5WzFdLCBlbnRyeVswXSwgdGhpcyQwKTtcbiAgICAgIH0sIHJldmVyc2UpO1xuICAgICAgcmV0dXJuIGl0ZXJhdGlvbnM7XG4gICAgfTtcblxuICAgIE1hcC5wcm90b3R5cGUuX19lbnN1cmVPd25lciA9IGZ1bmN0aW9uKG93bmVySUQpIHtcbiAgICAgIGlmIChvd25lcklEID09PSB0aGlzLl9fb3duZXJJRCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGlmICghb3duZXJJRCkge1xuICAgICAgICB0aGlzLl9fb3duZXJJRCA9IG93bmVySUQ7XG4gICAgICAgIHRoaXMuX19hbHRlcmVkID0gZmFsc2U7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1ha2VNYXAodGhpcy5zaXplLCB0aGlzLl9yb290LCBvd25lcklELCB0aGlzLl9faGFzaCk7XG4gICAgfTtcblxuXG4gIGZ1bmN0aW9uIGlzTWFwKG1heWJlTWFwKSB7XG4gICAgcmV0dXJuICEhKG1heWJlTWFwICYmIG1heWJlTWFwW0lTX01BUF9TRU5USU5FTF0pO1xuICB9XG5cbiAgTWFwLmlzTWFwID0gaXNNYXA7XG5cbiAgdmFyIElTX01BUF9TRU5USU5FTCA9ICdAQF9fSU1NVVRBQkxFX01BUF9fQEAnO1xuXG4gIHZhciBNYXBQcm90b3R5cGUgPSBNYXAucHJvdG90eXBlO1xuICBNYXBQcm90b3R5cGVbSVNfTUFQX1NFTlRJTkVMXSA9IHRydWU7XG4gIE1hcFByb3RvdHlwZVtERUxFVEVdID0gTWFwUHJvdG90eXBlLnJlbW92ZTtcbiAgTWFwUHJvdG90eXBlLnJlbW92ZUluID0gTWFwUHJvdG90eXBlLmRlbGV0ZUluO1xuXG5cbiAgLy8gI3ByYWdtYSBUcmllIE5vZGVzXG5cblxuXG4gICAgZnVuY3Rpb24gQXJyYXlNYXBOb2RlKG93bmVySUQsIGVudHJpZXMpIHtcbiAgICAgIHRoaXMub3duZXJJRCA9IG93bmVySUQ7XG4gICAgICB0aGlzLmVudHJpZXMgPSBlbnRyaWVzO1xuICAgIH1cblxuICAgIEFycmF5TWFwTm9kZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oc2hpZnQsIGtleUhhc2gsIGtleSwgbm90U2V0VmFsdWUpIHtcbiAgICAgIHZhciBlbnRyaWVzID0gdGhpcy5lbnRyaWVzO1xuICAgICAgZm9yICh2YXIgaWkgPSAwLCBsZW4gPSBlbnRyaWVzLmxlbmd0aDsgaWkgPCBsZW47IGlpKyspIHtcbiAgICAgICAgaWYgKGlzKGtleSwgZW50cmllc1tpaV1bMF0pKSB7XG4gICAgICAgICAgcmV0dXJuIGVudHJpZXNbaWldWzFdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbm90U2V0VmFsdWU7XG4gICAgfTtcblxuICAgIEFycmF5TWFwTm9kZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24ob3duZXJJRCwgc2hpZnQsIGtleUhhc2gsIGtleSwgdmFsdWUsIGRpZENoYW5nZVNpemUsIGRpZEFsdGVyKSB7XG4gICAgICB2YXIgcmVtb3ZlZCA9IHZhbHVlID09PSBOT1RfU0VUO1xuXG4gICAgICB2YXIgZW50cmllcyA9IHRoaXMuZW50cmllcztcbiAgICAgIHZhciBpZHggPSAwO1xuICAgICAgZm9yICh2YXIgbGVuID0gZW50cmllcy5sZW5ndGg7IGlkeCA8IGxlbjsgaWR4KyspIHtcbiAgICAgICAgaWYgKGlzKGtleSwgZW50cmllc1tpZHhdWzBdKSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB2YXIgZXhpc3RzID0gaWR4IDwgbGVuO1xuXG4gICAgICBpZiAoZXhpc3RzID8gZW50cmllc1tpZHhdWzFdID09PSB2YWx1ZSA6IHJlbW92ZWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIFNldFJlZihkaWRBbHRlcik7XG4gICAgICAocmVtb3ZlZCB8fCAhZXhpc3RzKSAmJiBTZXRSZWYoZGlkQ2hhbmdlU2l6ZSk7XG5cbiAgICAgIGlmIChyZW1vdmVkICYmIGVudHJpZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHJldHVybjsgLy8gdW5kZWZpbmVkXG4gICAgICB9XG5cbiAgICAgIGlmICghZXhpc3RzICYmICFyZW1vdmVkICYmIGVudHJpZXMubGVuZ3RoID49IE1BWF9BUlJBWV9NQVBfU0laRSkge1xuICAgICAgICByZXR1cm4gY3JlYXRlTm9kZXMob3duZXJJRCwgZW50cmllcywga2V5LCB2YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIHZhciBpc0VkaXRhYmxlID0gb3duZXJJRCAmJiBvd25lcklEID09PSB0aGlzLm93bmVySUQ7XG4gICAgICB2YXIgbmV3RW50cmllcyA9IGlzRWRpdGFibGUgPyBlbnRyaWVzIDogYXJyQ29weShlbnRyaWVzKTtcblxuICAgICAgaWYgKGV4aXN0cykge1xuICAgICAgICBpZiAocmVtb3ZlZCkge1xuICAgICAgICAgIGlkeCA9PT0gbGVuIC0gMSA/IG5ld0VudHJpZXMucG9wKCkgOiAobmV3RW50cmllc1tpZHhdID0gbmV3RW50cmllcy5wb3AoKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbmV3RW50cmllc1tpZHhdID0gW2tleSwgdmFsdWVdO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXdFbnRyaWVzLnB1c2goW2tleSwgdmFsdWVdKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzRWRpdGFibGUpIHtcbiAgICAgICAgdGhpcy5lbnRyaWVzID0gbmV3RW50cmllcztcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuZXcgQXJyYXlNYXBOb2RlKG93bmVySUQsIG5ld0VudHJpZXMpO1xuICAgIH07XG5cblxuXG5cbiAgICBmdW5jdGlvbiBCaXRtYXBJbmRleGVkTm9kZShvd25lcklELCBiaXRtYXAsIG5vZGVzKSB7XG4gICAgICB0aGlzLm93bmVySUQgPSBvd25lcklEO1xuICAgICAgdGhpcy5iaXRtYXAgPSBiaXRtYXA7XG4gICAgICB0aGlzLm5vZGVzID0gbm9kZXM7XG4gICAgfVxuXG4gICAgQml0bWFwSW5kZXhlZE5vZGUucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKHNoaWZ0LCBrZXlIYXNoLCBrZXksIG5vdFNldFZhbHVlKSB7XG4gICAgICBpZiAoa2V5SGFzaCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGtleUhhc2ggPSBoYXNoKGtleSk7XG4gICAgICB9XG4gICAgICB2YXIgYml0ID0gKDEgPDwgKChzaGlmdCA9PT0gMCA/IGtleUhhc2ggOiBrZXlIYXNoID4+PiBzaGlmdCkgJiBNQVNLKSk7XG4gICAgICB2YXIgYml0bWFwID0gdGhpcy5iaXRtYXA7XG4gICAgICByZXR1cm4gKGJpdG1hcCAmIGJpdCkgPT09IDAgPyBub3RTZXRWYWx1ZSA6XG4gICAgICAgIHRoaXMubm9kZXNbcG9wQ291bnQoYml0bWFwICYgKGJpdCAtIDEpKV0uZ2V0KHNoaWZ0ICsgU0hJRlQsIGtleUhhc2gsIGtleSwgbm90U2V0VmFsdWUpO1xuICAgIH07XG5cbiAgICBCaXRtYXBJbmRleGVkTm9kZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24ob3duZXJJRCwgc2hpZnQsIGtleUhhc2gsIGtleSwgdmFsdWUsIGRpZENoYW5nZVNpemUsIGRpZEFsdGVyKSB7XG4gICAgICBpZiAoa2V5SGFzaCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGtleUhhc2ggPSBoYXNoKGtleSk7XG4gICAgICB9XG4gICAgICB2YXIga2V5SGFzaEZyYWcgPSAoc2hpZnQgPT09IDAgPyBrZXlIYXNoIDoga2V5SGFzaCA+Pj4gc2hpZnQpICYgTUFTSztcbiAgICAgIHZhciBiaXQgPSAxIDw8IGtleUhhc2hGcmFnO1xuICAgICAgdmFyIGJpdG1hcCA9IHRoaXMuYml0bWFwO1xuICAgICAgdmFyIGV4aXN0cyA9IChiaXRtYXAgJiBiaXQpICE9PSAwO1xuXG4gICAgICBpZiAoIWV4aXN0cyAmJiB2YWx1ZSA9PT0gTk9UX1NFVCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgdmFyIGlkeCA9IHBvcENvdW50KGJpdG1hcCAmIChiaXQgLSAxKSk7XG4gICAgICB2YXIgbm9kZXMgPSB0aGlzLm5vZGVzO1xuICAgICAgdmFyIG5vZGUgPSBleGlzdHMgPyBub2Rlc1tpZHhdIDogdW5kZWZpbmVkO1xuICAgICAgdmFyIG5ld05vZGUgPSB1cGRhdGVOb2RlKG5vZGUsIG93bmVySUQsIHNoaWZ0ICsgU0hJRlQsIGtleUhhc2gsIGtleSwgdmFsdWUsIGRpZENoYW5nZVNpemUsIGRpZEFsdGVyKTtcblxuICAgICAgaWYgKG5ld05vZGUgPT09IG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIGlmICghZXhpc3RzICYmIG5ld05vZGUgJiYgbm9kZXMubGVuZ3RoID49IE1BWF9CSVRNQVBfSU5ERVhFRF9TSVpFKSB7XG4gICAgICAgIHJldHVybiBleHBhbmROb2Rlcyhvd25lcklELCBub2RlcywgYml0bWFwLCBrZXlIYXNoRnJhZywgbmV3Tm9kZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChleGlzdHMgJiYgIW5ld05vZGUgJiYgbm9kZXMubGVuZ3RoID09PSAyICYmIGlzTGVhZk5vZGUobm9kZXNbaWR4IF4gMV0pKSB7XG4gICAgICAgIHJldHVybiBub2Rlc1tpZHggXiAxXTtcbiAgICAgIH1cblxuICAgICAgaWYgKGV4aXN0cyAmJiBuZXdOb2RlICYmIG5vZGVzLmxlbmd0aCA9PT0gMSAmJiBpc0xlYWZOb2RlKG5ld05vZGUpKSB7XG4gICAgICAgIHJldHVybiBuZXdOb2RlO1xuICAgICAgfVxuXG4gICAgICB2YXIgaXNFZGl0YWJsZSA9IG93bmVySUQgJiYgb3duZXJJRCA9PT0gdGhpcy5vd25lcklEO1xuICAgICAgdmFyIG5ld0JpdG1hcCA9IGV4aXN0cyA/IG5ld05vZGUgPyBiaXRtYXAgOiBiaXRtYXAgXiBiaXQgOiBiaXRtYXAgfCBiaXQ7XG4gICAgICB2YXIgbmV3Tm9kZXMgPSBleGlzdHMgPyBuZXdOb2RlID9cbiAgICAgICAgc2V0SW4obm9kZXMsIGlkeCwgbmV3Tm9kZSwgaXNFZGl0YWJsZSkgOlxuICAgICAgICBzcGxpY2VPdXQobm9kZXMsIGlkeCwgaXNFZGl0YWJsZSkgOlxuICAgICAgICBzcGxpY2VJbihub2RlcywgaWR4LCBuZXdOb2RlLCBpc0VkaXRhYmxlKTtcblxuICAgICAgaWYgKGlzRWRpdGFibGUpIHtcbiAgICAgICAgdGhpcy5iaXRtYXAgPSBuZXdCaXRtYXA7XG4gICAgICAgIHRoaXMubm9kZXMgPSBuZXdOb2RlcztcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuZXcgQml0bWFwSW5kZXhlZE5vZGUob3duZXJJRCwgbmV3Qml0bWFwLCBuZXdOb2Rlcyk7XG4gICAgfTtcblxuXG5cblxuICAgIGZ1bmN0aW9uIEhhc2hBcnJheU1hcE5vZGUob3duZXJJRCwgY291bnQsIG5vZGVzKSB7XG4gICAgICB0aGlzLm93bmVySUQgPSBvd25lcklEO1xuICAgICAgdGhpcy5jb3VudCA9IGNvdW50O1xuICAgICAgdGhpcy5ub2RlcyA9IG5vZGVzO1xuICAgIH1cblxuICAgIEhhc2hBcnJheU1hcE5vZGUucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKHNoaWZ0LCBrZXlIYXNoLCBrZXksIG5vdFNldFZhbHVlKSB7XG4gICAgICBpZiAoa2V5SGFzaCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGtleUhhc2ggPSBoYXNoKGtleSk7XG4gICAgICB9XG4gICAgICB2YXIgaWR4ID0gKHNoaWZ0ID09PSAwID8ga2V5SGFzaCA6IGtleUhhc2ggPj4+IHNoaWZ0KSAmIE1BU0s7XG4gICAgICB2YXIgbm9kZSA9IHRoaXMubm9kZXNbaWR4XTtcbiAgICAgIHJldHVybiBub2RlID8gbm9kZS5nZXQoc2hpZnQgKyBTSElGVCwga2V5SGFzaCwga2V5LCBub3RTZXRWYWx1ZSkgOiBub3RTZXRWYWx1ZTtcbiAgICB9O1xuXG4gICAgSGFzaEFycmF5TWFwTm9kZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24ob3duZXJJRCwgc2hpZnQsIGtleUhhc2gsIGtleSwgdmFsdWUsIGRpZENoYW5nZVNpemUsIGRpZEFsdGVyKSB7XG4gICAgICBpZiAoa2V5SGFzaCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGtleUhhc2ggPSBoYXNoKGtleSk7XG4gICAgICB9XG4gICAgICB2YXIgaWR4ID0gKHNoaWZ0ID09PSAwID8ga2V5SGFzaCA6IGtleUhhc2ggPj4+IHNoaWZ0KSAmIE1BU0s7XG4gICAgICB2YXIgcmVtb3ZlZCA9IHZhbHVlID09PSBOT1RfU0VUO1xuICAgICAgdmFyIG5vZGVzID0gdGhpcy5ub2RlcztcbiAgICAgIHZhciBub2RlID0gbm9kZXNbaWR4XTtcblxuICAgICAgaWYgKHJlbW92ZWQgJiYgIW5vZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIHZhciBuZXdOb2RlID0gdXBkYXRlTm9kZShub2RlLCBvd25lcklELCBzaGlmdCArIFNISUZULCBrZXlIYXNoLCBrZXksIHZhbHVlLCBkaWRDaGFuZ2VTaXplLCBkaWRBbHRlcik7XG4gICAgICBpZiAobmV3Tm9kZSA9PT0gbm9kZSkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgdmFyIG5ld0NvdW50ID0gdGhpcy5jb3VudDtcbiAgICAgIGlmICghbm9kZSkge1xuICAgICAgICBuZXdDb3VudCsrO1xuICAgICAgfSBlbHNlIGlmICghbmV3Tm9kZSkge1xuICAgICAgICBuZXdDb3VudC0tO1xuICAgICAgICBpZiAobmV3Q291bnQgPCBNSU5fSEFTSF9BUlJBWV9NQVBfU0laRSkge1xuICAgICAgICAgIHJldHVybiBwYWNrTm9kZXMob3duZXJJRCwgbm9kZXMsIG5ld0NvdW50LCBpZHgpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHZhciBpc0VkaXRhYmxlID0gb3duZXJJRCAmJiBvd25lcklEID09PSB0aGlzLm93bmVySUQ7XG4gICAgICB2YXIgbmV3Tm9kZXMgPSBzZXRJbihub2RlcywgaWR4LCBuZXdOb2RlLCBpc0VkaXRhYmxlKTtcblxuICAgICAgaWYgKGlzRWRpdGFibGUpIHtcbiAgICAgICAgdGhpcy5jb3VudCA9IG5ld0NvdW50O1xuICAgICAgICB0aGlzLm5vZGVzID0gbmV3Tm9kZXM7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmV3IEhhc2hBcnJheU1hcE5vZGUob3duZXJJRCwgbmV3Q291bnQsIG5ld05vZGVzKTtcbiAgICB9O1xuXG5cblxuXG4gICAgZnVuY3Rpb24gSGFzaENvbGxpc2lvbk5vZGUob3duZXJJRCwga2V5SGFzaCwgZW50cmllcykge1xuICAgICAgdGhpcy5vd25lcklEID0gb3duZXJJRDtcbiAgICAgIHRoaXMua2V5SGFzaCA9IGtleUhhc2g7XG4gICAgICB0aGlzLmVudHJpZXMgPSBlbnRyaWVzO1xuICAgIH1cblxuICAgIEhhc2hDb2xsaXNpb25Ob2RlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihzaGlmdCwga2V5SGFzaCwga2V5LCBub3RTZXRWYWx1ZSkge1xuICAgICAgdmFyIGVudHJpZXMgPSB0aGlzLmVudHJpZXM7XG4gICAgICBmb3IgKHZhciBpaSA9IDAsIGxlbiA9IGVudHJpZXMubGVuZ3RoOyBpaSA8IGxlbjsgaWkrKykge1xuICAgICAgICBpZiAoaXMoa2V5LCBlbnRyaWVzW2lpXVswXSkpIHtcbiAgICAgICAgICByZXR1cm4gZW50cmllc1tpaV1bMV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBub3RTZXRWYWx1ZTtcbiAgICB9O1xuXG4gICAgSGFzaENvbGxpc2lvbk5vZGUucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKG93bmVySUQsIHNoaWZ0LCBrZXlIYXNoLCBrZXksIHZhbHVlLCBkaWRDaGFuZ2VTaXplLCBkaWRBbHRlcikge1xuICAgICAgaWYgKGtleUhhc2ggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBrZXlIYXNoID0gaGFzaChrZXkpO1xuICAgICAgfVxuXG4gICAgICB2YXIgcmVtb3ZlZCA9IHZhbHVlID09PSBOT1RfU0VUO1xuXG4gICAgICBpZiAoa2V5SGFzaCAhPT0gdGhpcy5rZXlIYXNoKSB7XG4gICAgICAgIGlmIChyZW1vdmVkKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgU2V0UmVmKGRpZEFsdGVyKTtcbiAgICAgICAgU2V0UmVmKGRpZENoYW5nZVNpemUpO1xuICAgICAgICByZXR1cm4gbWVyZ2VJbnRvTm9kZSh0aGlzLCBvd25lcklELCBzaGlmdCwga2V5SGFzaCwgW2tleSwgdmFsdWVdKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGVudHJpZXMgPSB0aGlzLmVudHJpZXM7XG4gICAgICB2YXIgaWR4ID0gMDtcbiAgICAgIGZvciAodmFyIGxlbiA9IGVudHJpZXMubGVuZ3RoOyBpZHggPCBsZW47IGlkeCsrKSB7XG4gICAgICAgIGlmIChpcyhrZXksIGVudHJpZXNbaWR4XVswXSkpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdmFyIGV4aXN0cyA9IGlkeCA8IGxlbjtcblxuICAgICAgaWYgKGV4aXN0cyA/IGVudHJpZXNbaWR4XVsxXSA9PT0gdmFsdWUgOiByZW1vdmVkKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICBTZXRSZWYoZGlkQWx0ZXIpO1xuICAgICAgKHJlbW92ZWQgfHwgIWV4aXN0cykgJiYgU2V0UmVmKGRpZENoYW5nZVNpemUpO1xuXG4gICAgICBpZiAocmVtb3ZlZCAmJiBsZW4gPT09IDIpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBWYWx1ZU5vZGUob3duZXJJRCwgdGhpcy5rZXlIYXNoLCBlbnRyaWVzW2lkeCBeIDFdKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGlzRWRpdGFibGUgPSBvd25lcklEICYmIG93bmVySUQgPT09IHRoaXMub3duZXJJRDtcbiAgICAgIHZhciBuZXdFbnRyaWVzID0gaXNFZGl0YWJsZSA/IGVudHJpZXMgOiBhcnJDb3B5KGVudHJpZXMpO1xuXG4gICAgICBpZiAoZXhpc3RzKSB7XG4gICAgICAgIGlmIChyZW1vdmVkKSB7XG4gICAgICAgICAgaWR4ID09PSBsZW4gLSAxID8gbmV3RW50cmllcy5wb3AoKSA6IChuZXdFbnRyaWVzW2lkeF0gPSBuZXdFbnRyaWVzLnBvcCgpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdFbnRyaWVzW2lkeF0gPSBba2V5LCB2YWx1ZV07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5ld0VudHJpZXMucHVzaChba2V5LCB2YWx1ZV0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNFZGl0YWJsZSkge1xuICAgICAgICB0aGlzLmVudHJpZXMgPSBuZXdFbnRyaWVzO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5ldyBIYXNoQ29sbGlzaW9uTm9kZShvd25lcklELCB0aGlzLmtleUhhc2gsIG5ld0VudHJpZXMpO1xuICAgIH07XG5cblxuXG5cbiAgICBmdW5jdGlvbiBWYWx1ZU5vZGUob3duZXJJRCwga2V5SGFzaCwgZW50cnkpIHtcbiAgICAgIHRoaXMub3duZXJJRCA9IG93bmVySUQ7XG4gICAgICB0aGlzLmtleUhhc2ggPSBrZXlIYXNoO1xuICAgICAgdGhpcy5lbnRyeSA9IGVudHJ5O1xuICAgIH1cblxuICAgIFZhbHVlTm9kZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oc2hpZnQsIGtleUhhc2gsIGtleSwgbm90U2V0VmFsdWUpIHtcbiAgICAgIHJldHVybiBpcyhrZXksIHRoaXMuZW50cnlbMF0pID8gdGhpcy5lbnRyeVsxXSA6IG5vdFNldFZhbHVlO1xuICAgIH07XG5cbiAgICBWYWx1ZU5vZGUucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKG93bmVySUQsIHNoaWZ0LCBrZXlIYXNoLCBrZXksIHZhbHVlLCBkaWRDaGFuZ2VTaXplLCBkaWRBbHRlcikge1xuICAgICAgdmFyIHJlbW92ZWQgPSB2YWx1ZSA9PT0gTk9UX1NFVDtcbiAgICAgIHZhciBrZXlNYXRjaCA9IGlzKGtleSwgdGhpcy5lbnRyeVswXSk7XG4gICAgICBpZiAoa2V5TWF0Y2ggPyB2YWx1ZSA9PT0gdGhpcy5lbnRyeVsxXSA6IHJlbW92ZWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIFNldFJlZihkaWRBbHRlcik7XG5cbiAgICAgIGlmIChyZW1vdmVkKSB7XG4gICAgICAgIFNldFJlZihkaWRDaGFuZ2VTaXplKTtcbiAgICAgICAgcmV0dXJuOyAvLyB1bmRlZmluZWRcbiAgICAgIH1cblxuICAgICAgaWYgKGtleU1hdGNoKSB7XG4gICAgICAgIGlmIChvd25lcklEICYmIG93bmVySUQgPT09IHRoaXMub3duZXJJRCkge1xuICAgICAgICAgIHRoaXMuZW50cnlbMV0gPSB2YWx1ZTtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFZhbHVlTm9kZShvd25lcklELCB0aGlzLmtleUhhc2gsIFtrZXksIHZhbHVlXSk7XG4gICAgICB9XG5cbiAgICAgIFNldFJlZihkaWRDaGFuZ2VTaXplKTtcbiAgICAgIHJldHVybiBtZXJnZUludG9Ob2RlKHRoaXMsIG93bmVySUQsIHNoaWZ0LCBoYXNoKGtleSksIFtrZXksIHZhbHVlXSk7XG4gICAgfTtcblxuXG5cbiAgLy8gI3ByYWdtYSBJdGVyYXRvcnNcblxuICBBcnJheU1hcE5vZGUucHJvdG90eXBlLml0ZXJhdGUgPVxuICBIYXNoQ29sbGlzaW9uTm9kZS5wcm90b3R5cGUuaXRlcmF0ZSA9IGZ1bmN0aW9uIChmbiwgcmV2ZXJzZSkge1xuICAgIHZhciBlbnRyaWVzID0gdGhpcy5lbnRyaWVzO1xuICAgIGZvciAodmFyIGlpID0gMCwgbWF4SW5kZXggPSBlbnRyaWVzLmxlbmd0aCAtIDE7IGlpIDw9IG1heEluZGV4OyBpaSsrKSB7XG4gICAgICBpZiAoZm4oZW50cmllc1tyZXZlcnNlID8gbWF4SW5kZXggLSBpaSA6IGlpXSkgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBCaXRtYXBJbmRleGVkTm9kZS5wcm90b3R5cGUuaXRlcmF0ZSA9XG4gIEhhc2hBcnJheU1hcE5vZGUucHJvdG90eXBlLml0ZXJhdGUgPSBmdW5jdGlvbiAoZm4sIHJldmVyc2UpIHtcbiAgICB2YXIgbm9kZXMgPSB0aGlzLm5vZGVzO1xuICAgIGZvciAodmFyIGlpID0gMCwgbWF4SW5kZXggPSBub2Rlcy5sZW5ndGggLSAxOyBpaSA8PSBtYXhJbmRleDsgaWkrKykge1xuICAgICAgdmFyIG5vZGUgPSBub2Rlc1tyZXZlcnNlID8gbWF4SW5kZXggLSBpaSA6IGlpXTtcbiAgICAgIGlmIChub2RlICYmIG5vZGUuaXRlcmF0ZShmbiwgcmV2ZXJzZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBWYWx1ZU5vZGUucHJvdG90eXBlLml0ZXJhdGUgPSBmdW5jdGlvbiAoZm4sIHJldmVyc2UpIHtcbiAgICByZXR1cm4gZm4odGhpcy5lbnRyeSk7XG4gIH1cblxuICBjcmVhdGVDbGFzcyhNYXBJdGVyYXRvciwgSXRlcmF0b3IpO1xuXG4gICAgZnVuY3Rpb24gTWFwSXRlcmF0b3IobWFwLCB0eXBlLCByZXZlcnNlKSB7XG4gICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICAgIHRoaXMuX3JldmVyc2UgPSByZXZlcnNlO1xuICAgICAgdGhpcy5fc3RhY2sgPSBtYXAuX3Jvb3QgJiYgbWFwSXRlcmF0b3JGcmFtZShtYXAuX3Jvb3QpO1xuICAgIH1cblxuICAgIE1hcEl0ZXJhdG9yLnByb3RvdHlwZS5uZXh0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgdHlwZSA9IHRoaXMuX3R5cGU7XG4gICAgICB2YXIgc3RhY2sgPSB0aGlzLl9zdGFjaztcbiAgICAgIHdoaWxlIChzdGFjaykge1xuICAgICAgICB2YXIgbm9kZSA9IHN0YWNrLm5vZGU7XG4gICAgICAgIHZhciBpbmRleCA9IHN0YWNrLmluZGV4Kys7XG4gICAgICAgIHZhciBtYXhJbmRleDtcbiAgICAgICAgaWYgKG5vZGUuZW50cnkpIHtcbiAgICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBtYXBJdGVyYXRvclZhbHVlKHR5cGUsIG5vZGUuZW50cnkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChub2RlLmVudHJpZXMpIHtcbiAgICAgICAgICBtYXhJbmRleCA9IG5vZGUuZW50cmllcy5sZW5ndGggLSAxO1xuICAgICAgICAgIGlmIChpbmRleCA8PSBtYXhJbmRleCkge1xuICAgICAgICAgICAgcmV0dXJuIG1hcEl0ZXJhdG9yVmFsdWUodHlwZSwgbm9kZS5lbnRyaWVzW3RoaXMuX3JldmVyc2UgPyBtYXhJbmRleCAtIGluZGV4IDogaW5kZXhdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbWF4SW5kZXggPSBub2RlLm5vZGVzLmxlbmd0aCAtIDE7XG4gICAgICAgICAgaWYgKGluZGV4IDw9IG1heEluZGV4KSB7XG4gICAgICAgICAgICB2YXIgc3ViTm9kZSA9IG5vZGUubm9kZXNbdGhpcy5fcmV2ZXJzZSA/IG1heEluZGV4IC0gaW5kZXggOiBpbmRleF07XG4gICAgICAgICAgICBpZiAoc3ViTm9kZSkge1xuICAgICAgICAgICAgICBpZiAoc3ViTm9kZS5lbnRyeSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXBJdGVyYXRvclZhbHVlKHR5cGUsIHN1Yk5vZGUuZW50cnkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHN0YWNrID0gdGhpcy5fc3RhY2sgPSBtYXBJdGVyYXRvckZyYW1lKHN1Yk5vZGUsIHN0YWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdGFjayA9IHRoaXMuX3N0YWNrID0gdGhpcy5fc3RhY2suX19wcmV2O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGl0ZXJhdG9yRG9uZSgpO1xuICAgIH07XG5cblxuICBmdW5jdGlvbiBtYXBJdGVyYXRvclZhbHVlKHR5cGUsIGVudHJ5KSB7XG4gICAgcmV0dXJuIGl0ZXJhdG9yVmFsdWUodHlwZSwgZW50cnlbMF0sIGVudHJ5WzFdKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1hcEl0ZXJhdG9yRnJhbWUobm9kZSwgcHJldikge1xuICAgIHJldHVybiB7XG4gICAgICBub2RlOiBub2RlLFxuICAgICAgaW5kZXg6IDAsXG4gICAgICBfX3ByZXY6IHByZXZcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gbWFrZU1hcChzaXplLCByb290LCBvd25lcklELCBoYXNoKSB7XG4gICAgdmFyIG1hcCA9IE9iamVjdC5jcmVhdGUoTWFwUHJvdG90eXBlKTtcbiAgICBtYXAuc2l6ZSA9IHNpemU7XG4gICAgbWFwLl9yb290ID0gcm9vdDtcbiAgICBtYXAuX19vd25lcklEID0gb3duZXJJRDtcbiAgICBtYXAuX19oYXNoID0gaGFzaDtcbiAgICBtYXAuX19hbHRlcmVkID0gZmFsc2U7XG4gICAgcmV0dXJuIG1hcDtcbiAgfVxuXG4gIHZhciBFTVBUWV9NQVA7XG4gIGZ1bmN0aW9uIGVtcHR5TWFwKCkge1xuICAgIHJldHVybiBFTVBUWV9NQVAgfHwgKEVNUFRZX01BUCA9IG1ha2VNYXAoMCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlTWFwKG1hcCwgaywgdikge1xuICAgIHZhciBuZXdSb290O1xuICAgIHZhciBuZXdTaXplO1xuICAgIGlmICghbWFwLl9yb290KSB7XG4gICAgICBpZiAodiA9PT0gTk9UX1NFVCkge1xuICAgICAgICByZXR1cm4gbWFwO1xuICAgICAgfVxuICAgICAgbmV3U2l6ZSA9IDE7XG4gICAgICBuZXdSb290ID0gbmV3IEFycmF5TWFwTm9kZShtYXAuX19vd25lcklELCBbW2ssIHZdXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBkaWRDaGFuZ2VTaXplID0gTWFrZVJlZihDSEFOR0VfTEVOR1RIKTtcbiAgICAgIHZhciBkaWRBbHRlciA9IE1ha2VSZWYoRElEX0FMVEVSKTtcbiAgICAgIG5ld1Jvb3QgPSB1cGRhdGVOb2RlKG1hcC5fcm9vdCwgbWFwLl9fb3duZXJJRCwgMCwgdW5kZWZpbmVkLCBrLCB2LCBkaWRDaGFuZ2VTaXplLCBkaWRBbHRlcik7XG4gICAgICBpZiAoIWRpZEFsdGVyLnZhbHVlKSB7XG4gICAgICAgIHJldHVybiBtYXA7XG4gICAgICB9XG4gICAgICBuZXdTaXplID0gbWFwLnNpemUgKyAoZGlkQ2hhbmdlU2l6ZS52YWx1ZSA/IHYgPT09IE5PVF9TRVQgPyAtMSA6IDEgOiAwKTtcbiAgICB9XG4gICAgaWYgKG1hcC5fX293bmVySUQpIHtcbiAgICAgIG1hcC5zaXplID0gbmV3U2l6ZTtcbiAgICAgIG1hcC5fcm9vdCA9IG5ld1Jvb3Q7XG4gICAgICBtYXAuX19oYXNoID0gdW5kZWZpbmVkO1xuICAgICAgbWFwLl9fYWx0ZXJlZCA9IHRydWU7XG4gICAgICByZXR1cm4gbWFwO1xuICAgIH1cbiAgICByZXR1cm4gbmV3Um9vdCA/IG1ha2VNYXAobmV3U2l6ZSwgbmV3Um9vdCkgOiBlbXB0eU1hcCgpO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlTm9kZShub2RlLCBvd25lcklELCBzaGlmdCwga2V5SGFzaCwga2V5LCB2YWx1ZSwgZGlkQ2hhbmdlU2l6ZSwgZGlkQWx0ZXIpIHtcbiAgICBpZiAoIW5vZGUpIHtcbiAgICAgIGlmICh2YWx1ZSA9PT0gTk9UX1NFVCkge1xuICAgICAgICByZXR1cm4gbm9kZTtcbiAgICAgIH1cbiAgICAgIFNldFJlZihkaWRBbHRlcik7XG4gICAgICBTZXRSZWYoZGlkQ2hhbmdlU2l6ZSk7XG4gICAgICByZXR1cm4gbmV3IFZhbHVlTm9kZShvd25lcklELCBrZXlIYXNoLCBba2V5LCB2YWx1ZV0pO1xuICAgIH1cbiAgICByZXR1cm4gbm9kZS51cGRhdGUob3duZXJJRCwgc2hpZnQsIGtleUhhc2gsIGtleSwgdmFsdWUsIGRpZENoYW5nZVNpemUsIGRpZEFsdGVyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzTGVhZk5vZGUobm9kZSkge1xuICAgIHJldHVybiBub2RlLmNvbnN0cnVjdG9yID09PSBWYWx1ZU5vZGUgfHwgbm9kZS5jb25zdHJ1Y3RvciA9PT0gSGFzaENvbGxpc2lvbk5vZGU7XG4gIH1cblxuICBmdW5jdGlvbiBtZXJnZUludG9Ob2RlKG5vZGUsIG93bmVySUQsIHNoaWZ0LCBrZXlIYXNoLCBlbnRyeSkge1xuICAgIGlmIChub2RlLmtleUhhc2ggPT09IGtleUhhc2gpIHtcbiAgICAgIHJldHVybiBuZXcgSGFzaENvbGxpc2lvbk5vZGUob3duZXJJRCwga2V5SGFzaCwgW25vZGUuZW50cnksIGVudHJ5XSk7XG4gICAgfVxuXG4gICAgdmFyIGlkeDEgPSAoc2hpZnQgPT09IDAgPyBub2RlLmtleUhhc2ggOiBub2RlLmtleUhhc2ggPj4+IHNoaWZ0KSAmIE1BU0s7XG4gICAgdmFyIGlkeDIgPSAoc2hpZnQgPT09IDAgPyBrZXlIYXNoIDoga2V5SGFzaCA+Pj4gc2hpZnQpICYgTUFTSztcblxuICAgIHZhciBuZXdOb2RlO1xuICAgIHZhciBub2RlcyA9IGlkeDEgPT09IGlkeDIgP1xuICAgICAgW21lcmdlSW50b05vZGUobm9kZSwgb3duZXJJRCwgc2hpZnQgKyBTSElGVCwga2V5SGFzaCwgZW50cnkpXSA6XG4gICAgICAoKG5ld05vZGUgPSBuZXcgVmFsdWVOb2RlKG93bmVySUQsIGtleUhhc2gsIGVudHJ5KSksIGlkeDEgPCBpZHgyID8gW25vZGUsIG5ld05vZGVdIDogW25ld05vZGUsIG5vZGVdKTtcblxuICAgIHJldHVybiBuZXcgQml0bWFwSW5kZXhlZE5vZGUob3duZXJJRCwgKDEgPDwgaWR4MSkgfCAoMSA8PCBpZHgyKSwgbm9kZXMpO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlTm9kZXMob3duZXJJRCwgZW50cmllcywga2V5LCB2YWx1ZSkge1xuICAgIGlmICghb3duZXJJRCkge1xuICAgICAgb3duZXJJRCA9IG5ldyBPd25lcklEKCk7XG4gICAgfVxuICAgIHZhciBub2RlID0gbmV3IFZhbHVlTm9kZShvd25lcklELCBoYXNoKGtleSksIFtrZXksIHZhbHVlXSk7XG4gICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IGVudHJpZXMubGVuZ3RoOyBpaSsrKSB7XG4gICAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2lpXTtcbiAgICAgIG5vZGUgPSBub2RlLnVwZGF0ZShvd25lcklELCAwLCB1bmRlZmluZWQsIGVudHJ5WzBdLCBlbnRyeVsxXSk7XG4gICAgfVxuICAgIHJldHVybiBub2RlO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFja05vZGVzKG93bmVySUQsIG5vZGVzLCBjb3VudCwgZXhjbHVkaW5nKSB7XG4gICAgdmFyIGJpdG1hcCA9IDA7XG4gICAgdmFyIHBhY2tlZElJID0gMDtcbiAgICB2YXIgcGFja2VkTm9kZXMgPSBuZXcgQXJyYXkoY291bnQpO1xuICAgIGZvciAodmFyIGlpID0gMCwgYml0ID0gMSwgbGVuID0gbm9kZXMubGVuZ3RoOyBpaSA8IGxlbjsgaWkrKywgYml0IDw8PSAxKSB7XG4gICAgICB2YXIgbm9kZSA9IG5vZGVzW2lpXTtcbiAgICAgIGlmIChub2RlICE9PSB1bmRlZmluZWQgJiYgaWkgIT09IGV4Y2x1ZGluZykge1xuICAgICAgICBiaXRtYXAgfD0gYml0O1xuICAgICAgICBwYWNrZWROb2Rlc1twYWNrZWRJSSsrXSA9IG5vZGU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXcgQml0bWFwSW5kZXhlZE5vZGUob3duZXJJRCwgYml0bWFwLCBwYWNrZWROb2Rlcyk7XG4gIH1cblxuICBmdW5jdGlvbiBleHBhbmROb2Rlcyhvd25lcklELCBub2RlcywgYml0bWFwLCBpbmNsdWRpbmcsIG5vZGUpIHtcbiAgICB2YXIgY291bnQgPSAwO1xuICAgIHZhciBleHBhbmRlZE5vZGVzID0gbmV3IEFycmF5KFNJWkUpO1xuICAgIGZvciAodmFyIGlpID0gMDsgYml0bWFwICE9PSAwOyBpaSsrLCBiaXRtYXAgPj4+PSAxKSB7XG4gICAgICBleHBhbmRlZE5vZGVzW2lpXSA9IGJpdG1hcCAmIDEgPyBub2Rlc1tjb3VudCsrXSA6IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgZXhwYW5kZWROb2Rlc1tpbmNsdWRpbmddID0gbm9kZTtcbiAgICByZXR1cm4gbmV3IEhhc2hBcnJheU1hcE5vZGUob3duZXJJRCwgY291bnQgKyAxLCBleHBhbmRlZE5vZGVzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1lcmdlSW50b01hcFdpdGgobWFwLCBtZXJnZXIsIGl0ZXJhYmxlcykge1xuICAgIHZhciBpdGVycyA9IFtdO1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCBpdGVyYWJsZXMubGVuZ3RoOyBpaSsrKSB7XG4gICAgICB2YXIgdmFsdWUgPSBpdGVyYWJsZXNbaWldO1xuICAgICAgdmFyIGl0ZXIgPSBLZXllZEl0ZXJhYmxlKHZhbHVlKTtcbiAgICAgIGlmICghaXNJdGVyYWJsZSh2YWx1ZSkpIHtcbiAgICAgICAgaXRlciA9IGl0ZXIubWFwKGZ1bmN0aW9uKHYgKSB7cmV0dXJuIGZyb21KUyh2KX0pO1xuICAgICAgfVxuICAgICAgaXRlcnMucHVzaChpdGVyKTtcbiAgICB9XG4gICAgcmV0dXJuIG1lcmdlSW50b0NvbGxlY3Rpb25XaXRoKG1hcCwgbWVyZ2VyLCBpdGVycyk7XG4gIH1cblxuICBmdW5jdGlvbiBkZWVwTWVyZ2VyKGV4aXN0aW5nLCB2YWx1ZSwga2V5KSB7XG4gICAgcmV0dXJuIGV4aXN0aW5nICYmIGV4aXN0aW5nLm1lcmdlRGVlcCAmJiBpc0l0ZXJhYmxlKHZhbHVlKSA/XG4gICAgICBleGlzdGluZy5tZXJnZURlZXAodmFsdWUpIDpcbiAgICAgIGlzKGV4aXN0aW5nLCB2YWx1ZSkgPyBleGlzdGluZyA6IHZhbHVlO1xuICB9XG5cbiAgZnVuY3Rpb24gZGVlcE1lcmdlcldpdGgobWVyZ2VyKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGV4aXN0aW5nLCB2YWx1ZSwga2V5KSAge1xuICAgICAgaWYgKGV4aXN0aW5nICYmIGV4aXN0aW5nLm1lcmdlRGVlcFdpdGggJiYgaXNJdGVyYWJsZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGV4aXN0aW5nLm1lcmdlRGVlcFdpdGgobWVyZ2VyLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgICB2YXIgbmV4dFZhbHVlID0gbWVyZ2VyKGV4aXN0aW5nLCB2YWx1ZSwga2V5KTtcbiAgICAgIHJldHVybiBpcyhleGlzdGluZywgbmV4dFZhbHVlKSA/IGV4aXN0aW5nIDogbmV4dFZhbHVlO1xuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBtZXJnZUludG9Db2xsZWN0aW9uV2l0aChjb2xsZWN0aW9uLCBtZXJnZXIsIGl0ZXJzKSB7XG4gICAgaXRlcnMgPSBpdGVycy5maWx0ZXIoZnVuY3Rpb24oeCApIHtyZXR1cm4geC5zaXplICE9PSAwfSk7XG4gICAgaWYgKGl0ZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGNvbGxlY3Rpb247XG4gICAgfVxuICAgIGlmIChjb2xsZWN0aW9uLnNpemUgPT09IDAgJiYgIWNvbGxlY3Rpb24uX19vd25lcklEICYmIGl0ZXJzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcmV0dXJuIGNvbGxlY3Rpb24uY29uc3RydWN0b3IoaXRlcnNbMF0pO1xuICAgIH1cbiAgICByZXR1cm4gY29sbGVjdGlvbi53aXRoTXV0YXRpb25zKGZ1bmN0aW9uKGNvbGxlY3Rpb24gKSB7XG4gICAgICB2YXIgbWVyZ2VJbnRvTWFwID0gbWVyZ2VyID9cbiAgICAgICAgZnVuY3Rpb24odmFsdWUsIGtleSkgIHtcbiAgICAgICAgICBjb2xsZWN0aW9uLnVwZGF0ZShrZXksIE5PVF9TRVQsIGZ1bmN0aW9uKGV4aXN0aW5nIClcbiAgICAgICAgICAgIHtyZXR1cm4gZXhpc3RpbmcgPT09IE5PVF9TRVQgPyB2YWx1ZSA6IG1lcmdlcihleGlzdGluZywgdmFsdWUsIGtleSl9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSA6XG4gICAgICAgIGZ1bmN0aW9uKHZhbHVlLCBrZXkpICB7XG4gICAgICAgICAgY29sbGVjdGlvbi5zZXQoa2V5LCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCBpdGVycy5sZW5ndGg7IGlpKyspIHtcbiAgICAgICAgaXRlcnNbaWldLmZvckVhY2gobWVyZ2VJbnRvTWFwKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZUluRGVlcE1hcChleGlzdGluZywga2V5UGF0aEl0ZXIsIG5vdFNldFZhbHVlLCB1cGRhdGVyKSB7XG4gICAgdmFyIGlzTm90U2V0ID0gZXhpc3RpbmcgPT09IE5PVF9TRVQ7XG4gICAgdmFyIHN0ZXAgPSBrZXlQYXRoSXRlci5uZXh0KCk7XG4gICAgaWYgKHN0ZXAuZG9uZSkge1xuICAgICAgdmFyIGV4aXN0aW5nVmFsdWUgPSBpc05vdFNldCA/IG5vdFNldFZhbHVlIDogZXhpc3Rpbmc7XG4gICAgICB2YXIgbmV3VmFsdWUgPSB1cGRhdGVyKGV4aXN0aW5nVmFsdWUpO1xuICAgICAgcmV0dXJuIG5ld1ZhbHVlID09PSBleGlzdGluZ1ZhbHVlID8gZXhpc3RpbmcgOiBuZXdWYWx1ZTtcbiAgICB9XG4gICAgaW52YXJpYW50KFxuICAgICAgaXNOb3RTZXQgfHwgKGV4aXN0aW5nICYmIGV4aXN0aW5nLnNldCksXG4gICAgICAnaW52YWxpZCBrZXlQYXRoJ1xuICAgICk7XG4gICAgdmFyIGtleSA9IHN0ZXAudmFsdWU7XG4gICAgdmFyIG5leHRFeGlzdGluZyA9IGlzTm90U2V0ID8gTk9UX1NFVCA6IGV4aXN0aW5nLmdldChrZXksIE5PVF9TRVQpO1xuICAgIHZhciBuZXh0VXBkYXRlZCA9IHVwZGF0ZUluRGVlcE1hcChcbiAgICAgIG5leHRFeGlzdGluZyxcbiAgICAgIGtleVBhdGhJdGVyLFxuICAgICAgbm90U2V0VmFsdWUsXG4gICAgICB1cGRhdGVyXG4gICAgKTtcbiAgICByZXR1cm4gbmV4dFVwZGF0ZWQgPT09IG5leHRFeGlzdGluZyA/IGV4aXN0aW5nIDpcbiAgICAgIG5leHRVcGRhdGVkID09PSBOT1RfU0VUID8gZXhpc3RpbmcucmVtb3ZlKGtleSkgOlxuICAgICAgKGlzTm90U2V0ID8gZW1wdHlNYXAoKSA6IGV4aXN0aW5nKS5zZXQoa2V5LCBuZXh0VXBkYXRlZCk7XG4gIH1cblxuICBmdW5jdGlvbiBwb3BDb3VudCh4KSB7XG4gICAgeCA9IHggLSAoKHggPj4gMSkgJiAweDU1NTU1NTU1KTtcbiAgICB4ID0gKHggJiAweDMzMzMzMzMzKSArICgoeCA+PiAyKSAmIDB4MzMzMzMzMzMpO1xuICAgIHggPSAoeCArICh4ID4+IDQpKSAmIDB4MGYwZjBmMGY7XG4gICAgeCA9IHggKyAoeCA+PiA4KTtcbiAgICB4ID0geCArICh4ID4+IDE2KTtcbiAgICByZXR1cm4geCAmIDB4N2Y7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRJbihhcnJheSwgaWR4LCB2YWwsIGNhbkVkaXQpIHtcbiAgICB2YXIgbmV3QXJyYXkgPSBjYW5FZGl0ID8gYXJyYXkgOiBhcnJDb3B5KGFycmF5KTtcbiAgICBuZXdBcnJheVtpZHhdID0gdmFsO1xuICAgIHJldHVybiBuZXdBcnJheTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNwbGljZUluKGFycmF5LCBpZHgsIHZhbCwgY2FuRWRpdCkge1xuICAgIHZhciBuZXdMZW4gPSBhcnJheS5sZW5ndGggKyAxO1xuICAgIGlmIChjYW5FZGl0ICYmIGlkeCArIDEgPT09IG5ld0xlbikge1xuICAgICAgYXJyYXlbaWR4XSA9IHZhbDtcbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG4gICAgdmFyIG5ld0FycmF5ID0gbmV3IEFycmF5KG5ld0xlbik7XG4gICAgdmFyIGFmdGVyID0gMDtcbiAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgbmV3TGVuOyBpaSsrKSB7XG4gICAgICBpZiAoaWkgPT09IGlkeCkge1xuICAgICAgICBuZXdBcnJheVtpaV0gPSB2YWw7XG4gICAgICAgIGFmdGVyID0gLTE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXdBcnJheVtpaV0gPSBhcnJheVtpaSArIGFmdGVyXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ld0FycmF5O1xuICB9XG5cbiAgZnVuY3Rpb24gc3BsaWNlT3V0KGFycmF5LCBpZHgsIGNhbkVkaXQpIHtcbiAgICB2YXIgbmV3TGVuID0gYXJyYXkubGVuZ3RoIC0gMTtcbiAgICBpZiAoY2FuRWRpdCAmJiBpZHggPT09IG5ld0xlbikge1xuICAgICAgYXJyYXkucG9wKCk7XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfVxuICAgIHZhciBuZXdBcnJheSA9IG5ldyBBcnJheShuZXdMZW4pO1xuICAgIHZhciBhZnRlciA9IDA7XG4gICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IG5ld0xlbjsgaWkrKykge1xuICAgICAgaWYgKGlpID09PSBpZHgpIHtcbiAgICAgICAgYWZ0ZXIgPSAxO1xuICAgICAgfVxuICAgICAgbmV3QXJyYXlbaWldID0gYXJyYXlbaWkgKyBhZnRlcl07XG4gICAgfVxuICAgIHJldHVybiBuZXdBcnJheTtcbiAgfVxuXG4gIHZhciBNQVhfQVJSQVlfTUFQX1NJWkUgPSBTSVpFIC8gNDtcbiAgdmFyIE1BWF9CSVRNQVBfSU5ERVhFRF9TSVpFID0gU0laRSAvIDI7XG4gIHZhciBNSU5fSEFTSF9BUlJBWV9NQVBfU0laRSA9IFNJWkUgLyA0O1xuXG4gIGNyZWF0ZUNsYXNzKExpc3QsIEluZGV4ZWRDb2xsZWN0aW9uKTtcblxuICAgIC8vIEBwcmFnbWEgQ29uc3RydWN0aW9uXG5cbiAgICBmdW5jdGlvbiBMaXN0KHZhbHVlKSB7XG4gICAgICB2YXIgZW1wdHkgPSBlbXB0eUxpc3QoKTtcbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBlbXB0eTtcbiAgICAgIH1cbiAgICAgIGlmIChpc0xpc3QodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHZhciBpdGVyID0gSW5kZXhlZEl0ZXJhYmxlKHZhbHVlKTtcbiAgICAgIHZhciBzaXplID0gaXRlci5zaXplO1xuICAgICAgaWYgKHNpemUgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIGVtcHR5O1xuICAgICAgfVxuICAgICAgYXNzZXJ0Tm90SW5maW5pdGUoc2l6ZSk7XG4gICAgICBpZiAoc2l6ZSA+IDAgJiYgc2l6ZSA8IFNJWkUpIHtcbiAgICAgICAgcmV0dXJuIG1ha2VMaXN0KDAsIHNpemUsIFNISUZULCBudWxsLCBuZXcgVk5vZGUoaXRlci50b0FycmF5KCkpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBlbXB0eS53aXRoTXV0YXRpb25zKGZ1bmN0aW9uKGxpc3QgKSB7XG4gICAgICAgIGxpc3Quc2V0U2l6ZShzaXplKTtcbiAgICAgICAgaXRlci5mb3JFYWNoKGZ1bmN0aW9uKHYsIGkpICB7cmV0dXJuIGxpc3Quc2V0KGksIHYpfSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBMaXN0Lm9mID0gZnVuY3Rpb24oLyouLi52YWx1ZXMqLykge1xuICAgICAgcmV0dXJuIHRoaXMoYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgTGlzdC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fdG9TdHJpbmcoJ0xpc3QgWycsICddJyk7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgQWNjZXNzXG5cbiAgICBMaXN0LnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihpbmRleCwgbm90U2V0VmFsdWUpIHtcbiAgICAgIGluZGV4ID0gd3JhcEluZGV4KHRoaXMsIGluZGV4KTtcbiAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgdGhpcy5zaXplKSB7XG4gICAgICAgIGluZGV4ICs9IHRoaXMuX29yaWdpbjtcbiAgICAgICAgdmFyIG5vZGUgPSBsaXN0Tm9kZUZvcih0aGlzLCBpbmRleCk7XG4gICAgICAgIHJldHVybiBub2RlICYmIG5vZGUuYXJyYXlbaW5kZXggJiBNQVNLXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBub3RTZXRWYWx1ZTtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBNb2RpZmljYXRpb25cblxuICAgIExpc3QucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKGluZGV4LCB2YWx1ZSkge1xuICAgICAgcmV0dXJuIHVwZGF0ZUxpc3QodGhpcywgaW5kZXgsIHZhbHVlKTtcbiAgICB9O1xuXG4gICAgTGlzdC5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24oaW5kZXgpIHtcbiAgICAgIHJldHVybiAhdGhpcy5oYXMoaW5kZXgpID8gdGhpcyA6XG4gICAgICAgIGluZGV4ID09PSAwID8gdGhpcy5zaGlmdCgpIDpcbiAgICAgICAgaW5kZXggPT09IHRoaXMuc2l6ZSAtIDEgPyB0aGlzLnBvcCgpIDpcbiAgICAgICAgdGhpcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS5pbnNlcnQgPSBmdW5jdGlvbihpbmRleCwgdmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLnNwbGljZShpbmRleCwgMCwgdmFsdWUpO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuc2l6ZSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9fb3duZXJJRCkge1xuICAgICAgICB0aGlzLnNpemUgPSB0aGlzLl9vcmlnaW4gPSB0aGlzLl9jYXBhY2l0eSA9IDA7XG4gICAgICAgIHRoaXMuX2xldmVsID0gU0hJRlQ7XG4gICAgICAgIHRoaXMuX3Jvb3QgPSB0aGlzLl90YWlsID0gbnVsbDtcbiAgICAgICAgdGhpcy5fX2hhc2ggPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX19hbHRlcmVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gZW1wdHlMaXN0KCk7XG4gICAgfTtcblxuICAgIExpc3QucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbigvKi4uLnZhbHVlcyovKSB7XG4gICAgICB2YXIgdmFsdWVzID0gYXJndW1lbnRzO1xuICAgICAgdmFyIG9sZFNpemUgPSB0aGlzLnNpemU7XG4gICAgICByZXR1cm4gdGhpcy53aXRoTXV0YXRpb25zKGZ1bmN0aW9uKGxpc3QgKSB7XG4gICAgICAgIHNldExpc3RCb3VuZHMobGlzdCwgMCwgb2xkU2l6ZSArIHZhbHVlcy5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgdmFsdWVzLmxlbmd0aDsgaWkrKykge1xuICAgICAgICAgIGxpc3Quc2V0KG9sZFNpemUgKyBpaSwgdmFsdWVzW2lpXSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS5wb3AgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBzZXRMaXN0Qm91bmRzKHRoaXMsIDAsIC0xKTtcbiAgICB9O1xuXG4gICAgTGlzdC5wcm90b3R5cGUudW5zaGlmdCA9IGZ1bmN0aW9uKC8qLi4udmFsdWVzKi8pIHtcbiAgICAgIHZhciB2YWx1ZXMgPSBhcmd1bWVudHM7XG4gICAgICByZXR1cm4gdGhpcy53aXRoTXV0YXRpb25zKGZ1bmN0aW9uKGxpc3QgKSB7XG4gICAgICAgIHNldExpc3RCb3VuZHMobGlzdCwgLXZhbHVlcy5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgdmFsdWVzLmxlbmd0aDsgaWkrKykge1xuICAgICAgICAgIGxpc3Quc2V0KGlpLCB2YWx1ZXNbaWldKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIExpc3QucHJvdG90eXBlLnNoaWZ0ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gc2V0TGlzdEJvdW5kcyh0aGlzLCAxKTtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBDb21wb3NpdGlvblxuXG4gICAgTGlzdC5wcm90b3R5cGUubWVyZ2UgPSBmdW5jdGlvbigvKi4uLml0ZXJzKi8pIHtcbiAgICAgIHJldHVybiBtZXJnZUludG9MaXN0V2l0aCh0aGlzLCB1bmRlZmluZWQsIGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIExpc3QucHJvdG90eXBlLm1lcmdlV2l0aCA9IGZ1bmN0aW9uKG1lcmdlcikge3ZhciBpdGVycyA9IFNMSUNFJDAuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgcmV0dXJuIG1lcmdlSW50b0xpc3RXaXRoKHRoaXMsIG1lcmdlciwgaXRlcnMpO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS5tZXJnZURlZXAgPSBmdW5jdGlvbigvKi4uLml0ZXJzKi8pIHtcbiAgICAgIHJldHVybiBtZXJnZUludG9MaXN0V2l0aCh0aGlzLCBkZWVwTWVyZ2VyLCBhcmd1bWVudHMpO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS5tZXJnZURlZXBXaXRoID0gZnVuY3Rpb24obWVyZ2VyKSB7dmFyIGl0ZXJzID0gU0xJQ0UkMC5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICByZXR1cm4gbWVyZ2VJbnRvTGlzdFdpdGgodGhpcywgZGVlcE1lcmdlcldpdGgobWVyZ2VyKSwgaXRlcnMpO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS5zZXRTaXplID0gZnVuY3Rpb24oc2l6ZSkge1xuICAgICAgcmV0dXJuIHNldExpc3RCb3VuZHModGhpcywgMCwgc2l6ZSk7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgSXRlcmF0aW9uXG5cbiAgICBMaXN0LnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcbiAgICAgIHZhciBzaXplID0gdGhpcy5zaXplO1xuICAgICAgaWYgKHdob2xlU2xpY2UoYmVnaW4sIGVuZCwgc2l6ZSkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gc2V0TGlzdEJvdW5kcyhcbiAgICAgICAgdGhpcyxcbiAgICAgICAgcmVzb2x2ZUJlZ2luKGJlZ2luLCBzaXplKSxcbiAgICAgICAgcmVzb2x2ZUVuZChlbmQsIHNpemUpXG4gICAgICApO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS5fX2l0ZXJhdG9yID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgdmFyIGluZGV4ID0gMDtcbiAgICAgIHZhciB2YWx1ZXMgPSBpdGVyYXRlTGlzdCh0aGlzLCByZXZlcnNlKTtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSAge1xuICAgICAgICB2YXIgdmFsdWUgPSB2YWx1ZXMoKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSBET05FID9cbiAgICAgICAgICBpdGVyYXRvckRvbmUoKSA6XG4gICAgICAgICAgaXRlcmF0b3JWYWx1ZSh0eXBlLCBpbmRleCsrLCB2YWx1ZSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgTGlzdC5wcm90b3R5cGUuX19pdGVyYXRlID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHtcbiAgICAgIHZhciBpbmRleCA9IDA7XG4gICAgICB2YXIgdmFsdWVzID0gaXRlcmF0ZUxpc3QodGhpcywgcmV2ZXJzZSk7XG4gICAgICB2YXIgdmFsdWU7XG4gICAgICB3aGlsZSAoKHZhbHVlID0gdmFsdWVzKCkpICE9PSBET05FKSB7XG4gICAgICAgIGlmIChmbih2YWx1ZSwgaW5kZXgrKywgdGhpcykgPT09IGZhbHNlKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9O1xuXG4gICAgTGlzdC5wcm90b3R5cGUuX19lbnN1cmVPd25lciA9IGZ1bmN0aW9uKG93bmVySUQpIHtcbiAgICAgIGlmIChvd25lcklEID09PSB0aGlzLl9fb3duZXJJRCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGlmICghb3duZXJJRCkge1xuICAgICAgICB0aGlzLl9fb3duZXJJRCA9IG93bmVySUQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1ha2VMaXN0KHRoaXMuX29yaWdpbiwgdGhpcy5fY2FwYWNpdHksIHRoaXMuX2xldmVsLCB0aGlzLl9yb290LCB0aGlzLl90YWlsLCBvd25lcklELCB0aGlzLl9faGFzaCk7XG4gICAgfTtcblxuXG4gIGZ1bmN0aW9uIGlzTGlzdChtYXliZUxpc3QpIHtcbiAgICByZXR1cm4gISEobWF5YmVMaXN0ICYmIG1heWJlTGlzdFtJU19MSVNUX1NFTlRJTkVMXSk7XG4gIH1cblxuICBMaXN0LmlzTGlzdCA9IGlzTGlzdDtcblxuICB2YXIgSVNfTElTVF9TRU5USU5FTCA9ICdAQF9fSU1NVVRBQkxFX0xJU1RfX0BAJztcblxuICB2YXIgTGlzdFByb3RvdHlwZSA9IExpc3QucHJvdG90eXBlO1xuICBMaXN0UHJvdG90eXBlW0lTX0xJU1RfU0VOVElORUxdID0gdHJ1ZTtcbiAgTGlzdFByb3RvdHlwZVtERUxFVEVdID0gTGlzdFByb3RvdHlwZS5yZW1vdmU7XG4gIExpc3RQcm90b3R5cGUuc2V0SW4gPSBNYXBQcm90b3R5cGUuc2V0SW47XG4gIExpc3RQcm90b3R5cGUuZGVsZXRlSW4gPVxuICBMaXN0UHJvdG90eXBlLnJlbW92ZUluID0gTWFwUHJvdG90eXBlLnJlbW92ZUluO1xuICBMaXN0UHJvdG90eXBlLnVwZGF0ZSA9IE1hcFByb3RvdHlwZS51cGRhdGU7XG4gIExpc3RQcm90b3R5cGUudXBkYXRlSW4gPSBNYXBQcm90b3R5cGUudXBkYXRlSW47XG4gIExpc3RQcm90b3R5cGUubWVyZ2VJbiA9IE1hcFByb3RvdHlwZS5tZXJnZUluO1xuICBMaXN0UHJvdG90eXBlLm1lcmdlRGVlcEluID0gTWFwUHJvdG90eXBlLm1lcmdlRGVlcEluO1xuICBMaXN0UHJvdG90eXBlLndpdGhNdXRhdGlvbnMgPSBNYXBQcm90b3R5cGUud2l0aE11dGF0aW9ucztcbiAgTGlzdFByb3RvdHlwZS5hc011dGFibGUgPSBNYXBQcm90b3R5cGUuYXNNdXRhYmxlO1xuICBMaXN0UHJvdG90eXBlLmFzSW1tdXRhYmxlID0gTWFwUHJvdG90eXBlLmFzSW1tdXRhYmxlO1xuICBMaXN0UHJvdG90eXBlLndhc0FsdGVyZWQgPSBNYXBQcm90b3R5cGUud2FzQWx0ZXJlZDtcblxuXG5cbiAgICBmdW5jdGlvbiBWTm9kZShhcnJheSwgb3duZXJJRCkge1xuICAgICAgdGhpcy5hcnJheSA9IGFycmF5O1xuICAgICAgdGhpcy5vd25lcklEID0gb3duZXJJRDtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBzZWVtcyBsaWtlIHRoZXNlIG1ldGhvZHMgYXJlIHZlcnkgc2ltaWxhclxuXG4gICAgVk5vZGUucHJvdG90eXBlLnJlbW92ZUJlZm9yZSA9IGZ1bmN0aW9uKG93bmVySUQsIGxldmVsLCBpbmRleCkge1xuICAgICAgaWYgKGluZGV4ID09PSBsZXZlbCA/IDEgPDwgbGV2ZWwgOiAwIHx8IHRoaXMuYXJyYXkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgdmFyIG9yaWdpbkluZGV4ID0gKGluZGV4ID4+PiBsZXZlbCkgJiBNQVNLO1xuICAgICAgaWYgKG9yaWdpbkluZGV4ID49IHRoaXMuYXJyYXkubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBuZXcgVk5vZGUoW10sIG93bmVySUQpO1xuICAgICAgfVxuICAgICAgdmFyIHJlbW92aW5nRmlyc3QgPSBvcmlnaW5JbmRleCA9PT0gMDtcbiAgICAgIHZhciBuZXdDaGlsZDtcbiAgICAgIGlmIChsZXZlbCA+IDApIHtcbiAgICAgICAgdmFyIG9sZENoaWxkID0gdGhpcy5hcnJheVtvcmlnaW5JbmRleF07XG4gICAgICAgIG5ld0NoaWxkID0gb2xkQ2hpbGQgJiYgb2xkQ2hpbGQucmVtb3ZlQmVmb3JlKG93bmVySUQsIGxldmVsIC0gU0hJRlQsIGluZGV4KTtcbiAgICAgICAgaWYgKG5ld0NoaWxkID09PSBvbGRDaGlsZCAmJiByZW1vdmluZ0ZpcnN0KSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChyZW1vdmluZ0ZpcnN0ICYmICFuZXdDaGlsZCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHZhciBlZGl0YWJsZSA9IGVkaXRhYmxlVk5vZGUodGhpcywgb3duZXJJRCk7XG4gICAgICBpZiAoIXJlbW92aW5nRmlyc3QpIHtcbiAgICAgICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IG9yaWdpbkluZGV4OyBpaSsrKSB7XG4gICAgICAgICAgZWRpdGFibGUuYXJyYXlbaWldID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobmV3Q2hpbGQpIHtcbiAgICAgICAgZWRpdGFibGUuYXJyYXlbb3JpZ2luSW5kZXhdID0gbmV3Q2hpbGQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gZWRpdGFibGU7XG4gICAgfTtcblxuICAgIFZOb2RlLnByb3RvdHlwZS5yZW1vdmVBZnRlciA9IGZ1bmN0aW9uKG93bmVySUQsIGxldmVsLCBpbmRleCkge1xuICAgICAgaWYgKGluZGV4ID09PSAobGV2ZWwgPyAxIDw8IGxldmVsIDogMCkgfHwgdGhpcy5hcnJheS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICB2YXIgc2l6ZUluZGV4ID0gKChpbmRleCAtIDEpID4+PiBsZXZlbCkgJiBNQVNLO1xuICAgICAgaWYgKHNpemVJbmRleCA+PSB0aGlzLmFycmF5Lmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgdmFyIG5ld0NoaWxkO1xuICAgICAgaWYgKGxldmVsID4gMCkge1xuICAgICAgICB2YXIgb2xkQ2hpbGQgPSB0aGlzLmFycmF5W3NpemVJbmRleF07XG4gICAgICAgIG5ld0NoaWxkID0gb2xkQ2hpbGQgJiYgb2xkQ2hpbGQucmVtb3ZlQWZ0ZXIob3duZXJJRCwgbGV2ZWwgLSBTSElGVCwgaW5kZXgpO1xuICAgICAgICBpZiAobmV3Q2hpbGQgPT09IG9sZENoaWxkICYmIHNpemVJbmRleCA9PT0gdGhpcy5hcnJheS5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIGVkaXRhYmxlID0gZWRpdGFibGVWTm9kZSh0aGlzLCBvd25lcklEKTtcbiAgICAgIGVkaXRhYmxlLmFycmF5LnNwbGljZShzaXplSW5kZXggKyAxKTtcbiAgICAgIGlmIChuZXdDaGlsZCkge1xuICAgICAgICBlZGl0YWJsZS5hcnJheVtzaXplSW5kZXhdID0gbmV3Q2hpbGQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gZWRpdGFibGU7XG4gICAgfTtcblxuXG5cbiAgdmFyIERPTkUgPSB7fTtcblxuICBmdW5jdGlvbiBpdGVyYXRlTGlzdChsaXN0LCByZXZlcnNlKSB7XG4gICAgdmFyIGxlZnQgPSBsaXN0Ll9vcmlnaW47XG4gICAgdmFyIHJpZ2h0ID0gbGlzdC5fY2FwYWNpdHk7XG4gICAgdmFyIHRhaWxQb3MgPSBnZXRUYWlsT2Zmc2V0KHJpZ2h0KTtcbiAgICB2YXIgdGFpbCA9IGxpc3QuX3RhaWw7XG5cbiAgICByZXR1cm4gaXRlcmF0ZU5vZGVPckxlYWYobGlzdC5fcm9vdCwgbGlzdC5fbGV2ZWwsIDApO1xuXG4gICAgZnVuY3Rpb24gaXRlcmF0ZU5vZGVPckxlYWYobm9kZSwgbGV2ZWwsIG9mZnNldCkge1xuICAgICAgcmV0dXJuIGxldmVsID09PSAwID9cbiAgICAgICAgaXRlcmF0ZUxlYWYobm9kZSwgb2Zmc2V0KSA6XG4gICAgICAgIGl0ZXJhdGVOb2RlKG5vZGUsIGxldmVsLCBvZmZzZXQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGl0ZXJhdGVMZWFmKG5vZGUsIG9mZnNldCkge1xuICAgICAgdmFyIGFycmF5ID0gb2Zmc2V0ID09PSB0YWlsUG9zID8gdGFpbCAmJiB0YWlsLmFycmF5IDogbm9kZSAmJiBub2RlLmFycmF5O1xuICAgICAgdmFyIGZyb20gPSBvZmZzZXQgPiBsZWZ0ID8gMCA6IGxlZnQgLSBvZmZzZXQ7XG4gICAgICB2YXIgdG8gPSByaWdodCAtIG9mZnNldDtcbiAgICAgIGlmICh0byA+IFNJWkUpIHtcbiAgICAgICAgdG8gPSBTSVpFO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgaWYgKGZyb20gPT09IHRvKSB7XG4gICAgICAgICAgcmV0dXJuIERPTkU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGlkeCA9IHJldmVyc2UgPyAtLXRvIDogZnJvbSsrO1xuICAgICAgICByZXR1cm4gYXJyYXkgJiYgYXJyYXlbaWR4XTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXRlcmF0ZU5vZGUobm9kZSwgbGV2ZWwsIG9mZnNldCkge1xuICAgICAgdmFyIHZhbHVlcztcbiAgICAgIHZhciBhcnJheSA9IG5vZGUgJiYgbm9kZS5hcnJheTtcbiAgICAgIHZhciBmcm9tID0gb2Zmc2V0ID4gbGVmdCA/IDAgOiAobGVmdCAtIG9mZnNldCkgPj4gbGV2ZWw7XG4gICAgICB2YXIgdG8gPSAoKHJpZ2h0IC0gb2Zmc2V0KSA+PiBsZXZlbCkgKyAxO1xuICAgICAgaWYgKHRvID4gU0laRSkge1xuICAgICAgICB0byA9IFNJWkU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSAge1xuICAgICAgICBkbyB7XG4gICAgICAgICAgaWYgKHZhbHVlcykge1xuICAgICAgICAgICAgdmFyIHZhbHVlID0gdmFsdWVzKCk7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IERPTkUpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFsdWVzID0gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGZyb20gPT09IHRvKSB7XG4gICAgICAgICAgICByZXR1cm4gRE9ORTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIGlkeCA9IHJldmVyc2UgPyAtLXRvIDogZnJvbSsrO1xuICAgICAgICAgIHZhbHVlcyA9IGl0ZXJhdGVOb2RlT3JMZWFmKFxuICAgICAgICAgICAgYXJyYXkgJiYgYXJyYXlbaWR4XSwgbGV2ZWwgLSBTSElGVCwgb2Zmc2V0ICsgKGlkeCA8PCBsZXZlbClcbiAgICAgICAgICApO1xuICAgICAgICB9IHdoaWxlICh0cnVlKTtcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gbWFrZUxpc3Qob3JpZ2luLCBjYXBhY2l0eSwgbGV2ZWwsIHJvb3QsIHRhaWwsIG93bmVySUQsIGhhc2gpIHtcbiAgICB2YXIgbGlzdCA9IE9iamVjdC5jcmVhdGUoTGlzdFByb3RvdHlwZSk7XG4gICAgbGlzdC5zaXplID0gY2FwYWNpdHkgLSBvcmlnaW47XG4gICAgbGlzdC5fb3JpZ2luID0gb3JpZ2luO1xuICAgIGxpc3QuX2NhcGFjaXR5ID0gY2FwYWNpdHk7XG4gICAgbGlzdC5fbGV2ZWwgPSBsZXZlbDtcbiAgICBsaXN0Ll9yb290ID0gcm9vdDtcbiAgICBsaXN0Ll90YWlsID0gdGFpbDtcbiAgICBsaXN0Ll9fb3duZXJJRCA9IG93bmVySUQ7XG4gICAgbGlzdC5fX2hhc2ggPSBoYXNoO1xuICAgIGxpc3QuX19hbHRlcmVkID0gZmFsc2U7XG4gICAgcmV0dXJuIGxpc3Q7XG4gIH1cblxuICB2YXIgRU1QVFlfTElTVDtcbiAgZnVuY3Rpb24gZW1wdHlMaXN0KCkge1xuICAgIHJldHVybiBFTVBUWV9MSVNUIHx8IChFTVBUWV9MSVNUID0gbWFrZUxpc3QoMCwgMCwgU0hJRlQpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZUxpc3QobGlzdCwgaW5kZXgsIHZhbHVlKSB7XG4gICAgaW5kZXggPSB3cmFwSW5kZXgobGlzdCwgaW5kZXgpO1xuXG4gICAgaWYgKGluZGV4ICE9PSBpbmRleCkge1xuICAgICAgcmV0dXJuIGxpc3Q7XG4gICAgfVxuXG4gICAgaWYgKGluZGV4ID49IGxpc3Quc2l6ZSB8fCBpbmRleCA8IDApIHtcbiAgICAgIHJldHVybiBsaXN0LndpdGhNdXRhdGlvbnMoZnVuY3Rpb24obGlzdCApIHtcbiAgICAgICAgaW5kZXggPCAwID9cbiAgICAgICAgICBzZXRMaXN0Qm91bmRzKGxpc3QsIGluZGV4KS5zZXQoMCwgdmFsdWUpIDpcbiAgICAgICAgICBzZXRMaXN0Qm91bmRzKGxpc3QsIDAsIGluZGV4ICsgMSkuc2V0KGluZGV4LCB2YWx1ZSlcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGluZGV4ICs9IGxpc3QuX29yaWdpbjtcblxuICAgIHZhciBuZXdUYWlsID0gbGlzdC5fdGFpbDtcbiAgICB2YXIgbmV3Um9vdCA9IGxpc3QuX3Jvb3Q7XG4gICAgdmFyIGRpZEFsdGVyID0gTWFrZVJlZihESURfQUxURVIpO1xuICAgIGlmIChpbmRleCA+PSBnZXRUYWlsT2Zmc2V0KGxpc3QuX2NhcGFjaXR5KSkge1xuICAgICAgbmV3VGFpbCA9IHVwZGF0ZVZOb2RlKG5ld1RhaWwsIGxpc3QuX19vd25lcklELCAwLCBpbmRleCwgdmFsdWUsIGRpZEFsdGVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3Um9vdCA9IHVwZGF0ZVZOb2RlKG5ld1Jvb3QsIGxpc3QuX19vd25lcklELCBsaXN0Ll9sZXZlbCwgaW5kZXgsIHZhbHVlLCBkaWRBbHRlcik7XG4gICAgfVxuXG4gICAgaWYgKCFkaWRBbHRlci52YWx1ZSkge1xuICAgICAgcmV0dXJuIGxpc3Q7XG4gICAgfVxuXG4gICAgaWYgKGxpc3QuX19vd25lcklEKSB7XG4gICAgICBsaXN0Ll9yb290ID0gbmV3Um9vdDtcbiAgICAgIGxpc3QuX3RhaWwgPSBuZXdUYWlsO1xuICAgICAgbGlzdC5fX2hhc2ggPSB1bmRlZmluZWQ7XG4gICAgICBsaXN0Ll9fYWx0ZXJlZCA9IHRydWU7XG4gICAgICByZXR1cm4gbGlzdDtcbiAgICB9XG4gICAgcmV0dXJuIG1ha2VMaXN0KGxpc3QuX29yaWdpbiwgbGlzdC5fY2FwYWNpdHksIGxpc3QuX2xldmVsLCBuZXdSb290LCBuZXdUYWlsKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZVZOb2RlKG5vZGUsIG93bmVySUQsIGxldmVsLCBpbmRleCwgdmFsdWUsIGRpZEFsdGVyKSB7XG4gICAgdmFyIGlkeCA9IChpbmRleCA+Pj4gbGV2ZWwpICYgTUFTSztcbiAgICB2YXIgbm9kZUhhcyA9IG5vZGUgJiYgaWR4IDwgbm9kZS5hcnJheS5sZW5ndGg7XG4gICAgaWYgKCFub2RlSGFzICYmIHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBub2RlO1xuICAgIH1cblxuICAgIHZhciBuZXdOb2RlO1xuXG4gICAgaWYgKGxldmVsID4gMCkge1xuICAgICAgdmFyIGxvd2VyTm9kZSA9IG5vZGUgJiYgbm9kZS5hcnJheVtpZHhdO1xuICAgICAgdmFyIG5ld0xvd2VyTm9kZSA9IHVwZGF0ZVZOb2RlKGxvd2VyTm9kZSwgb3duZXJJRCwgbGV2ZWwgLSBTSElGVCwgaW5kZXgsIHZhbHVlLCBkaWRBbHRlcik7XG4gICAgICBpZiAobmV3TG93ZXJOb2RlID09PSBsb3dlck5vZGUpIHtcbiAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgICB9XG4gICAgICBuZXdOb2RlID0gZWRpdGFibGVWTm9kZShub2RlLCBvd25lcklEKTtcbiAgICAgIG5ld05vZGUuYXJyYXlbaWR4XSA9IG5ld0xvd2VyTm9kZTtcbiAgICAgIHJldHVybiBuZXdOb2RlO1xuICAgIH1cblxuICAgIGlmIChub2RlSGFzICYmIG5vZGUuYXJyYXlbaWR4XSA9PT0gdmFsdWUpIHtcbiAgICAgIHJldHVybiBub2RlO1xuICAgIH1cblxuICAgIFNldFJlZihkaWRBbHRlcik7XG5cbiAgICBuZXdOb2RlID0gZWRpdGFibGVWTm9kZShub2RlLCBvd25lcklEKTtcbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiBpZHggPT09IG5ld05vZGUuYXJyYXkubGVuZ3RoIC0gMSkge1xuICAgICAgbmV3Tm9kZS5hcnJheS5wb3AoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3Tm9kZS5hcnJheVtpZHhdID0gdmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBuZXdOb2RlO1xuICB9XG5cbiAgZnVuY3Rpb24gZWRpdGFibGVWTm9kZShub2RlLCBvd25lcklEKSB7XG4gICAgaWYgKG93bmVySUQgJiYgbm9kZSAmJiBvd25lcklEID09PSBub2RlLm93bmVySUQpIHtcbiAgICAgIHJldHVybiBub2RlO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFZOb2RlKG5vZGUgPyBub2RlLmFycmF5LnNsaWNlKCkgOiBbXSwgb3duZXJJRCk7XG4gIH1cblxuICBmdW5jdGlvbiBsaXN0Tm9kZUZvcihsaXN0LCByYXdJbmRleCkge1xuICAgIGlmIChyYXdJbmRleCA+PSBnZXRUYWlsT2Zmc2V0KGxpc3QuX2NhcGFjaXR5KSkge1xuICAgICAgcmV0dXJuIGxpc3QuX3RhaWw7XG4gICAgfVxuICAgIGlmIChyYXdJbmRleCA8IDEgPDwgKGxpc3QuX2xldmVsICsgU0hJRlQpKSB7XG4gICAgICB2YXIgbm9kZSA9IGxpc3QuX3Jvb3Q7XG4gICAgICB2YXIgbGV2ZWwgPSBsaXN0Ll9sZXZlbDtcbiAgICAgIHdoaWxlIChub2RlICYmIGxldmVsID4gMCkge1xuICAgICAgICBub2RlID0gbm9kZS5hcnJheVsocmF3SW5kZXggPj4+IGxldmVsKSAmIE1BU0tdO1xuICAgICAgICBsZXZlbCAtPSBTSElGVDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBub2RlO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNldExpc3RCb3VuZHMobGlzdCwgYmVnaW4sIGVuZCkge1xuICAgIC8vIFNhbml0aXplIGJlZ2luICYgZW5kIHVzaW5nIHRoaXMgc2hvcnRoYW5kIGZvciBUb0ludDMyKGFyZ3VtZW50KVxuICAgIC8vIGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b2ludDMyXG4gICAgaWYgKGJlZ2luICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGJlZ2luID0gYmVnaW4gfCAwO1xuICAgIH1cbiAgICBpZiAoZW5kICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGVuZCA9IGVuZCB8IDA7XG4gICAgfVxuICAgIHZhciBvd25lciA9IGxpc3QuX19vd25lcklEIHx8IG5ldyBPd25lcklEKCk7XG4gICAgdmFyIG9sZE9yaWdpbiA9IGxpc3QuX29yaWdpbjtcbiAgICB2YXIgb2xkQ2FwYWNpdHkgPSBsaXN0Ll9jYXBhY2l0eTtcbiAgICB2YXIgbmV3T3JpZ2luID0gb2xkT3JpZ2luICsgYmVnaW47XG4gICAgdmFyIG5ld0NhcGFjaXR5ID0gZW5kID09PSB1bmRlZmluZWQgPyBvbGRDYXBhY2l0eSA6IGVuZCA8IDAgPyBvbGRDYXBhY2l0eSArIGVuZCA6IG9sZE9yaWdpbiArIGVuZDtcbiAgICBpZiAobmV3T3JpZ2luID09PSBvbGRPcmlnaW4gJiYgbmV3Q2FwYWNpdHkgPT09IG9sZENhcGFjaXR5KSB7XG4gICAgICByZXR1cm4gbGlzdDtcbiAgICB9XG5cbiAgICAvLyBJZiBpdCdzIGdvaW5nIHRvIGVuZCBhZnRlciBpdCBzdGFydHMsIGl0J3MgZW1wdHkuXG4gICAgaWYgKG5ld09yaWdpbiA+PSBuZXdDYXBhY2l0eSkge1xuICAgICAgcmV0dXJuIGxpc3QuY2xlYXIoKTtcbiAgICB9XG5cbiAgICB2YXIgbmV3TGV2ZWwgPSBsaXN0Ll9sZXZlbDtcbiAgICB2YXIgbmV3Um9vdCA9IGxpc3QuX3Jvb3Q7XG5cbiAgICAvLyBOZXcgb3JpZ2luIG1pZ2h0IG5lZWQgY3JlYXRpbmcgYSBoaWdoZXIgcm9vdC5cbiAgICB2YXIgb2Zmc2V0U2hpZnQgPSAwO1xuICAgIHdoaWxlIChuZXdPcmlnaW4gKyBvZmZzZXRTaGlmdCA8IDApIHtcbiAgICAgIG5ld1Jvb3QgPSBuZXcgVk5vZGUobmV3Um9vdCAmJiBuZXdSb290LmFycmF5Lmxlbmd0aCA/IFt1bmRlZmluZWQsIG5ld1Jvb3RdIDogW10sIG93bmVyKTtcbiAgICAgIG5ld0xldmVsICs9IFNISUZUO1xuICAgICAgb2Zmc2V0U2hpZnQgKz0gMSA8PCBuZXdMZXZlbDtcbiAgICB9XG4gICAgaWYgKG9mZnNldFNoaWZ0KSB7XG4gICAgICBuZXdPcmlnaW4gKz0gb2Zmc2V0U2hpZnQ7XG4gICAgICBvbGRPcmlnaW4gKz0gb2Zmc2V0U2hpZnQ7XG4gICAgICBuZXdDYXBhY2l0eSArPSBvZmZzZXRTaGlmdDtcbiAgICAgIG9sZENhcGFjaXR5ICs9IG9mZnNldFNoaWZ0O1xuICAgIH1cblxuICAgIHZhciBvbGRUYWlsT2Zmc2V0ID0gZ2V0VGFpbE9mZnNldChvbGRDYXBhY2l0eSk7XG4gICAgdmFyIG5ld1RhaWxPZmZzZXQgPSBnZXRUYWlsT2Zmc2V0KG5ld0NhcGFjaXR5KTtcblxuICAgIC8vIE5ldyBzaXplIG1pZ2h0IG5lZWQgY3JlYXRpbmcgYSBoaWdoZXIgcm9vdC5cbiAgICB3aGlsZSAobmV3VGFpbE9mZnNldCA+PSAxIDw8IChuZXdMZXZlbCArIFNISUZUKSkge1xuICAgICAgbmV3Um9vdCA9IG5ldyBWTm9kZShuZXdSb290ICYmIG5ld1Jvb3QuYXJyYXkubGVuZ3RoID8gW25ld1Jvb3RdIDogW10sIG93bmVyKTtcbiAgICAgIG5ld0xldmVsICs9IFNISUZUO1xuICAgIH1cblxuICAgIC8vIExvY2F0ZSBvciBjcmVhdGUgdGhlIG5ldyB0YWlsLlxuICAgIHZhciBvbGRUYWlsID0gbGlzdC5fdGFpbDtcbiAgICB2YXIgbmV3VGFpbCA9IG5ld1RhaWxPZmZzZXQgPCBvbGRUYWlsT2Zmc2V0ID9cbiAgICAgIGxpc3ROb2RlRm9yKGxpc3QsIG5ld0NhcGFjaXR5IC0gMSkgOlxuICAgICAgbmV3VGFpbE9mZnNldCA+IG9sZFRhaWxPZmZzZXQgPyBuZXcgVk5vZGUoW10sIG93bmVyKSA6IG9sZFRhaWw7XG5cbiAgICAvLyBNZXJnZSBUYWlsIGludG8gdHJlZS5cbiAgICBpZiAob2xkVGFpbCAmJiBuZXdUYWlsT2Zmc2V0ID4gb2xkVGFpbE9mZnNldCAmJiBuZXdPcmlnaW4gPCBvbGRDYXBhY2l0eSAmJiBvbGRUYWlsLmFycmF5Lmxlbmd0aCkge1xuICAgICAgbmV3Um9vdCA9IGVkaXRhYmxlVk5vZGUobmV3Um9vdCwgb3duZXIpO1xuICAgICAgdmFyIG5vZGUgPSBuZXdSb290O1xuICAgICAgZm9yICh2YXIgbGV2ZWwgPSBuZXdMZXZlbDsgbGV2ZWwgPiBTSElGVDsgbGV2ZWwgLT0gU0hJRlQpIHtcbiAgICAgICAgdmFyIGlkeCA9IChvbGRUYWlsT2Zmc2V0ID4+PiBsZXZlbCkgJiBNQVNLO1xuICAgICAgICBub2RlID0gbm9kZS5hcnJheVtpZHhdID0gZWRpdGFibGVWTm9kZShub2RlLmFycmF5W2lkeF0sIG93bmVyKTtcbiAgICAgIH1cbiAgICAgIG5vZGUuYXJyYXlbKG9sZFRhaWxPZmZzZXQgPj4+IFNISUZUKSAmIE1BU0tdID0gb2xkVGFpbDtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgc2l6ZSBoYXMgYmVlbiByZWR1Y2VkLCB0aGVyZSdzIGEgY2hhbmNlIHRoZSB0YWlsIG5lZWRzIHRvIGJlIHRyaW1tZWQuXG4gICAgaWYgKG5ld0NhcGFjaXR5IDwgb2xkQ2FwYWNpdHkpIHtcbiAgICAgIG5ld1RhaWwgPSBuZXdUYWlsICYmIG5ld1RhaWwucmVtb3ZlQWZ0ZXIob3duZXIsIDAsIG5ld0NhcGFjaXR5KTtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgbmV3IG9yaWdpbiBpcyB3aXRoaW4gdGhlIHRhaWwsIHRoZW4gd2UgZG8gbm90IG5lZWQgYSByb290LlxuICAgIGlmIChuZXdPcmlnaW4gPj0gbmV3VGFpbE9mZnNldCkge1xuICAgICAgbmV3T3JpZ2luIC09IG5ld1RhaWxPZmZzZXQ7XG4gICAgICBuZXdDYXBhY2l0eSAtPSBuZXdUYWlsT2Zmc2V0O1xuICAgICAgbmV3TGV2ZWwgPSBTSElGVDtcbiAgICAgIG5ld1Jvb3QgPSBudWxsO1xuICAgICAgbmV3VGFpbCA9IG5ld1RhaWwgJiYgbmV3VGFpbC5yZW1vdmVCZWZvcmUob3duZXIsIDAsIG5ld09yaWdpbik7XG5cbiAgICAvLyBPdGhlcndpc2UsIGlmIHRoZSByb290IGhhcyBiZWVuIHRyaW1tZWQsIGdhcmJhZ2UgY29sbGVjdC5cbiAgICB9IGVsc2UgaWYgKG5ld09yaWdpbiA+IG9sZE9yaWdpbiB8fCBuZXdUYWlsT2Zmc2V0IDwgb2xkVGFpbE9mZnNldCkge1xuICAgICAgb2Zmc2V0U2hpZnQgPSAwO1xuXG4gICAgICAvLyBJZGVudGlmeSB0aGUgbmV3IHRvcCByb290IG5vZGUgb2YgdGhlIHN1YnRyZWUgb2YgdGhlIG9sZCByb290LlxuICAgICAgd2hpbGUgKG5ld1Jvb3QpIHtcbiAgICAgICAgdmFyIGJlZ2luSW5kZXggPSAobmV3T3JpZ2luID4+PiBuZXdMZXZlbCkgJiBNQVNLO1xuICAgICAgICBpZiAoYmVnaW5JbmRleCAhPT0gKG5ld1RhaWxPZmZzZXQgPj4+IG5ld0xldmVsKSAmIE1BU0spIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoYmVnaW5JbmRleCkge1xuICAgICAgICAgIG9mZnNldFNoaWZ0ICs9ICgxIDw8IG5ld0xldmVsKSAqIGJlZ2luSW5kZXg7XG4gICAgICAgIH1cbiAgICAgICAgbmV3TGV2ZWwgLT0gU0hJRlQ7XG4gICAgICAgIG5ld1Jvb3QgPSBuZXdSb290LmFycmF5W2JlZ2luSW5kZXhdO1xuICAgICAgfVxuXG4gICAgICAvLyBUcmltIHRoZSBuZXcgc2lkZXMgb2YgdGhlIG5ldyByb290LlxuICAgICAgaWYgKG5ld1Jvb3QgJiYgbmV3T3JpZ2luID4gb2xkT3JpZ2luKSB7XG4gICAgICAgIG5ld1Jvb3QgPSBuZXdSb290LnJlbW92ZUJlZm9yZShvd25lciwgbmV3TGV2ZWwsIG5ld09yaWdpbiAtIG9mZnNldFNoaWZ0KTtcbiAgICAgIH1cbiAgICAgIGlmIChuZXdSb290ICYmIG5ld1RhaWxPZmZzZXQgPCBvbGRUYWlsT2Zmc2V0KSB7XG4gICAgICAgIG5ld1Jvb3QgPSBuZXdSb290LnJlbW92ZUFmdGVyKG93bmVyLCBuZXdMZXZlbCwgbmV3VGFpbE9mZnNldCAtIG9mZnNldFNoaWZ0KTtcbiAgICAgIH1cbiAgICAgIGlmIChvZmZzZXRTaGlmdCkge1xuICAgICAgICBuZXdPcmlnaW4gLT0gb2Zmc2V0U2hpZnQ7XG4gICAgICAgIG5ld0NhcGFjaXR5IC09IG9mZnNldFNoaWZ0O1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChsaXN0Ll9fb3duZXJJRCkge1xuICAgICAgbGlzdC5zaXplID0gbmV3Q2FwYWNpdHkgLSBuZXdPcmlnaW47XG4gICAgICBsaXN0Ll9vcmlnaW4gPSBuZXdPcmlnaW47XG4gICAgICBsaXN0Ll9jYXBhY2l0eSA9IG5ld0NhcGFjaXR5O1xuICAgICAgbGlzdC5fbGV2ZWwgPSBuZXdMZXZlbDtcbiAgICAgIGxpc3QuX3Jvb3QgPSBuZXdSb290O1xuICAgICAgbGlzdC5fdGFpbCA9IG5ld1RhaWw7XG4gICAgICBsaXN0Ll9faGFzaCA9IHVuZGVmaW5lZDtcbiAgICAgIGxpc3QuX19hbHRlcmVkID0gdHJ1ZTtcbiAgICAgIHJldHVybiBsaXN0O1xuICAgIH1cbiAgICByZXR1cm4gbWFrZUxpc3QobmV3T3JpZ2luLCBuZXdDYXBhY2l0eSwgbmV3TGV2ZWwsIG5ld1Jvb3QsIG5ld1RhaWwpO1xuICB9XG5cbiAgZnVuY3Rpb24gbWVyZ2VJbnRvTGlzdFdpdGgobGlzdCwgbWVyZ2VyLCBpdGVyYWJsZXMpIHtcbiAgICB2YXIgaXRlcnMgPSBbXTtcbiAgICB2YXIgbWF4U2l6ZSA9IDA7XG4gICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IGl0ZXJhYmxlcy5sZW5ndGg7IGlpKyspIHtcbiAgICAgIHZhciB2YWx1ZSA9IGl0ZXJhYmxlc1tpaV07XG4gICAgICB2YXIgaXRlciA9IEluZGV4ZWRJdGVyYWJsZSh2YWx1ZSk7XG4gICAgICBpZiAoaXRlci5zaXplID4gbWF4U2l6ZSkge1xuICAgICAgICBtYXhTaXplID0gaXRlci5zaXplO1xuICAgICAgfVxuICAgICAgaWYgKCFpc0l0ZXJhYmxlKHZhbHVlKSkge1xuICAgICAgICBpdGVyID0gaXRlci5tYXAoZnVuY3Rpb24odiApIHtyZXR1cm4gZnJvbUpTKHYpfSk7XG4gICAgICB9XG4gICAgICBpdGVycy5wdXNoKGl0ZXIpO1xuICAgIH1cbiAgICBpZiAobWF4U2l6ZSA+IGxpc3Quc2l6ZSkge1xuICAgICAgbGlzdCA9IGxpc3Quc2V0U2l6ZShtYXhTaXplKTtcbiAgICB9XG4gICAgcmV0dXJuIG1lcmdlSW50b0NvbGxlY3Rpb25XaXRoKGxpc3QsIG1lcmdlciwgaXRlcnMpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0VGFpbE9mZnNldChzaXplKSB7XG4gICAgcmV0dXJuIHNpemUgPCBTSVpFID8gMCA6ICgoKHNpemUgLSAxKSA+Pj4gU0hJRlQpIDw8IFNISUZUKTtcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKE9yZGVyZWRNYXAsIE1hcCk7XG5cbiAgICAvLyBAcHJhZ21hIENvbnN0cnVjdGlvblxuXG4gICAgZnVuY3Rpb24gT3JkZXJlZE1hcCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgPyBlbXB0eU9yZGVyZWRNYXAoKSA6XG4gICAgICAgIGlzT3JkZXJlZE1hcCh2YWx1ZSkgPyB2YWx1ZSA6XG4gICAgICAgIGVtcHR5T3JkZXJlZE1hcCgpLndpdGhNdXRhdGlvbnMoZnVuY3Rpb24obWFwICkge1xuICAgICAgICAgIHZhciBpdGVyID0gS2V5ZWRJdGVyYWJsZSh2YWx1ZSk7XG4gICAgICAgICAgYXNzZXJ0Tm90SW5maW5pdGUoaXRlci5zaXplKTtcbiAgICAgICAgICBpdGVyLmZvckVhY2goZnVuY3Rpb24odiwgaykgIHtyZXR1cm4gbWFwLnNldChrLCB2KX0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBPcmRlcmVkTWFwLm9mID0gZnVuY3Rpb24oLyouLi52YWx1ZXMqLykge1xuICAgICAgcmV0dXJuIHRoaXMoYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgT3JkZXJlZE1hcC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fdG9TdHJpbmcoJ09yZGVyZWRNYXAgeycsICd9Jyk7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgQWNjZXNzXG5cbiAgICBPcmRlcmVkTWFwLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihrLCBub3RTZXRWYWx1ZSkge1xuICAgICAgdmFyIGluZGV4ID0gdGhpcy5fbWFwLmdldChrKTtcbiAgICAgIHJldHVybiBpbmRleCAhPT0gdW5kZWZpbmVkID8gdGhpcy5fbGlzdC5nZXQoaW5kZXgpWzFdIDogbm90U2V0VmFsdWU7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgTW9kaWZpY2F0aW9uXG5cbiAgICBPcmRlcmVkTWFwLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuc2l6ZSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9fb3duZXJJRCkge1xuICAgICAgICB0aGlzLnNpemUgPSAwO1xuICAgICAgICB0aGlzLl9tYXAuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5fbGlzdC5jbGVhcigpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBlbXB0eU9yZGVyZWRNYXAoKTtcbiAgICB9O1xuXG4gICAgT3JkZXJlZE1hcC5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24oaywgdikge1xuICAgICAgcmV0dXJuIHVwZGF0ZU9yZGVyZWRNYXAodGhpcywgaywgdik7XG4gICAgfTtcblxuICAgIE9yZGVyZWRNYXAucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uKGspIHtcbiAgICAgIHJldHVybiB1cGRhdGVPcmRlcmVkTWFwKHRoaXMsIGssIE5PVF9TRVQpO1xuICAgIH07XG5cbiAgICBPcmRlcmVkTWFwLnByb3RvdHlwZS53YXNBbHRlcmVkID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbWFwLndhc0FsdGVyZWQoKSB8fCB0aGlzLl9saXN0Lndhc0FsdGVyZWQoKTtcbiAgICB9O1xuXG4gICAgT3JkZXJlZE1hcC5wcm90b3R5cGUuX19pdGVyYXRlID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIHJldHVybiB0aGlzLl9saXN0Ll9faXRlcmF0ZShcbiAgICAgICAgZnVuY3Rpb24oZW50cnkgKSB7cmV0dXJuIGVudHJ5ICYmIGZuKGVudHJ5WzFdLCBlbnRyeVswXSwgdGhpcyQwKX0sXG4gICAgICAgIHJldmVyc2VcbiAgICAgICk7XG4gICAgfTtcblxuICAgIE9yZGVyZWRNYXAucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbGlzdC5mcm9tRW50cnlTZXEoKS5fX2l0ZXJhdG9yKHR5cGUsIHJldmVyc2UpO1xuICAgIH07XG5cbiAgICBPcmRlcmVkTWFwLnByb3RvdHlwZS5fX2Vuc3VyZU93bmVyID0gZnVuY3Rpb24ob3duZXJJRCkge1xuICAgICAgaWYgKG93bmVySUQgPT09IHRoaXMuX19vd25lcklEKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgdmFyIG5ld01hcCA9IHRoaXMuX21hcC5fX2Vuc3VyZU93bmVyKG93bmVySUQpO1xuICAgICAgdmFyIG5ld0xpc3QgPSB0aGlzLl9saXN0Ll9fZW5zdXJlT3duZXIob3duZXJJRCk7XG4gICAgICBpZiAoIW93bmVySUQpIHtcbiAgICAgICAgdGhpcy5fX293bmVySUQgPSBvd25lcklEO1xuICAgICAgICB0aGlzLl9tYXAgPSBuZXdNYXA7XG4gICAgICAgIHRoaXMuX2xpc3QgPSBuZXdMaXN0O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBtYWtlT3JkZXJlZE1hcChuZXdNYXAsIG5ld0xpc3QsIG93bmVySUQsIHRoaXMuX19oYXNoKTtcbiAgICB9O1xuXG5cbiAgZnVuY3Rpb24gaXNPcmRlcmVkTWFwKG1heWJlT3JkZXJlZE1hcCkge1xuICAgIHJldHVybiBpc01hcChtYXliZU9yZGVyZWRNYXApICYmIGlzT3JkZXJlZChtYXliZU9yZGVyZWRNYXApO1xuICB9XG5cbiAgT3JkZXJlZE1hcC5pc09yZGVyZWRNYXAgPSBpc09yZGVyZWRNYXA7XG5cbiAgT3JkZXJlZE1hcC5wcm90b3R5cGVbSVNfT1JERVJFRF9TRU5USU5FTF0gPSB0cnVlO1xuICBPcmRlcmVkTWFwLnByb3RvdHlwZVtERUxFVEVdID0gT3JkZXJlZE1hcC5wcm90b3R5cGUucmVtb3ZlO1xuXG5cblxuICBmdW5jdGlvbiBtYWtlT3JkZXJlZE1hcChtYXAsIGxpc3QsIG93bmVySUQsIGhhc2gpIHtcbiAgICB2YXIgb21hcCA9IE9iamVjdC5jcmVhdGUoT3JkZXJlZE1hcC5wcm90b3R5cGUpO1xuICAgIG9tYXAuc2l6ZSA9IG1hcCA/IG1hcC5zaXplIDogMDtcbiAgICBvbWFwLl9tYXAgPSBtYXA7XG4gICAgb21hcC5fbGlzdCA9IGxpc3Q7XG4gICAgb21hcC5fX293bmVySUQgPSBvd25lcklEO1xuICAgIG9tYXAuX19oYXNoID0gaGFzaDtcbiAgICByZXR1cm4gb21hcDtcbiAgfVxuXG4gIHZhciBFTVBUWV9PUkRFUkVEX01BUDtcbiAgZnVuY3Rpb24gZW1wdHlPcmRlcmVkTWFwKCkge1xuICAgIHJldHVybiBFTVBUWV9PUkRFUkVEX01BUCB8fCAoRU1QVFlfT1JERVJFRF9NQVAgPSBtYWtlT3JkZXJlZE1hcChlbXB0eU1hcCgpLCBlbXB0eUxpc3QoKSkpO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlT3JkZXJlZE1hcChvbWFwLCBrLCB2KSB7XG4gICAgdmFyIG1hcCA9IG9tYXAuX21hcDtcbiAgICB2YXIgbGlzdCA9IG9tYXAuX2xpc3Q7XG4gICAgdmFyIGkgPSBtYXAuZ2V0KGspO1xuICAgIHZhciBoYXMgPSBpICE9PSB1bmRlZmluZWQ7XG4gICAgdmFyIG5ld01hcDtcbiAgICB2YXIgbmV3TGlzdDtcbiAgICBpZiAodiA9PT0gTk9UX1NFVCkgeyAvLyByZW1vdmVkXG4gICAgICBpZiAoIWhhcykge1xuICAgICAgICByZXR1cm4gb21hcDtcbiAgICAgIH1cbiAgICAgIGlmIChsaXN0LnNpemUgPj0gU0laRSAmJiBsaXN0LnNpemUgPj0gbWFwLnNpemUgKiAyKSB7XG4gICAgICAgIG5ld0xpc3QgPSBsaXN0LmZpbHRlcihmdW5jdGlvbihlbnRyeSwgaWR4KSAge3JldHVybiBlbnRyeSAhPT0gdW5kZWZpbmVkICYmIGkgIT09IGlkeH0pO1xuICAgICAgICBuZXdNYXAgPSBuZXdMaXN0LnRvS2V5ZWRTZXEoKS5tYXAoZnVuY3Rpb24oZW50cnkgKSB7cmV0dXJuIGVudHJ5WzBdfSkuZmxpcCgpLnRvTWFwKCk7XG4gICAgICAgIGlmIChvbWFwLl9fb3duZXJJRCkge1xuICAgICAgICAgIG5ld01hcC5fX293bmVySUQgPSBuZXdMaXN0Ll9fb3duZXJJRCA9IG9tYXAuX19vd25lcklEO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXdNYXAgPSBtYXAucmVtb3ZlKGspO1xuICAgICAgICBuZXdMaXN0ID0gaSA9PT0gbGlzdC5zaXplIC0gMSA/IGxpc3QucG9wKCkgOiBsaXN0LnNldChpLCB1bmRlZmluZWQpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaGFzKSB7XG4gICAgICAgIGlmICh2ID09PSBsaXN0LmdldChpKVsxXSkge1xuICAgICAgICAgIHJldHVybiBvbWFwO1xuICAgICAgICB9XG4gICAgICAgIG5ld01hcCA9IG1hcDtcbiAgICAgICAgbmV3TGlzdCA9IGxpc3Quc2V0KGksIFtrLCB2XSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXdNYXAgPSBtYXAuc2V0KGssIGxpc3Quc2l6ZSk7XG4gICAgICAgIG5ld0xpc3QgPSBsaXN0LnNldChsaXN0LnNpemUsIFtrLCB2XSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChvbWFwLl9fb3duZXJJRCkge1xuICAgICAgb21hcC5zaXplID0gbmV3TWFwLnNpemU7XG4gICAgICBvbWFwLl9tYXAgPSBuZXdNYXA7XG4gICAgICBvbWFwLl9saXN0ID0gbmV3TGlzdDtcbiAgICAgIG9tYXAuX19oYXNoID0gdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIG9tYXA7XG4gICAgfVxuICAgIHJldHVybiBtYWtlT3JkZXJlZE1hcChuZXdNYXAsIG5ld0xpc3QpO1xuICB9XG5cbiAgY3JlYXRlQ2xhc3MoVG9LZXllZFNlcXVlbmNlLCBLZXllZFNlcSk7XG4gICAgZnVuY3Rpb24gVG9LZXllZFNlcXVlbmNlKGluZGV4ZWQsIHVzZUtleXMpIHtcbiAgICAgIHRoaXMuX2l0ZXIgPSBpbmRleGVkO1xuICAgICAgdGhpcy5fdXNlS2V5cyA9IHVzZUtleXM7XG4gICAgICB0aGlzLnNpemUgPSBpbmRleGVkLnNpemU7XG4gICAgfVxuXG4gICAgVG9LZXllZFNlcXVlbmNlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihrZXksIG5vdFNldFZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5faXRlci5nZXQoa2V5LCBub3RTZXRWYWx1ZSk7XG4gICAgfTtcblxuICAgIFRvS2V5ZWRTZXF1ZW5jZS5wcm90b3R5cGUuaGFzID0gZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5faXRlci5oYXMoa2V5KTtcbiAgICB9O1xuXG4gICAgVG9LZXllZFNlcXVlbmNlLnByb3RvdHlwZS52YWx1ZVNlcSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2l0ZXIudmFsdWVTZXEoKTtcbiAgICB9O1xuXG4gICAgVG9LZXllZFNlcXVlbmNlLnByb3RvdHlwZS5yZXZlcnNlID0gZnVuY3Rpb24oKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICB2YXIgcmV2ZXJzZWRTZXF1ZW5jZSA9IHJldmVyc2VGYWN0b3J5KHRoaXMsIHRydWUpO1xuICAgICAgaWYgKCF0aGlzLl91c2VLZXlzKSB7XG4gICAgICAgIHJldmVyc2VkU2VxdWVuY2UudmFsdWVTZXEgPSBmdW5jdGlvbigpICB7cmV0dXJuIHRoaXMkMC5faXRlci50b1NlcSgpLnJldmVyc2UoKX07XG4gICAgICB9XG4gICAgICByZXR1cm4gcmV2ZXJzZWRTZXF1ZW5jZTtcbiAgICB9O1xuXG4gICAgVG9LZXllZFNlcXVlbmNlLnByb3RvdHlwZS5tYXAgPSBmdW5jdGlvbihtYXBwZXIsIGNvbnRleHQpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIHZhciBtYXBwZWRTZXF1ZW5jZSA9IG1hcEZhY3RvcnkodGhpcywgbWFwcGVyLCBjb250ZXh0KTtcbiAgICAgIGlmICghdGhpcy5fdXNlS2V5cykge1xuICAgICAgICBtYXBwZWRTZXF1ZW5jZS52YWx1ZVNlcSA9IGZ1bmN0aW9uKCkgIHtyZXR1cm4gdGhpcyQwLl9pdGVyLnRvU2VxKCkubWFwKG1hcHBlciwgY29udGV4dCl9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1hcHBlZFNlcXVlbmNlO1xuICAgIH07XG5cbiAgICBUb0tleWVkU2VxdWVuY2UucHJvdG90eXBlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICB2YXIgaWk7XG4gICAgICByZXR1cm4gdGhpcy5faXRlci5fX2l0ZXJhdGUoXG4gICAgICAgIHRoaXMuX3VzZUtleXMgP1xuICAgICAgICAgIGZ1bmN0aW9uKHYsIGspICB7cmV0dXJuIGZuKHYsIGssIHRoaXMkMCl9IDpcbiAgICAgICAgICAoKGlpID0gcmV2ZXJzZSA/IHJlc29sdmVTaXplKHRoaXMpIDogMCksXG4gICAgICAgICAgICBmdW5jdGlvbih2ICkge3JldHVybiBmbih2LCByZXZlcnNlID8gLS1paSA6IGlpKyssIHRoaXMkMCl9KSxcbiAgICAgICAgcmV2ZXJzZVxuICAgICAgKTtcbiAgICB9O1xuXG4gICAgVG9LZXllZFNlcXVlbmNlLnByb3RvdHlwZS5fX2l0ZXJhdG9yID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgaWYgKHRoaXMuX3VzZUtleXMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2l0ZXIuX19pdGVyYXRvcih0eXBlLCByZXZlcnNlKTtcbiAgICAgIH1cbiAgICAgIHZhciBpdGVyYXRvciA9IHRoaXMuX2l0ZXIuX19pdGVyYXRvcihJVEVSQVRFX1ZBTFVFUywgcmV2ZXJzZSk7XG4gICAgICB2YXIgaWkgPSByZXZlcnNlID8gcmVzb2x2ZVNpemUodGhpcykgOiAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHZhciBzdGVwID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICByZXR1cm4gc3RlcC5kb25lID8gc3RlcCA6XG4gICAgICAgICAgaXRlcmF0b3JWYWx1ZSh0eXBlLCByZXZlcnNlID8gLS1paSA6IGlpKyssIHN0ZXAudmFsdWUsIHN0ZXApO1xuICAgICAgfSk7XG4gICAgfTtcblxuICBUb0tleWVkU2VxdWVuY2UucHJvdG90eXBlW0lTX09SREVSRURfU0VOVElORUxdID0gdHJ1ZTtcblxuXG4gIGNyZWF0ZUNsYXNzKFRvSW5kZXhlZFNlcXVlbmNlLCBJbmRleGVkU2VxKTtcbiAgICBmdW5jdGlvbiBUb0luZGV4ZWRTZXF1ZW5jZShpdGVyKSB7XG4gICAgICB0aGlzLl9pdGVyID0gaXRlcjtcbiAgICAgIHRoaXMuc2l6ZSA9IGl0ZXIuc2l6ZTtcbiAgICB9XG5cbiAgICBUb0luZGV4ZWRTZXF1ZW5jZS5wcm90b3R5cGUuaW5jbHVkZXMgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2l0ZXIuaW5jbHVkZXModmFsdWUpO1xuICAgIH07XG5cbiAgICBUb0luZGV4ZWRTZXF1ZW5jZS5wcm90b3R5cGUuX19pdGVyYXRlID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIHJldHVybiB0aGlzLl9pdGVyLl9faXRlcmF0ZShmdW5jdGlvbih2ICkge3JldHVybiBmbih2LCBpdGVyYXRpb25zKyssIHRoaXMkMCl9LCByZXZlcnNlKTtcbiAgICB9O1xuXG4gICAgVG9JbmRleGVkU2VxdWVuY2UucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICB2YXIgaXRlcmF0b3IgPSB0aGlzLl9pdGVyLl9faXRlcmF0b3IoSVRFUkFURV9WQUxVRVMsIHJldmVyc2UpO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHZhciBzdGVwID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICByZXR1cm4gc3RlcC5kb25lID8gc3RlcCA6XG4gICAgICAgICAgaXRlcmF0b3JWYWx1ZSh0eXBlLCBpdGVyYXRpb25zKyssIHN0ZXAudmFsdWUsIHN0ZXApXG4gICAgICB9KTtcbiAgICB9O1xuXG5cblxuICBjcmVhdGVDbGFzcyhUb1NldFNlcXVlbmNlLCBTZXRTZXEpO1xuICAgIGZ1bmN0aW9uIFRvU2V0U2VxdWVuY2UoaXRlcikge1xuICAgICAgdGhpcy5faXRlciA9IGl0ZXI7XG4gICAgICB0aGlzLnNpemUgPSBpdGVyLnNpemU7XG4gICAgfVxuXG4gICAgVG9TZXRTZXF1ZW5jZS5wcm90b3R5cGUuaGFzID0gZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5faXRlci5pbmNsdWRlcyhrZXkpO1xuICAgIH07XG5cbiAgICBUb1NldFNlcXVlbmNlLnByb3RvdHlwZS5fX2l0ZXJhdGUgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgcmV0dXJuIHRoaXMuX2l0ZXIuX19pdGVyYXRlKGZ1bmN0aW9uKHYgKSB7cmV0dXJuIGZuKHYsIHYsIHRoaXMkMCl9LCByZXZlcnNlKTtcbiAgICB9O1xuXG4gICAgVG9TZXRTZXF1ZW5jZS5wcm90b3R5cGUuX19pdGVyYXRvciA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIHZhciBpdGVyYXRvciA9IHRoaXMuX2l0ZXIuX19pdGVyYXRvcihJVEVSQVRFX1ZBTFVFUywgcmV2ZXJzZSk7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgdmFyIHN0ZXAgPSBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgIHJldHVybiBzdGVwLmRvbmUgPyBzdGVwIDpcbiAgICAgICAgICBpdGVyYXRvclZhbHVlKHR5cGUsIHN0ZXAudmFsdWUsIHN0ZXAudmFsdWUsIHN0ZXApO1xuICAgICAgfSk7XG4gICAgfTtcblxuXG5cbiAgY3JlYXRlQ2xhc3MoRnJvbUVudHJpZXNTZXF1ZW5jZSwgS2V5ZWRTZXEpO1xuICAgIGZ1bmN0aW9uIEZyb21FbnRyaWVzU2VxdWVuY2UoZW50cmllcykge1xuICAgICAgdGhpcy5faXRlciA9IGVudHJpZXM7XG4gICAgICB0aGlzLnNpemUgPSBlbnRyaWVzLnNpemU7XG4gICAgfVxuXG4gICAgRnJvbUVudHJpZXNTZXF1ZW5jZS5wcm90b3R5cGUuZW50cnlTZXEgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9pdGVyLnRvU2VxKCk7XG4gICAgfTtcblxuICAgIEZyb21FbnRyaWVzU2VxdWVuY2UucHJvdG90eXBlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICByZXR1cm4gdGhpcy5faXRlci5fX2l0ZXJhdGUoZnVuY3Rpb24oZW50cnkgKSB7XG4gICAgICAgIC8vIENoZWNrIGlmIGVudHJ5IGV4aXN0cyBmaXJzdCBzbyBhcnJheSBhY2Nlc3MgZG9lc24ndCB0aHJvdyBmb3IgaG9sZXNcbiAgICAgICAgLy8gaW4gdGhlIHBhcmVudCBpdGVyYXRpb24uXG4gICAgICAgIGlmIChlbnRyeSkge1xuICAgICAgICAgIHZhbGlkYXRlRW50cnkoZW50cnkpO1xuICAgICAgICAgIHZhciBpbmRleGVkSXRlcmFibGUgPSBpc0l0ZXJhYmxlKGVudHJ5KTtcbiAgICAgICAgICByZXR1cm4gZm4oXG4gICAgICAgICAgICBpbmRleGVkSXRlcmFibGUgPyBlbnRyeS5nZXQoMSkgOiBlbnRyeVsxXSxcbiAgICAgICAgICAgIGluZGV4ZWRJdGVyYWJsZSA/IGVudHJ5LmdldCgwKSA6IGVudHJ5WzBdLFxuICAgICAgICAgICAgdGhpcyQwXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSwgcmV2ZXJzZSk7XG4gICAgfTtcblxuICAgIEZyb21FbnRyaWVzU2VxdWVuY2UucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICB2YXIgaXRlcmF0b3IgPSB0aGlzLl9pdGVyLl9faXRlcmF0b3IoSVRFUkFURV9WQUxVRVMsIHJldmVyc2UpO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgdmFyIHN0ZXAgPSBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgICAgaWYgKHN0ZXAuZG9uZSkge1xuICAgICAgICAgICAgcmV0dXJuIHN0ZXA7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhciBlbnRyeSA9IHN0ZXAudmFsdWU7XG4gICAgICAgICAgLy8gQ2hlY2sgaWYgZW50cnkgZXhpc3RzIGZpcnN0IHNvIGFycmF5IGFjY2VzcyBkb2Vzbid0IHRocm93IGZvciBob2xlc1xuICAgICAgICAgIC8vIGluIHRoZSBwYXJlbnQgaXRlcmF0aW9uLlxuICAgICAgICAgIGlmIChlbnRyeSkge1xuICAgICAgICAgICAgdmFsaWRhdGVFbnRyeShlbnRyeSk7XG4gICAgICAgICAgICB2YXIgaW5kZXhlZEl0ZXJhYmxlID0gaXNJdGVyYWJsZShlbnRyeSk7XG4gICAgICAgICAgICByZXR1cm4gaXRlcmF0b3JWYWx1ZShcbiAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgaW5kZXhlZEl0ZXJhYmxlID8gZW50cnkuZ2V0KDApIDogZW50cnlbMF0sXG4gICAgICAgICAgICAgIGluZGV4ZWRJdGVyYWJsZSA/IGVudHJ5LmdldCgxKSA6IGVudHJ5WzFdLFxuICAgICAgICAgICAgICBzdGVwXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcblxuXG4gIFRvSW5kZXhlZFNlcXVlbmNlLnByb3RvdHlwZS5jYWNoZVJlc3VsdCA9XG4gIFRvS2V5ZWRTZXF1ZW5jZS5wcm90b3R5cGUuY2FjaGVSZXN1bHQgPVxuICBUb1NldFNlcXVlbmNlLnByb3RvdHlwZS5jYWNoZVJlc3VsdCA9XG4gIEZyb21FbnRyaWVzU2VxdWVuY2UucHJvdG90eXBlLmNhY2hlUmVzdWx0ID1cbiAgICBjYWNoZVJlc3VsdFRocm91Z2g7XG5cblxuICBmdW5jdGlvbiBmbGlwRmFjdG9yeShpdGVyYWJsZSkge1xuICAgIHZhciBmbGlwU2VxdWVuY2UgPSBtYWtlU2VxdWVuY2UoaXRlcmFibGUpO1xuICAgIGZsaXBTZXF1ZW5jZS5faXRlciA9IGl0ZXJhYmxlO1xuICAgIGZsaXBTZXF1ZW5jZS5zaXplID0gaXRlcmFibGUuc2l6ZTtcbiAgICBmbGlwU2VxdWVuY2UuZmxpcCA9IGZ1bmN0aW9uKCkgIHtyZXR1cm4gaXRlcmFibGV9O1xuICAgIGZsaXBTZXF1ZW5jZS5yZXZlcnNlID0gZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIHJldmVyc2VkU2VxdWVuY2UgPSBpdGVyYWJsZS5yZXZlcnNlLmFwcGx5KHRoaXMpOyAvLyBzdXBlci5yZXZlcnNlKClcbiAgICAgIHJldmVyc2VkU2VxdWVuY2UuZmxpcCA9IGZ1bmN0aW9uKCkgIHtyZXR1cm4gaXRlcmFibGUucmV2ZXJzZSgpfTtcbiAgICAgIHJldHVybiByZXZlcnNlZFNlcXVlbmNlO1xuICAgIH07XG4gICAgZmxpcFNlcXVlbmNlLmhhcyA9IGZ1bmN0aW9uKGtleSApIHtyZXR1cm4gaXRlcmFibGUuaW5jbHVkZXMoa2V5KX07XG4gICAgZmxpcFNlcXVlbmNlLmluY2x1ZGVzID0gZnVuY3Rpb24oa2V5ICkge3JldHVybiBpdGVyYWJsZS5oYXMoa2V5KX07XG4gICAgZmxpcFNlcXVlbmNlLmNhY2hlUmVzdWx0ID0gY2FjaGVSZXN1bHRUaHJvdWdoO1xuICAgIGZsaXBTZXF1ZW5jZS5fX2l0ZXJhdGVVbmNhY2hlZCA9IGZ1bmN0aW9uIChmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgcmV0dXJuIGl0ZXJhYmxlLl9faXRlcmF0ZShmdW5jdGlvbih2LCBrKSAge3JldHVybiBmbihrLCB2LCB0aGlzJDApICE9PSBmYWxzZX0sIHJldmVyc2UpO1xuICAgIH1cbiAgICBmbGlwU2VxdWVuY2UuX19pdGVyYXRvclVuY2FjaGVkID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgaWYgKHR5cGUgPT09IElURVJBVEVfRU5UUklFUykge1xuICAgICAgICB2YXIgaXRlcmF0b3IgPSBpdGVyYWJsZS5fX2l0ZXJhdG9yKHR5cGUsIHJldmVyc2UpO1xuICAgICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgICB2YXIgc3RlcCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgICBpZiAoIXN0ZXAuZG9uZSkge1xuICAgICAgICAgICAgdmFyIGsgPSBzdGVwLnZhbHVlWzBdO1xuICAgICAgICAgICAgc3RlcC52YWx1ZVswXSA9IHN0ZXAudmFsdWVbMV07XG4gICAgICAgICAgICBzdGVwLnZhbHVlWzFdID0gaztcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHN0ZXA7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGl0ZXJhYmxlLl9faXRlcmF0b3IoXG4gICAgICAgIHR5cGUgPT09IElURVJBVEVfVkFMVUVTID8gSVRFUkFURV9LRVlTIDogSVRFUkFURV9WQUxVRVMsXG4gICAgICAgIHJldmVyc2VcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBmbGlwU2VxdWVuY2U7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIG1hcEZhY3RvcnkoaXRlcmFibGUsIG1hcHBlciwgY29udGV4dCkge1xuICAgIHZhciBtYXBwZWRTZXF1ZW5jZSA9IG1ha2VTZXF1ZW5jZShpdGVyYWJsZSk7XG4gICAgbWFwcGVkU2VxdWVuY2Uuc2l6ZSA9IGl0ZXJhYmxlLnNpemU7XG4gICAgbWFwcGVkU2VxdWVuY2UuaGFzID0gZnVuY3Rpb24oa2V5ICkge3JldHVybiBpdGVyYWJsZS5oYXMoa2V5KX07XG4gICAgbWFwcGVkU2VxdWVuY2UuZ2V0ID0gZnVuY3Rpb24oa2V5LCBub3RTZXRWYWx1ZSkgIHtcbiAgICAgIHZhciB2ID0gaXRlcmFibGUuZ2V0KGtleSwgTk9UX1NFVCk7XG4gICAgICByZXR1cm4gdiA9PT0gTk9UX1NFVCA/XG4gICAgICAgIG5vdFNldFZhbHVlIDpcbiAgICAgICAgbWFwcGVyLmNhbGwoY29udGV4dCwgdiwga2V5LCBpdGVyYWJsZSk7XG4gICAgfTtcbiAgICBtYXBwZWRTZXF1ZW5jZS5fX2l0ZXJhdGVVbmNhY2hlZCA9IGZ1bmN0aW9uIChmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgcmV0dXJuIGl0ZXJhYmxlLl9faXRlcmF0ZShcbiAgICAgICAgZnVuY3Rpb24odiwgaywgYykgIHtyZXR1cm4gZm4obWFwcGVyLmNhbGwoY29udGV4dCwgdiwgaywgYyksIGssIHRoaXMkMCkgIT09IGZhbHNlfSxcbiAgICAgICAgcmV2ZXJzZVxuICAgICAgKTtcbiAgICB9XG4gICAgbWFwcGVkU2VxdWVuY2UuX19pdGVyYXRvclVuY2FjaGVkID0gZnVuY3Rpb24gKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIHZhciBpdGVyYXRvciA9IGl0ZXJhYmxlLl9faXRlcmF0b3IoSVRFUkFURV9FTlRSSUVTLCByZXZlcnNlKTtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSAge1xuICAgICAgICB2YXIgc3RlcCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgaWYgKHN0ZXAuZG9uZSkge1xuICAgICAgICAgIHJldHVybiBzdGVwO1xuICAgICAgICB9XG4gICAgICAgIHZhciBlbnRyeSA9IHN0ZXAudmFsdWU7XG4gICAgICAgIHZhciBrZXkgPSBlbnRyeVswXTtcbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yVmFsdWUoXG4gICAgICAgICAgdHlwZSxcbiAgICAgICAgICBrZXksXG4gICAgICAgICAgbWFwcGVyLmNhbGwoY29udGV4dCwgZW50cnlbMV0sIGtleSwgaXRlcmFibGUpLFxuICAgICAgICAgIHN0ZXBcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gbWFwcGVkU2VxdWVuY2U7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIHJldmVyc2VGYWN0b3J5KGl0ZXJhYmxlLCB1c2VLZXlzKSB7XG4gICAgdmFyIHJldmVyc2VkU2VxdWVuY2UgPSBtYWtlU2VxdWVuY2UoaXRlcmFibGUpO1xuICAgIHJldmVyc2VkU2VxdWVuY2UuX2l0ZXIgPSBpdGVyYWJsZTtcbiAgICByZXZlcnNlZFNlcXVlbmNlLnNpemUgPSBpdGVyYWJsZS5zaXplO1xuICAgIHJldmVyc2VkU2VxdWVuY2UucmV2ZXJzZSA9IGZ1bmN0aW9uKCkgIHtyZXR1cm4gaXRlcmFibGV9O1xuICAgIGlmIChpdGVyYWJsZS5mbGlwKSB7XG4gICAgICByZXZlcnNlZFNlcXVlbmNlLmZsaXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmbGlwU2VxdWVuY2UgPSBmbGlwRmFjdG9yeShpdGVyYWJsZSk7XG4gICAgICAgIGZsaXBTZXF1ZW5jZS5yZXZlcnNlID0gZnVuY3Rpb24oKSAge3JldHVybiBpdGVyYWJsZS5mbGlwKCl9O1xuICAgICAgICByZXR1cm4gZmxpcFNlcXVlbmNlO1xuICAgICAgfTtcbiAgICB9XG4gICAgcmV2ZXJzZWRTZXF1ZW5jZS5nZXQgPSBmdW5jdGlvbihrZXksIG5vdFNldFZhbHVlKSBcbiAgICAgIHtyZXR1cm4gaXRlcmFibGUuZ2V0KHVzZUtleXMgPyBrZXkgOiAtMSAtIGtleSwgbm90U2V0VmFsdWUpfTtcbiAgICByZXZlcnNlZFNlcXVlbmNlLmhhcyA9IGZ1bmN0aW9uKGtleSApXG4gICAgICB7cmV0dXJuIGl0ZXJhYmxlLmhhcyh1c2VLZXlzID8ga2V5IDogLTEgLSBrZXkpfTtcbiAgICByZXZlcnNlZFNlcXVlbmNlLmluY2x1ZGVzID0gZnVuY3Rpb24odmFsdWUgKSB7cmV0dXJuIGl0ZXJhYmxlLmluY2x1ZGVzKHZhbHVlKX07XG4gICAgcmV2ZXJzZWRTZXF1ZW5jZS5jYWNoZVJlc3VsdCA9IGNhY2hlUmVzdWx0VGhyb3VnaDtcbiAgICByZXZlcnNlZFNlcXVlbmNlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uIChmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgcmV0dXJuIGl0ZXJhYmxlLl9faXRlcmF0ZShmdW5jdGlvbih2LCBrKSAge3JldHVybiBmbih2LCBrLCB0aGlzJDApfSwgIXJldmVyc2UpO1xuICAgIH07XG4gICAgcmV2ZXJzZWRTZXF1ZW5jZS5fX2l0ZXJhdG9yID1cbiAgICAgIGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpICB7cmV0dXJuIGl0ZXJhYmxlLl9faXRlcmF0b3IodHlwZSwgIXJldmVyc2UpfTtcbiAgICByZXR1cm4gcmV2ZXJzZWRTZXF1ZW5jZTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gZmlsdGVyRmFjdG9yeShpdGVyYWJsZSwgcHJlZGljYXRlLCBjb250ZXh0LCB1c2VLZXlzKSB7XG4gICAgdmFyIGZpbHRlclNlcXVlbmNlID0gbWFrZVNlcXVlbmNlKGl0ZXJhYmxlKTtcbiAgICBpZiAodXNlS2V5cykge1xuICAgICAgZmlsdGVyU2VxdWVuY2UuaGFzID0gZnVuY3Rpb24oa2V5ICkge1xuICAgICAgICB2YXIgdiA9IGl0ZXJhYmxlLmdldChrZXksIE5PVF9TRVQpO1xuICAgICAgICByZXR1cm4gdiAhPT0gTk9UX1NFVCAmJiAhIXByZWRpY2F0ZS5jYWxsKGNvbnRleHQsIHYsIGtleSwgaXRlcmFibGUpO1xuICAgICAgfTtcbiAgICAgIGZpbHRlclNlcXVlbmNlLmdldCA9IGZ1bmN0aW9uKGtleSwgbm90U2V0VmFsdWUpICB7XG4gICAgICAgIHZhciB2ID0gaXRlcmFibGUuZ2V0KGtleSwgTk9UX1NFVCk7XG4gICAgICAgIHJldHVybiB2ICE9PSBOT1RfU0VUICYmIHByZWRpY2F0ZS5jYWxsKGNvbnRleHQsIHYsIGtleSwgaXRlcmFibGUpID9cbiAgICAgICAgICB2IDogbm90U2V0VmFsdWU7XG4gICAgICB9O1xuICAgIH1cbiAgICBmaWx0ZXJTZXF1ZW5jZS5fX2l0ZXJhdGVVbmNhY2hlZCA9IGZ1bmN0aW9uIChmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgaXRlcmFibGUuX19pdGVyYXRlKGZ1bmN0aW9uKHYsIGssIGMpICB7XG4gICAgICAgIGlmIChwcmVkaWNhdGUuY2FsbChjb250ZXh0LCB2LCBrLCBjKSkge1xuICAgICAgICAgIGl0ZXJhdGlvbnMrKztcbiAgICAgICAgICByZXR1cm4gZm4odiwgdXNlS2V5cyA/IGsgOiBpdGVyYXRpb25zIC0gMSwgdGhpcyQwKTtcbiAgICAgICAgfVxuICAgICAgfSwgcmV2ZXJzZSk7XG4gICAgICByZXR1cm4gaXRlcmF0aW9ucztcbiAgICB9O1xuICAgIGZpbHRlclNlcXVlbmNlLl9faXRlcmF0b3JVbmNhY2hlZCA9IGZ1bmN0aW9uICh0eXBlLCByZXZlcnNlKSB7XG4gICAgICB2YXIgaXRlcmF0b3IgPSBpdGVyYWJsZS5fX2l0ZXJhdG9yKElURVJBVEVfRU5UUklFUywgcmV2ZXJzZSk7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICB2YXIgc3RlcCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgICBpZiAoc3RlcC5kb25lKSB7XG4gICAgICAgICAgICByZXR1cm4gc3RlcDtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIGVudHJ5ID0gc3RlcC52YWx1ZTtcbiAgICAgICAgICB2YXIga2V5ID0gZW50cnlbMF07XG4gICAgICAgICAgdmFyIHZhbHVlID0gZW50cnlbMV07XG4gICAgICAgICAgaWYgKHByZWRpY2F0ZS5jYWxsKGNvbnRleHQsIHZhbHVlLCBrZXksIGl0ZXJhYmxlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGl0ZXJhdG9yVmFsdWUodHlwZSwgdXNlS2V5cyA/IGtleSA6IGl0ZXJhdGlvbnMrKywgdmFsdWUsIHN0ZXApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBmaWx0ZXJTZXF1ZW5jZTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gY291bnRCeUZhY3RvcnkoaXRlcmFibGUsIGdyb3VwZXIsIGNvbnRleHQpIHtcbiAgICB2YXIgZ3JvdXBzID0gTWFwKCkuYXNNdXRhYmxlKCk7XG4gICAgaXRlcmFibGUuX19pdGVyYXRlKGZ1bmN0aW9uKHYsIGspICB7XG4gICAgICBncm91cHMudXBkYXRlKFxuICAgICAgICBncm91cGVyLmNhbGwoY29udGV4dCwgdiwgaywgaXRlcmFibGUpLFxuICAgICAgICAwLFxuICAgICAgICBmdW5jdGlvbihhICkge3JldHVybiBhICsgMX1cbiAgICAgICk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGdyb3Vwcy5hc0ltbXV0YWJsZSgpO1xuICB9XG5cblxuICBmdW5jdGlvbiBncm91cEJ5RmFjdG9yeShpdGVyYWJsZSwgZ3JvdXBlciwgY29udGV4dCkge1xuICAgIHZhciBpc0tleWVkSXRlciA9IGlzS2V5ZWQoaXRlcmFibGUpO1xuICAgIHZhciBncm91cHMgPSAoaXNPcmRlcmVkKGl0ZXJhYmxlKSA/IE9yZGVyZWRNYXAoKSA6IE1hcCgpKS5hc011dGFibGUoKTtcbiAgICBpdGVyYWJsZS5fX2l0ZXJhdGUoZnVuY3Rpb24odiwgaykgIHtcbiAgICAgIGdyb3Vwcy51cGRhdGUoXG4gICAgICAgIGdyb3VwZXIuY2FsbChjb250ZXh0LCB2LCBrLCBpdGVyYWJsZSksXG4gICAgICAgIGZ1bmN0aW9uKGEgKSB7cmV0dXJuIChhID0gYSB8fCBbXSwgYS5wdXNoKGlzS2V5ZWRJdGVyID8gW2ssIHZdIDogdiksIGEpfVxuICAgICAgKTtcbiAgICB9KTtcbiAgICB2YXIgY29lcmNlID0gaXRlcmFibGVDbGFzcyhpdGVyYWJsZSk7XG4gICAgcmV0dXJuIGdyb3Vwcy5tYXAoZnVuY3Rpb24oYXJyICkge3JldHVybiByZWlmeShpdGVyYWJsZSwgY29lcmNlKGFycikpfSk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIHNsaWNlRmFjdG9yeShpdGVyYWJsZSwgYmVnaW4sIGVuZCwgdXNlS2V5cykge1xuICAgIHZhciBvcmlnaW5hbFNpemUgPSBpdGVyYWJsZS5zaXplO1xuXG4gICAgLy8gU2FuaXRpemUgYmVnaW4gJiBlbmQgdXNpbmcgdGhpcyBzaG9ydGhhbmQgZm9yIFRvSW50MzIoYXJndW1lbnQpXG4gICAgLy8gaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvaW50MzJcbiAgICBpZiAoYmVnaW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgYmVnaW4gPSBiZWdpbiB8IDA7XG4gICAgfVxuICAgIGlmIChlbmQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgZW5kID0gZW5kIHwgMDtcbiAgICB9XG5cbiAgICBpZiAod2hvbGVTbGljZShiZWdpbiwgZW5kLCBvcmlnaW5hbFNpemUpKSB7XG4gICAgICByZXR1cm4gaXRlcmFibGU7XG4gICAgfVxuXG4gICAgdmFyIHJlc29sdmVkQmVnaW4gPSByZXNvbHZlQmVnaW4oYmVnaW4sIG9yaWdpbmFsU2l6ZSk7XG4gICAgdmFyIHJlc29sdmVkRW5kID0gcmVzb2x2ZUVuZChlbmQsIG9yaWdpbmFsU2l6ZSk7XG5cbiAgICAvLyBiZWdpbiBvciBlbmQgd2lsbCBiZSBOYU4gaWYgdGhleSB3ZXJlIHByb3ZpZGVkIGFzIG5lZ2F0aXZlIG51bWJlcnMgYW5kXG4gICAgLy8gdGhpcyBpdGVyYWJsZSdzIHNpemUgaXMgdW5rbm93bi4gSW4gdGhhdCBjYXNlLCBjYWNoZSBmaXJzdCBzbyB0aGVyZSBpc1xuICAgIC8vIGEga25vd24gc2l6ZSBhbmQgdGhlc2UgZG8gbm90IHJlc29sdmUgdG8gTmFOLlxuICAgIGlmIChyZXNvbHZlZEJlZ2luICE9PSByZXNvbHZlZEJlZ2luIHx8IHJlc29sdmVkRW5kICE9PSByZXNvbHZlZEVuZCkge1xuICAgICAgcmV0dXJuIHNsaWNlRmFjdG9yeShpdGVyYWJsZS50b1NlcSgpLmNhY2hlUmVzdWx0KCksIGJlZ2luLCBlbmQsIHVzZUtleXMpO1xuICAgIH1cblxuICAgIC8vIE5vdGU6IHJlc29sdmVkRW5kIGlzIHVuZGVmaW5lZCB3aGVuIHRoZSBvcmlnaW5hbCBzZXF1ZW5jZSdzIGxlbmd0aCBpc1xuICAgIC8vIHVua25vd24gYW5kIHRoaXMgc2xpY2UgZGlkIG5vdCBzdXBwbHkgYW4gZW5kIGFuZCBzaG91bGQgY29udGFpbiBhbGxcbiAgICAvLyBlbGVtZW50cyBhZnRlciByZXNvbHZlZEJlZ2luLlxuICAgIC8vIEluIHRoYXQgY2FzZSwgcmVzb2x2ZWRTaXplIHdpbGwgYmUgTmFOIGFuZCBzbGljZVNpemUgd2lsbCByZW1haW4gdW5kZWZpbmVkLlxuICAgIHZhciByZXNvbHZlZFNpemUgPSByZXNvbHZlZEVuZCAtIHJlc29sdmVkQmVnaW47XG4gICAgdmFyIHNsaWNlU2l6ZTtcbiAgICBpZiAocmVzb2x2ZWRTaXplID09PSByZXNvbHZlZFNpemUpIHtcbiAgICAgIHNsaWNlU2l6ZSA9IHJlc29sdmVkU2l6ZSA8IDAgPyAwIDogcmVzb2x2ZWRTaXplO1xuICAgIH1cblxuICAgIHZhciBzbGljZVNlcSA9IG1ha2VTZXF1ZW5jZShpdGVyYWJsZSk7XG5cbiAgICAvLyBJZiBpdGVyYWJsZS5zaXplIGlzIHVuZGVmaW5lZCwgdGhlIHNpemUgb2YgdGhlIHJlYWxpemVkIHNsaWNlU2VxIGlzXG4gICAgLy8gdW5rbm93biBhdCB0aGlzIHBvaW50IHVubGVzcyB0aGUgbnVtYmVyIG9mIGl0ZW1zIHRvIHNsaWNlIGlzIDBcbiAgICBzbGljZVNlcS5zaXplID0gc2xpY2VTaXplID09PSAwID8gc2xpY2VTaXplIDogaXRlcmFibGUuc2l6ZSAmJiBzbGljZVNpemUgfHwgdW5kZWZpbmVkO1xuXG4gICAgaWYgKCF1c2VLZXlzICYmIGlzU2VxKGl0ZXJhYmxlKSAmJiBzbGljZVNpemUgPj0gMCkge1xuICAgICAgc2xpY2VTZXEuZ2V0ID0gZnVuY3Rpb24gKGluZGV4LCBub3RTZXRWYWx1ZSkge1xuICAgICAgICBpbmRleCA9IHdyYXBJbmRleCh0aGlzLCBpbmRleCk7XG4gICAgICAgIHJldHVybiBpbmRleCA+PSAwICYmIGluZGV4IDwgc2xpY2VTaXplID9cbiAgICAgICAgICBpdGVyYWJsZS5nZXQoaW5kZXggKyByZXNvbHZlZEJlZ2luLCBub3RTZXRWYWx1ZSkgOlxuICAgICAgICAgIG5vdFNldFZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHNsaWNlU2VxLl9faXRlcmF0ZVVuY2FjaGVkID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIGlmIChzbGljZVNpemUgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZVJlc3VsdCgpLl9faXRlcmF0ZShmbiwgcmV2ZXJzZSk7XG4gICAgICB9XG4gICAgICB2YXIgc2tpcHBlZCA9IDA7XG4gICAgICB2YXIgaXNTa2lwcGluZyA9IHRydWU7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICBpdGVyYWJsZS5fX2l0ZXJhdGUoZnVuY3Rpb24odiwgaykgIHtcbiAgICAgICAgaWYgKCEoaXNTa2lwcGluZyAmJiAoaXNTa2lwcGluZyA9IHNraXBwZWQrKyA8IHJlc29sdmVkQmVnaW4pKSkge1xuICAgICAgICAgIGl0ZXJhdGlvbnMrKztcbiAgICAgICAgICByZXR1cm4gZm4odiwgdXNlS2V5cyA/IGsgOiBpdGVyYXRpb25zIC0gMSwgdGhpcyQwKSAhPT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICAgaXRlcmF0aW9ucyAhPT0gc2xpY2VTaXplO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBpdGVyYXRpb25zO1xuICAgIH07XG5cbiAgICBzbGljZVNlcS5fX2l0ZXJhdG9yVW5jYWNoZWQgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICBpZiAoc2xpY2VTaXplICE9PSAwICYmIHJldmVyc2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FjaGVSZXN1bHQoKS5fX2l0ZXJhdG9yKHR5cGUsIHJldmVyc2UpO1xuICAgICAgfVxuICAgICAgLy8gRG9uJ3QgYm90aGVyIGluc3RhbnRpYXRpbmcgcGFyZW50IGl0ZXJhdG9yIGlmIHRha2luZyAwLlxuICAgICAgdmFyIGl0ZXJhdG9yID0gc2xpY2VTaXplICE9PSAwICYmIGl0ZXJhYmxlLl9faXRlcmF0b3IodHlwZSwgcmV2ZXJzZSk7XG4gICAgICB2YXIgc2tpcHBlZCA9IDA7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgd2hpbGUgKHNraXBwZWQrKyA8IHJlc29sdmVkQmVnaW4pIHtcbiAgICAgICAgICBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCsraXRlcmF0aW9ucyA+IHNsaWNlU2l6ZSkge1xuICAgICAgICAgIHJldHVybiBpdGVyYXRvckRvbmUoKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc3RlcCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgaWYgKHVzZUtleXMgfHwgdHlwZSA9PT0gSVRFUkFURV9WQUxVRVMpIHtcbiAgICAgICAgICByZXR1cm4gc3RlcDtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSBJVEVSQVRFX0tFWVMpIHtcbiAgICAgICAgICByZXR1cm4gaXRlcmF0b3JWYWx1ZSh0eXBlLCBpdGVyYXRpb25zIC0gMSwgdW5kZWZpbmVkLCBzdGVwKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gaXRlcmF0b3JWYWx1ZSh0eXBlLCBpdGVyYXRpb25zIC0gMSwgc3RlcC52YWx1ZVsxXSwgc3RlcCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBzbGljZVNlcTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gdGFrZVdoaWxlRmFjdG9yeShpdGVyYWJsZSwgcHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgdmFyIHRha2VTZXF1ZW5jZSA9IG1ha2VTZXF1ZW5jZShpdGVyYWJsZSk7XG4gICAgdGFrZVNlcXVlbmNlLl9faXRlcmF0ZVVuY2FjaGVkID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlUmVzdWx0KCkuX19pdGVyYXRlKGZuLCByZXZlcnNlKTtcbiAgICAgIH1cbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIGl0ZXJhYmxlLl9faXRlcmF0ZShmdW5jdGlvbih2LCBrLCBjKSBcbiAgICAgICAge3JldHVybiBwcmVkaWNhdGUuY2FsbChjb250ZXh0LCB2LCBrLCBjKSAmJiArK2l0ZXJhdGlvbnMgJiYgZm4odiwgaywgdGhpcyQwKX1cbiAgICAgICk7XG4gICAgICByZXR1cm4gaXRlcmF0aW9ucztcbiAgICB9O1xuICAgIHRha2VTZXF1ZW5jZS5fX2l0ZXJhdG9yVW5jYWNoZWQgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZVJlc3VsdCgpLl9faXRlcmF0b3IodHlwZSwgcmV2ZXJzZSk7XG4gICAgICB9XG4gICAgICB2YXIgaXRlcmF0b3IgPSBpdGVyYWJsZS5fX2l0ZXJhdG9yKElURVJBVEVfRU5UUklFUywgcmV2ZXJzZSk7XG4gICAgICB2YXIgaXRlcmF0aW5nID0gdHJ1ZTtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSAge1xuICAgICAgICBpZiAoIWl0ZXJhdGluZykge1xuICAgICAgICAgIHJldHVybiBpdGVyYXRvckRvbmUoKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc3RlcCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgaWYgKHN0ZXAuZG9uZSkge1xuICAgICAgICAgIHJldHVybiBzdGVwO1xuICAgICAgICB9XG4gICAgICAgIHZhciBlbnRyeSA9IHN0ZXAudmFsdWU7XG4gICAgICAgIHZhciBrID0gZW50cnlbMF07XG4gICAgICAgIHZhciB2ID0gZW50cnlbMV07XG4gICAgICAgIGlmICghcHJlZGljYXRlLmNhbGwoY29udGV4dCwgdiwgaywgdGhpcyQwKSkge1xuICAgICAgICAgIGl0ZXJhdGluZyA9IGZhbHNlO1xuICAgICAgICAgIHJldHVybiBpdGVyYXRvckRvbmUoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHlwZSA9PT0gSVRFUkFURV9FTlRSSUVTID8gc3RlcCA6XG4gICAgICAgICAgaXRlcmF0b3JWYWx1ZSh0eXBlLCBrLCB2LCBzdGVwKTtcbiAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIHRha2VTZXF1ZW5jZTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gc2tpcFdoaWxlRmFjdG9yeShpdGVyYWJsZSwgcHJlZGljYXRlLCBjb250ZXh0LCB1c2VLZXlzKSB7XG4gICAgdmFyIHNraXBTZXF1ZW5jZSA9IG1ha2VTZXF1ZW5jZShpdGVyYWJsZSk7XG4gICAgc2tpcFNlcXVlbmNlLl9faXRlcmF0ZVVuY2FjaGVkID0gZnVuY3Rpb24gKGZuLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZVJlc3VsdCgpLl9faXRlcmF0ZShmbiwgcmV2ZXJzZSk7XG4gICAgICB9XG4gICAgICB2YXIgaXNTa2lwcGluZyA9IHRydWU7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICBpdGVyYWJsZS5fX2l0ZXJhdGUoZnVuY3Rpb24odiwgaywgYykgIHtcbiAgICAgICAgaWYgKCEoaXNTa2lwcGluZyAmJiAoaXNTa2lwcGluZyA9IHByZWRpY2F0ZS5jYWxsKGNvbnRleHQsIHYsIGssIGMpKSkpIHtcbiAgICAgICAgICBpdGVyYXRpb25zKys7XG4gICAgICAgICAgcmV0dXJuIGZuKHYsIHVzZUtleXMgPyBrIDogaXRlcmF0aW9ucyAtIDEsIHRoaXMkMCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGl0ZXJhdGlvbnM7XG4gICAgfTtcbiAgICBza2lwU2VxdWVuY2UuX19pdGVyYXRvclVuY2FjaGVkID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgaWYgKHJldmVyc2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FjaGVSZXN1bHQoKS5fX2l0ZXJhdG9yKHR5cGUsIHJldmVyc2UpO1xuICAgICAgfVxuICAgICAgdmFyIGl0ZXJhdG9yID0gaXRlcmFibGUuX19pdGVyYXRvcihJVEVSQVRFX0VOVFJJRVMsIHJldmVyc2UpO1xuICAgICAgdmFyIHNraXBwaW5nID0gdHJ1ZTtcbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSAge1xuICAgICAgICB2YXIgc3RlcCwgaywgdjtcbiAgICAgICAgZG8ge1xuICAgICAgICAgIHN0ZXAgPSBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgICAgaWYgKHN0ZXAuZG9uZSkge1xuICAgICAgICAgICAgaWYgKHVzZUtleXMgfHwgdHlwZSA9PT0gSVRFUkFURV9WQUxVRVMpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHN0ZXA7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09IElURVJBVEVfS0VZUykge1xuICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0b3JWYWx1ZSh0eXBlLCBpdGVyYXRpb25zKyssIHVuZGVmaW5lZCwgc3RlcCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0b3JWYWx1ZSh0eXBlLCBpdGVyYXRpb25zKyssIHN0ZXAudmFsdWVbMV0sIHN0ZXApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICB2YXIgZW50cnkgPSBzdGVwLnZhbHVlO1xuICAgICAgICAgIGsgPSBlbnRyeVswXTtcbiAgICAgICAgICB2ID0gZW50cnlbMV07XG4gICAgICAgICAgc2tpcHBpbmcgJiYgKHNraXBwaW5nID0gcHJlZGljYXRlLmNhbGwoY29udGV4dCwgdiwgaywgdGhpcyQwKSk7XG4gICAgICAgIH0gd2hpbGUgKHNraXBwaW5nKTtcbiAgICAgICAgcmV0dXJuIHR5cGUgPT09IElURVJBVEVfRU5UUklFUyA/IHN0ZXAgOlxuICAgICAgICAgIGl0ZXJhdG9yVmFsdWUodHlwZSwgaywgdiwgc3RlcCk7XG4gICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBza2lwU2VxdWVuY2U7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIGNvbmNhdEZhY3RvcnkoaXRlcmFibGUsIHZhbHVlcykge1xuICAgIHZhciBpc0tleWVkSXRlcmFibGUgPSBpc0tleWVkKGl0ZXJhYmxlKTtcbiAgICB2YXIgaXRlcnMgPSBbaXRlcmFibGVdLmNvbmNhdCh2YWx1ZXMpLm1hcChmdW5jdGlvbih2ICkge1xuICAgICAgaWYgKCFpc0l0ZXJhYmxlKHYpKSB7XG4gICAgICAgIHYgPSBpc0tleWVkSXRlcmFibGUgP1xuICAgICAgICAgIGtleWVkU2VxRnJvbVZhbHVlKHYpIDpcbiAgICAgICAgICBpbmRleGVkU2VxRnJvbVZhbHVlKEFycmF5LmlzQXJyYXkodikgPyB2IDogW3ZdKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNLZXllZEl0ZXJhYmxlKSB7XG4gICAgICAgIHYgPSBLZXllZEl0ZXJhYmxlKHYpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHY7XG4gICAgfSkuZmlsdGVyKGZ1bmN0aW9uKHYgKSB7cmV0dXJuIHYuc2l6ZSAhPT0gMH0pO1xuXG4gICAgaWYgKGl0ZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGl0ZXJhYmxlO1xuICAgIH1cblxuICAgIGlmIChpdGVycy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHZhciBzaW5nbGV0b24gPSBpdGVyc1swXTtcbiAgICAgIGlmIChzaW5nbGV0b24gPT09IGl0ZXJhYmxlIHx8XG4gICAgICAgICAgaXNLZXllZEl0ZXJhYmxlICYmIGlzS2V5ZWQoc2luZ2xldG9uKSB8fFxuICAgICAgICAgIGlzSW5kZXhlZChpdGVyYWJsZSkgJiYgaXNJbmRleGVkKHNpbmdsZXRvbikpIHtcbiAgICAgICAgcmV0dXJuIHNpbmdsZXRvbjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgY29uY2F0U2VxID0gbmV3IEFycmF5U2VxKGl0ZXJzKTtcbiAgICBpZiAoaXNLZXllZEl0ZXJhYmxlKSB7XG4gICAgICBjb25jYXRTZXEgPSBjb25jYXRTZXEudG9LZXllZFNlcSgpO1xuICAgIH0gZWxzZSBpZiAoIWlzSW5kZXhlZChpdGVyYWJsZSkpIHtcbiAgICAgIGNvbmNhdFNlcSA9IGNvbmNhdFNlcS50b1NldFNlcSgpO1xuICAgIH1cbiAgICBjb25jYXRTZXEgPSBjb25jYXRTZXEuZmxhdHRlbih0cnVlKTtcbiAgICBjb25jYXRTZXEuc2l6ZSA9IGl0ZXJzLnJlZHVjZShcbiAgICAgIGZ1bmN0aW9uKHN1bSwgc2VxKSAge1xuICAgICAgICBpZiAoc3VtICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB2YXIgc2l6ZSA9IHNlcS5zaXplO1xuICAgICAgICAgIGlmIChzaXplICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBzdW0gKyBzaXplO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIDBcbiAgICApO1xuICAgIHJldHVybiBjb25jYXRTZXE7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIGZsYXR0ZW5GYWN0b3J5KGl0ZXJhYmxlLCBkZXB0aCwgdXNlS2V5cykge1xuICAgIHZhciBmbGF0U2VxdWVuY2UgPSBtYWtlU2VxdWVuY2UoaXRlcmFibGUpO1xuICAgIGZsYXRTZXF1ZW5jZS5fX2l0ZXJhdGVVbmNhY2hlZCA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICB2YXIgc3RvcHBlZCA9IGZhbHNlO1xuICAgICAgZnVuY3Rpb24gZmxhdERlZXAoaXRlciwgY3VycmVudERlcHRoKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICAgIGl0ZXIuX19pdGVyYXRlKGZ1bmN0aW9uKHYsIGspICB7XG4gICAgICAgICAgaWYgKCghZGVwdGggfHwgY3VycmVudERlcHRoIDwgZGVwdGgpICYmIGlzSXRlcmFibGUodikpIHtcbiAgICAgICAgICAgIGZsYXREZWVwKHYsIGN1cnJlbnREZXB0aCArIDEpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZm4odiwgdXNlS2V5cyA/IGsgOiBpdGVyYXRpb25zKyssIHRoaXMkMCkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBzdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuICFzdG9wcGVkO1xuICAgICAgICB9LCByZXZlcnNlKTtcbiAgICAgIH1cbiAgICAgIGZsYXREZWVwKGl0ZXJhYmxlLCAwKTtcbiAgICAgIHJldHVybiBpdGVyYXRpb25zO1xuICAgIH1cbiAgICBmbGF0U2VxdWVuY2UuX19pdGVyYXRvclVuY2FjaGVkID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgdmFyIGl0ZXJhdG9yID0gaXRlcmFibGUuX19pdGVyYXRvcih0eXBlLCByZXZlcnNlKTtcbiAgICAgIHZhciBzdGFjayA9IFtdO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHdoaWxlIChpdGVyYXRvcikge1xuICAgICAgICAgIHZhciBzdGVwID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICAgIGlmIChzdGVwLmRvbmUgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICBpdGVyYXRvciA9IHN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhciB2ID0gc3RlcC52YWx1ZTtcbiAgICAgICAgICBpZiAodHlwZSA9PT0gSVRFUkFURV9FTlRSSUVTKSB7XG4gICAgICAgICAgICB2ID0gdlsxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCghZGVwdGggfHwgc3RhY2subGVuZ3RoIDwgZGVwdGgpICYmIGlzSXRlcmFibGUodikpIHtcbiAgICAgICAgICAgIHN0YWNrLnB1c2goaXRlcmF0b3IpO1xuICAgICAgICAgICAgaXRlcmF0b3IgPSB2Ll9faXRlcmF0b3IodHlwZSwgcmV2ZXJzZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1c2VLZXlzID8gc3RlcCA6IGl0ZXJhdG9yVmFsdWUodHlwZSwgaXRlcmF0aW9ucysrLCB2LCBzdGVwKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yRG9uZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBmbGF0U2VxdWVuY2U7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIGZsYXRNYXBGYWN0b3J5KGl0ZXJhYmxlLCBtYXBwZXIsIGNvbnRleHQpIHtcbiAgICB2YXIgY29lcmNlID0gaXRlcmFibGVDbGFzcyhpdGVyYWJsZSk7XG4gICAgcmV0dXJuIGl0ZXJhYmxlLnRvU2VxKCkubWFwKFxuICAgICAgZnVuY3Rpb24odiwgaykgIHtyZXR1cm4gY29lcmNlKG1hcHBlci5jYWxsKGNvbnRleHQsIHYsIGssIGl0ZXJhYmxlKSl9XG4gICAgKS5mbGF0dGVuKHRydWUpO1xuICB9XG5cblxuICBmdW5jdGlvbiBpbnRlcnBvc2VGYWN0b3J5KGl0ZXJhYmxlLCBzZXBhcmF0b3IpIHtcbiAgICB2YXIgaW50ZXJwb3NlZFNlcXVlbmNlID0gbWFrZVNlcXVlbmNlKGl0ZXJhYmxlKTtcbiAgICBpbnRlcnBvc2VkU2VxdWVuY2Uuc2l6ZSA9IGl0ZXJhYmxlLnNpemUgJiYgaXRlcmFibGUuc2l6ZSAqIDIgLTE7XG4gICAgaW50ZXJwb3NlZFNlcXVlbmNlLl9faXRlcmF0ZVVuY2FjaGVkID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIGl0ZXJhYmxlLl9faXRlcmF0ZShmdW5jdGlvbih2LCBrKSBcbiAgICAgICAge3JldHVybiAoIWl0ZXJhdGlvbnMgfHwgZm4oc2VwYXJhdG9yLCBpdGVyYXRpb25zKyssIHRoaXMkMCkgIT09IGZhbHNlKSAmJlxuICAgICAgICBmbih2LCBpdGVyYXRpb25zKyssIHRoaXMkMCkgIT09IGZhbHNlfSxcbiAgICAgICAgcmV2ZXJzZVxuICAgICAgKTtcbiAgICAgIHJldHVybiBpdGVyYXRpb25zO1xuICAgIH07XG4gICAgaW50ZXJwb3NlZFNlcXVlbmNlLl9faXRlcmF0b3JVbmNhY2hlZCA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIHZhciBpdGVyYXRvciA9IGl0ZXJhYmxlLl9faXRlcmF0b3IoSVRFUkFURV9WQUxVRVMsIHJldmVyc2UpO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgdmFyIHN0ZXA7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgaWYgKCFzdGVwIHx8IGl0ZXJhdGlvbnMgJSAyKSB7XG4gICAgICAgICAgc3RlcCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgICBpZiAoc3RlcC5kb25lKSB7XG4gICAgICAgICAgICByZXR1cm4gc3RlcDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGl0ZXJhdGlvbnMgJSAyID9cbiAgICAgICAgICBpdGVyYXRvclZhbHVlKHR5cGUsIGl0ZXJhdGlvbnMrKywgc2VwYXJhdG9yKSA6XG4gICAgICAgICAgaXRlcmF0b3JWYWx1ZSh0eXBlLCBpdGVyYXRpb25zKyssIHN0ZXAudmFsdWUsIHN0ZXApO1xuICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gaW50ZXJwb3NlZFNlcXVlbmNlO1xuICB9XG5cblxuICBmdW5jdGlvbiBzb3J0RmFjdG9yeShpdGVyYWJsZSwgY29tcGFyYXRvciwgbWFwcGVyKSB7XG4gICAgaWYgKCFjb21wYXJhdG9yKSB7XG4gICAgICBjb21wYXJhdG9yID0gZGVmYXVsdENvbXBhcmF0b3I7XG4gICAgfVxuICAgIHZhciBpc0tleWVkSXRlcmFibGUgPSBpc0tleWVkKGl0ZXJhYmxlKTtcbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIHZhciBlbnRyaWVzID0gaXRlcmFibGUudG9TZXEoKS5tYXAoXG4gICAgICBmdW5jdGlvbih2LCBrKSAge3JldHVybiBbaywgdiwgaW5kZXgrKywgbWFwcGVyID8gbWFwcGVyKHYsIGssIGl0ZXJhYmxlKSA6IHZdfVxuICAgICkudG9BcnJheSgpO1xuICAgIGVudHJpZXMuc29ydChmdW5jdGlvbihhLCBiKSAge3JldHVybiBjb21wYXJhdG9yKGFbM10sIGJbM10pIHx8IGFbMl0gLSBiWzJdfSkuZm9yRWFjaChcbiAgICAgIGlzS2V5ZWRJdGVyYWJsZSA/XG4gICAgICBmdW5jdGlvbih2LCBpKSAgeyBlbnRyaWVzW2ldLmxlbmd0aCA9IDI7IH0gOlxuICAgICAgZnVuY3Rpb24odiwgaSkgIHsgZW50cmllc1tpXSA9IHZbMV07IH1cbiAgICApO1xuICAgIHJldHVybiBpc0tleWVkSXRlcmFibGUgPyBLZXllZFNlcShlbnRyaWVzKSA6XG4gICAgICBpc0luZGV4ZWQoaXRlcmFibGUpID8gSW5kZXhlZFNlcShlbnRyaWVzKSA6XG4gICAgICBTZXRTZXEoZW50cmllcyk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIG1heEZhY3RvcnkoaXRlcmFibGUsIGNvbXBhcmF0b3IsIG1hcHBlcikge1xuICAgIGlmICghY29tcGFyYXRvcikge1xuICAgICAgY29tcGFyYXRvciA9IGRlZmF1bHRDb21wYXJhdG9yO1xuICAgIH1cbiAgICBpZiAobWFwcGVyKSB7XG4gICAgICB2YXIgZW50cnkgPSBpdGVyYWJsZS50b1NlcSgpXG4gICAgICAgIC5tYXAoZnVuY3Rpb24odiwgaykgIHtyZXR1cm4gW3YsIG1hcHBlcih2LCBrLCBpdGVyYWJsZSldfSlcbiAgICAgICAgLnJlZHVjZShmdW5jdGlvbihhLCBiKSAge3JldHVybiBtYXhDb21wYXJlKGNvbXBhcmF0b3IsIGFbMV0sIGJbMV0pID8gYiA6IGF9KTtcbiAgICAgIHJldHVybiBlbnRyeSAmJiBlbnRyeVswXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGl0ZXJhYmxlLnJlZHVjZShmdW5jdGlvbihhLCBiKSAge3JldHVybiBtYXhDb21wYXJlKGNvbXBhcmF0b3IsIGEsIGIpID8gYiA6IGF9KTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBtYXhDb21wYXJlKGNvbXBhcmF0b3IsIGEsIGIpIHtcbiAgICB2YXIgY29tcCA9IGNvbXBhcmF0b3IoYiwgYSk7XG4gICAgLy8gYiBpcyBjb25zaWRlcmVkIHRoZSBuZXcgbWF4IGlmIHRoZSBjb21wYXJhdG9yIGRlY2xhcmVzIHRoZW0gZXF1YWwsIGJ1dFxuICAgIC8vIHRoZXkgYXJlIG5vdCBlcXVhbCBhbmQgYiBpcyBpbiBmYWN0IGEgbnVsbGlzaCB2YWx1ZS5cbiAgICByZXR1cm4gKGNvbXAgPT09IDAgJiYgYiAhPT0gYSAmJiAoYiA9PT0gdW5kZWZpbmVkIHx8IGIgPT09IG51bGwgfHwgYiAhPT0gYikpIHx8IGNvbXAgPiAwO1xuICB9XG5cblxuICBmdW5jdGlvbiB6aXBXaXRoRmFjdG9yeShrZXlJdGVyLCB6aXBwZXIsIGl0ZXJzKSB7XG4gICAgdmFyIHppcFNlcXVlbmNlID0gbWFrZVNlcXVlbmNlKGtleUl0ZXIpO1xuICAgIHppcFNlcXVlbmNlLnNpemUgPSBuZXcgQXJyYXlTZXEoaXRlcnMpLm1hcChmdW5jdGlvbihpICkge3JldHVybiBpLnNpemV9KS5taW4oKTtcbiAgICAvLyBOb3RlOiB0aGlzIGEgZ2VuZXJpYyBiYXNlIGltcGxlbWVudGF0aW9uIG9mIF9faXRlcmF0ZSBpbiB0ZXJtcyBvZlxuICAgIC8vIF9faXRlcmF0b3Igd2hpY2ggbWF5IGJlIG1vcmUgZ2VuZXJpY2FsbHkgdXNlZnVsIGluIHRoZSBmdXR1cmUuXG4gICAgemlwU2VxdWVuY2UuX19pdGVyYXRlID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHtcbiAgICAgIC8qIGdlbmVyaWM6XG4gICAgICB2YXIgaXRlcmF0b3IgPSB0aGlzLl9faXRlcmF0b3IoSVRFUkFURV9FTlRSSUVTLCByZXZlcnNlKTtcbiAgICAgIHZhciBzdGVwO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgd2hpbGUgKCEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZSkge1xuICAgICAgICBpdGVyYXRpb25zKys7XG4gICAgICAgIGlmIChmbihzdGVwLnZhbHVlWzFdLCBzdGVwLnZhbHVlWzBdLCB0aGlzKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGl0ZXJhdGlvbnM7XG4gICAgICAqL1xuICAgICAgLy8gaW5kZXhlZDpcbiAgICAgIHZhciBpdGVyYXRvciA9IHRoaXMuX19pdGVyYXRvcihJVEVSQVRFX1ZBTFVFUywgcmV2ZXJzZSk7XG4gICAgICB2YXIgc3RlcDtcbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIHdoaWxlICghKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmUpIHtcbiAgICAgICAgaWYgKGZuKHN0ZXAudmFsdWUsIGl0ZXJhdGlvbnMrKywgdGhpcykgPT09IGZhbHNlKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBpdGVyYXRpb25zO1xuICAgIH07XG4gICAgemlwU2VxdWVuY2UuX19pdGVyYXRvclVuY2FjaGVkID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgdmFyIGl0ZXJhdG9ycyA9IGl0ZXJzLm1hcChmdW5jdGlvbihpIClcbiAgICAgICAge3JldHVybiAoaSA9IEl0ZXJhYmxlKGkpLCBnZXRJdGVyYXRvcihyZXZlcnNlID8gaS5yZXZlcnNlKCkgOiBpKSl9XG4gICAgICApO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgdmFyIGlzRG9uZSA9IGZhbHNlO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHZhciBzdGVwcztcbiAgICAgICAgaWYgKCFpc0RvbmUpIHtcbiAgICAgICAgICBzdGVwcyA9IGl0ZXJhdG9ycy5tYXAoZnVuY3Rpb24oaSApIHtyZXR1cm4gaS5uZXh0KCl9KTtcbiAgICAgICAgICBpc0RvbmUgPSBzdGVwcy5zb21lKGZ1bmN0aW9uKHMgKSB7cmV0dXJuIHMuZG9uZX0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc0RvbmUpIHtcbiAgICAgICAgICByZXR1cm4gaXRlcmF0b3JEb25lKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yVmFsdWUoXG4gICAgICAgICAgdHlwZSxcbiAgICAgICAgICBpdGVyYXRpb25zKyssXG4gICAgICAgICAgemlwcGVyLmFwcGx5KG51bGwsIHN0ZXBzLm1hcChmdW5jdGlvbihzICkge3JldHVybiBzLnZhbHVlfSkpXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiB6aXBTZXF1ZW5jZVxuICB9XG5cblxuICAvLyAjcHJhZ21hIEhlbHBlciBGdW5jdGlvbnNcblxuICBmdW5jdGlvbiByZWlmeShpdGVyLCBzZXEpIHtcbiAgICByZXR1cm4gaXNTZXEoaXRlcikgPyBzZXEgOiBpdGVyLmNvbnN0cnVjdG9yKHNlcSk7XG4gIH1cblxuICBmdW5jdGlvbiB2YWxpZGF0ZUVudHJ5KGVudHJ5KSB7XG4gICAgaWYgKGVudHJ5ICE9PSBPYmplY3QoZW50cnkpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdFeHBlY3RlZCBbSywgVl0gdHVwbGU6ICcgKyBlbnRyeSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVzb2x2ZVNpemUoaXRlcikge1xuICAgIGFzc2VydE5vdEluZmluaXRlKGl0ZXIuc2l6ZSk7XG4gICAgcmV0dXJuIGVuc3VyZVNpemUoaXRlcik7XG4gIH1cblxuICBmdW5jdGlvbiBpdGVyYWJsZUNsYXNzKGl0ZXJhYmxlKSB7XG4gICAgcmV0dXJuIGlzS2V5ZWQoaXRlcmFibGUpID8gS2V5ZWRJdGVyYWJsZSA6XG4gICAgICBpc0luZGV4ZWQoaXRlcmFibGUpID8gSW5kZXhlZEl0ZXJhYmxlIDpcbiAgICAgIFNldEl0ZXJhYmxlO1xuICB9XG5cbiAgZnVuY3Rpb24gbWFrZVNlcXVlbmNlKGl0ZXJhYmxlKSB7XG4gICAgcmV0dXJuIE9iamVjdC5jcmVhdGUoXG4gICAgICAoXG4gICAgICAgIGlzS2V5ZWQoaXRlcmFibGUpID8gS2V5ZWRTZXEgOlxuICAgICAgICBpc0luZGV4ZWQoaXRlcmFibGUpID8gSW5kZXhlZFNlcSA6XG4gICAgICAgIFNldFNlcVxuICAgICAgKS5wcm90b3R5cGVcbiAgICApO1xuICB9XG5cbiAgZnVuY3Rpb24gY2FjaGVSZXN1bHRUaHJvdWdoKCkge1xuICAgIGlmICh0aGlzLl9pdGVyLmNhY2hlUmVzdWx0KSB7XG4gICAgICB0aGlzLl9pdGVyLmNhY2hlUmVzdWx0KCk7XG4gICAgICB0aGlzLnNpemUgPSB0aGlzLl9pdGVyLnNpemU7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFNlcS5wcm90b3R5cGUuY2FjaGVSZXN1bHQuY2FsbCh0aGlzKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBkZWZhdWx0Q29tcGFyYXRvcihhLCBiKSB7XG4gICAgcmV0dXJuIGEgPiBiID8gMSA6IGEgPCBiID8gLTEgOiAwO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9yY2VJdGVyYXRvcihrZXlQYXRoKSB7XG4gICAgdmFyIGl0ZXIgPSBnZXRJdGVyYXRvcihrZXlQYXRoKTtcbiAgICBpZiAoIWl0ZXIpIHtcbiAgICAgIC8vIEFycmF5IG1pZ2h0IG5vdCBiZSBpdGVyYWJsZSBpbiB0aGlzIGVudmlyb25tZW50LCBzbyB3ZSBuZWVkIGEgZmFsbGJhY2tcbiAgICAgIC8vIHRvIG91ciB3cmFwcGVkIHR5cGUuXG4gICAgICBpZiAoIWlzQXJyYXlMaWtlKGtleVBhdGgpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0V4cGVjdGVkIGl0ZXJhYmxlIG9yIGFycmF5LWxpa2U6ICcgKyBrZXlQYXRoKTtcbiAgICAgIH1cbiAgICAgIGl0ZXIgPSBnZXRJdGVyYXRvcihJdGVyYWJsZShrZXlQYXRoKSk7XG4gICAgfVxuICAgIHJldHVybiBpdGVyO1xuICB9XG5cbiAgY3JlYXRlQ2xhc3MoUmVjb3JkLCBLZXllZENvbGxlY3Rpb24pO1xuXG4gICAgZnVuY3Rpb24gUmVjb3JkKGRlZmF1bHRWYWx1ZXMsIG5hbWUpIHtcbiAgICAgIHZhciBoYXNJbml0aWFsaXplZDtcblxuICAgICAgdmFyIFJlY29yZFR5cGUgPSBmdW5jdGlvbiBSZWNvcmQodmFsdWVzKSB7XG4gICAgICAgIGlmICh2YWx1ZXMgaW5zdGFuY2VvZiBSZWNvcmRUeXBlKSB7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICAgICAgfVxuICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUmVjb3JkVHlwZSkpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFJlY29yZFR5cGUodmFsdWVzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWhhc0luaXRpYWxpemVkKSB7XG4gICAgICAgICAgaGFzSW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMoZGVmYXVsdFZhbHVlcyk7XG4gICAgICAgICAgc2V0UHJvcHMoUmVjb3JkVHlwZVByb3RvdHlwZSwga2V5cyk7XG4gICAgICAgICAgUmVjb3JkVHlwZVByb3RvdHlwZS5zaXplID0ga2V5cy5sZW5ndGg7XG4gICAgICAgICAgUmVjb3JkVHlwZVByb3RvdHlwZS5fbmFtZSA9IG5hbWU7XG4gICAgICAgICAgUmVjb3JkVHlwZVByb3RvdHlwZS5fa2V5cyA9IGtleXM7XG4gICAgICAgICAgUmVjb3JkVHlwZVByb3RvdHlwZS5fZGVmYXVsdFZhbHVlcyA9IGRlZmF1bHRWYWx1ZXM7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbWFwID0gTWFwKHZhbHVlcyk7XG4gICAgICB9O1xuXG4gICAgICB2YXIgUmVjb3JkVHlwZVByb3RvdHlwZSA9IFJlY29yZFR5cGUucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShSZWNvcmRQcm90b3R5cGUpO1xuICAgICAgUmVjb3JkVHlwZVByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFJlY29yZFR5cGU7XG5cbiAgICAgIHJldHVybiBSZWNvcmRUeXBlO1xuICAgIH1cblxuICAgIFJlY29yZC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fdG9TdHJpbmcocmVjb3JkTmFtZSh0aGlzKSArICcgeycsICd9Jyk7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgQWNjZXNzXG5cbiAgICBSZWNvcmQucHJvdG90eXBlLmhhcyA9IGZ1bmN0aW9uKGspIHtcbiAgICAgIHJldHVybiB0aGlzLl9kZWZhdWx0VmFsdWVzLmhhc093blByb3BlcnR5KGspO1xuICAgIH07XG5cbiAgICBSZWNvcmQucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKGssIG5vdFNldFZhbHVlKSB7XG4gICAgICBpZiAoIXRoaXMuaGFzKGspKSB7XG4gICAgICAgIHJldHVybiBub3RTZXRWYWx1ZTtcbiAgICAgIH1cbiAgICAgIHZhciBkZWZhdWx0VmFsID0gdGhpcy5fZGVmYXVsdFZhbHVlc1trXTtcbiAgICAgIHJldHVybiB0aGlzLl9tYXAgPyB0aGlzLl9tYXAuZ2V0KGssIGRlZmF1bHRWYWwpIDogZGVmYXVsdFZhbDtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBNb2RpZmljYXRpb25cblxuICAgIFJlY29yZC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLl9fb3duZXJJRCkge1xuICAgICAgICB0aGlzLl9tYXAgJiYgdGhpcy5fbWFwLmNsZWFyKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgdmFyIFJlY29yZFR5cGUgPSB0aGlzLmNvbnN0cnVjdG9yO1xuICAgICAgcmV0dXJuIFJlY29yZFR5cGUuX2VtcHR5IHx8IChSZWNvcmRUeXBlLl9lbXB0eSA9IG1ha2VSZWNvcmQodGhpcywgZW1wdHlNYXAoKSkpO1xuICAgIH07XG5cbiAgICBSZWNvcmQucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKGssIHYpIHtcbiAgICAgIGlmICghdGhpcy5oYXMoaykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3Qgc2V0IHVua25vd24ga2V5IFwiJyArIGsgKyAnXCIgb24gJyArIHJlY29yZE5hbWUodGhpcykpO1xuICAgICAgfVxuICAgICAgdmFyIG5ld01hcCA9IHRoaXMuX21hcCAmJiB0aGlzLl9tYXAuc2V0KGssIHYpO1xuICAgICAgaWYgKHRoaXMuX19vd25lcklEIHx8IG5ld01hcCA9PT0gdGhpcy5fbWFwKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1ha2VSZWNvcmQodGhpcywgbmV3TWFwKTtcbiAgICB9O1xuXG4gICAgUmVjb3JkLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbihrKSB7XG4gICAgICBpZiAoIXRoaXMuaGFzKGspKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgdmFyIG5ld01hcCA9IHRoaXMuX21hcCAmJiB0aGlzLl9tYXAucmVtb3ZlKGspO1xuICAgICAgaWYgKHRoaXMuX19vd25lcklEIHx8IG5ld01hcCA9PT0gdGhpcy5fbWFwKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1ha2VSZWNvcmQodGhpcywgbmV3TWFwKTtcbiAgICB9O1xuXG4gICAgUmVjb3JkLnByb3RvdHlwZS53YXNBbHRlcmVkID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbWFwLndhc0FsdGVyZWQoKTtcbiAgICB9O1xuXG4gICAgUmVjb3JkLnByb3RvdHlwZS5fX2l0ZXJhdG9yID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgcmV0dXJuIEtleWVkSXRlcmFibGUodGhpcy5fZGVmYXVsdFZhbHVlcykubWFwKGZ1bmN0aW9uKF8sIGspICB7cmV0dXJuIHRoaXMkMC5nZXQoayl9KS5fX2l0ZXJhdG9yKHR5cGUsIHJldmVyc2UpO1xuICAgIH07XG5cbiAgICBSZWNvcmQucHJvdG90eXBlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICByZXR1cm4gS2V5ZWRJdGVyYWJsZSh0aGlzLl9kZWZhdWx0VmFsdWVzKS5tYXAoZnVuY3Rpb24oXywgaykgIHtyZXR1cm4gdGhpcyQwLmdldChrKX0pLl9faXRlcmF0ZShmbiwgcmV2ZXJzZSk7XG4gICAgfTtcblxuICAgIFJlY29yZC5wcm90b3R5cGUuX19lbnN1cmVPd25lciA9IGZ1bmN0aW9uKG93bmVySUQpIHtcbiAgICAgIGlmIChvd25lcklEID09PSB0aGlzLl9fb3duZXJJRCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHZhciBuZXdNYXAgPSB0aGlzLl9tYXAgJiYgdGhpcy5fbWFwLl9fZW5zdXJlT3duZXIob3duZXJJRCk7XG4gICAgICBpZiAoIW93bmVySUQpIHtcbiAgICAgICAgdGhpcy5fX293bmVySUQgPSBvd25lcklEO1xuICAgICAgICB0aGlzLl9tYXAgPSBuZXdNYXA7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1ha2VSZWNvcmQodGhpcywgbmV3TWFwLCBvd25lcklEKTtcbiAgICB9O1xuXG5cbiAgdmFyIFJlY29yZFByb3RvdHlwZSA9IFJlY29yZC5wcm90b3R5cGU7XG4gIFJlY29yZFByb3RvdHlwZVtERUxFVEVdID0gUmVjb3JkUHJvdG90eXBlLnJlbW92ZTtcbiAgUmVjb3JkUHJvdG90eXBlLmRlbGV0ZUluID1cbiAgUmVjb3JkUHJvdG90eXBlLnJlbW92ZUluID0gTWFwUHJvdG90eXBlLnJlbW92ZUluO1xuICBSZWNvcmRQcm90b3R5cGUubWVyZ2UgPSBNYXBQcm90b3R5cGUubWVyZ2U7XG4gIFJlY29yZFByb3RvdHlwZS5tZXJnZVdpdGggPSBNYXBQcm90b3R5cGUubWVyZ2VXaXRoO1xuICBSZWNvcmRQcm90b3R5cGUubWVyZ2VJbiA9IE1hcFByb3RvdHlwZS5tZXJnZUluO1xuICBSZWNvcmRQcm90b3R5cGUubWVyZ2VEZWVwID0gTWFwUHJvdG90eXBlLm1lcmdlRGVlcDtcbiAgUmVjb3JkUHJvdG90eXBlLm1lcmdlRGVlcFdpdGggPSBNYXBQcm90b3R5cGUubWVyZ2VEZWVwV2l0aDtcbiAgUmVjb3JkUHJvdG90eXBlLm1lcmdlRGVlcEluID0gTWFwUHJvdG90eXBlLm1lcmdlRGVlcEluO1xuICBSZWNvcmRQcm90b3R5cGUuc2V0SW4gPSBNYXBQcm90b3R5cGUuc2V0SW47XG4gIFJlY29yZFByb3RvdHlwZS51cGRhdGUgPSBNYXBQcm90b3R5cGUudXBkYXRlO1xuICBSZWNvcmRQcm90b3R5cGUudXBkYXRlSW4gPSBNYXBQcm90b3R5cGUudXBkYXRlSW47XG4gIFJlY29yZFByb3RvdHlwZS53aXRoTXV0YXRpb25zID0gTWFwUHJvdG90eXBlLndpdGhNdXRhdGlvbnM7XG4gIFJlY29yZFByb3RvdHlwZS5hc011dGFibGUgPSBNYXBQcm90b3R5cGUuYXNNdXRhYmxlO1xuICBSZWNvcmRQcm90b3R5cGUuYXNJbW11dGFibGUgPSBNYXBQcm90b3R5cGUuYXNJbW11dGFibGU7XG5cblxuICBmdW5jdGlvbiBtYWtlUmVjb3JkKGxpa2VSZWNvcmQsIG1hcCwgb3duZXJJRCkge1xuICAgIHZhciByZWNvcmQgPSBPYmplY3QuY3JlYXRlKE9iamVjdC5nZXRQcm90b3R5cGVPZihsaWtlUmVjb3JkKSk7XG4gICAgcmVjb3JkLl9tYXAgPSBtYXA7XG4gICAgcmVjb3JkLl9fb3duZXJJRCA9IG93bmVySUQ7XG4gICAgcmV0dXJuIHJlY29yZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlY29yZE5hbWUocmVjb3JkKSB7XG4gICAgcmV0dXJuIHJlY29yZC5fbmFtZSB8fCByZWNvcmQuY29uc3RydWN0b3IubmFtZSB8fCAnUmVjb3JkJztcbiAgfVxuXG4gIGZ1bmN0aW9uIHNldFByb3BzKHByb3RvdHlwZSwgbmFtZXMpIHtcbiAgICB0cnkge1xuICAgICAgbmFtZXMuZm9yRWFjaChzZXRQcm9wLmJpbmQodW5kZWZpbmVkLCBwcm90b3R5cGUpKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gT2JqZWN0LmRlZmluZVByb3BlcnR5IGZhaWxlZC4gUHJvYmFibHkgSUU4LlxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNldFByb3AocHJvdG90eXBlLCBuYW1lKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb3RvdHlwZSwgbmFtZSwge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KG5hbWUpO1xuICAgICAgfSxcbiAgICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgaW52YXJpYW50KHRoaXMuX19vd25lcklELCAnQ2Fubm90IHNldCBvbiBhbiBpbW11dGFibGUgcmVjb3JkLicpO1xuICAgICAgICB0aGlzLnNldChuYW1lLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVDbGFzcyhTZXQsIFNldENvbGxlY3Rpb24pO1xuXG4gICAgLy8gQHByYWdtYSBDb25zdHJ1Y3Rpb25cblxuICAgIGZ1bmN0aW9uIFNldCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgPyBlbXB0eVNldCgpIDpcbiAgICAgICAgaXNTZXQodmFsdWUpICYmICFpc09yZGVyZWQodmFsdWUpID8gdmFsdWUgOlxuICAgICAgICBlbXB0eVNldCgpLndpdGhNdXRhdGlvbnMoZnVuY3Rpb24oc2V0ICkge1xuICAgICAgICAgIHZhciBpdGVyID0gU2V0SXRlcmFibGUodmFsdWUpO1xuICAgICAgICAgIGFzc2VydE5vdEluZmluaXRlKGl0ZXIuc2l6ZSk7XG4gICAgICAgICAgaXRlci5mb3JFYWNoKGZ1bmN0aW9uKHYgKSB7cmV0dXJuIHNldC5hZGQodil9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgU2V0Lm9mID0gZnVuY3Rpb24oLyouLi52YWx1ZXMqLykge1xuICAgICAgcmV0dXJuIHRoaXMoYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgU2V0LmZyb21LZXlzID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzKEtleWVkSXRlcmFibGUodmFsdWUpLmtleVNlcSgpKTtcbiAgICB9O1xuXG4gICAgU2V0LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX190b1N0cmluZygnU2V0IHsnLCAnfScpO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIEFjY2Vzc1xuXG4gICAgU2V0LnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX21hcC5oYXModmFsdWUpO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIE1vZGlmaWNhdGlvblxuXG4gICAgU2V0LnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHVwZGF0ZVNldCh0aGlzLCB0aGlzLl9tYXAuc2V0KHZhbHVlLCB0cnVlKSk7XG4gICAgfTtcblxuICAgIFNldC5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiB1cGRhdGVTZXQodGhpcywgdGhpcy5fbWFwLnJlbW92ZSh2YWx1ZSkpO1xuICAgIH07XG5cbiAgICBTZXQucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdXBkYXRlU2V0KHRoaXMsIHRoaXMuX21hcC5jbGVhcigpKTtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBDb21wb3NpdGlvblxuXG4gICAgU2V0LnByb3RvdHlwZS51bmlvbiA9IGZ1bmN0aW9uKCkge3ZhciBpdGVycyA9IFNMSUNFJDAuY2FsbChhcmd1bWVudHMsIDApO1xuICAgICAgaXRlcnMgPSBpdGVycy5maWx0ZXIoZnVuY3Rpb24oeCApIHtyZXR1cm4geC5zaXplICE9PSAwfSk7XG4gICAgICBpZiAoaXRlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuc2l6ZSA9PT0gMCAmJiAhdGhpcy5fX293bmVySUQgJiYgaXRlcnMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yKGl0ZXJzWzBdKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLndpdGhNdXRhdGlvbnMoZnVuY3Rpb24oc2V0ICkge1xuICAgICAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgaXRlcnMubGVuZ3RoOyBpaSsrKSB7XG4gICAgICAgICAgU2V0SXRlcmFibGUoaXRlcnNbaWldKS5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlICkge3JldHVybiBzZXQuYWRkKHZhbHVlKX0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgU2V0LnByb3RvdHlwZS5pbnRlcnNlY3QgPSBmdW5jdGlvbigpIHt2YXIgaXRlcnMgPSBTTElDRSQwLmNhbGwoYXJndW1lbnRzLCAwKTtcbiAgICAgIGlmIChpdGVycy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICBpdGVycyA9IGl0ZXJzLm1hcChmdW5jdGlvbihpdGVyICkge3JldHVybiBTZXRJdGVyYWJsZShpdGVyKX0pO1xuICAgICAgdmFyIG9yaWdpbmFsU2V0ID0gdGhpcztcbiAgICAgIHJldHVybiB0aGlzLndpdGhNdXRhdGlvbnMoZnVuY3Rpb24oc2V0ICkge1xuICAgICAgICBvcmlnaW5hbFNldC5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlICkge1xuICAgICAgICAgIGlmICghaXRlcnMuZXZlcnkoZnVuY3Rpb24oaXRlciApIHtyZXR1cm4gaXRlci5pbmNsdWRlcyh2YWx1ZSl9KSkge1xuICAgICAgICAgICAgc2V0LnJlbW92ZSh2YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBTZXQucHJvdG90eXBlLnN1YnRyYWN0ID0gZnVuY3Rpb24oKSB7dmFyIGl0ZXJzID0gU0xJQ0UkMC5jYWxsKGFyZ3VtZW50cywgMCk7XG4gICAgICBpZiAoaXRlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgaXRlcnMgPSBpdGVycy5tYXAoZnVuY3Rpb24oaXRlciApIHtyZXR1cm4gU2V0SXRlcmFibGUoaXRlcil9KTtcbiAgICAgIHZhciBvcmlnaW5hbFNldCA9IHRoaXM7XG4gICAgICByZXR1cm4gdGhpcy53aXRoTXV0YXRpb25zKGZ1bmN0aW9uKHNldCApIHtcbiAgICAgICAgb3JpZ2luYWxTZXQuZm9yRWFjaChmdW5jdGlvbih2YWx1ZSApIHtcbiAgICAgICAgICBpZiAoaXRlcnMuc29tZShmdW5jdGlvbihpdGVyICkge3JldHVybiBpdGVyLmluY2x1ZGVzKHZhbHVlKX0pKSB7XG4gICAgICAgICAgICBzZXQucmVtb3ZlKHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIFNldC5wcm90b3R5cGUubWVyZ2UgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLnVuaW9uLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIFNldC5wcm90b3R5cGUubWVyZ2VXaXRoID0gZnVuY3Rpb24obWVyZ2VyKSB7dmFyIGl0ZXJzID0gU0xJQ0UkMC5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICByZXR1cm4gdGhpcy51bmlvbi5hcHBseSh0aGlzLCBpdGVycyk7XG4gICAgfTtcblxuICAgIFNldC5wcm90b3R5cGUuc29ydCA9IGZ1bmN0aW9uKGNvbXBhcmF0b3IpIHtcbiAgICAgIC8vIExhdGUgYmluZGluZ1xuICAgICAgcmV0dXJuIE9yZGVyZWRTZXQoc29ydEZhY3RvcnkodGhpcywgY29tcGFyYXRvcikpO1xuICAgIH07XG5cbiAgICBTZXQucHJvdG90eXBlLnNvcnRCeSA9IGZ1bmN0aW9uKG1hcHBlciwgY29tcGFyYXRvcikge1xuICAgICAgLy8gTGF0ZSBiaW5kaW5nXG4gICAgICByZXR1cm4gT3JkZXJlZFNldChzb3J0RmFjdG9yeSh0aGlzLCBjb21wYXJhdG9yLCBtYXBwZXIpKTtcbiAgICB9O1xuXG4gICAgU2V0LnByb3RvdHlwZS53YXNBbHRlcmVkID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbWFwLndhc0FsdGVyZWQoKTtcbiAgICB9O1xuXG4gICAgU2V0LnByb3RvdHlwZS5fX2l0ZXJhdGUgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgcmV0dXJuIHRoaXMuX21hcC5fX2l0ZXJhdGUoZnVuY3Rpb24oXywgaykgIHtyZXR1cm4gZm4oaywgaywgdGhpcyQwKX0sIHJldmVyc2UpO1xuICAgIH07XG5cbiAgICBTZXQucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbWFwLm1hcChmdW5jdGlvbihfLCBrKSAge3JldHVybiBrfSkuX19pdGVyYXRvcih0eXBlLCByZXZlcnNlKTtcbiAgICB9O1xuXG4gICAgU2V0LnByb3RvdHlwZS5fX2Vuc3VyZU93bmVyID0gZnVuY3Rpb24ob3duZXJJRCkge1xuICAgICAgaWYgKG93bmVySUQgPT09IHRoaXMuX19vd25lcklEKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgdmFyIG5ld01hcCA9IHRoaXMuX21hcC5fX2Vuc3VyZU93bmVyKG93bmVySUQpO1xuICAgICAgaWYgKCFvd25lcklEKSB7XG4gICAgICAgIHRoaXMuX19vd25lcklEID0gb3duZXJJRDtcbiAgICAgICAgdGhpcy5fbWFwID0gbmV3TWFwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLl9fbWFrZShuZXdNYXAsIG93bmVySUQpO1xuICAgIH07XG5cblxuICBmdW5jdGlvbiBpc1NldChtYXliZVNldCkge1xuICAgIHJldHVybiAhIShtYXliZVNldCAmJiBtYXliZVNldFtJU19TRVRfU0VOVElORUxdKTtcbiAgfVxuXG4gIFNldC5pc1NldCA9IGlzU2V0O1xuXG4gIHZhciBJU19TRVRfU0VOVElORUwgPSAnQEBfX0lNTVVUQUJMRV9TRVRfX0BAJztcblxuICB2YXIgU2V0UHJvdG90eXBlID0gU2V0LnByb3RvdHlwZTtcbiAgU2V0UHJvdG90eXBlW0lTX1NFVF9TRU5USU5FTF0gPSB0cnVlO1xuICBTZXRQcm90b3R5cGVbREVMRVRFXSA9IFNldFByb3RvdHlwZS5yZW1vdmU7XG4gIFNldFByb3RvdHlwZS5tZXJnZURlZXAgPSBTZXRQcm90b3R5cGUubWVyZ2U7XG4gIFNldFByb3RvdHlwZS5tZXJnZURlZXBXaXRoID0gU2V0UHJvdG90eXBlLm1lcmdlV2l0aDtcbiAgU2V0UHJvdG90eXBlLndpdGhNdXRhdGlvbnMgPSBNYXBQcm90b3R5cGUud2l0aE11dGF0aW9ucztcbiAgU2V0UHJvdG90eXBlLmFzTXV0YWJsZSA9IE1hcFByb3RvdHlwZS5hc011dGFibGU7XG4gIFNldFByb3RvdHlwZS5hc0ltbXV0YWJsZSA9IE1hcFByb3RvdHlwZS5hc0ltbXV0YWJsZTtcblxuICBTZXRQcm90b3R5cGUuX19lbXB0eSA9IGVtcHR5U2V0O1xuICBTZXRQcm90b3R5cGUuX19tYWtlID0gbWFrZVNldDtcblxuICBmdW5jdGlvbiB1cGRhdGVTZXQoc2V0LCBuZXdNYXApIHtcbiAgICBpZiAoc2V0Ll9fb3duZXJJRCkge1xuICAgICAgc2V0LnNpemUgPSBuZXdNYXAuc2l6ZTtcbiAgICAgIHNldC5fbWFwID0gbmV3TWFwO1xuICAgICAgcmV0dXJuIHNldDtcbiAgICB9XG4gICAgcmV0dXJuIG5ld01hcCA9PT0gc2V0Ll9tYXAgPyBzZXQgOlxuICAgICAgbmV3TWFwLnNpemUgPT09IDAgPyBzZXQuX19lbXB0eSgpIDpcbiAgICAgIHNldC5fX21ha2UobmV3TWFwKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1ha2VTZXQobWFwLCBvd25lcklEKSB7XG4gICAgdmFyIHNldCA9IE9iamVjdC5jcmVhdGUoU2V0UHJvdG90eXBlKTtcbiAgICBzZXQuc2l6ZSA9IG1hcCA/IG1hcC5zaXplIDogMDtcbiAgICBzZXQuX21hcCA9IG1hcDtcbiAgICBzZXQuX19vd25lcklEID0gb3duZXJJRDtcbiAgICByZXR1cm4gc2V0O1xuICB9XG5cbiAgdmFyIEVNUFRZX1NFVDtcbiAgZnVuY3Rpb24gZW1wdHlTZXQoKSB7XG4gICAgcmV0dXJuIEVNUFRZX1NFVCB8fCAoRU1QVFlfU0VUID0gbWFrZVNldChlbXB0eU1hcCgpKSk7XG4gIH1cblxuICBjcmVhdGVDbGFzcyhPcmRlcmVkU2V0LCBTZXQpO1xuXG4gICAgLy8gQHByYWdtYSBDb25zdHJ1Y3Rpb25cblxuICAgIGZ1bmN0aW9uIE9yZGVyZWRTZXQodmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gZW1wdHlPcmRlcmVkU2V0KCkgOlxuICAgICAgICBpc09yZGVyZWRTZXQodmFsdWUpID8gdmFsdWUgOlxuICAgICAgICBlbXB0eU9yZGVyZWRTZXQoKS53aXRoTXV0YXRpb25zKGZ1bmN0aW9uKHNldCApIHtcbiAgICAgICAgICB2YXIgaXRlciA9IFNldEl0ZXJhYmxlKHZhbHVlKTtcbiAgICAgICAgICBhc3NlcnROb3RJbmZpbml0ZShpdGVyLnNpemUpO1xuICAgICAgICAgIGl0ZXIuZm9yRWFjaChmdW5jdGlvbih2ICkge3JldHVybiBzZXQuYWRkKHYpfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIE9yZGVyZWRTZXQub2YgPSBmdW5jdGlvbigvKi4uLnZhbHVlcyovKSB7XG4gICAgICByZXR1cm4gdGhpcyhhcmd1bWVudHMpO1xuICAgIH07XG5cbiAgICBPcmRlcmVkU2V0LmZyb21LZXlzID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzKEtleWVkSXRlcmFibGUodmFsdWUpLmtleVNlcSgpKTtcbiAgICB9O1xuXG4gICAgT3JkZXJlZFNldC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fdG9TdHJpbmcoJ09yZGVyZWRTZXQgeycsICd9Jyk7XG4gICAgfTtcblxuXG4gIGZ1bmN0aW9uIGlzT3JkZXJlZFNldChtYXliZU9yZGVyZWRTZXQpIHtcbiAgICByZXR1cm4gaXNTZXQobWF5YmVPcmRlcmVkU2V0KSAmJiBpc09yZGVyZWQobWF5YmVPcmRlcmVkU2V0KTtcbiAgfVxuXG4gIE9yZGVyZWRTZXQuaXNPcmRlcmVkU2V0ID0gaXNPcmRlcmVkU2V0O1xuXG4gIHZhciBPcmRlcmVkU2V0UHJvdG90eXBlID0gT3JkZXJlZFNldC5wcm90b3R5cGU7XG4gIE9yZGVyZWRTZXRQcm90b3R5cGVbSVNfT1JERVJFRF9TRU5USU5FTF0gPSB0cnVlO1xuXG4gIE9yZGVyZWRTZXRQcm90b3R5cGUuX19lbXB0eSA9IGVtcHR5T3JkZXJlZFNldDtcbiAgT3JkZXJlZFNldFByb3RvdHlwZS5fX21ha2UgPSBtYWtlT3JkZXJlZFNldDtcblxuICBmdW5jdGlvbiBtYWtlT3JkZXJlZFNldChtYXAsIG93bmVySUQpIHtcbiAgICB2YXIgc2V0ID0gT2JqZWN0LmNyZWF0ZShPcmRlcmVkU2V0UHJvdG90eXBlKTtcbiAgICBzZXQuc2l6ZSA9IG1hcCA/IG1hcC5zaXplIDogMDtcbiAgICBzZXQuX21hcCA9IG1hcDtcbiAgICBzZXQuX19vd25lcklEID0gb3duZXJJRDtcbiAgICByZXR1cm4gc2V0O1xuICB9XG5cbiAgdmFyIEVNUFRZX09SREVSRURfU0VUO1xuICBmdW5jdGlvbiBlbXB0eU9yZGVyZWRTZXQoKSB7XG4gICAgcmV0dXJuIEVNUFRZX09SREVSRURfU0VUIHx8IChFTVBUWV9PUkRFUkVEX1NFVCA9IG1ha2VPcmRlcmVkU2V0KGVtcHR5T3JkZXJlZE1hcCgpKSk7XG4gIH1cblxuICBjcmVhdGVDbGFzcyhTdGFjaywgSW5kZXhlZENvbGxlY3Rpb24pO1xuXG4gICAgLy8gQHByYWdtYSBDb25zdHJ1Y3Rpb25cblxuICAgIGZ1bmN0aW9uIFN0YWNrKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCA/IGVtcHR5U3RhY2soKSA6XG4gICAgICAgIGlzU3RhY2sodmFsdWUpID8gdmFsdWUgOlxuICAgICAgICBlbXB0eVN0YWNrKCkudW5zaGlmdEFsbCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgU3RhY2sub2YgPSBmdW5jdGlvbigvKi4uLnZhbHVlcyovKSB7XG4gICAgICByZXR1cm4gdGhpcyhhcmd1bWVudHMpO1xuICAgIH07XG5cbiAgICBTdGFjay5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fdG9TdHJpbmcoJ1N0YWNrIFsnLCAnXScpO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIEFjY2Vzc1xuXG4gICAgU3RhY2sucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKGluZGV4LCBub3RTZXRWYWx1ZSkge1xuICAgICAgdmFyIGhlYWQgPSB0aGlzLl9oZWFkO1xuICAgICAgaW5kZXggPSB3cmFwSW5kZXgodGhpcywgaW5kZXgpO1xuICAgICAgd2hpbGUgKGhlYWQgJiYgaW5kZXgtLSkge1xuICAgICAgICBoZWFkID0gaGVhZC5uZXh0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhlYWQgPyBoZWFkLnZhbHVlIDogbm90U2V0VmFsdWU7XG4gICAgfTtcblxuICAgIFN0YWNrLnByb3RvdHlwZS5wZWVrID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5faGVhZCAmJiB0aGlzLl9oZWFkLnZhbHVlO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIE1vZGlmaWNhdGlvblxuXG4gICAgU3RhY2sucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbigvKi4uLnZhbHVlcyovKSB7XG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHZhciBuZXdTaXplID0gdGhpcy5zaXplICsgYXJndW1lbnRzLmxlbmd0aDtcbiAgICAgIHZhciBoZWFkID0gdGhpcy5faGVhZDtcbiAgICAgIGZvciAodmFyIGlpID0gYXJndW1lbnRzLmxlbmd0aCAtIDE7IGlpID49IDA7IGlpLS0pIHtcbiAgICAgICAgaGVhZCA9IHtcbiAgICAgICAgICB2YWx1ZTogYXJndW1lbnRzW2lpXSxcbiAgICAgICAgICBuZXh0OiBoZWFkXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5fX293bmVySUQpIHtcbiAgICAgICAgdGhpcy5zaXplID0gbmV3U2l6ZTtcbiAgICAgICAgdGhpcy5faGVhZCA9IGhlYWQ7XG4gICAgICAgIHRoaXMuX19oYXNoID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9fYWx0ZXJlZCA9IHRydWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1ha2VTdGFjayhuZXdTaXplLCBoZWFkKTtcbiAgICB9O1xuXG4gICAgU3RhY2sucHJvdG90eXBlLnB1c2hBbGwgPSBmdW5jdGlvbihpdGVyKSB7XG4gICAgICBpdGVyID0gSW5kZXhlZEl0ZXJhYmxlKGl0ZXIpO1xuICAgICAgaWYgKGl0ZXIuc2l6ZSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGFzc2VydE5vdEluZmluaXRlKGl0ZXIuc2l6ZSk7XG4gICAgICB2YXIgbmV3U2l6ZSA9IHRoaXMuc2l6ZTtcbiAgICAgIHZhciBoZWFkID0gdGhpcy5faGVhZDtcbiAgICAgIGl0ZXIucmV2ZXJzZSgpLmZvckVhY2goZnVuY3Rpb24odmFsdWUgKSB7XG4gICAgICAgIG5ld1NpemUrKztcbiAgICAgICAgaGVhZCA9IHtcbiAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgbmV4dDogaGVhZFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgICBpZiAodGhpcy5fX293bmVySUQpIHtcbiAgICAgICAgdGhpcy5zaXplID0gbmV3U2l6ZTtcbiAgICAgICAgdGhpcy5faGVhZCA9IGhlYWQ7XG4gICAgICAgIHRoaXMuX19oYXNoID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9fYWx0ZXJlZCA9IHRydWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1ha2VTdGFjayhuZXdTaXplLCBoZWFkKTtcbiAgICB9O1xuXG4gICAgU3RhY2sucHJvdG90eXBlLnBvcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2xpY2UoMSk7XG4gICAgfTtcblxuICAgIFN0YWNrLnByb3RvdHlwZS51bnNoaWZ0ID0gZnVuY3Rpb24oLyouLi52YWx1ZXMqLykge1xuICAgICAgcmV0dXJuIHRoaXMucHVzaC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG5cbiAgICBTdGFjay5wcm90b3R5cGUudW5zaGlmdEFsbCA9IGZ1bmN0aW9uKGl0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLnB1c2hBbGwoaXRlcik7XG4gICAgfTtcblxuICAgIFN0YWNrLnByb3RvdHlwZS5zaGlmdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMucG9wLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIFN0YWNrLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuc2l6ZSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9fb3duZXJJRCkge1xuICAgICAgICB0aGlzLnNpemUgPSAwO1xuICAgICAgICB0aGlzLl9oZWFkID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9faGFzaCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fX2FsdGVyZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBlbXB0eVN0YWNrKCk7XG4gICAgfTtcblxuICAgIFN0YWNrLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcbiAgICAgIGlmICh3aG9sZVNsaWNlKGJlZ2luLCBlbmQsIHRoaXMuc2l6ZSkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICB2YXIgcmVzb2x2ZWRCZWdpbiA9IHJlc29sdmVCZWdpbihiZWdpbiwgdGhpcy5zaXplKTtcbiAgICAgIHZhciByZXNvbHZlZEVuZCA9IHJlc29sdmVFbmQoZW5kLCB0aGlzLnNpemUpO1xuICAgICAgaWYgKHJlc29sdmVkRW5kICE9PSB0aGlzLnNpemUpIHtcbiAgICAgICAgLy8gc3VwZXIuc2xpY2UoYmVnaW4sIGVuZCk7XG4gICAgICAgIHJldHVybiBJbmRleGVkQ29sbGVjdGlvbi5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLCBiZWdpbiwgZW5kKTtcbiAgICAgIH1cbiAgICAgIHZhciBuZXdTaXplID0gdGhpcy5zaXplIC0gcmVzb2x2ZWRCZWdpbjtcbiAgICAgIHZhciBoZWFkID0gdGhpcy5faGVhZDtcbiAgICAgIHdoaWxlIChyZXNvbHZlZEJlZ2luLS0pIHtcbiAgICAgICAgaGVhZCA9IGhlYWQubmV4dDtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9fb3duZXJJRCkge1xuICAgICAgICB0aGlzLnNpemUgPSBuZXdTaXplO1xuICAgICAgICB0aGlzLl9oZWFkID0gaGVhZDtcbiAgICAgICAgdGhpcy5fX2hhc2ggPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX19hbHRlcmVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWFrZVN0YWNrKG5ld1NpemUsIGhlYWQpO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIE11dGFiaWxpdHlcblxuICAgIFN0YWNrLnByb3RvdHlwZS5fX2Vuc3VyZU93bmVyID0gZnVuY3Rpb24ob3duZXJJRCkge1xuICAgICAgaWYgKG93bmVySUQgPT09IHRoaXMuX19vd25lcklEKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgaWYgKCFvd25lcklEKSB7XG4gICAgICAgIHRoaXMuX19vd25lcklEID0gb3duZXJJRDtcbiAgICAgICAgdGhpcy5fX2FsdGVyZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWFrZVN0YWNrKHRoaXMuc2l6ZSwgdGhpcy5faGVhZCwgb3duZXJJRCwgdGhpcy5fX2hhc2gpO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIEl0ZXJhdGlvblxuXG4gICAgU3RhY2sucHJvdG90eXBlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7XG4gICAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXZlcnNlKCkuX19pdGVyYXRlKGZuKTtcbiAgICAgIH1cbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIHZhciBub2RlID0gdGhpcy5faGVhZDtcbiAgICAgIHdoaWxlIChub2RlKSB7XG4gICAgICAgIGlmIChmbihub2RlLnZhbHVlLCBpdGVyYXRpb25zKyssIHRoaXMpID09PSBmYWxzZSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIG5vZGUgPSBub2RlLm5leHQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gaXRlcmF0aW9ucztcbiAgICB9O1xuXG4gICAgU3RhY2sucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXZlcnNlKCkuX19pdGVyYXRvcih0eXBlKTtcbiAgICAgIH1cbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIHZhciBub2RlID0gdGhpcy5faGVhZDtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSAge1xuICAgICAgICBpZiAobm9kZSkge1xuICAgICAgICAgIHZhciB2YWx1ZSA9IG5vZGUudmFsdWU7XG4gICAgICAgICAgbm9kZSA9IG5vZGUubmV4dDtcbiAgICAgICAgICByZXR1cm4gaXRlcmF0b3JWYWx1ZSh0eXBlLCBpdGVyYXRpb25zKyssIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXRlcmF0b3JEb25lKCk7XG4gICAgICB9KTtcbiAgICB9O1xuXG5cbiAgZnVuY3Rpb24gaXNTdGFjayhtYXliZVN0YWNrKSB7XG4gICAgcmV0dXJuICEhKG1heWJlU3RhY2sgJiYgbWF5YmVTdGFja1tJU19TVEFDS19TRU5USU5FTF0pO1xuICB9XG5cbiAgU3RhY2suaXNTdGFjayA9IGlzU3RhY2s7XG5cbiAgdmFyIElTX1NUQUNLX1NFTlRJTkVMID0gJ0BAX19JTU1VVEFCTEVfU1RBQ0tfX0BAJztcblxuICB2YXIgU3RhY2tQcm90b3R5cGUgPSBTdGFjay5wcm90b3R5cGU7XG4gIFN0YWNrUHJvdG90eXBlW0lTX1NUQUNLX1NFTlRJTkVMXSA9IHRydWU7XG4gIFN0YWNrUHJvdG90eXBlLndpdGhNdXRhdGlvbnMgPSBNYXBQcm90b3R5cGUud2l0aE11dGF0aW9ucztcbiAgU3RhY2tQcm90b3R5cGUuYXNNdXRhYmxlID0gTWFwUHJvdG90eXBlLmFzTXV0YWJsZTtcbiAgU3RhY2tQcm90b3R5cGUuYXNJbW11dGFibGUgPSBNYXBQcm90b3R5cGUuYXNJbW11dGFibGU7XG4gIFN0YWNrUHJvdG90eXBlLndhc0FsdGVyZWQgPSBNYXBQcm90b3R5cGUud2FzQWx0ZXJlZDtcblxuXG4gIGZ1bmN0aW9uIG1ha2VTdGFjayhzaXplLCBoZWFkLCBvd25lcklELCBoYXNoKSB7XG4gICAgdmFyIG1hcCA9IE9iamVjdC5jcmVhdGUoU3RhY2tQcm90b3R5cGUpO1xuICAgIG1hcC5zaXplID0gc2l6ZTtcbiAgICBtYXAuX2hlYWQgPSBoZWFkO1xuICAgIG1hcC5fX293bmVySUQgPSBvd25lcklEO1xuICAgIG1hcC5fX2hhc2ggPSBoYXNoO1xuICAgIG1hcC5fX2FsdGVyZWQgPSBmYWxzZTtcbiAgICByZXR1cm4gbWFwO1xuICB9XG5cbiAgdmFyIEVNUFRZX1NUQUNLO1xuICBmdW5jdGlvbiBlbXB0eVN0YWNrKCkge1xuICAgIHJldHVybiBFTVBUWV9TVEFDSyB8fCAoRU1QVFlfU1RBQ0sgPSBtYWtlU3RhY2soMCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnRyaWJ1dGVzIGFkZGl0aW9uYWwgbWV0aG9kcyB0byBhIGNvbnN0cnVjdG9yXG4gICAqL1xuICBmdW5jdGlvbiBtaXhpbihjdG9yLCBtZXRob2RzKSB7XG4gICAgdmFyIGtleUNvcGllciA9IGZ1bmN0aW9uKGtleSApIHsgY3Rvci5wcm90b3R5cGVba2V5XSA9IG1ldGhvZHNba2V5XTsgfTtcbiAgICBPYmplY3Qua2V5cyhtZXRob2RzKS5mb3JFYWNoKGtleUNvcGllcik7XG4gICAgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyAmJlxuICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhtZXRob2RzKS5mb3JFYWNoKGtleUNvcGllcik7XG4gICAgcmV0dXJuIGN0b3I7XG4gIH1cblxuICBJdGVyYWJsZS5JdGVyYXRvciA9IEl0ZXJhdG9yO1xuXG4gIG1peGluKEl0ZXJhYmxlLCB7XG5cbiAgICAvLyAjIyMgQ29udmVyc2lvbiB0byBvdGhlciB0eXBlc1xuXG4gICAgdG9BcnJheTogZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnROb3RJbmZpbml0ZSh0aGlzLnNpemUpO1xuICAgICAgdmFyIGFycmF5ID0gbmV3IEFycmF5KHRoaXMuc2l6ZSB8fCAwKTtcbiAgICAgIHRoaXMudmFsdWVTZXEoKS5fX2l0ZXJhdGUoZnVuY3Rpb24odiwgaSkgIHsgYXJyYXlbaV0gPSB2OyB9KTtcbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9LFxuXG4gICAgdG9JbmRleGVkU2VxOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBuZXcgVG9JbmRleGVkU2VxdWVuY2UodGhpcyk7XG4gICAgfSxcblxuICAgIHRvSlM6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMudG9TZXEoKS5tYXAoXG4gICAgICAgIGZ1bmN0aW9uKHZhbHVlICkge3JldHVybiB2YWx1ZSAmJiB0eXBlb2YgdmFsdWUudG9KUyA9PT0gJ2Z1bmN0aW9uJyA/IHZhbHVlLnRvSlMoKSA6IHZhbHVlfVxuICAgICAgKS5fX3RvSlMoKTtcbiAgICB9LFxuXG4gICAgdG9KU09OOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLnRvU2VxKCkubWFwKFxuICAgICAgICBmdW5jdGlvbih2YWx1ZSApIHtyZXR1cm4gdmFsdWUgJiYgdHlwZW9mIHZhbHVlLnRvSlNPTiA9PT0gJ2Z1bmN0aW9uJyA/IHZhbHVlLnRvSlNPTigpIDogdmFsdWV9XG4gICAgICApLl9fdG9KUygpO1xuICAgIH0sXG5cbiAgICB0b0tleWVkU2VxOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBuZXcgVG9LZXllZFNlcXVlbmNlKHRoaXMsIHRydWUpO1xuICAgIH0sXG5cbiAgICB0b01hcDogZnVuY3Rpb24oKSB7XG4gICAgICAvLyBVc2UgTGF0ZSBCaW5kaW5nIGhlcmUgdG8gc29sdmUgdGhlIGNpcmN1bGFyIGRlcGVuZGVuY3kuXG4gICAgICByZXR1cm4gTWFwKHRoaXMudG9LZXllZFNlcSgpKTtcbiAgICB9LFxuXG4gICAgdG9PYmplY3Q6IGZ1bmN0aW9uKCkge1xuICAgICAgYXNzZXJ0Tm90SW5maW5pdGUodGhpcy5zaXplKTtcbiAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgIHRoaXMuX19pdGVyYXRlKGZ1bmN0aW9uKHYsIGspICB7IG9iamVjdFtrXSA9IHY7IH0pO1xuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9LFxuXG4gICAgdG9PcmRlcmVkTWFwOiBmdW5jdGlvbigpIHtcbiAgICAgIC8vIFVzZSBMYXRlIEJpbmRpbmcgaGVyZSB0byBzb2x2ZSB0aGUgY2lyY3VsYXIgZGVwZW5kZW5jeS5cbiAgICAgIHJldHVybiBPcmRlcmVkTWFwKHRoaXMudG9LZXllZFNlcSgpKTtcbiAgICB9LFxuXG4gICAgdG9PcmRlcmVkU2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIC8vIFVzZSBMYXRlIEJpbmRpbmcgaGVyZSB0byBzb2x2ZSB0aGUgY2lyY3VsYXIgZGVwZW5kZW5jeS5cbiAgICAgIHJldHVybiBPcmRlcmVkU2V0KGlzS2V5ZWQodGhpcykgPyB0aGlzLnZhbHVlU2VxKCkgOiB0aGlzKTtcbiAgICB9LFxuXG4gICAgdG9TZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgLy8gVXNlIExhdGUgQmluZGluZyBoZXJlIHRvIHNvbHZlIHRoZSBjaXJjdWxhciBkZXBlbmRlbmN5LlxuICAgICAgcmV0dXJuIFNldChpc0tleWVkKHRoaXMpID8gdGhpcy52YWx1ZVNlcSgpIDogdGhpcyk7XG4gICAgfSxcblxuICAgIHRvU2V0U2VxOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBuZXcgVG9TZXRTZXF1ZW5jZSh0aGlzKTtcbiAgICB9LFxuXG4gICAgdG9TZXE6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGlzSW5kZXhlZCh0aGlzKSA/IHRoaXMudG9JbmRleGVkU2VxKCkgOlxuICAgICAgICBpc0tleWVkKHRoaXMpID8gdGhpcy50b0tleWVkU2VxKCkgOlxuICAgICAgICB0aGlzLnRvU2V0U2VxKCk7XG4gICAgfSxcblxuICAgIHRvU3RhY2s6IGZ1bmN0aW9uKCkge1xuICAgICAgLy8gVXNlIExhdGUgQmluZGluZyBoZXJlIHRvIHNvbHZlIHRoZSBjaXJjdWxhciBkZXBlbmRlbmN5LlxuICAgICAgcmV0dXJuIFN0YWNrKGlzS2V5ZWQodGhpcykgPyB0aGlzLnZhbHVlU2VxKCkgOiB0aGlzKTtcbiAgICB9LFxuXG4gICAgdG9MaXN0OiBmdW5jdGlvbigpIHtcbiAgICAgIC8vIFVzZSBMYXRlIEJpbmRpbmcgaGVyZSB0byBzb2x2ZSB0aGUgY2lyY3VsYXIgZGVwZW5kZW5jeS5cbiAgICAgIHJldHVybiBMaXN0KGlzS2V5ZWQodGhpcykgPyB0aGlzLnZhbHVlU2VxKCkgOiB0aGlzKTtcbiAgICB9LFxuXG5cbiAgICAvLyAjIyMgQ29tbW9uIEphdmFTY3JpcHQgbWV0aG9kcyBhbmQgcHJvcGVydGllc1xuXG4gICAgdG9TdHJpbmc6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuICdbSXRlcmFibGVdJztcbiAgICB9LFxuXG4gICAgX190b1N0cmluZzogZnVuY3Rpb24oaGVhZCwgdGFpbCkge1xuICAgICAgaWYgKHRoaXMuc2l6ZSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gaGVhZCArIHRhaWw7XG4gICAgICB9XG4gICAgICByZXR1cm4gaGVhZCArICcgJyArIHRoaXMudG9TZXEoKS5tYXAodGhpcy5fX3RvU3RyaW5nTWFwcGVyKS5qb2luKCcsICcpICsgJyAnICsgdGFpbDtcbiAgICB9LFxuXG5cbiAgICAvLyAjIyMgRVM2IENvbGxlY3Rpb24gbWV0aG9kcyAoRVM2IEFycmF5IGFuZCBNYXApXG5cbiAgICBjb25jYXQ6IGZ1bmN0aW9uKCkge3ZhciB2YWx1ZXMgPSBTTElDRSQwLmNhbGwoYXJndW1lbnRzLCAwKTtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCBjb25jYXRGYWN0b3J5KHRoaXMsIHZhbHVlcykpO1xuICAgIH0sXG5cbiAgICBpbmNsdWRlczogZnVuY3Rpb24oc2VhcmNoVmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLnNvbWUoZnVuY3Rpb24odmFsdWUgKSB7cmV0dXJuIGlzKHZhbHVlLCBzZWFyY2hWYWx1ZSl9KTtcbiAgICB9LFxuXG4gICAgZW50cmllczogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fX2l0ZXJhdG9yKElURVJBVEVfRU5UUklFUyk7XG4gICAgfSxcblxuICAgIGV2ZXJ5OiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIGFzc2VydE5vdEluZmluaXRlKHRoaXMuc2l6ZSk7XG4gICAgICB2YXIgcmV0dXJuVmFsdWUgPSB0cnVlO1xuICAgICAgdGhpcy5fX2l0ZXJhdGUoZnVuY3Rpb24odiwgaywgYykgIHtcbiAgICAgICAgaWYgKCFwcmVkaWNhdGUuY2FsbChjb250ZXh0LCB2LCBrLCBjKSkge1xuICAgICAgICAgIHJldHVyblZhbHVlID0gZmFsc2U7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgICB9LFxuXG4gICAgZmlsdGVyOiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCBmaWx0ZXJGYWN0b3J5KHRoaXMsIHByZWRpY2F0ZSwgY29udGV4dCwgdHJ1ZSkpO1xuICAgIH0sXG5cbiAgICBmaW5kOiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQsIG5vdFNldFZhbHVlKSB7XG4gICAgICB2YXIgZW50cnkgPSB0aGlzLmZpbmRFbnRyeShwcmVkaWNhdGUsIGNvbnRleHQpO1xuICAgICAgcmV0dXJuIGVudHJ5ID8gZW50cnlbMV0gOiBub3RTZXRWYWx1ZTtcbiAgICB9LFxuXG4gICAgZmluZEVudHJ5OiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIHZhciBmb3VuZDtcbiAgICAgIHRoaXMuX19pdGVyYXRlKGZ1bmN0aW9uKHYsIGssIGMpICB7XG4gICAgICAgIGlmIChwcmVkaWNhdGUuY2FsbChjb250ZXh0LCB2LCBrLCBjKSkge1xuICAgICAgICAgIGZvdW5kID0gW2ssIHZdO1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gZm91bmQ7XG4gICAgfSxcblxuICAgIGZpbmRMYXN0RW50cnk6IGZ1bmN0aW9uKHByZWRpY2F0ZSwgY29udGV4dCkge1xuICAgICAgcmV0dXJuIHRoaXMudG9TZXEoKS5yZXZlcnNlKCkuZmluZEVudHJ5KHByZWRpY2F0ZSwgY29udGV4dCk7XG4gICAgfSxcblxuICAgIGZvckVhY2g6IGZ1bmN0aW9uKHNpZGVFZmZlY3QsIGNvbnRleHQpIHtcbiAgICAgIGFzc2VydE5vdEluZmluaXRlKHRoaXMuc2l6ZSk7XG4gICAgICByZXR1cm4gdGhpcy5fX2l0ZXJhdGUoY29udGV4dCA/IHNpZGVFZmZlY3QuYmluZChjb250ZXh0KSA6IHNpZGVFZmZlY3QpO1xuICAgIH0sXG5cbiAgICBqb2luOiBmdW5jdGlvbihzZXBhcmF0b3IpIHtcbiAgICAgIGFzc2VydE5vdEluZmluaXRlKHRoaXMuc2l6ZSk7XG4gICAgICBzZXBhcmF0b3IgPSBzZXBhcmF0b3IgIT09IHVuZGVmaW5lZCA/ICcnICsgc2VwYXJhdG9yIDogJywnO1xuICAgICAgdmFyIGpvaW5lZCA9ICcnO1xuICAgICAgdmFyIGlzRmlyc3QgPSB0cnVlO1xuICAgICAgdGhpcy5fX2l0ZXJhdGUoZnVuY3Rpb24odiApIHtcbiAgICAgICAgaXNGaXJzdCA/IChpc0ZpcnN0ID0gZmFsc2UpIDogKGpvaW5lZCArPSBzZXBhcmF0b3IpO1xuICAgICAgICBqb2luZWQgKz0gdiAhPT0gbnVsbCAmJiB2ICE9PSB1bmRlZmluZWQgPyB2LnRvU3RyaW5nKCkgOiAnJztcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGpvaW5lZDtcbiAgICB9LFxuXG4gICAga2V5czogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fX2l0ZXJhdG9yKElURVJBVEVfS0VZUyk7XG4gICAgfSxcblxuICAgIG1hcDogZnVuY3Rpb24obWFwcGVyLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgbWFwRmFjdG9yeSh0aGlzLCBtYXBwZXIsIGNvbnRleHQpKTtcbiAgICB9LFxuXG4gICAgcmVkdWNlOiBmdW5jdGlvbihyZWR1Y2VyLCBpbml0aWFsUmVkdWN0aW9uLCBjb250ZXh0KSB7XG4gICAgICBhc3NlcnROb3RJbmZpbml0ZSh0aGlzLnNpemUpO1xuICAgICAgdmFyIHJlZHVjdGlvbjtcbiAgICAgIHZhciB1c2VGaXJzdDtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikge1xuICAgICAgICB1c2VGaXJzdCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZWR1Y3Rpb24gPSBpbml0aWFsUmVkdWN0aW9uO1xuICAgICAgfVxuICAgICAgdGhpcy5fX2l0ZXJhdGUoZnVuY3Rpb24odiwgaywgYykgIHtcbiAgICAgICAgaWYgKHVzZUZpcnN0KSB7XG4gICAgICAgICAgdXNlRmlyc3QgPSBmYWxzZTtcbiAgICAgICAgICByZWR1Y3Rpb24gPSB2O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlZHVjdGlvbiA9IHJlZHVjZXIuY2FsbChjb250ZXh0LCByZWR1Y3Rpb24sIHYsIGssIGMpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZWR1Y3Rpb247XG4gICAgfSxcblxuICAgIHJlZHVjZVJpZ2h0OiBmdW5jdGlvbihyZWR1Y2VyLCBpbml0aWFsUmVkdWN0aW9uLCBjb250ZXh0KSB7XG4gICAgICB2YXIgcmV2ZXJzZWQgPSB0aGlzLnRvS2V5ZWRTZXEoKS5yZXZlcnNlKCk7XG4gICAgICByZXR1cm4gcmV2ZXJzZWQucmVkdWNlLmFwcGx5KHJldmVyc2VkLCBhcmd1bWVudHMpO1xuICAgIH0sXG5cbiAgICByZXZlcnNlOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCByZXZlcnNlRmFjdG9yeSh0aGlzLCB0cnVlKSk7XG4gICAgfSxcblxuICAgIHNsaWNlOiBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgc2xpY2VGYWN0b3J5KHRoaXMsIGJlZ2luLCBlbmQsIHRydWUpKTtcbiAgICB9LFxuXG4gICAgc29tZTogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gIXRoaXMuZXZlcnkobm90KHByZWRpY2F0ZSksIGNvbnRleHQpO1xuICAgIH0sXG5cbiAgICBzb3J0OiBmdW5jdGlvbihjb21wYXJhdG9yKSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgc29ydEZhY3RvcnkodGhpcywgY29tcGFyYXRvcikpO1xuICAgIH0sXG5cbiAgICB2YWx1ZXM6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX19pdGVyYXRvcihJVEVSQVRFX1ZBTFVFUyk7XG4gICAgfSxcblxuXG4gICAgLy8gIyMjIE1vcmUgc2VxdWVudGlhbCBtZXRob2RzXG5cbiAgICBidXRMYXN0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLnNsaWNlKDAsIC0xKTtcbiAgICB9LFxuXG4gICAgaXNFbXB0eTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5zaXplICE9PSB1bmRlZmluZWQgPyB0aGlzLnNpemUgPT09IDAgOiAhdGhpcy5zb21lKGZ1bmN0aW9uKCkgIHtyZXR1cm4gdHJ1ZX0pO1xuICAgIH0sXG5cbiAgICBjb3VudDogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gZW5zdXJlU2l6ZShcbiAgICAgICAgcHJlZGljYXRlID8gdGhpcy50b1NlcSgpLmZpbHRlcihwcmVkaWNhdGUsIGNvbnRleHQpIDogdGhpc1xuICAgICAgKTtcbiAgICB9LFxuXG4gICAgY291bnRCeTogZnVuY3Rpb24oZ3JvdXBlciwgY29udGV4dCkge1xuICAgICAgcmV0dXJuIGNvdW50QnlGYWN0b3J5KHRoaXMsIGdyb3VwZXIsIGNvbnRleHQpO1xuICAgIH0sXG5cbiAgICBlcXVhbHM6IGZ1bmN0aW9uKG90aGVyKSB7XG4gICAgICByZXR1cm4gZGVlcEVxdWFsKHRoaXMsIG90aGVyKTtcbiAgICB9LFxuXG4gICAgZW50cnlTZXE6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGl0ZXJhYmxlID0gdGhpcztcbiAgICAgIGlmIChpdGVyYWJsZS5fY2FjaGUpIHtcbiAgICAgICAgLy8gV2UgY2FjaGUgYXMgYW4gZW50cmllcyBhcnJheSwgc28gd2UgY2FuIGp1c3QgcmV0dXJuIHRoZSBjYWNoZSFcbiAgICAgICAgcmV0dXJuIG5ldyBBcnJheVNlcShpdGVyYWJsZS5fY2FjaGUpO1xuICAgICAgfVxuICAgICAgdmFyIGVudHJpZXNTZXF1ZW5jZSA9IGl0ZXJhYmxlLnRvU2VxKCkubWFwKGVudHJ5TWFwcGVyKS50b0luZGV4ZWRTZXEoKTtcbiAgICAgIGVudHJpZXNTZXF1ZW5jZS5mcm9tRW50cnlTZXEgPSBmdW5jdGlvbigpICB7cmV0dXJuIGl0ZXJhYmxlLnRvU2VxKCl9O1xuICAgICAgcmV0dXJuIGVudHJpZXNTZXF1ZW5jZTtcbiAgICB9LFxuXG4gICAgZmlsdGVyTm90OiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIHJldHVybiB0aGlzLmZpbHRlcihub3QocHJlZGljYXRlKSwgY29udGV4dCk7XG4gICAgfSxcblxuICAgIGZpbmRMYXN0OiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQsIG5vdFNldFZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy50b0tleWVkU2VxKCkucmV2ZXJzZSgpLmZpbmQocHJlZGljYXRlLCBjb250ZXh0LCBub3RTZXRWYWx1ZSk7XG4gICAgfSxcblxuICAgIGZpcnN0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmZpbmQocmV0dXJuVHJ1ZSk7XG4gICAgfSxcblxuICAgIGZsYXRNYXA6IGZ1bmN0aW9uKG1hcHBlciwgY29udGV4dCkge1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIGZsYXRNYXBGYWN0b3J5KHRoaXMsIG1hcHBlciwgY29udGV4dCkpO1xuICAgIH0sXG5cbiAgICBmbGF0dGVuOiBmdW5jdGlvbihkZXB0aCkge1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIGZsYXR0ZW5GYWN0b3J5KHRoaXMsIGRlcHRoLCB0cnVlKSk7XG4gICAgfSxcblxuICAgIGZyb21FbnRyeVNlcTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gbmV3IEZyb21FbnRyaWVzU2VxdWVuY2UodGhpcyk7XG4gICAgfSxcblxuICAgIGdldDogZnVuY3Rpb24oc2VhcmNoS2V5LCBub3RTZXRWYWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZmluZChmdW5jdGlvbihfLCBrZXkpICB7cmV0dXJuIGlzKGtleSwgc2VhcmNoS2V5KX0sIHVuZGVmaW5lZCwgbm90U2V0VmFsdWUpO1xuICAgIH0sXG5cbiAgICBnZXRJbjogZnVuY3Rpb24oc2VhcmNoS2V5UGF0aCwgbm90U2V0VmFsdWUpIHtcbiAgICAgIHZhciBuZXN0ZWQgPSB0aGlzO1xuICAgICAgLy8gTm90ZTogaW4gYW4gRVM2IGVudmlyb25tZW50LCB3ZSB3b3VsZCBwcmVmZXI6XG4gICAgICAvLyBmb3IgKHZhciBrZXkgb2Ygc2VhcmNoS2V5UGF0aCkge1xuICAgICAgdmFyIGl0ZXIgPSBmb3JjZUl0ZXJhdG9yKHNlYXJjaEtleVBhdGgpO1xuICAgICAgdmFyIHN0ZXA7XG4gICAgICB3aGlsZSAoIShzdGVwID0gaXRlci5uZXh0KCkpLmRvbmUpIHtcbiAgICAgICAgdmFyIGtleSA9IHN0ZXAudmFsdWU7XG4gICAgICAgIG5lc3RlZCA9IG5lc3RlZCAmJiBuZXN0ZWQuZ2V0ID8gbmVzdGVkLmdldChrZXksIE5PVF9TRVQpIDogTk9UX1NFVDtcbiAgICAgICAgaWYgKG5lc3RlZCA9PT0gTk9UX1NFVCkge1xuICAgICAgICAgIHJldHVybiBub3RTZXRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG5lc3RlZDtcbiAgICB9LFxuXG4gICAgZ3JvdXBCeTogZnVuY3Rpb24oZ3JvdXBlciwgY29udGV4dCkge1xuICAgICAgcmV0dXJuIGdyb3VwQnlGYWN0b3J5KHRoaXMsIGdyb3VwZXIsIGNvbnRleHQpO1xuICAgIH0sXG5cbiAgICBoYXM6IGZ1bmN0aW9uKHNlYXJjaEtleSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0KHNlYXJjaEtleSwgTk9UX1NFVCkgIT09IE5PVF9TRVQ7XG4gICAgfSxcblxuICAgIGhhc0luOiBmdW5jdGlvbihzZWFyY2hLZXlQYXRoKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRJbihzZWFyY2hLZXlQYXRoLCBOT1RfU0VUKSAhPT0gTk9UX1NFVDtcbiAgICB9LFxuXG4gICAgaXNTdWJzZXQ6IGZ1bmN0aW9uKGl0ZXIpIHtcbiAgICAgIGl0ZXIgPSB0eXBlb2YgaXRlci5pbmNsdWRlcyA9PT0gJ2Z1bmN0aW9uJyA/IGl0ZXIgOiBJdGVyYWJsZShpdGVyKTtcbiAgICAgIHJldHVybiB0aGlzLmV2ZXJ5KGZ1bmN0aW9uKHZhbHVlICkge3JldHVybiBpdGVyLmluY2x1ZGVzKHZhbHVlKX0pO1xuICAgIH0sXG5cbiAgICBpc1N1cGVyc2V0OiBmdW5jdGlvbihpdGVyKSB7XG4gICAgICBpdGVyID0gdHlwZW9mIGl0ZXIuaXNTdWJzZXQgPT09ICdmdW5jdGlvbicgPyBpdGVyIDogSXRlcmFibGUoaXRlcik7XG4gICAgICByZXR1cm4gaXRlci5pc1N1YnNldCh0aGlzKTtcbiAgICB9LFxuXG4gICAga2V5U2VxOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLnRvU2VxKCkubWFwKGtleU1hcHBlcikudG9JbmRleGVkU2VxKCk7XG4gICAgfSxcblxuICAgIGxhc3Q6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMudG9TZXEoKS5yZXZlcnNlKCkuZmlyc3QoKTtcbiAgICB9LFxuXG4gICAgbWF4OiBmdW5jdGlvbihjb21wYXJhdG9yKSB7XG4gICAgICByZXR1cm4gbWF4RmFjdG9yeSh0aGlzLCBjb21wYXJhdG9yKTtcbiAgICB9LFxuXG4gICAgbWF4Qnk6IGZ1bmN0aW9uKG1hcHBlciwgY29tcGFyYXRvcikge1xuICAgICAgcmV0dXJuIG1heEZhY3RvcnkodGhpcywgY29tcGFyYXRvciwgbWFwcGVyKTtcbiAgICB9LFxuXG4gICAgbWluOiBmdW5jdGlvbihjb21wYXJhdG9yKSB7XG4gICAgICByZXR1cm4gbWF4RmFjdG9yeSh0aGlzLCBjb21wYXJhdG9yID8gbmVnKGNvbXBhcmF0b3IpIDogZGVmYXVsdE5lZ0NvbXBhcmF0b3IpO1xuICAgIH0sXG5cbiAgICBtaW5CeTogZnVuY3Rpb24obWFwcGVyLCBjb21wYXJhdG9yKSB7XG4gICAgICByZXR1cm4gbWF4RmFjdG9yeSh0aGlzLCBjb21wYXJhdG9yID8gbmVnKGNvbXBhcmF0b3IpIDogZGVmYXVsdE5lZ0NvbXBhcmF0b3IsIG1hcHBlcik7XG4gICAgfSxcblxuICAgIHJlc3Q6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2xpY2UoMSk7XG4gICAgfSxcblxuICAgIHNraXA6IGZ1bmN0aW9uKGFtb3VudCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2xpY2UoTWF0aC5tYXgoMCwgYW1vdW50KSk7XG4gICAgfSxcblxuICAgIHNraXBMYXN0OiBmdW5jdGlvbihhbW91bnQpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCB0aGlzLnRvU2VxKCkucmV2ZXJzZSgpLnNraXAoYW1vdW50KS5yZXZlcnNlKCkpO1xuICAgIH0sXG5cbiAgICBza2lwV2hpbGU6IGZ1bmN0aW9uKHByZWRpY2F0ZSwgY29udGV4dCkge1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIHNraXBXaGlsZUZhY3RvcnkodGhpcywgcHJlZGljYXRlLCBjb250ZXh0LCB0cnVlKSk7XG4gICAgfSxcblxuICAgIHNraXBVbnRpbDogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gdGhpcy5za2lwV2hpbGUobm90KHByZWRpY2F0ZSksIGNvbnRleHQpO1xuICAgIH0sXG5cbiAgICBzb3J0Qnk6IGZ1bmN0aW9uKG1hcHBlciwgY29tcGFyYXRvcikge1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIHNvcnRGYWN0b3J5KHRoaXMsIGNvbXBhcmF0b3IsIG1hcHBlcikpO1xuICAgIH0sXG5cbiAgICB0YWtlOiBmdW5jdGlvbihhbW91bnQpIHtcbiAgICAgIHJldHVybiB0aGlzLnNsaWNlKDAsIE1hdGgubWF4KDAsIGFtb3VudCkpO1xuICAgIH0sXG5cbiAgICB0YWtlTGFzdDogZnVuY3Rpb24oYW1vdW50KSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgdGhpcy50b1NlcSgpLnJldmVyc2UoKS50YWtlKGFtb3VudCkucmV2ZXJzZSgpKTtcbiAgICB9LFxuXG4gICAgdGFrZVdoaWxlOiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCB0YWtlV2hpbGVGYWN0b3J5KHRoaXMsIHByZWRpY2F0ZSwgY29udGV4dCkpO1xuICAgIH0sXG5cbiAgICB0YWtlVW50aWw6IGZ1bmN0aW9uKHByZWRpY2F0ZSwgY29udGV4dCkge1xuICAgICAgcmV0dXJuIHRoaXMudGFrZVdoaWxlKG5vdChwcmVkaWNhdGUpLCBjb250ZXh0KTtcbiAgICB9LFxuXG4gICAgdmFsdWVTZXE6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMudG9JbmRleGVkU2VxKCk7XG4gICAgfSxcblxuXG4gICAgLy8gIyMjIEhhc2hhYmxlIE9iamVjdFxuXG4gICAgaGFzaENvZGU6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX19oYXNoIHx8ICh0aGlzLl9faGFzaCA9IGhhc2hJdGVyYWJsZSh0aGlzKSk7XG4gICAgfVxuXG5cbiAgICAvLyAjIyMgSW50ZXJuYWxcblxuICAgIC8vIGFic3RyYWN0IF9faXRlcmF0ZShmbiwgcmV2ZXJzZSlcblxuICAgIC8vIGFic3RyYWN0IF9faXRlcmF0b3IodHlwZSwgcmV2ZXJzZSlcbiAgfSk7XG5cbiAgLy8gdmFyIElTX0lURVJBQkxFX1NFTlRJTkVMID0gJ0BAX19JTU1VVEFCTEVfSVRFUkFCTEVfX0BAJztcbiAgLy8gdmFyIElTX0tFWUVEX1NFTlRJTkVMID0gJ0BAX19JTU1VVEFCTEVfS0VZRURfX0BAJztcbiAgLy8gdmFyIElTX0lOREVYRURfU0VOVElORUwgPSAnQEBfX0lNTVVUQUJMRV9JTkRFWEVEX19AQCc7XG4gIC8vIHZhciBJU19PUkRFUkVEX1NFTlRJTkVMID0gJ0BAX19JTU1VVEFCTEVfT1JERVJFRF9fQEAnO1xuXG4gIHZhciBJdGVyYWJsZVByb3RvdHlwZSA9IEl0ZXJhYmxlLnByb3RvdHlwZTtcbiAgSXRlcmFibGVQcm90b3R5cGVbSVNfSVRFUkFCTEVfU0VOVElORUxdID0gdHJ1ZTtcbiAgSXRlcmFibGVQcm90b3R5cGVbSVRFUkFUT1JfU1lNQk9MXSA9IEl0ZXJhYmxlUHJvdG90eXBlLnZhbHVlcztcbiAgSXRlcmFibGVQcm90b3R5cGUuX190b0pTID0gSXRlcmFibGVQcm90b3R5cGUudG9BcnJheTtcbiAgSXRlcmFibGVQcm90b3R5cGUuX190b1N0cmluZ01hcHBlciA9IHF1b3RlU3RyaW5nO1xuICBJdGVyYWJsZVByb3RvdHlwZS5pbnNwZWN0ID1cbiAgSXRlcmFibGVQcm90b3R5cGUudG9Tb3VyY2UgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXMudG9TdHJpbmcoKTsgfTtcbiAgSXRlcmFibGVQcm90b3R5cGUuY2hhaW4gPSBJdGVyYWJsZVByb3RvdHlwZS5mbGF0TWFwO1xuICBJdGVyYWJsZVByb3RvdHlwZS5jb250YWlucyA9IEl0ZXJhYmxlUHJvdG90eXBlLmluY2x1ZGVzO1xuXG4gIC8vIFRlbXBvcmFyeSB3YXJuaW5nIGFib3V0IHVzaW5nIGxlbmd0aFxuICAoZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoSXRlcmFibGVQcm90b3R5cGUsICdsZW5ndGgnLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlmICghSXRlcmFibGUubm9MZW5ndGhXYXJuaW5nKSB7XG4gICAgICAgICAgICB2YXIgc3RhY2s7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIHN0YWNrID0gZXJyb3Iuc3RhY2s7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc3RhY2suaW5kZXhPZignX3dyYXBPYmplY3QnKSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgY29uc29sZSAmJiBjb25zb2xlLndhcm4gJiYgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgICdpdGVyYWJsZS5sZW5ndGggaGFzIGJlZW4gZGVwcmVjYXRlZCwgJytcbiAgICAgICAgICAgICAgICAndXNlIGl0ZXJhYmxlLnNpemUgb3IgaXRlcmFibGUuY291bnQoKS4gJytcbiAgICAgICAgICAgICAgICAnVGhpcyB3YXJuaW5nIHdpbGwgYmVjb21lIGEgc2lsZW50IGVycm9yIGluIGEgZnV0dXJlIHZlcnNpb24uICcgK1xuICAgICAgICAgICAgICAgIHN0YWNrXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLnNpemU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICB9KSgpO1xuXG5cblxuICBtaXhpbihLZXllZEl0ZXJhYmxlLCB7XG5cbiAgICAvLyAjIyMgTW9yZSBzZXF1ZW50aWFsIG1ldGhvZHNcblxuICAgIGZsaXA6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIGZsaXBGYWN0b3J5KHRoaXMpKTtcbiAgICB9LFxuXG4gICAgZmluZEtleTogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICB2YXIgZW50cnkgPSB0aGlzLmZpbmRFbnRyeShwcmVkaWNhdGUsIGNvbnRleHQpO1xuICAgICAgcmV0dXJuIGVudHJ5ICYmIGVudHJ5WzBdO1xuICAgIH0sXG5cbiAgICBmaW5kTGFzdEtleTogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gdGhpcy50b1NlcSgpLnJldmVyc2UoKS5maW5kS2V5KHByZWRpY2F0ZSwgY29udGV4dCk7XG4gICAgfSxcblxuICAgIGtleU9mOiBmdW5jdGlvbihzZWFyY2hWYWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZmluZEtleShmdW5jdGlvbih2YWx1ZSApIHtyZXR1cm4gaXModmFsdWUsIHNlYXJjaFZhbHVlKX0pO1xuICAgIH0sXG5cbiAgICBsYXN0S2V5T2Y6IGZ1bmN0aW9uKHNlYXJjaFZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5maW5kTGFzdEtleShmdW5jdGlvbih2YWx1ZSApIHtyZXR1cm4gaXModmFsdWUsIHNlYXJjaFZhbHVlKX0pO1xuICAgIH0sXG5cbiAgICBtYXBFbnRyaWVzOiBmdW5jdGlvbihtYXBwZXIsIGNvbnRleHQpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLFxuICAgICAgICB0aGlzLnRvU2VxKCkubWFwKFxuICAgICAgICAgIGZ1bmN0aW9uKHYsIGspICB7cmV0dXJuIG1hcHBlci5jYWxsKGNvbnRleHQsIFtrLCB2XSwgaXRlcmF0aW9ucysrLCB0aGlzJDApfVxuICAgICAgICApLmZyb21FbnRyeVNlcSgpXG4gICAgICApO1xuICAgIH0sXG5cbiAgICBtYXBLZXlzOiBmdW5jdGlvbihtYXBwZXIsIGNvbnRleHQpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLFxuICAgICAgICB0aGlzLnRvU2VxKCkuZmxpcCgpLm1hcChcbiAgICAgICAgICBmdW5jdGlvbihrLCB2KSAge3JldHVybiBtYXBwZXIuY2FsbChjb250ZXh0LCBrLCB2LCB0aGlzJDApfVxuICAgICAgICApLmZsaXAoKVxuICAgICAgKTtcbiAgICB9XG5cbiAgfSk7XG5cbiAgdmFyIEtleWVkSXRlcmFibGVQcm90b3R5cGUgPSBLZXllZEl0ZXJhYmxlLnByb3RvdHlwZTtcbiAgS2V5ZWRJdGVyYWJsZVByb3RvdHlwZVtJU19LRVlFRF9TRU5USU5FTF0gPSB0cnVlO1xuICBLZXllZEl0ZXJhYmxlUHJvdG90eXBlW0lURVJBVE9SX1NZTUJPTF0gPSBJdGVyYWJsZVByb3RvdHlwZS5lbnRyaWVzO1xuICBLZXllZEl0ZXJhYmxlUHJvdG90eXBlLl9fdG9KUyA9IEl0ZXJhYmxlUHJvdG90eXBlLnRvT2JqZWN0O1xuICBLZXllZEl0ZXJhYmxlUHJvdG90eXBlLl9fdG9TdHJpbmdNYXBwZXIgPSBmdW5jdGlvbih2LCBrKSAge3JldHVybiBKU09OLnN0cmluZ2lmeShrKSArICc6ICcgKyBxdW90ZVN0cmluZyh2KX07XG5cblxuXG4gIG1peGluKEluZGV4ZWRJdGVyYWJsZSwge1xuXG4gICAgLy8gIyMjIENvbnZlcnNpb24gdG8gb3RoZXIgdHlwZXNcblxuICAgIHRvS2V5ZWRTZXE6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIG5ldyBUb0tleWVkU2VxdWVuY2UodGhpcywgZmFsc2UpO1xuICAgIH0sXG5cblxuICAgIC8vICMjIyBFUzYgQ29sbGVjdGlvbiBtZXRob2RzIChFUzYgQXJyYXkgYW5kIE1hcClcblxuICAgIGZpbHRlcjogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgZmlsdGVyRmFjdG9yeSh0aGlzLCBwcmVkaWNhdGUsIGNvbnRleHQsIGZhbHNlKSk7XG4gICAgfSxcblxuICAgIGZpbmRJbmRleDogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICB2YXIgZW50cnkgPSB0aGlzLmZpbmRFbnRyeShwcmVkaWNhdGUsIGNvbnRleHQpO1xuICAgICAgcmV0dXJuIGVudHJ5ID8gZW50cnlbMF0gOiAtMTtcbiAgICB9LFxuXG4gICAgaW5kZXhPZjogZnVuY3Rpb24oc2VhcmNoVmFsdWUpIHtcbiAgICAgIHZhciBrZXkgPSB0aGlzLnRvS2V5ZWRTZXEoKS5rZXlPZihzZWFyY2hWYWx1ZSk7XG4gICAgICByZXR1cm4ga2V5ID09PSB1bmRlZmluZWQgPyAtMSA6IGtleTtcbiAgICB9LFxuXG4gICAgbGFzdEluZGV4T2Y6IGZ1bmN0aW9uKHNlYXJjaFZhbHVlKSB7XG4gICAgICB2YXIga2V5ID0gdGhpcy50b0tleWVkU2VxKCkucmV2ZXJzZSgpLmtleU9mKHNlYXJjaFZhbHVlKTtcbiAgICAgIHJldHVybiBrZXkgPT09IHVuZGVmaW5lZCA/IC0xIDoga2V5O1xuXG4gICAgICAvLyB2YXIgaW5kZXggPVxuICAgICAgLy8gcmV0dXJuIHRoaXMudG9TZXEoKS5yZXZlcnNlKCkuaW5kZXhPZihzZWFyY2hWYWx1ZSk7XG4gICAgfSxcblxuICAgIHJldmVyc2U6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIHJldmVyc2VGYWN0b3J5KHRoaXMsIGZhbHNlKSk7XG4gICAgfSxcblxuICAgIHNsaWNlOiBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgc2xpY2VGYWN0b3J5KHRoaXMsIGJlZ2luLCBlbmQsIGZhbHNlKSk7XG4gICAgfSxcblxuICAgIHNwbGljZTogZnVuY3Rpb24oaW5kZXgsIHJlbW92ZU51bSAvKiwgLi4udmFsdWVzKi8pIHtcbiAgICAgIHZhciBudW1BcmdzID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICAgIHJlbW92ZU51bSA9IE1hdGgubWF4KHJlbW92ZU51bSB8IDAsIDApO1xuICAgICAgaWYgKG51bUFyZ3MgPT09IDAgfHwgKG51bUFyZ3MgPT09IDIgJiYgIXJlbW92ZU51bSkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICAvLyBJZiBpbmRleCBpcyBuZWdhdGl2ZSwgaXQgc2hvdWxkIHJlc29sdmUgcmVsYXRpdmUgdG8gdGhlIHNpemUgb2YgdGhlXG4gICAgICAvLyBjb2xsZWN0aW9uLiBIb3dldmVyIHNpemUgbWF5IGJlIGV4cGVuc2l2ZSB0byBjb21wdXRlIGlmIG5vdCBjYWNoZWQsIHNvXG4gICAgICAvLyBvbmx5IGNhbGwgY291bnQoKSBpZiB0aGUgbnVtYmVyIGlzIGluIGZhY3QgbmVnYXRpdmUuXG4gICAgICBpbmRleCA9IHJlc29sdmVCZWdpbihpbmRleCwgaW5kZXggPCAwID8gdGhpcy5jb3VudCgpIDogdGhpcy5zaXplKTtcbiAgICAgIHZhciBzcGxpY2VkID0gdGhpcy5zbGljZSgwLCBpbmRleCk7XG4gICAgICByZXR1cm4gcmVpZnkoXG4gICAgICAgIHRoaXMsXG4gICAgICAgIG51bUFyZ3MgPT09IDEgP1xuICAgICAgICAgIHNwbGljZWQgOlxuICAgICAgICAgIHNwbGljZWQuY29uY2F0KGFyckNvcHkoYXJndW1lbnRzLCAyKSwgdGhpcy5zbGljZShpbmRleCArIHJlbW92ZU51bSkpXG4gICAgICApO1xuICAgIH0sXG5cblxuICAgIC8vICMjIyBNb3JlIGNvbGxlY3Rpb24gbWV0aG9kc1xuXG4gICAgZmluZExhc3RJbmRleDogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICB2YXIga2V5ID0gdGhpcy50b0tleWVkU2VxKCkuZmluZExhc3RLZXkocHJlZGljYXRlLCBjb250ZXh0KTtcbiAgICAgIHJldHVybiBrZXkgPT09IHVuZGVmaW5lZCA/IC0xIDoga2V5O1xuICAgIH0sXG5cbiAgICBmaXJzdDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXQoMCk7XG4gICAgfSxcblxuICAgIGZsYXR0ZW46IGZ1bmN0aW9uKGRlcHRoKSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgZmxhdHRlbkZhY3RvcnkodGhpcywgZGVwdGgsIGZhbHNlKSk7XG4gICAgfSxcblxuICAgIGdldDogZnVuY3Rpb24oaW5kZXgsIG5vdFNldFZhbHVlKSB7XG4gICAgICBpbmRleCA9IHdyYXBJbmRleCh0aGlzLCBpbmRleCk7XG4gICAgICByZXR1cm4gKGluZGV4IDwgMCB8fCAodGhpcy5zaXplID09PSBJbmZpbml0eSB8fFxuICAgICAgICAgICh0aGlzLnNpemUgIT09IHVuZGVmaW5lZCAmJiBpbmRleCA+IHRoaXMuc2l6ZSkpKSA/XG4gICAgICAgIG5vdFNldFZhbHVlIDpcbiAgICAgICAgdGhpcy5maW5kKGZ1bmN0aW9uKF8sIGtleSkgIHtyZXR1cm4ga2V5ID09PSBpbmRleH0sIHVuZGVmaW5lZCwgbm90U2V0VmFsdWUpO1xuICAgIH0sXG5cbiAgICBoYXM6IGZ1bmN0aW9uKGluZGV4KSB7XG4gICAgICBpbmRleCA9IHdyYXBJbmRleCh0aGlzLCBpbmRleCk7XG4gICAgICByZXR1cm4gaW5kZXggPj0gMCAmJiAodGhpcy5zaXplICE9PSB1bmRlZmluZWQgP1xuICAgICAgICB0aGlzLnNpemUgPT09IEluZmluaXR5IHx8IGluZGV4IDwgdGhpcy5zaXplIDpcbiAgICAgICAgdGhpcy5pbmRleE9mKGluZGV4KSAhPT0gLTFcbiAgICAgICk7XG4gICAgfSxcblxuICAgIGludGVycG9zZTogZnVuY3Rpb24oc2VwYXJhdG9yKSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgaW50ZXJwb3NlRmFjdG9yeSh0aGlzLCBzZXBhcmF0b3IpKTtcbiAgICB9LFxuXG4gICAgaW50ZXJsZWF2ZTogZnVuY3Rpb24oLyouLi5pdGVyYWJsZXMqLykge1xuICAgICAgdmFyIGl0ZXJhYmxlcyA9IFt0aGlzXS5jb25jYXQoYXJyQ29weShhcmd1bWVudHMpKTtcbiAgICAgIHZhciB6aXBwZWQgPSB6aXBXaXRoRmFjdG9yeSh0aGlzLnRvU2VxKCksIEluZGV4ZWRTZXEub2YsIGl0ZXJhYmxlcyk7XG4gICAgICB2YXIgaW50ZXJsZWF2ZWQgPSB6aXBwZWQuZmxhdHRlbih0cnVlKTtcbiAgICAgIGlmICh6aXBwZWQuc2l6ZSkge1xuICAgICAgICBpbnRlcmxlYXZlZC5zaXplID0gemlwcGVkLnNpemUgKiBpdGVyYWJsZXMubGVuZ3RoO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIGludGVybGVhdmVkKTtcbiAgICB9LFxuXG4gICAgbGFzdDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXQoLTEpO1xuICAgIH0sXG5cbiAgICBza2lwV2hpbGU6IGZ1bmN0aW9uKHByZWRpY2F0ZSwgY29udGV4dCkge1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIHNraXBXaGlsZUZhY3RvcnkodGhpcywgcHJlZGljYXRlLCBjb250ZXh0LCBmYWxzZSkpO1xuICAgIH0sXG5cbiAgICB6aXA6IGZ1bmN0aW9uKC8qLCAuLi5pdGVyYWJsZXMgKi8pIHtcbiAgICAgIHZhciBpdGVyYWJsZXMgPSBbdGhpc10uY29uY2F0KGFyckNvcHkoYXJndW1lbnRzKSk7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgemlwV2l0aEZhY3RvcnkodGhpcywgZGVmYXVsdFppcHBlciwgaXRlcmFibGVzKSk7XG4gICAgfSxcblxuICAgIHppcFdpdGg6IGZ1bmN0aW9uKHppcHBlci8qLCAuLi5pdGVyYWJsZXMgKi8pIHtcbiAgICAgIHZhciBpdGVyYWJsZXMgPSBhcnJDb3B5KGFyZ3VtZW50cyk7XG4gICAgICBpdGVyYWJsZXNbMF0gPSB0aGlzO1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIHppcFdpdGhGYWN0b3J5KHRoaXMsIHppcHBlciwgaXRlcmFibGVzKSk7XG4gICAgfVxuXG4gIH0pO1xuXG4gIEluZGV4ZWRJdGVyYWJsZS5wcm90b3R5cGVbSVNfSU5ERVhFRF9TRU5USU5FTF0gPSB0cnVlO1xuICBJbmRleGVkSXRlcmFibGUucHJvdG90eXBlW0lTX09SREVSRURfU0VOVElORUxdID0gdHJ1ZTtcblxuXG5cbiAgbWl4aW4oU2V0SXRlcmFibGUsIHtcblxuICAgIC8vICMjIyBFUzYgQ29sbGVjdGlvbiBtZXRob2RzIChFUzYgQXJyYXkgYW5kIE1hcClcblxuICAgIGdldDogZnVuY3Rpb24odmFsdWUsIG5vdFNldFZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5oYXModmFsdWUpID8gdmFsdWUgOiBub3RTZXRWYWx1ZTtcbiAgICB9LFxuXG4gICAgaW5jbHVkZXM6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5oYXModmFsdWUpO1xuICAgIH0sXG5cblxuICAgIC8vICMjIyBNb3JlIHNlcXVlbnRpYWwgbWV0aG9kc1xuXG4gICAga2V5U2VxOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLnZhbHVlU2VxKCk7XG4gICAgfVxuXG4gIH0pO1xuXG4gIFNldEl0ZXJhYmxlLnByb3RvdHlwZS5oYXMgPSBJdGVyYWJsZVByb3RvdHlwZS5pbmNsdWRlcztcblxuXG4gIC8vIE1peGluIHN1YmNsYXNzZXNcblxuICBtaXhpbihLZXllZFNlcSwgS2V5ZWRJdGVyYWJsZS5wcm90b3R5cGUpO1xuICBtaXhpbihJbmRleGVkU2VxLCBJbmRleGVkSXRlcmFibGUucHJvdG90eXBlKTtcbiAgbWl4aW4oU2V0U2VxLCBTZXRJdGVyYWJsZS5wcm90b3R5cGUpO1xuXG4gIG1peGluKEtleWVkQ29sbGVjdGlvbiwgS2V5ZWRJdGVyYWJsZS5wcm90b3R5cGUpO1xuICBtaXhpbihJbmRleGVkQ29sbGVjdGlvbiwgSW5kZXhlZEl0ZXJhYmxlLnByb3RvdHlwZSk7XG4gIG1peGluKFNldENvbGxlY3Rpb24sIFNldEl0ZXJhYmxlLnByb3RvdHlwZSk7XG5cblxuICAvLyAjcHJhZ21hIEhlbHBlciBmdW5jdGlvbnNcblxuICBmdW5jdGlvbiBrZXlNYXBwZXIodiwgaykge1xuICAgIHJldHVybiBrO1xuICB9XG5cbiAgZnVuY3Rpb24gZW50cnlNYXBwZXIodiwgaykge1xuICAgIHJldHVybiBbaywgdl07XG4gIH1cblxuICBmdW5jdGlvbiBub3QocHJlZGljYXRlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuICFwcmVkaWNhdGUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBuZWcocHJlZGljYXRlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIC1wcmVkaWNhdGUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBxdW90ZVN0cmluZyh2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gSlNPTi5zdHJpbmdpZnkodmFsdWUpIDogdmFsdWU7XG4gIH1cblxuICBmdW5jdGlvbiBkZWZhdWx0WmlwcGVyKCkge1xuICAgIHJldHVybiBhcnJDb3B5KGFyZ3VtZW50cyk7XG4gIH1cblxuICBmdW5jdGlvbiBkZWZhdWx0TmVnQ29tcGFyYXRvcihhLCBiKSB7XG4gICAgcmV0dXJuIGEgPCBiID8gMSA6IGEgPiBiID8gLTEgOiAwO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFzaEl0ZXJhYmxlKGl0ZXJhYmxlKSB7XG4gICAgaWYgKGl0ZXJhYmxlLnNpemUgPT09IEluZmluaXR5KSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgdmFyIG9yZGVyZWQgPSBpc09yZGVyZWQoaXRlcmFibGUpO1xuICAgIHZhciBrZXllZCA9IGlzS2V5ZWQoaXRlcmFibGUpO1xuICAgIHZhciBoID0gb3JkZXJlZCA/IDEgOiAwO1xuICAgIHZhciBzaXplID0gaXRlcmFibGUuX19pdGVyYXRlKFxuICAgICAga2V5ZWQgP1xuICAgICAgICBvcmRlcmVkID9cbiAgICAgICAgICBmdW5jdGlvbih2LCBrKSAgeyBoID0gMzEgKiBoICsgaGFzaE1lcmdlKGhhc2godiksIGhhc2goaykpIHwgMDsgfSA6XG4gICAgICAgICAgZnVuY3Rpb24odiwgaykgIHsgaCA9IGggKyBoYXNoTWVyZ2UoaGFzaCh2KSwgaGFzaChrKSkgfCAwOyB9IDpcbiAgICAgICAgb3JkZXJlZCA/XG4gICAgICAgICAgZnVuY3Rpb24odiApIHsgaCA9IDMxICogaCArIGhhc2godikgfCAwOyB9IDpcbiAgICAgICAgICBmdW5jdGlvbih2ICkgeyBoID0gaCArIGhhc2godikgfCAwOyB9XG4gICAgKTtcbiAgICByZXR1cm4gbXVybXVySGFzaE9mU2l6ZShzaXplLCBoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG11cm11ckhhc2hPZlNpemUoc2l6ZSwgaCkge1xuICAgIGggPSBpbXVsKGgsIDB4Q0M5RTJENTEpO1xuICAgIGggPSBpbXVsKGggPDwgMTUgfCBoID4+PiAtMTUsIDB4MUI4NzM1OTMpO1xuICAgIGggPSBpbXVsKGggPDwgMTMgfCBoID4+PiAtMTMsIDUpO1xuICAgIGggPSAoaCArIDB4RTY1NDZCNjQgfCAwKSBeIHNpemU7XG4gICAgaCA9IGltdWwoaCBeIGggPj4+IDE2LCAweDg1RUJDQTZCKTtcbiAgICBoID0gaW11bChoIF4gaCA+Pj4gMTMsIDB4QzJCMkFFMzUpO1xuICAgIGggPSBzbWkoaCBeIGggPj4+IDE2KTtcbiAgICByZXR1cm4gaDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhc2hNZXJnZShhLCBiKSB7XG4gICAgcmV0dXJuIGEgXiBiICsgMHg5RTM3NzlCOSArIChhIDw8IDYpICsgKGEgPj4gMikgfCAwOyAvLyBpbnRcbiAgfVxuXG4gIHZhciBJbW11dGFibGUgPSB7XG5cbiAgICBJdGVyYWJsZTogSXRlcmFibGUsXG5cbiAgICBTZXE6IFNlcSxcbiAgICBDb2xsZWN0aW9uOiBDb2xsZWN0aW9uLFxuICAgIE1hcDogTWFwLFxuICAgIE9yZGVyZWRNYXA6IE9yZGVyZWRNYXAsXG4gICAgTGlzdDogTGlzdCxcbiAgICBTdGFjazogU3RhY2ssXG4gICAgU2V0OiBTZXQsXG4gICAgT3JkZXJlZFNldDogT3JkZXJlZFNldCxcblxuICAgIFJlY29yZDogUmVjb3JkLFxuICAgIFJhbmdlOiBSYW5nZSxcbiAgICBSZXBlYXQ6IFJlcGVhdCxcblxuICAgIGlzOiBpcyxcbiAgICBmcm9tSlM6IGZyb21KU1xuXG4gIH07XG5cbiAgcmV0dXJuIEltbXV0YWJsZTtcblxufSkpOyIsIi8vIFV0aWxpdHkgcHJvdG9jb2wgZm9yIG1lYXN1cmluZyB3aGVuIGEgc3RhdGVDaGFuZ2UgdGFrZXMgZWZmZWN0LlxuXG52YXIgUmFuZG9tSUQgPSByZXF1aXJlKCcuL3JhbmRvbWlkLmpzJyk7XG52YXIgTmV0d29yayA9IHJlcXVpcmUoJy4vbmV0d29yay5qcycpLk5ldHdvcms7XG52YXIgUm91dGUgPSByZXF1aXJlKCcuL3JvdXRlLmpzJyk7XG52YXIgUGF0Y2ggPSByZXF1aXJlKCcuL3BhdGNoLmpzJyk7XG5cbnZhciAkQWNrID0gbmV3IFJvdXRlLiRTcGVjaWFsKCdhY2snKTtcblxuZnVuY3Rpb24gQWNrKG1ldGFMZXZlbCwgaWQpIHtcbiAgdGhpcy5tZXRhTGV2ZWwgPSBtZXRhTGV2ZWwgfHwgMDtcbiAgdGhpcy5pZCA9IGlkIHx8IFJhbmRvbUlELnJhbmRvbUlkKDE2KTtcbiAgdGhpcy5kb25lID0gZmFsc2U7XG59XG5cbkFjay5wcm90b3R5cGUuYXJtID0gZnVuY3Rpb24gKCkge1xuICBOZXR3b3JrLnN0YXRlQ2hhbmdlKFBhdGNoLnN1YihbJEFjaywgdGhpcy5pZF0sIHRoaXMubWV0YUxldmVsKSk7XG4gIE5ldHdvcmsuc2VuZChbJEFjaywgdGhpcy5pZF0sIHRoaXMubWV0YUxldmVsKTtcbn07XG5cbkFjay5wcm90b3R5cGUuZGlzYXJtID0gZnVuY3Rpb24gKCkge1xuICBOZXR3b3JrLnN0YXRlQ2hhbmdlKFBhdGNoLnVuc3ViKFskQWNrLCB0aGlzLmlkXSwgdGhpcy5tZXRhTGV2ZWwpKTtcbn07XG5cbkFjay5wcm90b3R5cGUuY2hlY2sgPSBmdW5jdGlvbiAoZSkge1xuICBpZiAoIXRoaXMuZG9uZSkge1xuICAgIGlmIChlLnR5cGUgPT09ICdtZXNzYWdlJykge1xuICAgICAgdmFyIG0gPSBQYXRjaC5zdHJpcEF0TWV0YShlLm1lc3NhZ2UsIHRoaXMubWV0YUxldmVsKTtcbiAgICAgIGlmIChtICYmIG1bMF0gPT09ICRBY2sgJiYgbVsxXSA9PT0gdGhpcy5pZCkge1xuXHR0aGlzLmRpc2FybSgpO1xuXHR0aGlzLmRvbmUgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gdGhpcy5kb25lO1xufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbm1vZHVsZS5leHBvcnRzLiRBY2sgPSAkQWNrO1xubW9kdWxlLmV4cG9ydHMuQWNrID0gQWNrO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgSW1tdXRhYmxlID0gcmVxdWlyZSgnaW1tdXRhYmxlJyk7XG52YXIgTmV0d29yayA9IHJlcXVpcmUoJy4vbmV0d29yay5qcycpLk5ldHdvcms7XG52YXIgTXV4ID0gcmVxdWlyZSgnLi9tdXguanMnKTtcbnZhciBQYXRjaCA9IHJlcXVpcmUoJy4vcGF0Y2guanMnKTtcbnZhciBSb3V0ZSA9IHJlcXVpcmUoJy4vcm91dGUuanMnKTtcbnZhciBVdGlsID0gcmVxdWlyZSgnLi91dGlsLmpzJyk7XG5cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmZ1bmN0aW9uIHNwYXduQWN0b3Ioc3RhdGUsIGJvb3RGbikge1xuICBOZXR3b3JrLnNwYXduKG5ldyBBY3RvcihzdGF0ZSwgYm9vdEZuKSk7XG59XG5cbmZ1bmN0aW9uIEFjdG9yKHN0YXRlLCBib290Rm4pIHtcbiAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xuICB0aGlzLmZhY2V0cyA9IEltbXV0YWJsZS5TZXQoKTtcbiAgdGhpcy5tdXggPSBuZXcgTXV4Lk11eCgpO1xuXG4gIHRoaXMuYm9vdCA9IGZ1bmN0aW9uKCkge1xuICAgIGJvb3RGbi5jYWxsKHRoaXMuc3RhdGUpO1xuICAgIHRoaXMuY2hlY2tGb3JUZXJtaW5hdGlvbigpO1xuICB9O1xufVxuXG5BY3Rvci5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbihlKSB7XG4gIHRoaXMuZmFjZXRzLmZvckVhY2goZnVuY3Rpb24gKGYpIHtcbiAgICBmLmhhbmRsZUV2ZW50KGUpO1xuICB9KTtcbiAgdGhpcy5jaGVja0ZvclRlcm1pbmF0aW9uKCk7XG59O1xuXG5BY3Rvci5wcm90b3R5cGUuYWRkRmFjZXQgPSBmdW5jdGlvbihmYWNldCkge1xuICB0aGlzLmZhY2V0cyA9IHRoaXMuZmFjZXRzLmFkZChmYWNldCk7XG59O1xuXG5BY3Rvci5wcm90b3R5cGUucmVtb3ZlRmFjZXQgPSBmdW5jdGlvbihmYWNldCkge1xuICB0aGlzLmZhY2V0cyA9IHRoaXMuZmFjZXRzLnJlbW92ZShmYWNldCk7XG59O1xuXG5BY3Rvci5wcm90b3R5cGUuY2hlY2tGb3JUZXJtaW5hdGlvbiA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5mYWNldHMuaXNFbXB0eSgpKSB7XG4gICAgTmV0d29yay5leGl0KCk7XG4gIH1cbn07XG5cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmZ1bmN0aW9uIGNyZWF0ZUZhY2V0KCkge1xuICByZXR1cm4gbmV3IEZhY2V0KE5ldHdvcmsuYWN0aXZlQmVoYXZpb3IoKSk7XG59XG5cbmZ1bmN0aW9uIEZhY2V0KGFjdG9yKSB7XG4gIHRoaXMuYWN0b3IgPSBhY3RvcjtcbiAgdGhpcy5lbmRwb2ludHMgPSBJbW11dGFibGUuTWFwKCk7XG4gIHRoaXMuaW5pdEJsb2NrcyA9IEltbXV0YWJsZS5MaXN0KCk7XG4gIHRoaXMuZG9uZUJsb2NrcyA9IEltbXV0YWJsZS5MaXN0KCk7XG59XG5cbkZhY2V0LnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uKGUpIHtcbiAgdmFyIGZhY2V0ID0gdGhpcztcbiAgdGhpcy5lbmRwb2ludHMuZm9yRWFjaChmdW5jdGlvbihlbmRwb2ludCkge1xuICAgIGVuZHBvaW50LmhhbmRsZXJGbi5jYWxsKGZhY2V0LmFjdG9yLnN0YXRlLCBlKTtcbiAgfSk7XG4gIHRoaXMucmVmcmVzaCgpO1xufTtcblxuRmFjZXQucHJvdG90eXBlLmFkZEFzc2VydGlvbiA9IGZ1bmN0aW9uKGFzc2VydGlvbkZuKSB7XG4gIHJldHVybiB0aGlzLmFkZEVuZHBvaW50KG5ldyBFbmRwb2ludChhc3NlcnRpb25GbiwgZnVuY3Rpb24oZSkge30pKTtcbn07XG5cbkZhY2V0LnByb3RvdHlwZS5vbkV2ZW50ID0gZnVuY3Rpb24oaXNUZXJtaW5hbCwgZXZlbnRUeXBlLCBzdWJzY3JpcHRpb25GbiwgcHJvamVjdGlvbkZuLCBoYW5kbGVyRm4pIHtcbiAgdmFyIGZhY2V0ID0gdGhpcztcbiAgc3dpdGNoIChldmVudFR5cGUpIHtcblxuICBjYXNlICdtZXNzYWdlJzpcbiAgICByZXR1cm4gdGhpcy5hZGRFbmRwb2ludChuZXcgRW5kcG9pbnQoc3Vic2NyaXB0aW9uRm4sIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGlmIChlLnR5cGUgPT09ICdtZXNzYWdlJykge1xuICAgICAgICB2YXIgcHJvaiA9IHByb2plY3Rpb25Gbi5jYWxsKGZhY2V0LmFjdG9yLnN0YXRlKTtcbiAgICAgICAgdmFyIHNwZWMgPSBQYXRjaC5wcmVwZW5kQXRNZXRhKHByb2ouYXNzZXJ0aW9uLCBwcm9qLm1ldGFsZXZlbCk7XG4gICAgICAgIHZhciBtYXRjaCA9IFJvdXRlLm1hdGNoUGF0dGVybihlLm1lc3NhZ2UsIHNwZWMpO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhtYXRjaCk7XG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgIGlmIChpc1Rlcm1pbmFsKSB7IGZhY2V0LnRlcm1pbmF0ZSgpOyB9XG4gICAgICAgICAgVXRpbC5rd0FwcGx5KGhhbmRsZXJGbiwgZmFjZXQuYWN0b3Iuc3RhdGUsIG1hdGNoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pKTtcblxuICBjYXNlICdhc3NlcnRlZCc6IC8qIGZhbGwgdGhyb3VnaCAqL1xuICBjYXNlICdyZXRyYWN0ZWQnOlxuICAgIHJldHVybiB0aGlzLmFkZEVuZHBvaW50KG5ldyBFbmRwb2ludChzdWJzY3JpcHRpb25GbiwgZnVuY3Rpb24oZSkge1xuICAgICAgaWYgKGUudHlwZSA9PT0gJ3N0YXRlQ2hhbmdlJykge1xuICAgICAgICB2YXIgcHJvaiA9IHByb2plY3Rpb25Gbi5jYWxsKGZhY2V0LmFjdG9yLnN0YXRlKTtcbiAgICAgICAgdmFyIHNwZWMgPSBQYXRjaC5wcmVwZW5kQXRNZXRhKHByb2ouYXNzZXJ0aW9uLCBwcm9qLm1ldGFsZXZlbCk7XG4gICAgICAgIHZhciBjb21waWxlZFNwZWMgPSBSb3V0ZS5jb21waWxlUHJvamVjdGlvbihzcGVjKTtcbiAgICAgICAgdmFyIG9iamVjdHMgPSBSb3V0ZS5wcm9qZWN0T2JqZWN0cyhldmVudFR5cGUgPT09ICdhc3NlcnRlZCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGUucGF0Y2guYWRkZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGUucGF0Y2gucmVtb3ZlZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21waWxlZFNwZWMpO1xuICAgICAgICBpZiAob2JqZWN0cyAmJiBvYmplY3RzLnNpemUgPiAwKSB7XG4gICAgICAgICAgLy8gY29uc29sZS5sb2cob2JqZWN0cy50b0FycmF5KCkpO1xuICAgICAgICAgIGlmIChpc1Rlcm1pbmFsKSB7IGZhY2V0LnRlcm1pbmF0ZSgpOyB9XG4gICAgICAgICAgb2JqZWN0cy5mb3JFYWNoKGZ1bmN0aW9uIChvKSB7IFV0aWwua3dBcHBseShoYW5kbGVyRm4sIGZhY2V0LmFjdG9yLnN0YXRlLCBvKTsgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KSk7XG5cbiAgY2FzZSAncmlzaW5nRWRnZSc6XG4gICAgdmFyIGVuZHBvaW50ID0gbmV3IEVuZHBvaW50KGZ1bmN0aW9uKCkgeyByZXR1cm4gUGF0Y2guZW1wdHlQYXRjaDsgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZXdWYWx1ZSA9IHN1YnNjcmlwdGlvbkZuLmNhbGwoZmFjZXQuYWN0b3Iuc3RhdGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdWYWx1ZSAmJiAhdGhpcy5jdXJyZW50VmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1Rlcm1pbmFsKSB7IGZhY2V0LnRlcm1pbmF0ZSgpOyB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyRm4uY2FsbChmYWNldC5hY3Rvci5zdGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFZhbHVlID0gbmV3VmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgIGVuZHBvaW50LmN1cnJlbnRWYWx1ZSA9IGZhbHNlO1xuICAgIHJldHVybiB0aGlzLmFkZEVuZHBvaW50KGVuZHBvaW50KTtcblxuICBkZWZhdWx0OlxuICAgIHRocm93IG5ldyBFcnJvcihcIlVuc3VwcG9ydGVkIEZhY2V0IGV2ZW50VHlwZTogXCIgKyBldmVudFR5cGUpO1xuICB9XG59O1xuXG5GYWNldC5wcm90b3R5cGUuYWRkRW5kcG9pbnQgPSBmdW5jdGlvbihlbmRwb2ludCkge1xuICB2YXIgcGF0Y2ggPSBlbmRwb2ludC5zdWJzY3JpcHRpb25Gbi5jYWxsKHRoaXMuYWN0b3Iuc3RhdGUpO1xuICB2YXIgciA9IHRoaXMuYWN0b3IubXV4LmFkZFN0cmVhbShwYXRjaCk7XG4gIHRoaXMuZW5kcG9pbnRzID0gdGhpcy5lbmRwb2ludHMuc2V0KHIucGlkLCBlbmRwb2ludCk7XG4gIE5ldHdvcmsuc3RhdGVDaGFuZ2Uoci5kZWx0YUFnZ3JlZ2F0ZSk7XG4gIHJldHVybiB0aGlzOyAvLyBmb3IgY2hhaW5pbmdcbn07XG5cbkZhY2V0LnByb3RvdHlwZS5hZGRJbml0QmxvY2sgPSBmdW5jdGlvbih0aHVuaykge1xuICB0aGlzLmluaXRCbG9ja3MgPSB0aGlzLmluaXRCbG9ja3MucHVzaCh0aHVuayk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuRmFjZXQucHJvdG90eXBlLmFkZERvbmVCbG9jayA9IGZ1bmN0aW9uKHRodW5rKSB7XG4gIHRoaXMuZG9uZUJsb2NrcyA9IHRoaXMuZG9uZUJsb2Nrcy5wdXNoKHRodW5rKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5GYWNldC5wcm90b3R5cGUucmVmcmVzaCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgZmFjZXQgPSB0aGlzO1xuICB2YXIgYWdncmVnYXRlID0gUGF0Y2guZW1wdHlQYXRjaDtcbiAgdGhpcy5lbmRwb2ludHMuZm9yRWFjaChmdW5jdGlvbihlbmRwb2ludCwgZWlkKSB7XG4gICAgdmFyIHBhdGNoID1cbiAgICAgICAgUGF0Y2gucmV0cmFjdChTeW5kaWNhdGUuX18pLmFuZFRoZW4oZW5kcG9pbnQuc3Vic2NyaXB0aW9uRm4uY2FsbChmYWNldC5hY3Rvci5zdGF0ZSkpO1xuICAgIHZhciByID0gZmFjZXQuYWN0b3IubXV4LnVwZGF0ZVN0cmVhbShlaWQsIHBhdGNoKTtcbiAgICBhZ2dyZWdhdGUgPSBhZ2dyZWdhdGUuYW5kVGhlbihyLmRlbHRhQWdncmVnYXRlKTtcbiAgfSk7XG4gIE5ldHdvcmsuc3RhdGVDaGFuZ2UoYWdncmVnYXRlKTtcbn07XG5cbkZhY2V0LnByb3RvdHlwZS5jb21wbGV0ZUJ1aWxkID0gZnVuY3Rpb24oKSB7XG4gIHZhciBmYWNldCA9IHRoaXM7XG4gIHRoaXMuYWN0b3IuYWRkRmFjZXQodGhpcyk7XG4gIHRoaXMuaW5pdEJsb2Nrcy5mb3JFYWNoKGZ1bmN0aW9uKGIpIHsgYi5jYWxsKGZhY2V0LmFjdG9yLnN0YXRlKTsgfSk7XG59O1xuXG5GYWNldC5wcm90b3R5cGUudGVybWluYXRlID0gZnVuY3Rpb24oKSB7XG4gIHZhciBmYWNldCA9IHRoaXM7XG4gIHZhciBhZ2dyZWdhdGUgPSBQYXRjaC5lbXB0eVBhdGNoO1xuICB0aGlzLmVuZHBvaW50cy5mb3JFYWNoKGZ1bmN0aW9uKGVuZHBvaW50LCBlaWQpIHtcbiAgICB2YXIgciA9IGZhY2V0LmFjdG9yLm11eC5yZW1vdmVTdHJlYW0oZWlkKTtcbiAgICBhZ2dyZWdhdGUgPSBhZ2dyZWdhdGUuYW5kVGhlbihyLmRlbHRhQWdncmVnYXRlKTtcbiAgfSk7XG4gIE5ldHdvcmsuc3RhdGVDaGFuZ2UoYWdncmVnYXRlKTtcbiAgdGhpcy5lbmRwb2ludHMgPSBJbW11dGFibGUuTWFwKCk7XG4gIHRoaXMuYWN0b3IucmVtb3ZlRmFjZXQodGhpcyk7XG4gIHRoaXMuZG9uZUJsb2Nrcy5mb3JFYWNoKGZ1bmN0aW9uKGIpIHsgYi5jYWxsKGZhY2V0LmFjdG9yLnN0YXRlKTsgfSk7XG59O1xuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5mdW5jdGlvbiBFbmRwb2ludChzdWJzY3JpcHRpb25GbiwgaGFuZGxlckZuKSB7XG4gIHRoaXMuc3Vic2NyaXB0aW9uRm4gPSBzdWJzY3JpcHRpb25GbjtcbiAgdGhpcy5oYW5kbGVyRm4gPSBoYW5kbGVyRm47XG59XG5cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbm1vZHVsZS5leHBvcnRzLnNwYXduQWN0b3IgPSBzcGF3bkFjdG9yO1xubW9kdWxlLmV4cG9ydHMuY3JlYXRlRmFjZXQgPSBjcmVhdGVGYWNldDtcbiIsInZhciBJbW11dGFibGUgPSByZXF1aXJlKCdpbW11dGFibGUnKTtcbnZhciBSb3V0ZSA9IHJlcXVpcmUoJy4vcm91dGUuanMnKTtcbnZhciBQYXRjaCA9IHJlcXVpcmUoJy4vcGF0Y2guanMnKTtcbnZhciBVdGlsID0gcmVxdWlyZSgnLi91dGlsLmpzJyk7XG5cbmZ1bmN0aW9uIERlbWFuZE1hdGNoZXIoZGVtYW5kU3BlYywgc3VwcGx5U3BlYywgb3B0aW9ucykge1xuICBvcHRpb25zID0gVXRpbC5leHRlbmQoe1xuICAgIG1ldGFMZXZlbDogMCxcbiAgICBvbkRlbWFuZEluY3JlYXNlOiBmdW5jdGlvbiAoY2FwdHVyZXMpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJTeW5kaWNhdGU6IFVuaGFuZGxlZCBpbmNyZWFzZSBpbiBkZW1hbmRcIiwgY2FwdHVyZXMpO1xuICAgIH0sXG4gICAgb25TdXBwbHlEZWNyZWFzZTogZnVuY3Rpb24gKGNhcHR1cmVzKSB7XG4gICAgICBjb25zb2xlLmVycm9yKFwiU3luZGljYXRlOiBVbmhhbmRsZWQgZGVjcmVhc2UgaW4gc3VwcGx5XCIsIGNhcHR1cmVzKTtcbiAgICB9XG4gIH0sIG9wdGlvbnMpO1xuICB0aGlzLm1ldGFMZXZlbCA9IG9wdGlvbnMubWV0YUxldmVsO1xuICB0aGlzLm9uRGVtYW5kSW5jcmVhc2UgPSBvcHRpb25zLm9uRGVtYW5kSW5jcmVhc2U7XG4gIHRoaXMub25TdXBwbHlEZWNyZWFzZSA9IG9wdGlvbnMub25TdXBwbHlEZWNyZWFzZTtcbiAgdGhpcy5kZW1hbmRTcGVjID0gZGVtYW5kU3BlYztcbiAgdGhpcy5zdXBwbHlTcGVjID0gc3VwcGx5U3BlYztcbiAgdGhpcy5kZW1hbmRQYXR0ZXJuID0gUm91dGUucHJvamVjdGlvblRvUGF0dGVybihkZW1hbmRTcGVjKTtcbiAgdGhpcy5zdXBwbHlQYXR0ZXJuID0gUm91dGUucHJvamVjdGlvblRvUGF0dGVybihzdXBwbHlTcGVjKTtcbiAgdGhpcy5kZW1hbmRQcm9qZWN0aW9uID0gUm91dGUuY29tcGlsZVByb2plY3Rpb24oUGF0Y2gucHJlcGVuZEF0TWV0YShkZW1hbmRTcGVjLCB0aGlzLm1ldGFMZXZlbCkpO1xuICB0aGlzLnN1cHBseVByb2plY3Rpb24gPSBSb3V0ZS5jb21waWxlUHJvamVjdGlvbihQYXRjaC5wcmVwZW5kQXRNZXRhKHN1cHBseVNwZWMsIHRoaXMubWV0YUxldmVsKSk7XG4gIHRoaXMuY3VycmVudERlbWFuZCA9IEltbXV0YWJsZS5TZXQoKTtcbiAgdGhpcy5jdXJyZW50U3VwcGx5ID0gSW1tdXRhYmxlLlNldCgpO1xufVxuXG5EZW1hbmRNYXRjaGVyLnByb3RvdHlwZS5ib290ID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gUGF0Y2guc3ViKHRoaXMuZGVtYW5kUGF0dGVybiwgdGhpcy5tZXRhTGV2ZWwpXG4gICAgLmFuZFRoZW4oUGF0Y2guc3ViKHRoaXMuc3VwcGx5UGF0dGVybiwgdGhpcy5tZXRhTGV2ZWwpKTtcbn07XG5cbkRlbWFuZE1hdGNoZXIucHJvdG90eXBlLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24gKGUpIHtcbiAgaWYgKGUudHlwZSA9PT0gXCJzdGF0ZUNoYW5nZVwiKSB7XG4gICAgdGhpcy5oYW5kbGVQYXRjaChlLnBhdGNoKTtcbiAgfVxufTtcblxuRGVtYW5kTWF0Y2hlci5wcm90b3R5cGUuaGFuZGxlUGF0Y2ggPSBmdW5jdGlvbiAocCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdmFyIGFkZGVkRGVtYW5kID0gUm91dGUudHJpZUtleXMoUm91dGUucHJvamVjdChwLmFkZGVkLCBzZWxmLmRlbWFuZFByb2plY3Rpb24pKTtcbiAgdmFyIHJlbW92ZWREZW1hbmQgPSBSb3V0ZS50cmllS2V5cyhSb3V0ZS5wcm9qZWN0KHAucmVtb3ZlZCwgc2VsZi5kZW1hbmRQcm9qZWN0aW9uKSk7XG4gIHZhciBhZGRlZFN1cHBseSA9IFJvdXRlLnRyaWVLZXlzKFJvdXRlLnByb2plY3QocC5hZGRlZCwgc2VsZi5zdXBwbHlQcm9qZWN0aW9uKSk7XG4gIHZhciByZW1vdmVkU3VwcGx5ID0gUm91dGUudHJpZUtleXMoUm91dGUucHJvamVjdChwLnJlbW92ZWQsIHNlbGYuc3VwcGx5UHJvamVjdGlvbikpO1xuXG4gIGlmIChhZGRlZERlbWFuZCA9PT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlN5bmRpY2F0ZTogd2lsZGNhcmQgZGVtYW5kIGRldGVjdGVkOlxcblwiICtcblx0XHQgICAgc2VsZi5kZW1hbmRTcGVjICsgXCJcXG5cIiArXG5cdFx0ICAgIHAucHJldHR5KCkpO1xuICB9XG4gIGlmIChhZGRlZFN1cHBseSA9PT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlN5bmRpY2F0ZTogd2lsZGNhcmQgc3VwcGx5IGRldGVjdGVkOlxcblwiICtcblx0XHQgICAgc2VsZi5zdXBwbHlTcGVjICsgXCJcXG5cIiArXG5cdFx0ICAgIHAucHJldHR5KCkpO1xuICB9XG5cbiAgc2VsZi5jdXJyZW50U3VwcGx5ID0gc2VsZi5jdXJyZW50U3VwcGx5LnVuaW9uKGFkZGVkU3VwcGx5KTtcbiAgc2VsZi5jdXJyZW50RGVtYW5kID0gc2VsZi5jdXJyZW50RGVtYW5kLnN1YnRyYWN0KHJlbW92ZWREZW1hbmQpO1xuXG4gIHJlbW92ZWRTdXBwbHkuZm9yRWFjaChmdW5jdGlvbiAoY2FwdHVyZXMpIHtcbiAgICBpZiAoc2VsZi5jdXJyZW50RGVtYW5kLmhhcyhjYXB0dXJlcykpIHtcbiAgICAgIHNlbGYub25TdXBwbHlEZWNyZWFzZShSb3V0ZS5jYXB0dXJlVG9PYmplY3QoY2FwdHVyZXMsIHNlbGYuc3VwcGx5UHJvamVjdGlvbikpO1xuICAgIH1cbiAgfSk7XG4gIGFkZGVkRGVtYW5kLmZvckVhY2goZnVuY3Rpb24gKGNhcHR1cmVzKSB7XG4gICAgaWYgKCFzZWxmLmN1cnJlbnRTdXBwbHkuaGFzKGNhcHR1cmVzKSkge1xuICAgICAgc2VsZi5vbkRlbWFuZEluY3JlYXNlKFJvdXRlLmNhcHR1cmVUb09iamVjdChjYXB0dXJlcywgc2VsZi5kZW1hbmRQcm9qZWN0aW9uKSk7XG4gICAgfVxuICB9KTtcblxuICBzZWxmLmN1cnJlbnRTdXBwbHkgPSBzZWxmLmN1cnJlbnRTdXBwbHkuc3VidHJhY3QocmVtb3ZlZFN1cHBseSk7XG4gIHNlbGYuY3VycmVudERlbWFuZCA9IHNlbGYuY3VycmVudERlbWFuZC51bmlvbihhZGRlZERlbWFuZCk7XG59O1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxubW9kdWxlLmV4cG9ydHMuRGVtYW5kTWF0Y2hlciA9IERlbWFuZE1hdGNoZXI7XG4iLCIvLyBET00gZnJhZ21lbnQgZGlzcGxheSBkcml2ZXJcbnZhciBQYXRjaCA9IHJlcXVpcmUoXCIuL3BhdGNoLmpzXCIpO1xudmFyIERlbWFuZE1hdGNoZXIgPSByZXF1aXJlKCcuL2RlbWFuZC1tYXRjaGVyLmpzJykuRGVtYW5kTWF0Y2hlcjtcbnZhciBBY2sgPSByZXF1aXJlKCcuL2Fjay5qcycpLkFjaztcbnZhciBTZWFsID0gcmVxdWlyZSgnLi9zZWFsLmpzJykuU2VhbDtcblxudmFyIE5ldHdvcmtfID0gcmVxdWlyZShcIi4vbmV0d29yay5qc1wiKTtcbnZhciBOZXR3b3JrID0gTmV0d29ya18uTmV0d29yaztcbnZhciBfXyA9IE5ldHdvcmtfLl9fO1xudmFyIF8kID0gTmV0d29ya18uXyQ7XG5cbmZ1bmN0aW9uIHNwYXduRE9NRHJpdmVyKGRvbVdyYXBGdW5jdGlvbiwgalF1ZXJ5V3JhcEZ1bmN0aW9uKSB7XG4gIGRvbVdyYXBGdW5jdGlvbiA9IGRvbVdyYXBGdW5jdGlvbiB8fCBkZWZhdWx0V3JhcEZ1bmN0aW9uO1xuICB2YXIgc3BlYyA9IGRvbVdyYXBGdW5jdGlvbihfJCgnc2VsZWN0b3InKSwgXyQoJ2ZyYWdtZW50Q2xhc3MnKSwgXyQoJ2ZyYWdtZW50U3BlYycpKTtcbiAgTmV0d29yay5zcGF3bihcbiAgICBuZXcgRGVtYW5kTWF0Y2hlcihzcGVjLFxuXHRcdCAgICAgIFBhdGNoLmFkdmVydGlzZShzcGVjKSxcblx0XHQgICAgICB7XG5cdFx0XHRvbkRlbWFuZEluY3JlYXNlOiBmdW5jdGlvbiAoYykge1xuXHRcdFx0ICBOZXR3b3JrLnNwYXduKG5ldyBET01GcmFnbWVudChjLnNlbGVjdG9yLFxuXHRcdFx0XHRcdFx0XHRjLmZyYWdtZW50Q2xhc3MsXG5cdFx0XHRcdFx0XHRcdGMuZnJhZ21lbnRTcGVjLFxuXHRcdFx0XHRcdFx0XHRkb21XcmFwRnVuY3Rpb24sXG5cdFx0XHRcdFx0XHRcdGpRdWVyeVdyYXBGdW5jdGlvbikpO1xuXHRcdFx0fVxuXHRcdCAgICAgIH0pKTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdFdyYXBGdW5jdGlvbihzZWxlY3RvciwgZnJhZ21lbnRDbGFzcywgZnJhZ21lbnRTcGVjKSB7XG4gIHJldHVybiBbXCJET01cIiwgc2VsZWN0b3IsIGZyYWdtZW50Q2xhc3MsIGZyYWdtZW50U3BlY107XG59XG5cbmZ1bmN0aW9uIERPTUZyYWdtZW50KHNlbGVjdG9yLCBmcmFnbWVudENsYXNzLCBmcmFnbWVudFNwZWMsIGRvbVdyYXBGdW5jdGlvbiwgalF1ZXJ5V3JhcEZ1bmN0aW9uKSB7XG4gIHRoaXMuc2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgdGhpcy5mcmFnbWVudENsYXNzID0gZnJhZ21lbnRDbGFzcztcbiAgdGhpcy5mcmFnbWVudFNwZWMgPSBmcmFnbWVudFNwZWM7XG4gIHRoaXMuZG9tV3JhcEZ1bmN0aW9uID0gZG9tV3JhcEZ1bmN0aW9uO1xuICB0aGlzLmpRdWVyeVdyYXBGdW5jdGlvbiA9IGpRdWVyeVdyYXBGdW5jdGlvbjtcbiAgdGhpcy5kZW1hbmRFeGlzdHMgPSBmYWxzZTtcbiAgdGhpcy5zdWJzY3JpcHRpb25Fc3RhYmxpc2hlZCA9IG5ldyBBY2soKTtcbiAgdGhpcy5ub2RlcyA9IHRoaXMuYnVpbGROb2RlcygpO1xufVxuXG5ET01GcmFnbWVudC5wcm90b3R5cGUuYm9vdCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgc3BlY2lmaWNhdGlvbiA9IHNlbGYuZG9tV3JhcEZ1bmN0aW9uKHNlbGYuc2VsZWN0b3IsIHNlbGYuZnJhZ21lbnRDbGFzcywgc2VsZi5mcmFnbWVudFNwZWMpO1xuXG4gIE5ldHdvcmsuc3Bhd24obmV3IE5ldHdvcmsoZnVuY3Rpb24gKCkge1xuICAgIFN5bmRpY2F0ZS5KUXVlcnkuc3Bhd25KUXVlcnlEcml2ZXIoc2VsZi5zZWxlY3RvcitcIiA+IC5cIitzZWxmLmZyYWdtZW50Q2xhc3MsXG5cdFx0XHRcdCAgICAgICAxLFxuXHRcdFx0XHQgICAgICAgc2VsZi5qUXVlcnlXcmFwRnVuY3Rpb24pO1xuICAgIE5ldHdvcmsuc3Bhd24oe1xuICAgICAgZGVtYW5kRXhpc3RzOiBmYWxzZSxcbiAgICAgIHN1YnNjcmlwdGlvbkVzdGFibGlzaGVkOiBuZXcgQWNrKDEpLFxuICAgICAgYm9vdDogZnVuY3Rpb24gKCkge1xuXHR0aGlzLnN1YnNjcmlwdGlvbkVzdGFibGlzaGVkLmFybSgpO1xuXHRyZXR1cm4gUGF0Y2guc3ViKFBhdGNoLmFkdmVydGlzZShzcGVjaWZpY2F0aW9uKSwgMSk7XG4gICAgICB9LFxuICAgICAgaGFuZGxlRXZlbnQ6IGZ1bmN0aW9uIChlKSB7XG5cdHRoaXMuc3Vic2NyaXB0aW9uRXN0YWJsaXNoZWQuY2hlY2soZSk7XG5cdGlmIChlLnR5cGUgPT09IFwic3RhdGVDaGFuZ2VcIikge1xuXHQgIGlmIChlLnBhdGNoLmhhc0FkZGVkKCkpIHRoaXMuZGVtYW5kRXhpc3RzID0gdHJ1ZTtcblx0ICBpZiAoZS5wYXRjaC5oYXNSZW1vdmVkKCkpIHRoaXMuZGVtYW5kRXhpc3RzID0gZmFsc2U7XG5cdH1cblx0aWYgKHRoaXMuc3Vic2NyaXB0aW9uRXN0YWJsaXNoZWQuZG9uZSAmJiAhdGhpcy5kZW1hbmRFeGlzdHMpIHtcblx0ICBOZXR3b3JrLmV4aXROZXR3b3JrKCk7XG5cdH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfSkpO1xuXG4gIHRoaXMuc3Vic2NyaXB0aW9uRXN0YWJsaXNoZWQuYXJtKCk7XG4gIHJldHVybiBQYXRjaC5zdWIoc3BlY2lmaWNhdGlvbikuYW5kVGhlbihQYXRjaC5wdWIoc3BlY2lmaWNhdGlvbikpO1xufTtcblxuRE9NRnJhZ21lbnQucHJvdG90eXBlLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24gKGUpIHtcbiAgdGhpcy5zdWJzY3JpcHRpb25Fc3RhYmxpc2hlZC5jaGVjayhlKTtcbiAgaWYgKGUudHlwZSA9PT0gXCJzdGF0ZUNoYW5nZVwiKSB7XG4gICAgaWYgKGUucGF0Y2guaGFzQWRkZWQoKSkgdGhpcy5kZW1hbmRFeGlzdHMgPSB0cnVlO1xuICAgIGlmIChlLnBhdGNoLmhhc1JlbW92ZWQoKSkgdGhpcy5kZW1hbmRFeGlzdHMgPSBmYWxzZTtcbiAgfVxuICBpZiAodGhpcy5zdWJzY3JpcHRpb25Fc3RhYmxpc2hlZC5kb25lICYmICF0aGlzLmRlbWFuZEV4aXN0cykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIG4gPSB0aGlzLm5vZGVzW2ldO1xuICAgICAgbi5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG4pO1xuICAgIH1cbiAgICBOZXR3b3JrLmV4aXQoKTtcbiAgfVxufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGlzQXR0cmlidXRlcyh4KSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KHgpICYmICgoeC5sZW5ndGggPT09IDApIHx8IEFycmF5LmlzQXJyYXkoeFswXSkpO1xufVxuXG5ET01GcmFnbWVudC5wcm90b3R5cGUuaW50ZXJwcmV0U3BlYyA9IGZ1bmN0aW9uIChzcGVjKSB7XG4gIC8vIEZyYWdtZW50IHNwZWNzIGFyZSByb3VnaGx5IEpTT04tZXF1aXZhbGVudHMgb2YgU1hNTC5cbiAgLy8gc3BlYyA6Oj09IFtcInRhZ1wiLCBbW1wiYXR0clwiLCBcInZhbHVlXCJdLCAuLi5dLCBzcGVjLCBzcGVjLCAuLi5dXG4gIC8vICAgICAgICAgfCBbXCJ0YWdcIiwgc3BlYywgc3BlYywgLi4uXVxuICAvLyAgICAgICAgIHwgXCJjZGF0YVwiXG4gIGlmICh0eXBlb2Yoc3BlYykgPT09IFwic3RyaW5nXCIgfHwgdHlwZW9mKHNwZWMpID09PSBcIm51bWJlclwiKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHNwZWMpO1xuICB9IGVsc2UgaWYgKCQuaXNBcnJheShzcGVjKSkge1xuICAgIHZhciB0YWdOYW1lID0gc3BlY1swXTtcbiAgICB2YXIgaGFzQXR0cnMgPSBpc0F0dHJpYnV0ZXMoc3BlY1sxXSk7XG4gICAgdmFyIGF0dHJzID0gaGFzQXR0cnMgPyBzcGVjWzFdIDoge307XG4gICAgdmFyIGtpZEluZGV4ID0gaGFzQXR0cnMgPyAyIDogMTtcblxuICAgIC8vIFdvdyEgU3VjaCBYU1MhIE1hbnkgaGFja3MhIFNvIHZ1bG5lcmFiaWxpdHkhIEFtYXplIVxuICAgIHZhciBuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWdOYW1lKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBuLnNldEF0dHJpYnV0ZShhdHRyc1tpXVswXSwgYXR0cnNbaV1bMV0pO1xuICAgIH1cbiAgICBmb3IgKHZhciBpID0ga2lkSW5kZXg7IGkgPCBzcGVjLmxlbmd0aDsgaSsrKSB7XG4gICAgICBuLmFwcGVuZENoaWxkKHRoaXMuaW50ZXJwcmV0U3BlYyhzcGVjW2ldKSk7XG4gICAgfVxuICAgIHJldHVybiBuO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihcIklsbC1mb3JtZWQgRE9NIHNwZWNpZmljYXRpb25cIik7XG4gIH1cbn07XG5cbkRPTUZyYWdtZW50LnByb3RvdHlwZS5idWlsZE5vZGVzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBub2RlcyA9IFtdO1xuICAkKHNlbGYuc2VsZWN0b3IpLmVhY2goZnVuY3Rpb24gKGluZGV4LCBkb21Ob2RlKSB7XG4gICAgdmFyIG4gPSBzZWxmLmludGVycHJldFNwZWMoc2VsZi5mcmFnbWVudFNwZWMuc2VhbENvbnRlbnRzKTtcbiAgICBpZiAoJ2NsYXNzTGlzdCcgaW4gbikge1xuICAgICAgbi5jbGFzc0xpc3QuYWRkKHNlbGYuZnJhZ21lbnRDbGFzcyk7XG4gICAgfVxuICAgIGRvbU5vZGUuYXBwZW5kQ2hpbGQobik7XG4gICAgbm9kZXMucHVzaChuKTtcbiAgfSk7XG4gIHJldHVybiBub2Rlcztcbn07XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5tb2R1bGUuZXhwb3J0cy5zcGF3bkRPTURyaXZlciA9IHNwYXduRE9NRHJpdmVyO1xubW9kdWxlLmV4cG9ydHMuZGVmYXVsdFdyYXBGdW5jdGlvbiA9IGRlZmF1bHRXcmFwRnVuY3Rpb247XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIEltbXV0YWJsZSA9IHJlcXVpcmUoJ2ltbXV0YWJsZScpO1xudmFyIE5ldHdvcmsgPSByZXF1aXJlKCcuL25ldHdvcmsuanMnKS5OZXR3b3JrO1xuXG5mdW5jdGlvbiBHcm91bmQoYm9vdEZuKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5zdGVwcGVySWQgPSBudWxsO1xuICB0aGlzLmJhc2VTdGFjayA9IEltbXV0YWJsZS5MaXN0Lm9mKHsgbmV0d29yazogdGhpcywgYWN0aXZlUGlkOiAtMSB9KTtcbiAgTmV0d29yay53aXRoTmV0d29ya1N0YWNrKHRoaXMuYmFzZVN0YWNrLCBmdW5jdGlvbiAoKSB7XG4gICAgc2VsZi5uZXR3b3JrID0gbmV3IE5ldHdvcmsoYm9vdEZuKTtcbiAgfSk7XG59XG5cbkdyb3VuZC5wcm90b3R5cGUuc3RlcCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICByZXR1cm4gTmV0d29yay53aXRoTmV0d29ya1N0YWNrKHRoaXMuYmFzZVN0YWNrLCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHNlbGYubmV0d29yay5zdGVwKCk7XG4gIH0pO1xufTtcblxuR3JvdW5kLnByb3RvdHlwZS5jaGVja1BpZCA9IGZ1bmN0aW9uIChwaWQpIHtcbiAgaWYgKHBpZCAhPT0gLTEpIGNvbnNvbGUuZXJyb3IoJ1dlaXJkIHBpZCBpbiBHcm91bmQnLCBwaWQpO1xufTtcblxuR3JvdW5kLnByb3RvdHlwZS5tYXJrUnVubmFibGUgPSBmdW5jdGlvbiAocGlkKSB7XG4gIHRoaXMuY2hlY2tQaWQocGlkKTtcbiAgdGhpcy5zdGFydFN0ZXBwaW5nKCk7XG59O1xuXG5Hcm91bmQucHJvdG90eXBlLnN0YXJ0U3RlcHBpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgaWYgKHRoaXMuc3RlcHBlcklkKSByZXR1cm47XG4gIGlmICh0aGlzLnN0ZXAoKSkge1xuICAgIHRoaXMuc3RlcHBlcklkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBzZWxmLnN0ZXBwZXJJZCA9IG51bGw7XG4gICAgICBzZWxmLnN0YXJ0U3RlcHBpbmcoKTtcbiAgICB9LCAwKTtcbiAgfVxuICByZXR1cm4gdGhpczsgLy8gYmVjYXVzZSB0aGUgc3luZGljYXRlYyBjb21waWxlciBjaGFpbnMgc3RhcnRTdGVwcGluZyBhZnRlciB0aGUgY3RvclxufTtcblxuR3JvdW5kLnByb3RvdHlwZS5zdG9wU3RlcHBpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnN0ZXBwZXJJZCkge1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnN0ZXBwZXJJZCk7XG4gICAgdGhpcy5zdGVwcGVySWQgPSBudWxsO1xuICB9XG59O1xuXG5Hcm91bmQucHJvdG90eXBlLmtpbGwgPSBmdW5jdGlvbiAocGlkLCBleG4pIHtcbiAgdGhpcy5jaGVja1BpZChwaWQpO1xuICBjb25zb2xlLmxvZyhcIkdyb3VuZCBuZXR3b3JrIHRlcm1pbmF0ZWRcIik7XG4gIHRoaXMuc3RvcFN0ZXBwaW5nKCk7XG59O1xuXG5Hcm91bmQucHJvdG90eXBlLmVucXVldWVBY3Rpb24gPSBmdW5jdGlvbiAocGlkLCBhY3Rpb24pIHtcbiAgdGhpcy5jaGVja1BpZChwaWQpO1xuXG4gIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgY2FzZSAnc3RhdGVDaGFuZ2UnOlxuICAgIGlmIChhY3Rpb24ucGF0Y2guaXNOb25FbXB0eSgpKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdZb3UgaGF2ZSBzdWJzY3JpYmVkIHRvIGEgbm9uZXhpc3RlbnQgZXZlbnQgc291cmNlLicsXG5cdFx0ICAgIGFjdGlvbi5wYXRjaC5wcmV0dHkoKSk7XG4gICAgfVxuICAgIGJyZWFrO1xuXG4gIGNhc2UgJ21lc3NhZ2UnOlxuICAgIGNvbnNvbGUuZXJyb3IoJ1lvdSBoYXZlIHNlbnQgYSBtZXNzYWdlIGludG8gdGhlIG91dGVyIHZvaWQuJywgYWN0aW9uKTtcbiAgICBicmVhaztcblxuICBkZWZhdWx0OlxuICAgIGNvbnNvbGUuZXJyb3IoJ0ludGVybmFsIGVycm9yOiB1bmV4cGVjdGVkIGFjdGlvbiBhdCBncm91bmQgbGV2ZWwnLCBhY3Rpb24pO1xuICAgIGJyZWFrO1xuICB9XG59O1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxubW9kdWxlLmV4cG9ydHMuR3JvdW5kID0gR3JvdW5kO1xuIiwiLy8gSlF1ZXJ5IGV2ZW50IGRyaXZlclxudmFyIFBhdGNoID0gcmVxdWlyZShcIi4vcGF0Y2guanNcIik7XG52YXIgRGVtYW5kTWF0Y2hlciA9IHJlcXVpcmUoJy4vZGVtYW5kLW1hdGNoZXIuanMnKS5EZW1hbmRNYXRjaGVyO1xuXG52YXIgTmV0d29ya18gPSByZXF1aXJlKFwiLi9uZXR3b3JrLmpzXCIpO1xudmFyIE5ldHdvcmsgPSBOZXR3b3JrXy5OZXR3b3JrO1xudmFyIF9fID0gTmV0d29ya18uX187XG52YXIgXyQgPSBOZXR3b3JrXy5fJDtcblxuZnVuY3Rpb24gc3Bhd25KUXVlcnlEcml2ZXIoYmFzZVNlbGVjdG9yLCBtZXRhTGV2ZWwsIHdyYXBGdW5jdGlvbikge1xuICBtZXRhTGV2ZWwgPSBtZXRhTGV2ZWwgfHwgMDtcbiAgd3JhcEZ1bmN0aW9uID0gd3JhcEZ1bmN0aW9uIHx8IGRlZmF1bHRXcmFwRnVuY3Rpb247XG4gIE5ldHdvcmsuc3Bhd24oXG4gICAgbmV3IERlbWFuZE1hdGNoZXIoUGF0Y2gub2JzZXJ2ZSh3cmFwRnVuY3Rpb24oXyQoJ3NlbGVjdG9yJyksIF8kKCdldmVudE5hbWUnKSwgX18pKSxcblx0XHQgICAgICBQYXRjaC5hZHZlcnRpc2Uod3JhcEZ1bmN0aW9uKF8kKCdzZWxlY3RvcicpLCBfJCgnZXZlbnROYW1lJyksIF9fKSksXG5cdFx0ICAgICAge1xuXHRcdFx0bWV0YUxldmVsOiBtZXRhTGV2ZWwsXG5cdFx0XHRvbkRlbWFuZEluY3JlYXNlOiBmdW5jdGlvbiAoYykge1xuXHRcdFx0ICBOZXR3b3JrLnNwYXduKG5ldyBKUXVlcnlFdmVudFJvdXRlcihiYXNlU2VsZWN0b3IsXG5cdFx0XHRcdFx0XHRcdCAgICAgIGMuc2VsZWN0b3IsXG5cdFx0XHRcdFx0XHRcdCAgICAgIGMuZXZlbnROYW1lLFxuXHRcdFx0XHRcdFx0XHQgICAgICBtZXRhTGV2ZWwsXG5cdFx0XHRcdFx0XHRcdCAgICAgIHdyYXBGdW5jdGlvbikpO1xuXHRcdFx0fVxuXHRcdCAgICAgIH0pKTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdFdyYXBGdW5jdGlvbihzZWxlY3RvciwgZXZlbnROYW1lLCBldmVudFZhbHVlKSB7XG4gIHJldHVybiBbXCJqUXVlcnlcIiwgc2VsZWN0b3IsIGV2ZW50TmFtZSwgZXZlbnRWYWx1ZV07XG59XG5cbmZ1bmN0aW9uIEpRdWVyeUV2ZW50Um91dGVyKGJhc2VTZWxlY3Rvciwgc2VsZWN0b3IsIGV2ZW50TmFtZSwgbWV0YUxldmVsLCB3cmFwRnVuY3Rpb24pIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLmJhc2VTZWxlY3RvciA9IGJhc2VTZWxlY3RvciB8fCBudWxsO1xuICB0aGlzLnNlbGVjdG9yID0gc2VsZWN0b3I7XG4gIHRoaXMuZXZlbnROYW1lID0gZXZlbnROYW1lO1xuICB0aGlzLm1ldGFMZXZlbCA9IG1ldGFMZXZlbCB8fCAwO1xuICB0aGlzLndyYXBGdW5jdGlvbiA9IHdyYXBGdW5jdGlvbiB8fCBkZWZhdWx0V3JhcEZ1bmN0aW9uO1xuICB0aGlzLnByZXZlbnREZWZhdWx0ID0gKHRoaXMuZXZlbnROYW1lLmNoYXJBdCgwKSAhPT0gXCIrXCIpO1xuICB0aGlzLmhhbmRsZXIgPVxuICAgIE5ldHdvcmsud3JhcChmdW5jdGlvbiAoZSkge1xuICAgICAgTmV0d29yay5zZW5kKHNlbGYud3JhcEZ1bmN0aW9uKHNlbGYuc2VsZWN0b3IsIHNlbGYuZXZlbnROYW1lLCBlKSwgc2VsZi5tZXRhTGV2ZWwpO1xuICAgICAgaWYgKHNlbGYucHJldmVudERlZmF1bHQpIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHJldHVybiAhc2VsZi5wcmV2ZW50RGVmYXVsdDtcbiAgICB9KTtcbiAgdGhpcy5jb21wdXRlTm9kZXMoKS5vbih0aGlzLnByZXZlbnREZWZhdWx0ID8gdGhpcy5ldmVudE5hbWUgOiB0aGlzLmV2ZW50TmFtZS5zdWJzdHJpbmcoMSksXG5cdFx0XHQgdGhpcy5oYW5kbGVyKTtcbn1cblxuSlF1ZXJ5RXZlbnRSb3V0ZXIucHJvdG90eXBlLmJvb3QgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBQYXRjaC5wdWIodGhpcy53cmFwRnVuY3Rpb24odGhpcy5zZWxlY3RvciwgdGhpcy5ldmVudE5hbWUsIF9fKSwgdGhpcy5tZXRhTGV2ZWwpXG4gICAgLmFuZFRoZW4oUGF0Y2guc3ViKFBhdGNoLm9ic2VydmUodGhpcy53cmFwRnVuY3Rpb24odGhpcy5zZWxlY3RvciwgdGhpcy5ldmVudE5hbWUsIF9fKSksXG5cdFx0ICAgICAgIHRoaXMubWV0YUxldmVsKSk7XG59O1xuXG5KUXVlcnlFdmVudFJvdXRlci5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAoZSkge1xuICBpZiAoZS50eXBlID09PSBcInN0YXRlQ2hhbmdlXCIgJiYgZS5wYXRjaC5oYXNSZW1vdmVkKCkpIHtcbiAgICB0aGlzLmNvbXB1dGVOb2RlcygpLm9mZih0aGlzLmV2ZW50TmFtZSwgdGhpcy5oYW5kbGVyKTtcbiAgICBOZXR3b3JrLmV4aXQoKTtcbiAgfVxufTtcblxuSlF1ZXJ5RXZlbnRSb3V0ZXIucHJvdG90eXBlLmNvbXB1dGVOb2RlcyA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuYmFzZVNlbGVjdG9yKSB7XG4gICAgcmV0dXJuICQodGhpcy5iYXNlU2VsZWN0b3IpLmNoaWxkcmVuKHRoaXMuc2VsZWN0b3IpLmFkZEJhY2sodGhpcy5zZWxlY3Rvcik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuICQodGhpcy5zZWxlY3Rvcik7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHNpbXBsaWZ5RE9NRXZlbnQoZSkge1xuICB2YXIga2V5cyA9IFtdO1xuICBmb3IgKHZhciBrIGluIGUpIHtcbiAgICB2YXIgdiA9IGVba107XG4gICAgaWYgKHR5cGVvZiB2ID09PSAnb2JqZWN0JykgY29udGludWU7XG4gICAgaWYgKHR5cGVvZiB2ID09PSAnZnVuY3Rpb24nKSBjb250aW51ZTtcbiAgICBrZXlzLnB1c2goayk7XG4gIH1cbiAga2V5cy5zb3J0KCk7XG4gIHZhciBzaW1wbGlmaWVkID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIHNpbXBsaWZpZWQucHVzaChba2V5c1tpXSwgZVtrZXlzW2ldXV0pO1xuICB9XG4gIHJldHVybiBzaW1wbGlmaWVkO1xufVxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxubW9kdWxlLmV4cG9ydHMuc3Bhd25KUXVlcnlEcml2ZXIgPSBzcGF3bkpRdWVyeURyaXZlcjtcbm1vZHVsZS5leHBvcnRzLnNpbXBsaWZ5RE9NRXZlbnQgPSBzaW1wbGlmeURPTUV2ZW50O1xubW9kdWxlLmV4cG9ydHMuZGVmYXVsdFdyYXBGdW5jdGlvbiA9IGRlZmF1bHRXcmFwRnVuY3Rpb247XG4iLCJcInVzZSBzdHJpY3RcIjtcblxuZnVuY3Rpb24gY29weUtleXMoa2V5cywgdG8sIGZyb20pIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdG9ba2V5c1tpXV0gPSBmcm9tW2tleXNbaV1dO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vbmV0d29yay5qc1wiKTtcblxubW9kdWxlLmV4cG9ydHMuUm91dGUgPSByZXF1aXJlKFwiLi9yb3V0ZS5qc1wiKTtcbmNvcHlLZXlzKFsnX18nLCAnXyQnLCAnJENhcHR1cmUnLCAnJFNwZWNpYWwnLFxuXHQgICdpc19lbXB0eVRyaWUnLCAnZW1wdHlUcmllJyxcblx0ICAnZW1iZWRkZWRUcmllJywgJ2NvbXBpbGVQYXR0ZXJuJyxcblx0ICAnY29tcGlsZVByb2plY3Rpb24nLCAncHJvamVjdCcsICdwcm9qZWN0T2JqZWN0cycsXG5cdCAgJ3ByZXR0eVRyaWUnXSxcblx0IG1vZHVsZS5leHBvcnRzLFxuXHQgbW9kdWxlLmV4cG9ydHMuUm91dGUpO1xuXG52YXIgU2VhbCA9IHJlcXVpcmUoJy4vc2VhbC5qcycpXG5jb3B5S2V5cyhbJ1NlYWwnLCAnc2VhbCddLFxuXHQgbW9kdWxlLmV4cG9ydHMsXG5cdCBTZWFsKTtcblxubW9kdWxlLmV4cG9ydHMuRGVtYW5kTWF0Y2hlciA9IHJlcXVpcmUoJy4vZGVtYW5kLW1hdGNoZXIuanMnKS5EZW1hbmRNYXRjaGVyO1xubW9kdWxlLmV4cG9ydHMuQWNrID0gcmVxdWlyZSgnLi9hY2suanMnKS5BY2s7XG5cbm1vZHVsZS5leHBvcnRzLlJhbmRvbUlEID0gcmVxdWlyZSgnLi9yYW5kb21pZC5qcycpO1xubW9kdWxlLmV4cG9ydHMuRE9NID0gcmVxdWlyZShcIi4vZG9tLWRyaXZlci5qc1wiKTtcbm1vZHVsZS5leHBvcnRzLkpRdWVyeSA9IHJlcXVpcmUoXCIuL2pxdWVyeS1kcml2ZXIuanNcIik7XG4vLyBtb2R1bGUuZXhwb3J0cy5Sb3V0aW5nVGFibGVXaWRnZXQgPSByZXF1aXJlKFwiLi9yb3V0aW5nLXRhYmxlLXdpZGdldC5qc1wiKTtcbi8vIG1vZHVsZS5leHBvcnRzLldlYlNvY2tldCA9IHJlcXVpcmUoXCIuL3dlYnNvY2tldC1kcml2ZXIuanNcIik7XG5tb2R1bGUuZXhwb3J0cy5SZWZsZWN0ID0gcmVxdWlyZShcIi4vcmVmbGVjdC5qc1wiKTtcblxubW9kdWxlLmV4cG9ydHMuUGF0Y2ggPSByZXF1aXJlKFwiLi9wYXRjaC5qc1wiKTtcbmNvcHlLZXlzKFsnZW1wdHlQYXRjaCcsXG5cdCAgJ29ic2VydmUnLCAnYXRNZXRhJywgJ2FkdmVydGlzZScsXG5cdCAgJ2lzT2JzZXJ2ZScsICdpc0F0TWV0YScsICdpc0FkdmVydGlzZScsXG5cdCAgJ2Fzc2VydCcsICdyZXRyYWN0JywgJ3N1YicsICd1bnN1YicsICdwdWInLCAndW5wdWInLFxuXHQgICdwYXRjaFNlcSddLFxuXHQgbW9kdWxlLmV4cG9ydHMsXG5cdCBtb2R1bGUuZXhwb3J0cy5QYXRjaCk7XG5cbm1vZHVsZS5leHBvcnRzLkdyb3VuZCA9IHJlcXVpcmUoXCIuL2dyb3VuZC5qc1wiKS5Hcm91bmQ7XG5tb2R1bGUuZXhwb3J0cy5BY3RvciA9IHJlcXVpcmUoXCIuL2FjdG9yLmpzXCIpO1xuLy8gbW9kdWxlLmV4cG9ydHMuU3B5ID0gcmVxdWlyZShcIi4vc3B5LmpzXCIpLlNweTtcbi8vIG1vZHVsZS5leHBvcnRzLldha2VEZXRlY3RvciA9IHJlcXVpcmUoXCIuL3dha2UtZGV0ZWN0b3IuanNcIikuV2FrZURldGVjdG9yO1xuXG4vLyB2YXIgV29ya2VyID0gcmVxdWlyZShcIi4vd29ya2VyLmpzXCIpO1xuLy8gbW9kdWxlLmV4cG9ydHMuV29ya2VyID0gV29ya2VyLldvcmtlcjtcbi8vIG1vZHVsZS5leHBvcnRzLldvcmtlckdyb3VuZCA9IFdvcmtlci5Xb3JrZXJHcm91bmQ7XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIEltbXV0YWJsZSA9IHJlcXVpcmUoJ2ltbXV0YWJsZScpO1xudmFyIFJvdXRlID0gcmVxdWlyZSgnLi9yb3V0ZS5qcycpO1xudmFyIFBhdGNoID0gcmVxdWlyZSgnLi9wYXRjaC5qcycpO1xuXG5mdW5jdGlvbiBNdXgobmV4dFBpZCwgcm91dGluZ1RhYmxlLCBpbnRlcmVzdFRhYmxlKSB7XG4gIHRoaXMubmV4dFBpZCA9IG5leHRQaWQgfHwgMDtcbiAgdGhpcy5yb3V0aW5nVGFibGUgPSByb3V0aW5nVGFibGUgfHwgUm91dGUuZW1wdHlUcmllO1xuICB0aGlzLmludGVyZXN0VGFibGUgPSBpbnRlcmVzdFRhYmxlIHx8IEltbXV0YWJsZS5NYXAoKTsgLy8gcGlkIC0+IFRyaWVcbn1cblxuTXV4LnByb3RvdHlwZS5zaGFsbG93Q29weSA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIG5ldyBNdXgodGhpcy5uZXh0UGlkLCB0aGlzLnJvdXRpbmdUYWJsZSwgdGhpcy5pbnRlcmVzdFRhYmxlKTtcbn07XG5cbk11eC5wcm90b3R5cGUuYWRkU3RyZWFtID0gZnVuY3Rpb24gKGluaXRpYWxQYXRjaCkge1xuICB2YXIgbmV3UGlkID0gdGhpcy5uZXh0UGlkKys7XG4gIHJldHVybiB0aGlzLnVwZGF0ZVN0cmVhbShuZXdQaWQsIGluaXRpYWxQYXRjaCk7XG59O1xuXG5NdXgucHJvdG90eXBlLnJlbW92ZVN0cmVhbSA9IGZ1bmN0aW9uIChwaWQpIHtcbiAgcmV0dXJuIHRoaXMudXBkYXRlU3RyZWFtKHBpZCwgUGF0Y2gucmVtb3ZlRXZlcnl0aGluZ1BhdGNoKTtcbn07XG5cbk11eC5wcm90b3R5cGUudXBkYXRlU3RyZWFtID0gZnVuY3Rpb24gKHBpZCwgdW5jbGFtcGVkUGF0Y2gpIHtcbiAgdmFyIG9sZEludGVyZXN0cyA9IHRoaXMuaW50ZXJlc3RzT2YocGlkKTtcbiAgdmFyIG9sZFJvdXRpbmdUYWJsZSA9IHRoaXMucm91dGluZ1RhYmxlO1xuICB2YXIgZGVsdGEgPSB1bmNsYW1wZWRQYXRjaC5sYWJlbChJbW11dGFibGUuU2V0Lm9mKHBpZCkpLmxpbWl0KG9sZEludGVyZXN0cyk7XG4gIHZhciBkZWx0YUFnZ3JlZ2F0ZSA9IGRlbHRhLmNvbXB1dGVBZ2dyZWdhdGUocGlkLCBvbGRSb3V0aW5nVGFibGUpO1xuICB2YXIgbmV3SW50ZXJlc3RzID0gZGVsdGEuYXBwbHlUbyhvbGRJbnRlcmVzdHMpO1xuICB2YXIgbmV3Um91dGluZ1RhYmxlID0gZGVsdGEuYXBwbHlUbyhvbGRSb3V0aW5nVGFibGUpO1xuXG4gIHRoaXMucm91dGluZ1RhYmxlID0gbmV3Um91dGluZ1RhYmxlO1xuXG4gIGlmIChSb3V0ZS5pc19lbXB0eVRyaWUobmV3SW50ZXJlc3RzKSkge1xuICAgIHRoaXMuaW50ZXJlc3RUYWJsZSA9IHRoaXMuaW50ZXJlc3RUYWJsZS5yZW1vdmUocGlkKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmludGVyZXN0VGFibGUgPSB0aGlzLmludGVyZXN0VGFibGUuc2V0KHBpZCwgbmV3SW50ZXJlc3RzKTtcbiAgfVxuXG4gIHJldHVybiB7IHBpZDogcGlkLFxuXHQgICBkZWx0YTogZGVsdGEsXG5cdCAgIGRlbHRhQWdncmVnYXRlOiBkZWx0YUFnZ3JlZ2F0ZSB9O1xufTtcblxudmFyIGF0TWV0YUV2ZXJ5dGhpbmcgPSBSb3V0ZS5jb21waWxlUGF0dGVybih0cnVlLCBQYXRjaC5hdE1ldGEoUm91dGUuX18pKTtcbnZhciBhdE1ldGFCcmFuY2hLZXlzID0gSW1tdXRhYmxlLkxpc3QoW1JvdXRlLlNPQSwgUGF0Y2guJEF0TWV0YV0pO1xudmFyIG9ubHlNZXRhID0gSW1tdXRhYmxlLlNldC5vZihcIm1ldGFcIik7XG5cbmZ1bmN0aW9uIGVjaG9DYW5jZWxsZWRUcmllKHQpIHtcbiAgcmV0dXJuIFJvdXRlLnN1YnRyYWN0KHQsIGF0TWV0YUV2ZXJ5dGhpbmcsIGZ1bmN0aW9uICh2MSwgdjIpIHtcbiAgICByZXR1cm4gdjEuaGFzKFwibWV0YVwiKSA/IG9ubHlNZXRhIDogbnVsbDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVFdmVudHMob2xkTXV4LCBuZXdNdXgsIHVwZGF0ZVN0cmVhbVJlc3VsdCkge1xuICB2YXIgYWN0aW5nUGlkID0gdXBkYXRlU3RyZWFtUmVzdWx0LnBpZDtcbiAgdmFyIGRlbHRhID0gdXBkYXRlU3RyZWFtUmVzdWx0LmRlbHRhO1xuICB2YXIgZGVsdGFBZ2dyZWdhdGUgPSB1cGRhdGVTdHJlYW1SZXN1bHQuZGVsdGFBZ2dyZWdhdGU7XG4gIHZhciBkZWx0YUFnZ3JlZ2F0ZU5vRWNobyA9IChhY3RpbmdQaWQgPT09IFwibWV0YVwiKVxuICAgICAgPyBkZWx0YSAvLyBiZWNhdXNlIGVjaG8tY2FuY2VsbGF0aW9uIG1lYW5zIHRoYXQgbWV0YS1TQ05zIGFyZSBhbHdheXMgbmV3IGluZm9ybWF0aW9uXG4gICAgICA6IG5ldyBQYXRjaC5QYXRjaChSb3V0ZS50cmllUHJ1bmVCcmFuY2goZGVsdGFBZ2dyZWdhdGUuYWRkZWQsIGF0TWV0YUJyYW5jaEtleXMpLFxuXHRcdFx0Um91dGUudHJpZVBydW5lQnJhbmNoKGRlbHRhQWdncmVnYXRlLnJlbW92ZWQsIGF0TWV0YUJyYW5jaEtleXMpKTtcbiAgdmFyIG9sZFJvdXRpbmdUYWJsZSA9IG9sZE11eC5yb3V0aW5nVGFibGU7XG4gIHZhciBuZXdSb3V0aW5nVGFibGUgPSBuZXdNdXgucm91dGluZ1RhYmxlO1xuICB2YXIgYWZmZWN0ZWRQaWRzID1cbiAgICAgIGNvbXB1dGVBZmZlY3RlZFBpZHMob2xkUm91dGluZ1RhYmxlLCBkZWx0YUFnZ3JlZ2F0ZU5vRWNobykuYWRkKGFjdGluZ1BpZCkucmVtb3ZlKFwibWV0YVwiKTtcbiAgcmV0dXJuIHtcbiAgICBldmVudE1hcDogSW1tdXRhYmxlLk1hcCgpLndpdGhNdXRhdGlvbnMoZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgYWZmZWN0ZWRQaWRzLmZvckVhY2goZnVuY3Rpb24gKHBpZCkge1xuXHR2YXIgcGF0Y2hGb3JQaWQ7XG5cdGlmIChwaWQgPT09IGFjdGluZ1BpZCkge1xuXHQgIHZhciBwYXJ0MSA9IG5ldyBQYXRjaC5QYXRjaChcblx0ICAgIGVjaG9DYW5jZWxsZWRUcmllKFBhdGNoLmJpYXNlZEludGVyc2VjdGlvbihuZXdSb3V0aW5nVGFibGUsIGRlbHRhLmFkZGVkKSksXG5cdCAgICBlY2hvQ2FuY2VsbGVkVHJpZShQYXRjaC5iaWFzZWRJbnRlcnNlY3Rpb24ob2xkUm91dGluZ1RhYmxlLCBkZWx0YS5yZW1vdmVkKSkpO1xuXHQgIHZhciBwYXJ0MiA9IG5ldyBQYXRjaC5QYXRjaChQYXRjaC5iaWFzZWRJbnRlcnNlY3Rpb24oZGVsdGFBZ2dyZWdhdGVOb0VjaG8uYWRkZWQsXG5cdFx0XHRcdFx0XHRcdCAgICAgICBuZXdNdXguaW50ZXJlc3RzT2YocGlkKSksXG5cdFx0XHRcdCAgICAgIFBhdGNoLmJpYXNlZEludGVyc2VjdGlvbihkZWx0YUFnZ3JlZ2F0ZU5vRWNoby5yZW1vdmVkLFxuXHRcdFx0XHRcdFx0XHQgICAgICAgb2xkTXV4LmludGVyZXN0c09mKHBpZCkpKTtcblx0ICBwYXRjaEZvclBpZCA9IHBhcnQxLnVuc2FmZVVuaW9uKHBhcnQyKTtcblx0fSBlbHNlIHtcblx0ICBwYXRjaEZvclBpZCA9IGRlbHRhQWdncmVnYXRlTm9FY2hvLnZpZXdGcm9tKG9sZE11eC5pbnRlcmVzdHNPZihwaWQpKTtcblx0fVxuXHRpZiAocGF0Y2hGb3JQaWQuaXNOb25FbXB0eSgpKSB7XG5cdCAgcmVzdWx0LnNldChwaWQsIHBhdGNoRm9yUGlkKTtcblx0fVxuICAgICAgfSk7XG4gICAgfSksXG4gICAgbWV0YUV2ZW50czogKGFjdGluZ1BpZCA9PT0gXCJtZXRhXCIpXG4gICAgICA/IEltbXV0YWJsZS5MaXN0KClcbiAgICAgIDogSW1tdXRhYmxlLkxpc3Qub2YoZGVsdGEuY29tcHV0ZUFnZ3JlZ2F0ZShhY3RpbmdQaWQsIG9sZFJvdXRpbmdUYWJsZSwgdHJ1ZSkuZHJvcCgpKVxuICB9O1xufVxuXG5mdW5jdGlvbiBjb21wdXRlQWZmZWN0ZWRQaWRzKHJvdXRpbmdUYWJsZSwgZGVsdGEpIHtcbiAgdmFyIGNvdmVyID0gUm91dGUuX3VuaW9uKGRlbHRhLmFkZGVkLCBkZWx0YS5yZW1vdmVkKTtcbiAgcm91dGluZ1RhYmxlID0gUm91dGUudHJpZVN0ZXAocm91dGluZ1RhYmxlLCBSb3V0ZS5TT0EpO1xuICByb3V0aW5nVGFibGUgPSBSb3V0ZS50cmllU3RlcChyb3V0aW5nVGFibGUsIFBhdGNoLiRPYnNlcnZlKTtcbiAgcmV0dXJuIFJvdXRlLm1hdGNoVHJpZShjb3Zlciwgcm91dGluZ1RhYmxlLCBJbW11dGFibGUuU2V0KCksXG5cdFx0XHQgZnVuY3Rpb24gKHYsIHIsIGFjYykge1xuXHRcdFx0ICAgcmV0dXJuIGFjYy51bmlvbihSb3V0ZS50cmllU3RlcChyLCBSb3V0ZS5FT0EpLnZhbHVlKTtcblx0XHRcdCB9KTtcbn1cblxuTXV4LnByb3RvdHlwZS5yb3V0ZU1lc3NhZ2UgPSBmdW5jdGlvbiAoYm9keSkge1xuICBpZiAoUm91dGUubWF0Y2hWYWx1ZSh0aGlzLnJvdXRpbmdUYWJsZSwgYm9keSkgPT09IG51bGwpIHtcbiAgICByZXR1cm4gUm91dGUubWF0Y2hWYWx1ZSh0aGlzLnJvdXRpbmdUYWJsZSwgUGF0Y2gub2JzZXJ2ZShib2R5KSkgfHwgSW1tdXRhYmxlLlNldCgpO1xuICB9IGVsc2Uge1xuICAgIC8vIFNvbWUgb3RoZXIgc3RyZWFtIGhhcyBkZWNsYXJlZCBib2R5XG4gICAgcmV0dXJuIEltbXV0YWJsZS5TZXQoKTtcbiAgfVxufTtcblxuTXV4LnByb3RvdHlwZS5pbnRlcmVzdHNPZiA9IGZ1bmN0aW9uIChwaWQpIHtcbiAgcmV0dXJuIHRoaXMuaW50ZXJlc3RUYWJsZS5nZXQocGlkLCBSb3V0ZS5lbXB0eVRyaWUpO1xufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbm1vZHVsZS5leHBvcnRzLk11eCA9IE11eDtcbm1vZHVsZS5leHBvcnRzLmNvbXB1dGVFdmVudHMgPSBjb21wdXRlRXZlbnRzO1xubW9kdWxlLmV4cG9ydHMuY29tcHV0ZUFmZmVjdGVkUGlkcyA9IGNvbXB1dGVBZmZlY3RlZFBpZHM7XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIEltbXV0YWJsZSA9IHJlcXVpcmUoJ2ltbXV0YWJsZScpO1xudmFyIFJvdXRlID0gcmVxdWlyZSgnLi9yb3V0ZS5qcycpO1xudmFyIFBhdGNoID0gcmVxdWlyZSgnLi9wYXRjaC5qcycpO1xudmFyIE11eCA9IHJlcXVpcmUoJy4vbXV4LmpzJyk7XG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cbi8qIEV2ZW50cyBhbmQgQWN0aW9ucyAqL1xuXG5mdW5jdGlvbiBzdGF0ZUNoYW5nZShwYXRjaCkge1xuICByZXR1cm4geyB0eXBlOiAnc3RhdGVDaGFuZ2UnLCBwYXRjaDogcGF0Y2ggfTtcbn1cblxuZnVuY3Rpb24gbWVzc2FnZShib2R5KSB7XG4gIHJldHVybiB7IHR5cGU6ICdtZXNzYWdlJywgbWVzc2FnZTogYm9keSB9O1xufVxuXG5mdW5jdGlvbiBzcGF3bihiZWhhdmlvcikge1xuICByZXR1cm4geyB0eXBlOiAnc3Bhd24nLCBiZWhhdmlvcjogYmVoYXZpb3IgfTtcbn1cblxuZnVuY3Rpb24gdGVybWluYXRlKCkge1xuICByZXR1cm4geyB0eXBlOiAndGVybWluYXRlJyB9O1xufVxuXG5mdW5jdGlvbiB0ZXJtaW5hdGVOZXR3b3JrKCkge1xuICByZXR1cm4geyB0eXBlOiAndGVybWluYXRlTmV0d29yaycgfTtcbn1cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuLyogTmV0d29yayAqL1xuXG5mdW5jdGlvbiBOZXR3b3JrKGJvb3RGbikge1xuICB0aGlzLnBlbmRpbmdBY3Rpb25zID0gSW1tdXRhYmxlLkxpc3QoKTsgLy8gb2YgW3BpZCwgQWN0aW9uXVxuICB0aGlzLnByb2Nlc3NUYWJsZSA9IEltbXV0YWJsZS5NYXAoKTsgLy8gcGlkIC0+IEJlaGF2aW9yXG4gIHRoaXMucnVubmFibGVQaWRzID0gSW1tdXRhYmxlLlNldCgpOyAvLyBvZiBwaWRcbiAgdGhpcy5tdXggPSBuZXcgTXV4Lk11eCgpO1xuICB0aGlzLm9uU3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAobXV4LCBkZWx0YUFnZ3JlZ2F0ZSkge307XG4gIHRoaXMuYXNDaGlsZCgnbWV0YScsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJvb3RGbigpIH0sIHRydWUpO1xufVxuXG4vLyBDbGFzcyBzdGF0ZSBhbmQgbWV0aG9kc1xuXG5OZXR3b3JrLnN0YWNrID0gSW1tdXRhYmxlLkxpc3QoKTtcblxuTmV0d29yay5jdXJyZW50ID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gTmV0d29yay5zdGFjay5sYXN0KCkubmV0d29yaztcbn07XG5cbk5ldHdvcmsuYWN0aXZlUGlkID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gTmV0d29yay5zdGFjay5sYXN0KCkuYWN0aXZlUGlkO1xufTtcblxuTmV0d29yay5hY3RpdmVCZWhhdmlvciA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGVudHJ5ID0gTmV0d29yay5zdGFjay5sYXN0KCk7XG4gIHZhciBwID0gZW50cnkubmV0d29yay5wcm9jZXNzVGFibGUuZ2V0KGVudHJ5LmFjdGl2ZVBpZCk7XG4gIHJldHVybiBwID8gcC5iZWhhdmlvciA6IG51bGw7XG59O1xuXG5OZXR3b3JrLndpdGhOZXR3b3JrU3RhY2sgPSBmdW5jdGlvbiAoc3RhY2ssIGYpIHtcbiAgdmFyIG9sZFN0YWNrID0gTmV0d29yay5zdGFjaztcbiAgTmV0d29yay5zdGFjayA9IHN0YWNrO1xuICB2YXIgcmVzdWx0O1xuICB0cnkge1xuICAgIHJlc3VsdCA9IGYoKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIE5ldHdvcmsuc3RhY2sgPSBvbGRTdGFjaztcbiAgICB0aHJvdyBlO1xuICB9XG4gIE5ldHdvcmsuc3RhY2sgPSBvbGRTdGFjaztcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbk5ldHdvcmsud3JhcCA9IGZ1bmN0aW9uIChmKSB7XG4gIHZhciBzYXZlZFN0YWNrID0gTmV0d29yay5zdGFjaztcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYWN0dWFscyA9IGFyZ3VtZW50cztcbiAgICByZXR1cm4gTmV0d29yay53aXRoTmV0d29ya1N0YWNrKHNhdmVkU3RhY2ssIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciByZXN1bHQgPSBOZXR3b3JrLmN1cnJlbnQoKS5hc0NoaWxkKE5ldHdvcmsuYWN0aXZlUGlkKCksIGZ1bmN0aW9uICgpIHtcblx0cmV0dXJuIGYuYXBwbHkobnVsbCwgYWN0dWFscyk7XG4gICAgICB9KTtcbiAgICAgIE5ldHdvcmsuc3RhY2sucmV2ZXJzZSgpLmZvckVhY2goZnVuY3Rpb24gKGVudHJ5KSB7XG5cdGVudHJ5Lm5ldHdvcmsubWFya1J1bm5hYmxlKGVudHJ5LmFjdGl2ZVBpZCk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSk7XG4gIH07XG59O1xuXG5OZXR3b3JrLmVucXVldWVBY3Rpb24gPSBmdW5jdGlvbiAoYWN0aW9uKSB7XG4gIHZhciBlbnRyeSA9IE5ldHdvcmsuc3RhY2subGFzdCgpO1xuICBlbnRyeS5uZXR3b3JrLmVucXVldWVBY3Rpb24oZW50cnkuYWN0aXZlUGlkLCBhY3Rpb24pO1xufTtcblxuTmV0d29yay5zZW5kID0gZnVuY3Rpb24gKGJvZHksIG1ldGFMZXZlbCkge1xuICBOZXR3b3JrLmVucXVldWVBY3Rpb24obWVzc2FnZShQYXRjaC5wcmVwZW5kQXRNZXRhKGJvZHksIG1ldGFMZXZlbCB8fCAwKSkpO1xufTtcblxuTmV0d29yay5zdGF0ZUNoYW5nZSA9IGZ1bmN0aW9uIChwYXRjaCkge1xuICBOZXR3b3JrLmVucXVldWVBY3Rpb24oc3RhdGVDaGFuZ2UocGF0Y2gpKTtcbn07XG5cbk5ldHdvcmsuc3Bhd24gPSBmdW5jdGlvbiAoYmVoYXZpb3IpIHtcbiAgTmV0d29yay5lbnF1ZXVlQWN0aW9uKHNwYXduKGJlaGF2aW9yKSk7XG59O1xuXG5OZXR3b3JrLmV4aXQgPSBmdW5jdGlvbiAoZXhuKSB7XG4gIE5ldHdvcmsuY3VycmVudCgpLmtpbGwoTmV0d29yay5hY3RpdmVQaWQoKSwgZXhuKTtcbn07XG5cbk5ldHdvcmsuZXhpdE5ldHdvcmsgPSBmdW5jdGlvbiAoKSB7XG4gIE5ldHdvcmsuZW5xdWV1ZUFjdGlvbih0ZXJtaW5hdGVOZXR3b3JrKCkpO1xufTtcblxuTmV0d29yay5pbmVydEJlaGF2aW9yID0ge1xuICBoYW5kbGVFdmVudDogZnVuY3Rpb24gKGUpIHt9XG59O1xuXG4vLyBJbnN0YW5jZSBtZXRob2RzXG5cbk5ldHdvcmsucHJvdG90eXBlLmFzQ2hpbGQgPSBmdW5jdGlvbiAocGlkLCBmLCBvbWl0TGl2ZW5lc3NDaGVjaykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBwID0gdGhpcy5wcm9jZXNzVGFibGUuZ2V0KHBpZCwgbnVsbCk7XG4gIGlmICghb21pdExpdmVuZXNzQ2hlY2sgJiYgKHAgPT09IG51bGwpKSB7XG4gICAgY29uc29sZS53YXJuKFwiTmV0d29yay5hc0NoaWxkIGVsaWRpbmcgaW52b2NhdGlvbiBvZiBkZWFkIHByb2Nlc3NcIiwgcGlkKTtcbiAgICByZXR1cm47XG4gIH1cblxuICByZXR1cm4gTmV0d29yay53aXRoTmV0d29ya1N0YWNrKFxuICAgIE5ldHdvcmsuc3RhY2sucHVzaCh7IG5ldHdvcms6IHRoaXMsIGFjdGl2ZVBpZDogcGlkIH0pLFxuICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRyeSB7XG5cdHJldHVybiBmKHApO1xuICAgICAgfSBjYXRjaCAoZSkge1xuXHRzZWxmLmtpbGwocGlkLCBlKTtcbiAgICAgIH1cbiAgICB9KTtcbn07XG5cbk5ldHdvcmsucHJvdG90eXBlLmtpbGwgPSBmdW5jdGlvbiAocGlkLCBleG4pIHtcbiAgaWYgKGV4biAmJiBleG4uc3RhY2spIHtcbiAgICBjb25zb2xlLmxvZyhcIlByb2Nlc3MgZXhpdGluZ1wiLCBwaWQsIGV4biwgZXhuLnN0YWNrKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zb2xlLmxvZyhcIlByb2Nlc3MgZXhpdGluZ1wiLCBwaWQsIGV4bik7XG4gIH1cbiAgdmFyIHAgPSB0aGlzLnByb2Nlc3NUYWJsZS5nZXQocGlkKTtcbiAgdGhpcy5wcm9jZXNzVGFibGUgPSB0aGlzLnByb2Nlc3NUYWJsZS5zZXQocGlkLCB7IGJlaGF2aW9yOiBOZXR3b3JrLmluZXJ0QmVoYXZpb3IgfSk7XG4gIGlmIChwKSB7XG4gICAgaWYgKHAuYmVoYXZpb3IudHJhcGV4aXQpIHtcbiAgICAgIHRoaXMuYXNDaGlsZChwaWQsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHAuYmVoYXZpb3IudHJhcGV4aXQoZXhuKTsgfSwgdHJ1ZSk7XG4gICAgfVxuICAgIHRoaXMuZW5xdWV1ZUFjdGlvbihwaWQsIHRlcm1pbmF0ZSgpKTtcbiAgfVxufTtcblxuTmV0d29yay5wcm90b3R5cGUuYm9vdCA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gTmVlZGVkIGluIG9yZGVyIGZvciBhIG5ldyBOZXR3b3JrIHRvIGJlIG1hcmtlZCBhcyBcInJ1bm5hYmxlXCIsIHNvXG4gIC8vIGl0cyBpbml0aWFsIGFjdGlvbnMgZ2V0IHBlcmZvcm1lZC5cbn07XG5cbk5ldHdvcmsucHJvdG90eXBlLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24gKGUpIHtcbiAgc3dpdGNoIChlLnR5cGUpIHtcbiAgY2FzZSAnc3RhdGVDaGFuZ2UnOlxuICAgIHRoaXMuZW5xdWV1ZUFjdGlvbignbWV0YScsIHN0YXRlQ2hhbmdlKGUucGF0Y2gubGlmdCgpKSk7XG4gICAgYnJlYWs7XG4gIGNhc2UgJ21lc3NhZ2UnOlxuICAgIHRoaXMuZW5xdWV1ZUFjdGlvbignbWV0YScsIG1lc3NhZ2UoUGF0Y2guYXRNZXRhKGUubWVzc2FnZSkpKTtcbiAgICBicmVhaztcbiAgZGVmYXVsdDpcbiAgICB2YXIgZXhuID0gbmV3IEVycm9yKFwiRXZlbnQgdHlwZSBcIiArIGUudHlwZSArIFwiIG5vdCB1bmRlcnN0b29kXCIpO1xuICAgIGV4bi5ldmVudCA9IGU7XG4gICAgdGhyb3cgZXhuO1xuICB9XG4gIHJldHVybiB0cnVlO1xufTtcblxuTmV0d29yay5wcm90b3R5cGUuc3RlcCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuZGlzcGF0Y2hBY3Rpb25zKClcbiAgICAmJiB0aGlzLnJ1blJ1bm5hYmxlUGlkcygpXG4gICAgJiYgKCh0aGlzLnBlbmRpbmdBY3Rpb25zLnNpemUgPiAwKSB8fCAodGhpcy5ydW5uYWJsZVBpZHMuc2l6ZSA+IDApKTtcbn07XG5cbk5ldHdvcmsucHJvdG90eXBlLmVucXVldWVBY3Rpb24gPSBmdW5jdGlvbiAocGlkLCBhY3Rpb24pIHtcbiAgdGhpcy5wZW5kaW5nQWN0aW9ucyA9IHRoaXMucGVuZGluZ0FjdGlvbnMucHVzaChbcGlkLCBhY3Rpb25dKTtcbn07XG5cbk5ldHdvcmsucHJvdG90eXBlLmRpc3BhdGNoQWN0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgYWN0aW9uUXVldWUgPSB0aGlzLnBlbmRpbmdBY3Rpb25zO1xuICB0aGlzLnBlbmRpbmdBY3Rpb25zID0gSW1tdXRhYmxlLkxpc3QoKTtcbiAgdmFyIGFsaXZlID0gdHJ1ZTtcbiAgYWN0aW9uUXVldWUuZm9yRWFjaChmdW5jdGlvbiAoZW50cnkpIHtcbiAgICB2YXIgcGlkID0gZW50cnlbMF07XG4gICAgdmFyIGFjdGlvbiA9IGVudHJ5WzFdO1xuICAgIGlmICghc2VsZi5pbnRlcnByZXRBY3Rpb24ocGlkLCBhY3Rpb24pKSB7XG4gICAgICBhbGl2ZSA9IGZhbHNlO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBhbGl2ZTtcbn07XG5cbk5ldHdvcmsucHJvdG90eXBlLm1hcmtSdW5uYWJsZSA9IGZ1bmN0aW9uIChwaWQpIHtcbiAgdGhpcy5ydW5uYWJsZVBpZHMgPSB0aGlzLnJ1bm5hYmxlUGlkcy5hZGQocGlkKTtcbn07XG5cbk5ldHdvcmsucHJvdG90eXBlLnJ1blJ1bm5hYmxlUGlkcyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgcGlkU2V0ID0gdGhpcy5ydW5uYWJsZVBpZHM7XG4gIHRoaXMucnVubmFibGVQaWRzID0gSW1tdXRhYmxlLlNldCgpO1xuICBwaWRTZXQuZm9yRWFjaChmdW5jdGlvbiAocGlkKSB7XG4gICAgdmFyIGNoaWxkQnVzeSA9IHNlbGYuYXNDaGlsZChwaWQsIGZ1bmN0aW9uIChwKSB7XG4gICAgICByZXR1cm4gcC5iZWhhdmlvci5zdGVwIC8vIGV4aXN0cywgaGF2ZW4ndCBjYWxsZWQgaXQgeWV0XG5cdCYmIHAuYmVoYXZpb3Iuc3RlcCgpO1xuICAgIH0pO1xuICAgIGlmIChjaGlsZEJ1c3kpIHNlbGYubWFya1J1bm5hYmxlKHBpZCk7XG4gIH0pO1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbk5ldHdvcmsucHJvdG90eXBlLmludGVycHJldEFjdGlvbiA9IGZ1bmN0aW9uIChwaWQsIGFjdGlvbikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICBjYXNlICdzdGF0ZUNoYW5nZSc6XG4gICAgdmFyIG9sZE11eCA9IHRoaXMubXV4LnNoYWxsb3dDb3B5KCk7XG4gICAgdGhpcy5kZWxpdmVyUGF0Y2hlcyhvbGRNdXgsIHRoaXMubXV4LnVwZGF0ZVN0cmVhbShwaWQsIGFjdGlvbi5wYXRjaCkpO1xuICAgIHJldHVybiB0cnVlO1xuXG4gIGNhc2UgJ21lc3NhZ2UnOlxuICAgIGlmIChQYXRjaC5pc09ic2VydmUoYWN0aW9uLm1lc3NhZ2UpKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1Byb2Nlc3MgJyArIHBpZCArICcgc2VuZCBtZXNzYWdlIGNvbnRhaW5pbmcgcXVlcnknLCBhY3Rpb24ubWVzc2FnZSk7XG4gICAgfVxuICAgIGlmIChwaWQgIT09ICdtZXRhJyAmJiBQYXRjaC5pc0F0TWV0YShhY3Rpb24ubWVzc2FnZSkpIHtcbiAgICAgIE5ldHdvcmsuc2VuZChhY3Rpb24ubWVzc2FnZVsxXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubXV4LnJvdXRlTWVzc2FnZShhY3Rpb24ubWVzc2FnZSkuZm9yRWFjaChmdW5jdGlvbiAocGlkKSB7XG5cdHNlbGYuZGVsaXZlckV2ZW50KHBpZCwgYWN0aW9uKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcblxuICBjYXNlICdzcGF3bic6XG4gICAgdmFyIG9sZE11eCA9IHRoaXMubXV4LnNoYWxsb3dDb3B5KCk7XG4gICAgdmFyIHAgPSB7IGJlaGF2aW9yOiBhY3Rpb24uYmVoYXZpb3IgfTtcbiAgICB2YXIgcGlkID0gdGhpcy5tdXgubmV4dFBpZDtcbiAgICB0aGlzLnByb2Nlc3NUYWJsZSA9IHRoaXMucHJvY2Vzc1RhYmxlLnNldChwaWQsIHApO1xuICAgIHZhciBpbml0aWFsUGF0Y2ggPSBQYXRjaC5lbXB0eVBhdGNoO1xuICAgIGlmIChwLmJlaGF2aW9yLmJvb3QpIHtcbiAgICAgIGluaXRpYWxQYXRjaCA9IHRoaXMuYXNDaGlsZChwaWQsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHAuYmVoYXZpb3IuYm9vdCgpIH0pO1xuICAgICAgaW5pdGlhbFBhdGNoID0gaW5pdGlhbFBhdGNoIHx8IFBhdGNoLmVtcHR5UGF0Y2g7XG4gICAgICB0aGlzLm1hcmtSdW5uYWJsZShwaWQpO1xuICAgIH1cbiAgICB0aGlzLmRlbGl2ZXJQYXRjaGVzKG9sZE11eCwgdGhpcy5tdXguYWRkU3RyZWFtKGluaXRpYWxQYXRjaCkpO1xuICAgIHJldHVybiB0cnVlO1xuXG4gIGNhc2UgJ3Rlcm1pbmF0ZSc6XG4gICAgdmFyIG9sZE11eCA9IHRoaXMubXV4LnNoYWxsb3dDb3B5KCk7XG4gICAgdGhpcy5kZWxpdmVyUGF0Y2hlcyhvbGRNdXgsIHRoaXMubXV4LnJlbW92ZVN0cmVhbShwaWQpKTtcbiAgICBjb25zb2xlLmxvZyhcIlByb2Nlc3MgZXhpdCBjb21wbGV0ZVwiLCBwaWQpO1xuICAgIHRoaXMucHJvY2Vzc1RhYmxlID0gdGhpcy5wcm9jZXNzVGFibGUucmVtb3ZlKHBpZCk7XG4gICAgcmV0dXJuIHRydWU7XG5cbiAgY2FzZSAndGVybWluYXRlTmV0d29yayc6XG4gICAgTmV0d29yay5leGl0KCk7XG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIGRlZmF1bHQ6XG4gICAgdmFyIGV4biA9IG5ldyBFcnJvcihcIkFjdGlvbiB0eXBlIFwiICsgYWN0aW9uLnR5cGUgKyBcIiBub3QgdW5kZXJzdG9vZFwiKTtcbiAgICBleG4uYWN0aW9uID0gYWN0aW9uO1xuICAgIHRocm93IGV4bjtcbiAgfVxufTtcblxuTmV0d29yay5wcm90b3R5cGUuZGVsaXZlclBhdGNoZXMgPSBmdW5jdGlvbiAob2xkTXV4LCB1cGRhdGVTdHJlYW1SZXN1bHQpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgZXZlbnRzID0gTXV4LmNvbXB1dGVFdmVudHMob2xkTXV4LCB0aGlzLm11eCwgdXBkYXRlU3RyZWFtUmVzdWx0KTtcbiAgZXZlbnRzLmV2ZW50TWFwLmZvckVhY2goZnVuY3Rpb24gKHBhdGNoLCBwaWQpIHtcbiAgICBzZWxmLmRlbGl2ZXJFdmVudChwaWQsIHN0YXRlQ2hhbmdlKHBhdGNoKSk7XG4gIH0pO1xuICBldmVudHMubWV0YUV2ZW50cy5mb3JFYWNoKE5ldHdvcmsuc3RhdGVDaGFuZ2UpO1xuICB0aGlzLm9uU3RhdGVDaGFuZ2UodGhpcy5tdXgsIHVwZGF0ZVN0cmVhbVJlc3VsdC5kZWx0YUFnZ3JlZ2F0ZSk7XG59O1xuXG5OZXR3b3JrLnByb3RvdHlwZS5kZWxpdmVyRXZlbnQgPSBmdW5jdGlvbiAocGlkLCBldmVudCkge1xuICB2YXIgY2hpbGRCdXN5ID0gdGhpcy5hc0NoaWxkKHBpZCwgZnVuY3Rpb24gKHApIHsgcmV0dXJuIHAuYmVoYXZpb3IuaGFuZGxlRXZlbnQoZXZlbnQpOyB9KTtcbiAgaWYgKGNoaWxkQnVzeSkgdGhpcy5tYXJrUnVubmFibGUocGlkKTtcbn07XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5tb2R1bGUuZXhwb3J0cy5zdGF0ZUNoYW5nZSA9IHN0YXRlQ2hhbmdlO1xubW9kdWxlLmV4cG9ydHMubWVzc2FnZSA9IG1lc3NhZ2U7XG5tb2R1bGUuZXhwb3J0cy5zcGF3biA9IHNwYXduO1xubW9kdWxlLmV4cG9ydHMudGVybWluYXRlID0gdGVybWluYXRlO1xubW9kdWxlLmV4cG9ydHMudGVybWluYXRlTmV0d29yayA9IHRlcm1pbmF0ZU5ldHdvcms7XG5cbm1vZHVsZS5leHBvcnRzLk5ldHdvcmsgPSBOZXR3b3JrO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBSb3V0ZSA9IHJlcXVpcmUoXCIuL3JvdXRlLmpzXCIpO1xudmFyIEltbXV0YWJsZSA9IHJlcXVpcmUoXCJpbW11dGFibGVcIik7XG5cbnZhciBfXyA9IFJvdXRlLl9fO1xudmFyIF8kID0gUm91dGUuXyQ7XG5cbmZ1bmN0aW9uIFBhdGNoKGFkZGVkLCByZW1vdmVkKSB7XG4gIHRoaXMuYWRkZWQgPSBhZGRlZDtcbiAgdGhpcy5yZW1vdmVkID0gcmVtb3ZlZDtcbn1cblxudmFyIGVtcHR5UGF0Y2ggPSBuZXcgUGF0Y2goUm91dGUuZW1wdHlUcmllLCBSb3V0ZS5lbXB0eVRyaWUpO1xudmFyIHJlbW92ZUV2ZXJ5dGhpbmdQYXRjaCA9IG5ldyBQYXRjaChSb3V0ZS5lbXB0eVRyaWUsIFJvdXRlLmNvbXBpbGVQYXR0ZXJuKHRydWUsIF9fKSk7XG5cbnZhciAkT2JzZXJ2ZSA9IG5ldyBSb3V0ZS4kU3BlY2lhbChcIiRPYnNlcnZlXCIpO1xudmFyICRBdE1ldGEgPSBuZXcgUm91dGUuJFNwZWNpYWwoXCIkQXRNZXRhXCIpO1xudmFyICRBZHZlcnRpc2UgPSBuZXcgUm91dGUuJFNwZWNpYWwoXCIkQWR2ZXJ0aXNlXCIpO1xuXG5mdW5jdGlvbiBvYnNlcnZlKHApIHsgcmV0dXJuIFskT2JzZXJ2ZSwgcF07IH1cbmZ1bmN0aW9uIGF0TWV0YShwKSB7IHJldHVybiBbJEF0TWV0YSwgcF07IH1cbmZ1bmN0aW9uIGFkdmVydGlzZShwKSB7IHJldHVybiBbJEFkdmVydGlzZSwgcF07IH1cblxuZnVuY3Rpb24gaXNPYnNlcnZlKHApIHsgcmV0dXJuIHBbMF0gPT09ICRPYnNlcnZlOyB9XG5mdW5jdGlvbiBpc0F0TWV0YShwKSB7IHJldHVybiBwWzBdID09PSAkQXRNZXRhOyB9XG5mdW5jdGlvbiBpc0FkdmVydGlzZShwKSB7IHJldHVybiBwWzBdID09PSAkQWR2ZXJ0aXNlOyB9XG5cbmZ1bmN0aW9uIHByZXBlbmRBdE1ldGEocCwgbGV2ZWwpIHtcbiAgd2hpbGUgKGxldmVsLS0pIHtcbiAgICBwID0gYXRNZXRhKHApO1xuICB9XG4gIHJldHVybiBwO1xufVxuXG5mdW5jdGlvbiBzdHJpcEF0TWV0YShwLCBsZXZlbCkge1xuICB3aGlsZSAobGV2ZWwtLSkge1xuICAgIGlmIChwLmxlbmd0aCA9PT0gMiAmJiBwWzBdID09PSAkQXRNZXRhKSB7XG4gICAgICBwID0gcFsxXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG4gIHJldHVybiBwO1xufVxuXG5mdW5jdGlvbiBvYnNlcnZlQXRNZXRhKHAsIGxldmVsKSB7XG4gIGlmIChsZXZlbCA9PT0gMCkge1xuICAgIHJldHVybiBSb3V0ZS5jb21waWxlUGF0dGVybih0cnVlLCBvYnNlcnZlKHApKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gUm91dGUuX3VuaW9uKFxuICAgICAgUm91dGUuY29tcGlsZVBhdHRlcm4odHJ1ZSwgb2JzZXJ2ZShwcmVwZW5kQXRNZXRhKHAsIGxldmVsKSkpLFxuICAgICAgUm91dGUuY29tcGlsZVBhdHRlcm4odHJ1ZSwgYXRNZXRhKFJvdXRlLmVtYmVkZGVkVHJpZShvYnNlcnZlQXRNZXRhKHAsIGxldmVsIC0gMSkpKSkpO1xuICB9XG59XG5cbmZ1bmN0aW9uIF9jaGVjayhwKSB7XG4gIGlmIChwIGluc3RhbmNlb2YgUGF0Y2gpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgY29uc3RydWN0IHBhdGNoIHBhdHRlcm4gdXNpbmcgYW4gZW1iZWRkZWQgcGF0Y2hcIik7XG4gIH1cbiAgcmV0dXJuIHA7XG59XG5cbmZ1bmN0aW9uIGFzc2VydChwLCBtZXRhTGV2ZWwpIHtcbiAgcmV0dXJuIG5ldyBQYXRjaChSb3V0ZS5jb21waWxlUGF0dGVybih0cnVlLCBwcmVwZW5kQXRNZXRhKF9jaGVjayhwKSwgbWV0YUxldmVsIHx8IDApKSxcblx0XHQgICBSb3V0ZS5lbXB0eVRyaWUpO1xufVxuXG5mdW5jdGlvbiByZXRyYWN0KHAsIG1ldGFMZXZlbCkge1xuICByZXR1cm4gbmV3IFBhdGNoKFJvdXRlLmVtcHR5VHJpZSxcblx0XHQgICBSb3V0ZS5jb21waWxlUGF0dGVybih0cnVlLCBwcmVwZW5kQXRNZXRhKF9jaGVjayhwKSwgbWV0YUxldmVsIHx8IDApKSk7XG59XG5cbmZ1bmN0aW9uIHN1YihwLCBtZXRhTGV2ZWwpIHtcbiAgcmV0dXJuIG5ldyBQYXRjaChvYnNlcnZlQXRNZXRhKF9jaGVjayhwKSwgbWV0YUxldmVsIHx8IDApLCBSb3V0ZS5lbXB0eVRyaWUpO1xufVxuXG5mdW5jdGlvbiB1bnN1YihwLCBtZXRhTGV2ZWwpIHtcbiAgcmV0dXJuIG5ldyBQYXRjaChSb3V0ZS5lbXB0eVRyaWUsIG9ic2VydmVBdE1ldGEoX2NoZWNrKHApLCBtZXRhTGV2ZWwgfHwgMCkpO1xufVxuXG5mdW5jdGlvbiBwdWIocCwgbWV0YUxldmVsKSB7XG4gIHJldHVybiBhc3NlcnQoYWR2ZXJ0aXNlKF9jaGVjayhwKSksIG1ldGFMZXZlbCk7XG59XG5cbmZ1bmN0aW9uIHVucHViKHAsIG1ldGFMZXZlbCkge1xuICByZXR1cm4gcmV0cmFjdChhZHZlcnRpc2UoX2NoZWNrKHApKSwgbWV0YUxldmVsKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cblBhdGNoLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBQYXRjaCkpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIEltbXV0YWJsZS5pcyh0aGlzLmFkZGVkLCBvdGhlci5hZGRlZCkgJiYgSW1tdXRhYmxlLmlzKHRoaXMucmVtb3ZlZCwgb3RoZXIucmVtb3ZlZCk7XG59O1xuXG5QYXRjaC5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuYWRkZWQgPT09IFJvdXRlLmVtcHR5VHJpZSAmJiB0aGlzLnJlbW92ZWQgPT09IFJvdXRlLmVtcHR5VHJpZTtcbn07XG5cblBhdGNoLnByb3RvdHlwZS5pc05vbkVtcHR5ID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gIXRoaXMuaXNFbXB0eSgpO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLmhhc0FkZGVkID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5hZGRlZCAhPT0gUm91dGUuZW1wdHlUcmllO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLmhhc1JlbW92ZWQgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLnJlbW92ZWQgIT09IFJvdXRlLmVtcHR5VHJpZTtcbn07XG5cblBhdGNoLnByb3RvdHlwZS5saWZ0ID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gbmV3IFBhdGNoKFJvdXRlLmNvbXBpbGVQYXR0ZXJuKHRydWUsIGF0TWV0YShSb3V0ZS5lbWJlZGRlZFRyaWUodGhpcy5hZGRlZCkpKSxcblx0XHQgICBSb3V0ZS5jb21waWxlUGF0dGVybih0cnVlLCBhdE1ldGEoUm91dGUuZW1iZWRkZWRUcmllKHRoaXMucmVtb3ZlZCkpKSk7XG59O1xuXG52YXIgYXRNZXRhUHJvaiA9IFJvdXRlLmNvbXBpbGVQcm9qZWN0aW9uKGF0TWV0YShfJCkpO1xuUGF0Y2gucHJvdG90eXBlLmRyb3AgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBuZXcgUGF0Y2goUm91dGUucHJvamVjdCh0aGlzLmFkZGVkLCBhdE1ldGFQcm9qKSxcblx0XHQgICBSb3V0ZS5wcm9qZWN0KHRoaXMucmVtb3ZlZCwgYXRNZXRhUHJvaikpO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLnN0cmlwID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gbmV3IFBhdGNoKFJvdXRlLnJlbGFiZWwodGhpcy5hZGRlZCwgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHRydWU7IH0pLFxuXHRcdCAgIFJvdXRlLnJlbGFiZWwodGhpcy5yZW1vdmVkLCBmdW5jdGlvbiAodikgeyByZXR1cm4gdHJ1ZTsgfSkpO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLmxhYmVsID0gZnVuY3Rpb24gKGxhYmVsVmFsdWUpIHtcbiAgcmV0dXJuIG5ldyBQYXRjaChSb3V0ZS5yZWxhYmVsKHRoaXMuYWRkZWQsIGZ1bmN0aW9uICh2KSB7IHJldHVybiBsYWJlbFZhbHVlOyB9KSxcblx0XHQgICBSb3V0ZS5yZWxhYmVsKHRoaXMucmVtb3ZlZCwgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIGxhYmVsVmFsdWU7IH0pKTtcbn07XG5cblBhdGNoLnByb3RvdHlwZS5saW1pdCA9IGZ1bmN0aW9uIChib3VuZCkge1xuICByZXR1cm4gbmV3IFBhdGNoKFJvdXRlLnN1YnRyYWN0KHRoaXMuYWRkZWQsIGJvdW5kLCBmdW5jdGlvbiAodjEsIHYyKSB7IHJldHVybiBudWxsOyB9KSxcblx0XHQgICBSb3V0ZS5pbnRlcnNlY3QodGhpcy5yZW1vdmVkLCBib3VuZCwgZnVuY3Rpb24gKHYxLCB2MikgeyByZXR1cm4gdjE7IH0pKTtcbn07XG5cbnZhciBtZXRhTGFiZWxTZXQgPSBJbW11dGFibGUuU2V0KFtcIm1ldGFcIl0pO1xuUGF0Y2gucHJvdG90eXBlLmNvbXB1dGVBZ2dyZWdhdGUgPSBmdW5jdGlvbiAobGFiZWwsIGJhc2UsIHJlbW92ZU1ldGEgLyogb3B0aW9uYWwgZmxhZyAqLykge1xuICByZXR1cm4gbmV3IFBhdGNoKFJvdXRlLnN1YnRyYWN0KHRoaXMuYWRkZWQsIGJhc2UsIGFkZENvbWJpbmVyKSxcblx0XHQgICBSb3V0ZS5zdWJ0cmFjdCh0aGlzLnJlbW92ZWQsIGJhc2UsIHJlbW92ZUNvbWJpbmVyKSk7XG5cbiAgZnVuY3Rpb24gYWRkQ29tYmluZXIodjEsIHYyKSB7XG4gICAgaWYgKHJlbW92ZU1ldGEgJiYgSW1tdXRhYmxlLmlzKHYyLCBtZXRhTGFiZWxTZXQpKSB7XG4gICAgICByZXR1cm4gdjE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZUNvbWJpbmVyKHYxLCB2Mikge1xuICAgIGlmICh2Mi5zaXplID09PSAxKSB7XG4gICAgICByZXR1cm4gdjE7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChyZW1vdmVNZXRhICYmIHYyLnNpemUgPT09IDIgJiYgdjIuaGFzKFwibWV0YVwiKSkge1xuXHRyZXR1cm4gdjE7XG4gICAgICB9IGVsc2Uge1xuXHRyZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cblBhdGNoLnByb3RvdHlwZS5hcHBseVRvID0gZnVuY3Rpb24gKGJhc2UpIHtcbiAgcmV0dXJuIFJvdXRlLl91bmlvbihSb3V0ZS5zdWJ0cmFjdChiYXNlLCB0aGlzLnJlbW92ZWQpLCB0aGlzLmFkZGVkKTtcbn07XG5cblBhdGNoLnByb3RvdHlwZS51cGRhdGVJbnRlcmVzdHMgPSBmdW5jdGlvbiAoYmFzZSkge1xuICByZXR1cm4gUm91dGUuX3VuaW9uKFJvdXRlLnN1YnRyYWN0KGJhc2UsIHRoaXMucmVtb3ZlZCwgZnVuY3Rpb24gKHYxLCB2MikgeyByZXR1cm4gbnVsbDsgfSksXG5cdFx0ICAgICAgdGhpcy5hZGRlZCxcblx0XHQgICAgICBmdW5jdGlvbiAodjEsIHYyKSB7IHJldHVybiB0cnVlOyB9KTtcbn07XG5cblBhdGNoLnByb3RvdHlwZS51bmFwcGx5VG8gPSBmdW5jdGlvbiAoYmFzZSkge1xuICByZXR1cm4gUm91dGUuX3VuaW9uKFJvdXRlLnN1YnRyYWN0KGJhc2UsIHRoaXMuYWRkZWQpLCB0aGlzLnJlbW92ZWQpO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLmFuZFRoZW4gPSBmdW5jdGlvbiAobmV4dFBhdGNoKSB7XG4gIHJldHVybiBuZXcgUGF0Y2gobmV4dFBhdGNoLnVwZGF0ZUludGVyZXN0cyh0aGlzLmFkZGVkKSxcblx0XHQgICBSb3V0ZS5fdW5pb24oUm91dGUuc3VidHJhY3QodGhpcy5yZW1vdmVkLFxuXHRcdFx0XHRcdCAgICAgICBuZXh0UGF0Y2guYWRkZWQsXG5cdFx0XHRcdFx0ICAgICAgIGZ1bmN0aW9uICh2MSwgdjIpIHsgcmV0dXJuIG51bGw7IH0pLFxuXHRcdFx0XHRuZXh0UGF0Y2gucmVtb3ZlZCxcblx0XHRcdFx0ZnVuY3Rpb24gKHYxLCB2MikgeyByZXR1cm4gdHJ1ZTsgfSkpO1xufTtcblxuZnVuY3Rpb24gcGF0Y2hTZXEoLyogcGF0Y2gsIHBhdGNoLCAuLi4gKi8pIHtcbiAgdmFyIHAgPSBlbXB0eVBhdGNoO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHAgPSBwLmFuZFRoZW4oYXJndW1lbnRzW2ldKTtcbiAgfVxuICByZXR1cm4gcDtcbn1cblxuZnVuY3Rpb24gY29tcHV0ZVBhdGNoKG9sZEJhc2UsIG5ld0Jhc2UpIHtcbiAgcmV0dXJuIG5ldyBQYXRjaChSb3V0ZS5zdWJ0cmFjdChuZXdCYXNlLCBvbGRCYXNlKSxcblx0XHQgICBSb3V0ZS5zdWJ0cmFjdChvbGRCYXNlLCBuZXdCYXNlKSk7XG59XG5cbmZ1bmN0aW9uIGJpYXNlZEludGVyc2VjdGlvbihvYmplY3QsIHN1YmplY3QpIHtcbiAgc3ViamVjdCA9IFJvdXRlLnRyaWVTdGVwKHN1YmplY3QsIFJvdXRlLlNPQSk7XG4gIHN1YmplY3QgPSBSb3V0ZS50cmllU3RlcChzdWJqZWN0LCAkT2JzZXJ2ZSk7XG4gIHJldHVybiBSb3V0ZS5pbnRlcnNlY3Qob2JqZWN0LCBzdWJqZWN0LFxuXHRcdFx0IGZ1bmN0aW9uICh2MSwgdjIpIHsgcmV0dXJuIHRydWU7IH0sXG5cdFx0XHQgZnVuY3Rpb24gKHYsIHIpIHsgcmV0dXJuIFJvdXRlLnRyaWVTdGVwKHIsIFJvdXRlLkVPQSk7IH0pO1xufVxuXG5QYXRjaC5wcm90b3R5cGUudmlld0Zyb20gPSBmdW5jdGlvbiAoaW50ZXJlc3RzKSB7XG4gIHJldHVybiBuZXcgUGF0Y2goYmlhc2VkSW50ZXJzZWN0aW9uKHRoaXMuYWRkZWQsIGludGVyZXN0cyksXG5cdFx0ICAgYmlhc2VkSW50ZXJzZWN0aW9uKHRoaXMucmVtb3ZlZCwgaW50ZXJlc3RzKSk7XG59O1xuXG5QYXRjaC5wcm90b3R5cGUudW5zYWZlVW5pb24gPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgLy8gVW5zYWZlIGJlY2F1c2UgZG9lcyBub3QgbmVjZXNzYXJpbHkgcHJlc2VydmUgaW52YXJpYW50IHRoYXQgYWRkZWRcbiAgLy8gYW5kIHJlbW92ZWQgYXJlIGRpc2pvaW50LlxuICByZXR1cm4gbmV3IFBhdGNoKFJvdXRlLl91bmlvbih0aGlzLmFkZGVkLCBvdGhlci5hZGRlZCksXG5cdFx0ICAgUm91dGUuX3VuaW9uKHRoaXMucmVtb3ZlZCwgb3RoZXIucmVtb3ZlZCkpO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLnByb2plY3QgPSBmdW5jdGlvbiAoY29tcGlsZWRQcm9qZWN0aW9uKSB7XG4gIHJldHVybiBuZXcgUGF0Y2goUm91dGUucHJvamVjdCh0aGlzLmFkZGVkLCBjb21waWxlZFByb2plY3Rpb24pLFxuXHRcdCAgIFJvdXRlLnByb2plY3QodGhpcy5yZW1vdmVkLCBjb21waWxlZFByb2plY3Rpb24pKTtcbn07XG5cblBhdGNoLnByb3RvdHlwZS5wcm9qZWN0T2JqZWN0cyA9IGZ1bmN0aW9uIChjb21waWxlZFByb2plY3Rpb24pIHtcbiAgcmV0dXJuIFtSb3V0ZS5wcm9qZWN0T2JqZWN0cyh0aGlzLmFkZGVkLCBjb21waWxlZFByb2plY3Rpb24pLFxuXHQgIFJvdXRlLnByb2plY3RPYmplY3RzKHRoaXMucmVtb3ZlZCwgY29tcGlsZWRQcm9qZWN0aW9uKV07XG59O1xuXG5QYXRjaC5wcm90b3R5cGUucHJldHR5ID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gKFwiPDw8PDw8PDwgUmVtb3ZlZDpcXG5cIiArIFJvdXRlLnByZXR0eVRyaWUodGhpcy5yZW1vdmVkKSArIFwiXFxuXCIgK1xuXHQgIFwiPT09PT09PT0gQWRkZWQ6XFxuXCIgKyBSb3V0ZS5wcmV0dHlUcmllKHRoaXMuYWRkZWQpICsgXCJcXG5cIiArXG5cdCAgXCI+Pj4+Pj4+PlwiKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbm1vZHVsZS5leHBvcnRzLlBhdGNoID0gUGF0Y2g7XG5tb2R1bGUuZXhwb3J0cy5lbXB0eVBhdGNoID0gZW1wdHlQYXRjaDtcbm1vZHVsZS5leHBvcnRzLnJlbW92ZUV2ZXJ5dGhpbmdQYXRjaCA9IHJlbW92ZUV2ZXJ5dGhpbmdQYXRjaDtcblxubW9kdWxlLmV4cG9ydHMuJE9ic2VydmUgPSAkT2JzZXJ2ZTtcbm1vZHVsZS5leHBvcnRzLiRBdE1ldGEgPSAkQXRNZXRhO1xubW9kdWxlLmV4cG9ydHMuJEFkdmVydGlzZSA9ICRBZHZlcnRpc2U7XG5tb2R1bGUuZXhwb3J0cy5vYnNlcnZlID0gb2JzZXJ2ZTtcbm1vZHVsZS5leHBvcnRzLmF0TWV0YSA9IGF0TWV0YTtcbm1vZHVsZS5leHBvcnRzLmFkdmVydGlzZSA9IGFkdmVydGlzZTtcbm1vZHVsZS5leHBvcnRzLmlzT2JzZXJ2ZSA9IGlzT2JzZXJ2ZTtcbm1vZHVsZS5leHBvcnRzLmlzQXRNZXRhID0gaXNBdE1ldGE7XG5tb2R1bGUuZXhwb3J0cy5pc0FkdmVydGlzZSA9IGlzQWR2ZXJ0aXNlO1xuXG5tb2R1bGUuZXhwb3J0cy5wcmVwZW5kQXRNZXRhID0gcHJlcGVuZEF0TWV0YTtcbm1vZHVsZS5leHBvcnRzLnN0cmlwQXRNZXRhID0gc3RyaXBBdE1ldGE7XG5tb2R1bGUuZXhwb3J0cy5vYnNlcnZlQXRNZXRhID0gb2JzZXJ2ZUF0TWV0YTtcbm1vZHVsZS5leHBvcnRzLmFzc2VydCA9IGFzc2VydDtcbm1vZHVsZS5leHBvcnRzLnJldHJhY3QgPSByZXRyYWN0O1xubW9kdWxlLmV4cG9ydHMuc3ViID0gc3ViO1xubW9kdWxlLmV4cG9ydHMudW5zdWIgPSB1bnN1Yjtcbm1vZHVsZS5leHBvcnRzLnB1YiA9IHB1Yjtcbm1vZHVsZS5leHBvcnRzLnVucHViID0gdW5wdWI7XG5cbm1vZHVsZS5leHBvcnRzLnBhdGNoU2VxID0gcGF0Y2hTZXE7XG5tb2R1bGUuZXhwb3J0cy5jb21wdXRlUGF0Y2ggPSBjb21wdXRlUGF0Y2g7XG5tb2R1bGUuZXhwb3J0cy5iaWFzZWRJbnRlcnNlY3Rpb24gPSBiaWFzZWRJbnRlcnNlY3Rpb247XG4iLCJ2YXIgcmFuZG9tSWQ7XG5cbmlmICgodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpICYmXG4gICAgKHR5cGVvZiB3aW5kb3cuY3J5cHRvICE9PSAndW5kZWZpbmVkJykgJiZcbiAgICAodHlwZW9mIHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzICE9PSAndW5kZWZpbmVkJykpIHtcbiAgcmFuZG9tSWQgPSBmdW5jdGlvbiAoYnl0ZUNvdW50KSB7XG4gICAgdmFyIGJ1ZiA9IG5ldyBVaW50OEFycmF5KGJ5dGVDb3VudCk7XG4gICAgd2luZG93LmNyeXB0by5nZXRSYW5kb21WYWx1ZXMoYnVmKTtcbiAgICByZXR1cm4gYnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGJ1ZikpLnJlcGxhY2UoLz0vZywnJyk7XG4gIH07XG59IGVsc2Uge1xuICB2YXIgY3J5cHRvO1xuICB0cnkge1xuICAgIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuICB9IGNhdGNoIChlKSB7fVxuICBpZiAoKHR5cGVvZiBjcnlwdG8gIT09ICd1bmRlZmluZWQnKSAmJlxuICAgICAgKHR5cGVvZiBjcnlwdG8ucmFuZG9tQnl0ZXMgIT09ICd1bmRlZmluZWQnKSkge1xuICAgIHJhbmRvbUlkID0gZnVuY3Rpb24gKGJ5dGVDb3VudCkge1xuICAgICAgcmV0dXJuIGNyeXB0by5yYW5kb21CeXRlcyhieXRlQ291bnQpLmJhc2U2NFNsaWNlKCkucmVwbGFjZSgvPS9nLCcnKTtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUud2FybignTm8gc3VpdGFibGUgaW1wbGVtZW50YXRpb24gZm9yIFJhbmRvbUlELnJhbmRvbUlkIGF2YWlsYWJsZS4nKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cy5yYW5kb21JZCA9IHJhbmRvbUlkO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8vIFJlZmxlY3Rpb24gb24gZnVuY3Rpb24gZm9ybWFsIHBhcmFtZXRlciBsaXN0cy5cbi8vIFRoaXMgbW9kdWxlIGlzIGJhc2VkIG9uIEFuZ3VsYXIncyBcImluamVjdG9yXCIgY29kZSxcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2FuZ3VsYXIuanMvYmxvYi9tYXN0ZXIvc3JjL2F1dG8vaW5qZWN0b3IuanMsXG4vLyBNSVQgbGljZW5zZWQsIGFuZCBoZW5jZTpcbi8vIENvcHlyaWdodCAoYykgMjAxMC0yMDE0IEdvb2dsZSwgSW5jLiBodHRwOi8vYW5ndWxhcmpzLm9yZ1xuLy8gQ29weXJpZ2h0IChjKSAyMDE0IFRvbnkgR2Fybm9jay1Kb25lc1xuXG52YXIgRk5fQVJHUyA9IC9eZnVuY3Rpb25cXHMqW15cXChdKlxcKFxccyooW15cXCldKilcXCkvbTtcbnZhciBGTl9BUkdfU1BMSVQgPSAvLC87XG52YXIgU1RSSVBfQ09NTUVOVFMgPSAvKChcXC9cXC8uKiQpfChcXC9cXCpbXFxzXFxTXSo/XFwqXFwvKSkvbWc7XG5cbmZ1bmN0aW9uIGZvcm1hbFBhcmFtZXRlcnMoZm4pIHtcbiAgICB2YXIgcmVzdWx0ID0gW107XG5cbiAgICB2YXIgZm5UZXh0ID0gZm4udG9TdHJpbmcoKS5yZXBsYWNlKFNUUklQX0NPTU1FTlRTLCAnJyk7XG4gICAgdmFyIGFyZ0RlY2wgPSBmblRleHQubWF0Y2goRk5fQVJHUyk7XG4gICAgdmFyIGFyZ3MgPSBhcmdEZWNsWzFdLnNwbGl0KEZOX0FSR19TUExJVCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG5cdHZhciB0cmltbWVkID0gYXJnc1tpXS50cmltKCk7XG5cdGlmICh0cmltbWVkKSB7IHJlc3VsdC5wdXNoKHRyaW1tZWQpOyB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMuZm9ybWFsUGFyYW1ldGVycyA9IGZvcm1hbFBhcmFtZXRlcnM7XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIEltbXV0YWJsZSA9IHJlcXVpcmUoXCJpbW11dGFibGVcIik7XG5cbmZ1bmN0aW9uIG1ha2VTdHJ1Y3R1cmVDb25zdHJ1Y3RvcihsYWJlbCwgYXJndW1lbnROYW1lcykge1xuICB2YXIgJFN5bmRpY2F0ZU1ldGEkID0ge1xuICAgIGxhYmVsOiBsYWJlbCxcbiAgICBhcmd1bWVudHM6IGFyZ3VtZW50TmFtZXNcbiAgfTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciByZXN1bHQgPSB7XCIkU3luZGljYXRlTWV0YSRcIjogJFN5bmRpY2F0ZU1ldGEkfTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50TmFtZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlc3VsdFthcmd1bWVudE5hbWVzW2ldXSA9IGFyZ3VtZW50c1tpXTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcbn1cblxuZnVuY3Rpb24gaXNTdHJ1Y3R1cmUocykge1xuICByZXR1cm4gKHMgIT09IG51bGwpICYmICh0eXBlb2YgcyA9PT0gJ29iamVjdCcpICYmIChcIiRTeW5kaWNhdGVNZXRhJFwiIGluIHMpO1xufVxuXG5mdW5jdGlvbiBzdHJ1Y3R1cmVUb0FycmF5KHMpIHtcbiAgdmFyIHJlc3VsdCA9IFtzLiRTeW5kaWNhdGVNZXRhJC5sYWJlbF07XG4gIHZhciBhcmdzID0gcy4kU3luZGljYXRlTWV0YSQuYXJndW1lbnRzO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICByZXN1bHQucHVzaChzW2FyZ3NbaV1dKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiAkU3BlY2lhbChuYW1lKSB7XG4gIHRoaXMubmFtZSA9IG5hbWU7XG59XG5cbnZhciBfXyA9IG5ldyAkU3BlY2lhbChcIndpbGRjYXJkXCIpOyAvKiB3aWxkY2FyZCBtYXJrZXIgKi9cblxudmFyIFNPQSA9IG5ldyAkU3BlY2lhbChcIltcIik7IC8vIHN0YXJ0IG9mIGFycmF5XG52YXIgRU9BID0gbmV3ICRTcGVjaWFsKFwiXVwiKTsgLy8gZW5kIG9mIGFycmF5XG5cbmZ1bmN0aW9uIGRpZShtZXNzYWdlKSB7XG4gIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbn1cblxuZnVuY3Rpb24gJEVtYmVkZGVkKHRyaWUpIHtcbiAgdGhpcy50cmllID0gdHJpZTtcbn1cblxuZnVuY3Rpb24gZW1iZWRkZWRUcmllKHRyaWUpIHtcbiAgcmV0dXJuIG5ldyAkRW1iZWRkZWQodHJpZSk7XG59XG5cbi8vIFRoZSBuYW1lIGFyZ3VtZW50IHNob3VsZCBiZSBhIHN0cmluZyBvciBudWxsOyBpdCBkZWZhdWx0cyB0byBudWxsLlxuLy8gVGhlIHBhdHRlcm4gYXJndW1lbnQgZGVmYXVsdHMgdG8gd2lsZGNhcmQsIF9fLlxuZnVuY3Rpb24gJENhcHR1cmUobmFtZSwgcGF0dGVybikge1xuICB0aGlzLm5hbWUgPSBuYW1lIHx8IG51bGw7XG4gIHRoaXMucGF0dGVybiA9ICh0eXBlb2YgcGF0dGVybiA9PT0gJ3VuZGVmaW5lZCcgPyBfXyA6IHBhdHRlcm4pO1xufVxuXG4vLyBBYmJyZXZpYXRpb246IF8kKC4uLikgPD09PiBuZXcgJENhcHR1cmUoLi4uKVxuZnVuY3Rpb24gXyQobmFtZSwgcGF0dGVybikge1xuICByZXR1cm4gbmV3ICRDYXB0dXJlKG5hbWUsIHBhdHRlcm4pO1xufVxuXG5mdW5jdGlvbiBpc0NhcHR1cmUoeCkgeyByZXR1cm4geCBpbnN0YW5jZW9mICRDYXB0dXJlIHx8IHggPT09IF8kOyB9XG5mdW5jdGlvbiBjYXB0dXJlTmFtZSh4KSB7IHJldHVybiB4IGluc3RhbmNlb2YgJENhcHR1cmUgPyB4Lm5hbWUgOiBudWxsOyB9XG5mdW5jdGlvbiBjYXB0dXJlUGF0dGVybih4KSB7IHJldHVybiB4IGluc3RhbmNlb2YgJENhcHR1cmUgPyB4LnBhdHRlcm4gOiBfXzsgfVxuXG52YXIgU09DID0gbmV3ICRTcGVjaWFsKFwie1wiKTsgLy8gc3RhcnQgb2YgY2FwdHVyZVxudmFyIEVPQyA9IG5ldyAkU3BlY2lhbChcIn1cIik7IC8vIGVuZCBvZiBjYXB0dXJlXG5cbmZ1bmN0aW9uICRTdWNjZXNzKHZhbHVlKSB7XG4gIHRoaXMudmFsdWUgPSB2YWx1ZTtcbn1cblxuJFN1Y2Nlc3MucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChvdGhlcikge1xuICBpZiAoIShvdGhlciBpbnN0YW5jZW9mICRTdWNjZXNzKSkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gSW1tdXRhYmxlLmlzKHRoaXMudmFsdWUsIG90aGVyLnZhbHVlKTtcbn07XG5cbmZ1bmN0aW9uICRXaWxkY2FyZFNlcXVlbmNlKHRyaWUpIHtcbiAgdGhpcy50cmllID0gdHJpZTtcbn1cblxuJFdpbGRjYXJkU2VxdWVuY2UucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChvdGhlcikge1xuICBpZiAoIShvdGhlciBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gSW1tdXRhYmxlLmlzKHRoaXMudHJpZSwgb3RoZXIudHJpZSk7XG59O1xuXG5mdW5jdGlvbiBpc19lbXB0eVRyaWUobSkge1xuICByZXR1cm4gSW1tdXRhYmxlLmlzKG0sIGVtcHR5VHJpZSk7XG59XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gQ29uc3RydWN0b3JzXG5cbnZhciBlbXB0eVRyaWUgPSBJbW11dGFibGUuTWFwKCk7XG5cbmZ1bmN0aW9uIHJzdWNjZXNzKHYpIHtcbiAgcmV0dXJuICh2ID09PSBudWxsKSA/IGVtcHR5VHJpZSA6IG5ldyAkU3VjY2Vzcyh2KTtcbn1cblxuZnVuY3Rpb24gcnNlcShlLCByKSB7XG4gIGlmIChyID09PSBlbXB0eVRyaWUpIHJldHVybiBlbXB0eVRyaWU7XG4gIHJldHVybiBlbXB0eVRyaWUuc2V0KGUsIHIpO1xufVxuXG5mdW5jdGlvbiByd2lsZChyKSB7XG4gIHJldHVybiByc2VxKF9fLCByKTtcbn1cblxuZnVuY3Rpb24gcndpbGRzZXEocikge1xuICByZXR1cm4gKHIgPT09IGVtcHR5VHJpZSkgPyBlbXB0eVRyaWUgOiBuZXcgJFdpbGRjYXJkU2VxdWVuY2Uocik7XG59XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBjb21waWxlUGF0dGVybih2LCBwKSB7XG4gIGlmICghcCkgZGllKFwiY29tcGlsZVBhdHRlcm46IG1pc3NpbmcgcGF0dGVyblwiKTtcbiAgcmV0dXJuIHdhbGsocCwgcnNlcShFT0EsIHJzdWNjZXNzKHYpKSk7XG5cbiAgZnVuY3Rpb24gd2FsayhwLCBhY2MpIHtcbiAgICBpZiAocCA9PT0gX18pIHJldHVybiByd2lsZChhY2MpO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkocCkpIHtcbiAgICAgIGFjYyA9IHJzZXEoRU9BLCBhY2MpO1xuICAgICAgZm9yICh2YXIgaSA9IHAubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcblx0YWNjID0gd2FsayhwW2ldLCBhY2MpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJzZXEoU09BLCBhY2MpO1xuICAgIH1cblxuICAgIGlmIChJbW11dGFibGUuTGlzdC5pc0xpc3QocCkpIHtcbiAgICAgIGFjYyA9IHJzZXEoRU9BLCBhY2MpO1xuICAgICAgcC5yZXZlcnNlKCkuZm9yRWFjaChmdW5jdGlvbiAoZWxlbWVudCkge1xuXHRhY2MgPSB3YWxrKGVsZW1lbnQsIGFjYyk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByc2VxKFNPQSwgYWNjKTtcbiAgICB9XG5cbiAgICBpZiAoaXNTdHJ1Y3R1cmUocCkpIHtcbiAgICAgIHZhciBhcmdzID0gcC4kU3luZGljYXRlTWV0YSQuYXJndW1lbnRzO1xuICAgICAgYWNjID0gcnNlcShFT0EsIGFjYyk7XG4gICAgICBmb3IgKHZhciBpID0gYXJncy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBhY2MgPSB3YWxrKHBbYXJnc1tpXV0sIGFjYyk7XG4gICAgICB9XG4gICAgICBhY2MgPSByc2VxKHAuJFN5bmRpY2F0ZU1ldGEkLmxhYmVsLCBhY2MpO1xuICAgICAgcmV0dXJuIHJzZXEoU09BLCBhY2MpO1xuICAgIH1cblxuICAgIGlmIChwIGluc3RhbmNlb2YgJEVtYmVkZGVkKSB7XG4gICAgICByZXR1cm4gYXBwZW5kVHJpZShwLnRyaWUsIGZ1bmN0aW9uICh2KSB7IHJldHVybiBhY2M7IH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcnNlcShwLCBhY2MpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBtYXRjaFBhdHRlcm4odiwgcCkge1xuICB2YXIgY2FwdHVyZUNvdW50ID0gMDtcbiAgdmFyIHJlc3VsdCA9IHt9O1xuICB0cnkge1xuICAgIHdhbGsodiwgcCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAoZS5tYXRjaFBhdHRlcm5GYWlsZWQpIHJldHVybiBudWxsO1xuICAgIHRocm93IGU7XG4gIH1cbiAgcmVzdWx0Lmxlbmd0aCA9IGNhcHR1cmVDb3VudDtcbiAgcmV0dXJuIHJlc3VsdDtcblxuICBmdW5jdGlvbiB3YWxrKHYsIHApIHtcbiAgICBpZiAocCA9PT0gdikgcmV0dXJuO1xuXG4gICAgaWYgKHAgPT09IF9fKSByZXR1cm47XG5cbiAgICBpZiAoaXNTdHJ1Y3R1cmUocCkpIHsgcCA9IHN0cnVjdHVyZVRvQXJyYXkocCk7IH1cbiAgICBpZiAoaXNTdHJ1Y3R1cmUodikpIHsgdiA9IHN0cnVjdHVyZVRvQXJyYXkodik7IH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KHApICYmIEFycmF5LmlzQXJyYXkodikgJiYgcC5sZW5ndGggPT09IHYubGVuZ3RoKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHAubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgd2Fsayh2W2ldLCBwW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoaXNDYXB0dXJlKHApKSB7XG4gICAgICB2YXIgdGhpc0NhcHR1cmUgPSBjYXB0dXJlQ291bnQrKztcbiAgICAgIHdhbGsodiwgY2FwdHVyZVBhdHRlcm4ocCkpO1xuICAgICAgcmVzdWx0W2NhcHR1cmVOYW1lKHApIHx8ICgnJCcgKyB0aGlzQ2FwdHVyZSldID0gdjtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocCBpbnN0YW5jZW9mICRFbWJlZGRlZCkge1xuICAgICAgZGllKFwiJEVtYmVkZGVkIHBhdHRlcm5zIG5vdCBzdXBwb3J0ZWQgaW4gbWF0Y2hQYXR0ZXJuKClcIik7XG4gICAgfVxuXG4gICAgdGhyb3cge21hdGNoUGF0dGVybkZhaWxlZDogdHJ1ZX07XG4gIH1cbn1cblxuZnVuY3Rpb24gcnVwZGF0ZShyLCBrZXksIGspIHtcbiAgdmFyIG9sZFdpbGQgPSByLmdldChfXywgZW1wdHlUcmllKTtcbiAgaWYgKEltbXV0YWJsZS5pcyhrLCBvbGRXaWxkKSkge1xuICAgIHJldHVybiByLnJlbW92ZShrZXkpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiByLnNldChrZXksIGspO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJsb29rdXAociwga2V5KSB7XG4gIHJldHVybiByLmdldChrZXksIGVtcHR5VHJpZSk7XG59XG5cbmZ1bmN0aW9uIHJsb29rdXBXaWxkKHIsIGtleSkge1xuICB2YXIgcmVzdWx0ID0gci5nZXQoa2V5LCBmYWxzZSk7XG4gIGlmIChyZXN1bHQpIHJldHVybiByZXN1bHQ7XG4gIHZhciB3aWxkRWRnZSA9IHJsb29rdXAociwgX18pO1xuICBpZiAoaXNfa2V5T3BlbihrZXkpKSByZXR1cm4gcndpbGRzZXEod2lsZEVkZ2UpO1xuICBpZiAoaXNfa2V5Q2xvc2Uoa2V5KSkgcmV0dXJuICh3aWxkRWRnZSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSA/IHdpbGRFZGdlLnRyaWUgOiBlbXB0eVRyaWU7XG4gIHJldHVybiB3aWxkRWRnZTtcbn1cblxuZnVuY3Rpb24gaXNfa2V5T3BlbihrKSB7XG4gIHJldHVybiBrID09PSBTT0E7XG59XG5cbmZ1bmN0aW9uIGlzX2tleUNsb3NlKGspIHtcbiAgcmV0dXJuIGsgPT09IEVPQTtcbn1cblxuZnVuY3Rpb24gaXNfa2V5Tm9ybWFsKGspIHtcbiAgcmV0dXJuICEoaXNfa2V5T3BlbihrKSB8fCBpc19rZXlDbG9zZShrKSk7XG59XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG52YXIgdW5pb25TdWNjZXNzZXNEZWZhdWx0ID0gZnVuY3Rpb24gKHYxLCB2Mikge1xuICBpZiAodjEgPT09IHRydWUpIHJldHVybiB2MjtcbiAgaWYgKHYyID09PSB0cnVlKSByZXR1cm4gdjE7XG4gIHJldHVybiB2MS51bmlvbih2Mik7XG59O1xuXG52YXIgaW50ZXJzZWN0U3VjY2Vzc2VzRGVmYXVsdCA9IGZ1bmN0aW9uICh2MSwgdjIpIHtcbiAgcmV0dXJuIHYxO1xufTtcblxudmFyIHN1YnRyYWN0U3VjY2Vzc2VzRGVmYXVsdCA9IGZ1bmN0aW9uICh2MSwgdjIpIHtcbiAgdmFyIHIgPSB2MS5zdWJ0cmFjdCh2Mik7XG4gIGlmIChyLmlzRW1wdHkoKSkgcmV0dXJuIG51bGw7XG4gIHJldHVybiByO1xufTtcblxudmFyIG1hdGNoVHJpZVN1Y2Nlc3NlcyA9IGZ1bmN0aW9uICh2MSwgdjIsIGFjYykge1xuICByZXR1cm4gYWNjLnVuaW9uKHYyKTtcbn07XG5cbnZhciBwcm9qZWN0U3VjY2VzcyA9IGZ1bmN0aW9uICh2KSB7XG4gIHJldHVybiB2O1xufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGV4cGFuZFdpbGRzZXEocikge1xuICByZXR1cm4gdW5pb24ocndpbGQocndpbGRzZXEocikpLCByc2VxKEVPQSwgcikpO1xufVxuXG5mdW5jdGlvbiB1bmlvbihvMSwgbzIsIHVuaW9uU3VjY2Vzc2VzT3B0KSB7XG4gIHZhciB1bmlvblN1Y2Nlc3NlcyA9IHVuaW9uU3VjY2Vzc2VzT3B0IHx8IHVuaW9uU3VjY2Vzc2VzRGVmYXVsdDtcbiAgcmV0dXJuIG1lcmdlKG8xLCBvMik7XG5cbiAgZnVuY3Rpb24gbWVyZ2UobzEsIG8yKSB7XG4gICAgaWYgKGlzX2VtcHR5VHJpZShvMSkpIHJldHVybiBvMjtcbiAgICBpZiAoaXNfZW1wdHlUcmllKG8yKSkgcmV0dXJuIG8xO1xuICAgIHJldHVybiB3YWxrKG8xLCBvMik7XG4gIH1cblxuICBmdW5jdGlvbiB3YWxrKHIxLCByMikge1xuICAgIGlmIChyMSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG4gICAgICBpZiAocjIgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHRyZXR1cm4gcndpbGRzZXEod2FsayhyMS50cmllLCByMi50cmllKSk7XG4gICAgICB9XG4gICAgICByMSA9IGV4cGFuZFdpbGRzZXEocjEudHJpZSk7XG4gICAgfSBlbHNlIGlmIChyMiBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG4gICAgICByMiA9IGV4cGFuZFdpbGRzZXEocjIudHJpZSk7XG4gICAgfVxuXG4gICAgaWYgKHIxIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcbiAgICAgIGlmIChyMiBpbnN0YW5jZW9mICRTdWNjZXNzKSB7XG5cdHJldHVybiByc3VjY2Vzcyh1bmlvblN1Y2Nlc3NlcyhyMS52YWx1ZSwgcjIudmFsdWUpKTtcbiAgICAgIH0gZWxzZSB7XG5cdGRpZShcIlJvdXRlLnVuaW9uOiBsZWZ0IHNob3J0IVwiKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHIyIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcbiAgICAgIGRpZShcIlJvdXRlLnVuaW9uOiByaWdodCBzaG9ydCFcIik7XG4gICAgfVxuXG4gICAgdmFyIHcgPSBtZXJnZShybG9va3VwKHIxLCBfXyksIHJsb29rdXAocjIsIF9fKSk7XG4gICAgdmFyIHRhcmdldDtcblxuICAgIGZ1bmN0aW9uIGV4YW1pbmVLZXkoa2V5KSB7XG4gICAgICBpZiAoKGtleSAhPT0gX18pICYmICF0YXJnZXQuaGFzKGtleSkpIHtcblx0dGFyZ2V0ID0gcnVwZGF0ZSh0YXJnZXQsIGtleSwgbWVyZ2Uocmxvb2t1cFdpbGQocjEsIGtleSksIHJsb29rdXBXaWxkKHIyLCBrZXkpKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzX2VtcHR5VHJpZSh3KSkge1xuICAgICAgdmFyIHNtYWxsZXIgPSByMS5zaXplIDwgcjIuc2l6ZSA/IHIxIDogcjI7XG4gICAgICB2YXIgbGFyZ2VyICA9IHIxLnNpemUgPCByMi5zaXplID8gcjIgOiByMTtcbiAgICAgIHRhcmdldCA9IGxhcmdlcjtcbiAgICAgIHNtYWxsZXIuZm9yRWFjaChmdW5jdGlvbiAodmFsLCBrZXkpIHtcblx0dmFyIGsgPSBtZXJnZShybG9va3VwKHNtYWxsZXIsIGtleSksIHJsb29rdXAobGFyZ2VyLCBrZXkpKTtcblx0dGFyZ2V0ID0gcnVwZGF0ZSh0YXJnZXQsIGtleSwgayk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGFyZ2V0ID0gcndpbGQodyk7XG4gICAgICByMS5mb3JFYWNoKGZ1bmN0aW9uICh2YWwsIGtleSkgeyBleGFtaW5lS2V5KGtleSkgfSk7XG4gICAgICByMi5mb3JFYWNoKGZ1bmN0aW9uICh2YWwsIGtleSkgeyBleGFtaW5lS2V5KGtleSkgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfVxufVxuXG5mdW5jdGlvbiB1bmlvbk4oKSB7XG4gIHZhciBhY2MgPSBlbXB0eVRyaWU7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgYWNjID0gdW5pb24oYWNjLCBhcmd1bWVudHNbaV0pO1xuICB9XG4gIHJldHVybiBhY2M7XG59XG5cbmZ1bmN0aW9uIGludGVyc2VjdChvMSwgbzIsIGludGVyc2VjdFN1Y2Nlc3Nlc09wdCwgbGVmdFNob3J0T3B0KSB7XG4gIHZhciBpbnRlcnNlY3RTdWNjZXNzZXMgPSBpbnRlcnNlY3RTdWNjZXNzZXNPcHQgfHwgaW50ZXJzZWN0U3VjY2Vzc2VzRGVmYXVsdDtcbiAgdmFyIGxlZnRTaG9ydCA9IGxlZnRTaG9ydE9wdCB8fCBmdW5jdGlvbiAodiwgcikge1xuICAgIGRpZShcIlJvdXRlLmludGVyc2VjdDogbGVmdCBzaWRlIHNob3J0IVwiKTtcbiAgfTtcbiAgcmV0dXJuIHdhbGsobzEsIG8yKTtcblxuICBmdW5jdGlvbiB3YWxrRmxpcHBlZChyMiwgcjEpIHsgcmV0dXJuIHdhbGsocjEsIHIyKTsgfVxuXG4gIGZ1bmN0aW9uIHdhbGsocjEsIHIyKSB7XG4gICAgLy8gSU5WQVJJQU5UOiByMSBpcyBhIHBhcnQgb2YgdGhlIG9yaWdpbmFsIG8xLCBhbmRcbiAgICAvLyBsaWtld2lzZSBmb3IgcjIuIFRoaXMgaXMgc28gdGhhdCB0aGUgZmlyc3QgYXJnIHRvXG4gICAgLy8gaW50ZXJzZWN0U3VjY2Vzc2VzIGFsd2F5cyBjb21lcyBmcm9tIHIxLCBhbmQgdGhlIHNlY29uZFxuICAgIC8vIGZyb20gcjIuXG4gICAgaWYgKGlzX2VtcHR5VHJpZShyMSkpIHJldHVybiBlbXB0eVRyaWU7XG4gICAgaWYgKGlzX2VtcHR5VHJpZShyMikpIHJldHVybiBlbXB0eVRyaWU7XG5cbiAgICBpZiAocjEgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuICAgICAgaWYgKHIyIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0cmV0dXJuIHJ3aWxkc2VxKHdhbGsocjEudHJpZSwgcjIudHJpZSkpO1xuICAgICAgfVxuICAgICAgcjEgPSBleHBhbmRXaWxkc2VxKHIxLnRyaWUpO1xuICAgIH0gZWxzZSBpZiAocjIgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuICAgICAgcjIgPSBleHBhbmRXaWxkc2VxKHIyLnRyaWUpO1xuICAgIH1cblxuICAgIGlmIChyMSBpbnN0YW5jZW9mICRTdWNjZXNzKSB7XG4gICAgICBpZiAocjIgaW5zdGFuY2VvZiAkU3VjY2Vzcykge1xuXHRyZXR1cm4gcnN1Y2Nlc3MoaW50ZXJzZWN0U3VjY2Vzc2VzKHIxLnZhbHVlLCByMi52YWx1ZSkpO1xuICAgICAgfSBlbHNlIHtcblx0cmV0dXJuIGxlZnRTaG9ydChyMS52YWx1ZSwgcjIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciB3MSA9IHJsb29rdXAocjEsIF9fKTtcbiAgICB2YXIgdzIgPSBybG9va3VwKHIyLCBfXyk7XG4gICAgdmFyIHcgPSB3YWxrKHcxLCB3Mik7XG5cbiAgICB2YXIgdGFyZ2V0ID0gZW1wdHlUcmllO1xuXG4gICAgZnVuY3Rpb24gZXhhbWluZUtleShrZXkpIHtcbiAgICAgIGlmICgoa2V5ICE9PSBfXykgJiYgIXRhcmdldC5oYXMoa2V5KSkge1xuXHR0YXJnZXQgPSBydXBkYXRlKHRhcmdldCwga2V5LCB3YWxrKHJsb29rdXBXaWxkKHIxLCBrZXkpLCBybG9va3VwV2lsZChyMiwga2V5KSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpc19lbXB0eVRyaWUodzEpKSB7XG4gICAgICBpZiAoaXNfZW1wdHlUcmllKHcyKSkge1xuXHQocjEuc2l6ZSA8IHIyLnNpemUgPyByMSA6IHIyKS5mb3JFYWNoKGZ1bmN0aW9uICh2YWwsIGtleSkgeyBleGFtaW5lS2V5KGtleSkgfSk7XG4gICAgICB9IGVsc2Uge1xuXHRyMS5mb3JFYWNoKGZ1bmN0aW9uICh2YWwsIGtleSkgeyBleGFtaW5lS2V5KGtleSkgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChpc19lbXB0eVRyaWUodzIpKSB7XG5cdHIyLmZvckVhY2goZnVuY3Rpb24gKHZhbCwga2V5KSB7IGV4YW1pbmVLZXkoa2V5KSB9KTtcbiAgICAgIH0gZWxzZSB7XG5cdHRhcmdldCA9IHJ1cGRhdGUodGFyZ2V0LCBfXywgdyk7XG5cdHIxLmZvckVhY2goZnVuY3Rpb24gKHZhbCwga2V5KSB7IGV4YW1pbmVLZXkoa2V5KSB9KTtcblx0cjIuZm9yRWFjaChmdW5jdGlvbiAodmFsLCBrZXkpIHsgZXhhbWluZUtleShrZXkpIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9XG59XG5cbi8vIFRoZSBzdWJ0cmFjdFN1Y2Nlc3NlcyBmdW5jdGlvbiBzaG91bGQgcmV0dXJuIG51bGwgdG8gc2lnbmFsIFwibm9cbi8vIHJlbWFpbmluZyBzdWNjZXNzIHZhbHVlc1wiLlxuZnVuY3Rpb24gc3VidHJhY3QobzEsIG8yLCBzdWJ0cmFjdFN1Y2Nlc3Nlc09wdCkge1xuICB2YXIgc3VidHJhY3RTdWNjZXNzZXMgPSBzdWJ0cmFjdFN1Y2Nlc3Nlc09wdCB8fCBzdWJ0cmFjdFN1Y2Nlc3Nlc0RlZmF1bHQ7XG4gIHJldHVybiB3YWxrKG8xLCBvMik7XG5cbiAgZnVuY3Rpb24gd2Fsa0ZsaXBwZWQocjIsIHIxKSB7IHJldHVybiB3YWxrKHIxLCByMik7IH1cblxuICBmdW5jdGlvbiB3YWxrKHIxLCByMikge1xuICAgIGlmIChpc19lbXB0eVRyaWUocjEpKSB7XG4gICAgICByZXR1cm4gZW1wdHlUcmllO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaXNfZW1wdHlUcmllKHIyKSkge1xuXHRyZXR1cm4gcjE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHIxIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcbiAgICAgIGlmIChyMiBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG5cdHJldHVybiByd2lsZHNlcSh3YWxrKHIxLnRyaWUsIHIyLnRyaWUpKTtcbiAgICAgIH1cbiAgICAgIHIxID0gZXhwYW5kV2lsZHNlcShyMS50cmllKTtcbiAgICB9IGVsc2UgaWYgKHIyIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcbiAgICAgIHIyID0gZXhwYW5kV2lsZHNlcShyMi50cmllKTtcbiAgICB9XG5cbiAgICBpZiAocjEgaW5zdGFuY2VvZiAkU3VjY2VzcyAmJiByMiBpbnN0YW5jZW9mICRTdWNjZXNzKSB7XG4gICAgICByZXR1cm4gcnN1Y2Nlc3Moc3VidHJhY3RTdWNjZXNzZXMocjEudmFsdWUsIHIyLnZhbHVlKSk7XG4gICAgfVxuXG4gICAgdmFyIHcxID0gcmxvb2t1cChyMSwgX18pO1xuICAgIHZhciB3MiA9IHJsb29rdXAocjIsIF9fKTtcbiAgICB2YXIgdyA9IHdhbGsodzEsIHcyKTtcbiAgICB2YXIgdGFyZ2V0O1xuXG4gICAgZnVuY3Rpb24gZXhhbWluZUtleShrZXkpIHtcbiAgICAgIGlmIChrZXkgIT09IF9fKSB7XG5cdHZhciBrMSA9IHJsb29rdXBXaWxkKHIxLCBrZXkpO1xuXHR2YXIgazIgPSBybG9va3VwV2lsZChyMiwga2V5KTtcblx0dmFyIHVwZGF0ZWRLID0gd2FsayhrMSwgazIpO1xuXG5cdC8vIEhlcmUgd2UgZW5zdXJlIGEgXCJtaW5pbWFsXCIgcmVtYWluZGVyIGluIGNhc2VzXG5cdC8vIHdoZXJlIGFmdGVyIGFuIGVyYXN1cmUsIGEgcGFydGljdWxhciBrZXknc1xuXHQvLyBjb250aW51YXRpb24gaXMgdGhlIHNhbWUgYXMgdGhlIHdpbGRjYXJkJ3Ncblx0Ly8gY29udGludWF0aW9uLiBUT0RPOiB0aGUgZXF1YWxzIGNoZWNrIG1heVxuXHQvLyBiZSBleHBlbnNpdmUuIElmIHNvLCBob3cgY2FuIGl0IGJlIG1hZGVcblx0Ly8gY2hlYXBlcj9cblx0aWYgKGlzX2tleU9wZW4oa2V5KSkge1xuXHQgIHRhcmdldCA9IHJ1cGRhdGUodGFyZ2V0LCBrZXksXG5cdFx0XHQgICAoKHVwZGF0ZWRLIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpICYmXG5cdFx0XHQgICAgSW1tdXRhYmxlLmlzKHVwZGF0ZWRLLnRyaWUsIHcpKVxuXHRcdFx0ICAgPyB3XG5cdFx0XHQgICA6IHVwZGF0ZWRLKTtcblx0fSBlbHNlIHtcblx0ICB0YXJnZXQgPSBydXBkYXRlKHRhcmdldCwga2V5LCB1cGRhdGVkSyk7XG5cdH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNfZW1wdHlUcmllKHcyKSkge1xuICAgICAgdGFyZ2V0ID0gcjE7XG4gICAgICByMi5mb3JFYWNoKGZ1bmN0aW9uICh2YWwsIGtleSkgeyBleGFtaW5lS2V5KGtleSkgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRhcmdldCA9IGVtcHR5VHJpZTtcbiAgICAgIHRhcmdldCA9IHJ1cGRhdGUodGFyZ2V0LCBfXywgdyk7XG4gICAgICByMS5mb3JFYWNoKGZ1bmN0aW9uICh2YWwsIGtleSkgeyBleGFtaW5lS2V5KGtleSkgfSk7XG4gICAgICByMi5mb3JFYWNoKGZ1bmN0aW9uICh2YWwsIGtleSkgeyBleGFtaW5lS2V5KGtleSkgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbGxhcHNlV2lsZGNhcmRTZXF1ZW5jZXModGFyZ2V0KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb2xsYXBzZVdpbGRjYXJkU2VxdWVuY2VzKHRhcmdldCkge1xuICAvLyBIZXJlLCB0aGUgdGFyZ2V0IGlzIGNvbXBsZXRlLiBJZiBpdCBoYXMgb25seSB0d28ga2V5cyxcbiAgLy8gb25lIHdpbGQgYW5kIG9uZSBpc19rZXlDbG9zZSwgYW5kIHdpbGQncyBjb250aW51YXRpb25cbiAgLy8gaXMgYSAkV2lsZGNhcmRTZXF1ZW5jZSBhbmQgdGhlIG90aGVyIGNvbnRpbnVhdGlvbiBpc1xuICAvLyBpZGVudGljYWwgdG8gdGhlIHNlcXVlbmNlJ3MgY29udGludWF0aW9uLCB0aGVuIHJlcGxhY2VcbiAgLy8gdGhlIHdob2xlIHRoaW5nIHdpdGggYSBuZXN0ZWQgJFdpbGRjYXJkU2VxdWVuY2UuXG4gIC8vIChXZSBrbm93IHcgPT09IHJsb29rdXAodGFyZ2V0LCBfXykgZnJvbSBiZWZvcmUuKVxuICAvL1xuICAvLyBUT0RPOiBJIHN1c3BlY3QgYWN0dWFsbHkgdGhpcyBhcHBsaWVzIGV2ZW4gaWYgdGhlcmUgYXJlXG4gIC8vIG1vcmUgdGhhbiB0d28ga2V5cywgc28gbG9uZyBhcyBhbGwgdGhlaXIgY29udGludWF0aW9uc1xuICAvLyBhcmUgaWRlbnRpY2FsIGFuZCB0aGVyZSdzIGF0IGxlYXN0IG9uZSBpc19rZXlDbG9zZVxuICAvLyBhbG9uZ3NpZGUgYSB3aWxkLlxuICBpZiAodGFyZ2V0LnNpemUgPT09IDIpIHtcbiAgICB2YXIgZmluYWxXID0gcmxvb2t1cCh0YXJnZXQsIF9fKTtcbiAgICBpZiAoZmluYWxXIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcbiAgICAgIHRhcmdldC5mb3JFYWNoKGZ1bmN0aW9uIChrLCBrZXkpIHtcblx0aWYgKChrZXkgIT09IF9fKSAmJiBpc19rZXlDbG9zZShrZXkpKSB7XG5cdCAgaWYgKEltbXV0YWJsZS5pcyhrLCBmaW5hbFcudHJpZSkpIHtcblx0ICAgIHRhcmdldCA9IGZpbmFsVztcblx0ICAgIHJldHVybiBmYWxzZTsgLy8gdGVybWluYXRlIHRoZSBpdGVyYXRpb24gZWFybHlcblx0ICB9XG5cdH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG4vLyBSZXR1cm5zIG51bGwgb24gZmFpbGVkIG1hdGNoLCBvdGhlcndpc2UgdGhlIGFwcHJvcHJpYXRlIHN1Y2Nlc3Ncbi8vIHZhbHVlIGNvbnRhaW5lZCBpbiB0aGUgdHJpZSByLlxuZnVuY3Rpb24gbWF0Y2hWYWx1ZShyLCB2KSB7XG4gIHZhciBmYWlsdXJlUmVzdWx0ID0gbnVsbDtcblxuICB2YXIgdnMgPSBJbW11dGFibGUuTGlzdC5vZih2KTtcbiAgdmFyIHN0YWNrID0gW0ltbXV0YWJsZS5MaXN0KCldO1xuXG4gIHdoaWxlICghaXNfZW1wdHlUcmllKHIpKSB7XG4gICAgaWYgKHIgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuICAgICAgaWYgKHN0YWNrLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhaWx1cmVSZXN1bHQ7XG4gICAgICB2cyA9IHN0YWNrLnBvcCgpO1xuICAgICAgciA9IHIudHJpZTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChyIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcbiAgICAgIGlmICh2cy5zaXplID09PSAwICYmIHN0YWNrLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHIudmFsdWU7XG4gICAgICByZXR1cm4gZmFpbHVyZVJlc3VsdDtcbiAgICB9XG5cbiAgICBpZiAodnMuc2l6ZSA9PT0gMCkge1xuICAgICAgaWYgKHN0YWNrLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhaWx1cmVSZXN1bHQ7XG4gICAgICB2cyA9IHN0YWNrLnBvcCgpO1xuICAgICAgciA9IHJsb29rdXAociwgRU9BKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHZhciB2ID0gdnMuZmlyc3QoKTtcbiAgICB2cyA9IHZzLnNoaWZ0KCk7XG5cbiAgICBpZiAodHlwZW9mIHYgPT09ICdzdHJpbmcnICYmIHYuc3Vic3RyaW5nKDAsIDIpID09PSAnX18nKSB7XG4gICAgICBkaWUoXCJDYW5ub3QgbWF0Y2ggc3BlY2lhbCBzdHJpbmcgc3RhcnRpbmcgd2l0aCBfX1wiKTtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2KSkge1xuICAgICAgaWYgKHIuaGFzKFNPQSkpIHtcblx0ciA9IHJsb29rdXAociwgU09BKTtcblx0c3RhY2sucHVzaCh2cyk7XG5cdHZzID0gSW1tdXRhYmxlLkxpc3Qodik7XG4gICAgICB9IGVsc2Uge1xuXHRyID0gcmxvb2t1cChyLCBfXyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChpc1N0cnVjdHVyZSh2KSkge1xuICAgICAgaWYgKHIuaGFzKFNPQSkpIHtcbiAgICAgICAgciA9IHJsb29rdXAociwgU09BKTtcbiAgICAgICAgc3RhY2sucHVzaCh2cyk7XG4gICAgICAgIHZzID0gSW1tdXRhYmxlLkxpc3Qub2Yodi4kU3luZGljYXRlTWV0YSQubGFiZWwpO1xuICAgICAgICB2YXIgYXJncyA9IHYuJFN5bmRpY2F0ZU1ldGEkLmFyZ3VtZW50cztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdnMgPSB2cy5wdXNoKHZbYXJnc1tpXV0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByID0gcmxvb2t1cChyLCBfXyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChyLmhhcyh2KSkge1xuXHRyID0gcmxvb2t1cChyLCB2KTtcbiAgICAgIH0gZWxzZSB7XG5cdHIgPSBybG9va3VwKHIsIF9fKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFpbHVyZVJlc3VsdDtcbn1cblxuZnVuY3Rpb24gbWF0Y2hUcmllKG8xLCBvMiwgc2VlZCwgbGVmdFNob3J0T3B0KSB7XG4gIHZhciBhY2MgPSB0eXBlb2Ygc2VlZCA9PT0gJ3VuZGVmaW5lZCcgPyBJbW11dGFibGUuU2V0KCkgOiBzZWVkOyAvLyB2YXJpYWJsZSB1cGRhdGVkIGltcGVyYXRpdmVseVxuICB2YXIgbGVmdFNob3J0ID0gbGVmdFNob3J0T3B0IHx8IGZ1bmN0aW9uICh2LCByLCBhY2MpIHtcbiAgICBkaWUoXCJSb3V0ZS5tYXRjaFRyaWU6IGxlZnQgc2lkZSBzaG9ydCFcIik7XG4gIH07XG4gIHdhbGsobzEsIG8yKTtcbiAgcmV0dXJuIGFjYztcblxuICBmdW5jdGlvbiB3YWxrRmxpcHBlZChyMiwgcjEpIHsgcmV0dXJuIHdhbGsocjEsIHIyKTsgfVxuXG4gIGZ1bmN0aW9uIHdhbGsocjEsIHIyKSB7XG4gICAgaWYgKGlzX2VtcHR5VHJpZShyMSkgfHwgaXNfZW1wdHlUcmllKHIyKSkgcmV0dXJuO1xuXG4gICAgaWYgKHIxIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcbiAgICAgIGlmIChyMiBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG5cdHdhbGsocjEudHJpZSwgcjIudHJpZSk7XG5cdHJldHVybjtcbiAgICAgIH1cbiAgICAgIHIxID0gZXhwYW5kV2lsZHNlcShyMS50cmllKTtcbiAgICB9IGVsc2UgaWYgKHIyIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcbiAgICAgIHIyID0gZXhwYW5kV2lsZHNlcShyMi50cmllKTtcbiAgICB9XG5cbiAgICBpZiAocjEgaW5zdGFuY2VvZiAkU3VjY2Vzcykge1xuICAgICAgaWYgKHIyIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcblx0YWNjID0gbWF0Y2hUcmllU3VjY2Vzc2VzKHIxLnZhbHVlLCByMi52YWx1ZSwgYWNjKTtcbiAgICAgIH0gZWxzZSB7XG5cdGFjYyA9IGxlZnRTaG9ydChyMS52YWx1ZSwgcjIsIGFjYyk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIGlmIChyMiBpbnN0YW5jZW9mICRTdWNjZXNzKSB7XG4gICAgICBkaWUoXCJSb3V0ZS5tYXRjaFRyaWU6IHJpZ2h0IHNpZGUgc2hvcnQhXCIpO1xuICAgIH1cblxuICAgIHZhciB3MSA9IHJsb29rdXAocjEsIF9fKTtcbiAgICB2YXIgdzIgPSBybG9va3VwKHIyLCBfXyk7XG4gICAgd2Fsayh3MSwgdzIpO1xuXG4gICAgZnVuY3Rpb24gZXhhbWluZUtleShrZXkpIHtcbiAgICAgIGlmIChrZXkgIT09IF9fKSB7XG5cdHZhciBrMSA9IHJsb29rdXAocjEsIGtleSk7XG5cdHZhciBrMiA9IHJsb29rdXAocjIsIGtleSk7XG5cdGlmIChpc19lbXB0eVRyaWUoazEpKSB7XG5cdCAgaWYgKGlzX2VtcHR5VHJpZShrMikpIHtcblx0ICAgIHJldHVybjtcblx0ICB9IGVsc2Uge1xuXHQgICAgd2Fsa1dpbGQod2FsaywgdzEsIGtleSwgazIpO1xuXHQgIH1cblx0fSBlbHNlIHtcblx0ICBpZiAoaXNfZW1wdHlUcmllKGsyKSkge1xuXHQgICAgd2Fsa1dpbGQod2Fsa0ZsaXBwZWQsIHcyLCBrZXksIGsxKTtcblx0ICB9IGVsc2Uge1xuXHQgICAgd2FsayhrMSwgazIpO1xuXHQgIH1cblx0fVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIE9wdGltaXplIHNpbWlsYXJseSB0byBpbnRlcnNlY3QoKS5cbiAgICBpZiAoaXNfZW1wdHlUcmllKHcxKSkge1xuICAgICAgaWYgKGlzX2VtcHR5VHJpZSh3MikpIHtcblx0KHIxLnNpemUgPCByMi5zaXplID8gcjEgOiByMikuZm9yRWFjaChmdW5jdGlvbiAodmFsLCBrZXkpIHsgZXhhbWluZUtleShrZXkpIH0pO1xuICAgICAgfSBlbHNlIHtcblx0cjEuZm9yRWFjaChmdW5jdGlvbiAodmFsLCBrZXkpIHsgZXhhbWluZUtleShrZXkpIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaXNfZW1wdHlUcmllKHcyKSkge1xuXHRyMi5mb3JFYWNoKGZ1bmN0aW9uICh2YWwsIGtleSkgeyBleGFtaW5lS2V5KGtleSkgfSk7XG4gICAgICB9IGVsc2Uge1xuXHRyMS5mb3JFYWNoKGZ1bmN0aW9uICh2YWwsIGtleSkgeyBleGFtaW5lS2V5KGtleSkgfSk7XG5cdHIyLmZvckVhY2goZnVuY3Rpb24gKHZhbCwga2V5KSB7IGV4YW1pbmVLZXkoa2V5KSB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB3YWxrV2lsZCh3YWxrZXIsIHcsIGtleSwgaykge1xuICAgIGlmIChpc19lbXB0eVRyaWUodykpIHJldHVybjtcbiAgICBpZiAoaXNfa2V5T3BlbihrZXkpKSB7XG4gICAgICB3YWxrZXIocndpbGRzZXEodyksIGspO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaXNfa2V5Q2xvc2Uoa2V5KSkge1xuICAgICAgaWYgKHcgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkgd2Fsa2VyKHcudHJpZSwgayk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHdhbGtlcih3LCBrKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBhcHBlbmRUcmllKG0sIG1UYWlsRm4pIHtcbiAgcmV0dXJuIHdhbGsobSk7XG5cbiAgZnVuY3Rpb24gd2FsayhtKSB7XG4gICAgaWYgKGlzX2VtcHR5VHJpZShtKSkgcmV0dXJuIGVtcHR5VHJpZTtcbiAgICBpZiAobSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSByZXR1cm4gcndpbGRzZXEod2FsayhtLnRyaWUpKTtcbiAgICBpZiAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSBkaWUoXCJJbGwtZm9ybWVkIHRyaWVcIik7XG5cbiAgICB2YXIgdGFyZ2V0ID0gZW1wdHlUcmllO1xuICAgIG0uZm9yRWFjaChmdW5jdGlvbiAoaywga2V5KSB7XG4gICAgICBpZiAoaXNfa2V5Q2xvc2Uoa2V5KSAmJiAoayBpbnN0YW5jZW9mICRTdWNjZXNzKSkge1xuXHR0YXJnZXQgPSB1bmlvbih0YXJnZXQsIG1UYWlsRm4oay52YWx1ZSkpO1xuICAgICAgfSBlbHNlIHtcblx0dGFyZ2V0ID0gcnVwZGF0ZSh0YXJnZXQsIGtleSwgd2FsayhrKSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfVxufVxuXG5mdW5jdGlvbiB0cmllUHJ1bmVCcmFuY2gobSwga2V5cykge1xuICBpZiAoa2V5cy5pc0VtcHR5KCkpIHJldHVybiBlbXB0eVRyaWU7XG5cbiAgaWYgKGlzX2VtcHR5VHJpZShtKSkgcmV0dXJuIGVtcHR5VHJpZTtcbiAgaWYgKG0gaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuICAgIHJldHVybiBjb2xsYXBzZVdpbGRjYXJkU2VxdWVuY2VzKHRyaWVQcnVuZUJyYW5jaChleHBhbmRXaWxkc2VxKG0udHJpZSksIGtleXMpKTtcbiAgfVxuICBpZiAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSByZXR1cm4gbTtcblxuICB2YXIga2V5ID0ga2V5cy5maXJzdCgpO1xuICB2YXIgcmVzdCA9IGtleXMuc2hpZnQoKTtcbiAgcmV0dXJuIHJ1cGRhdGUobSwga2V5LCB0cmllUHJ1bmVCcmFuY2gocmxvb2t1cFdpbGQobSwga2V5KSwgcmVzdCkpO1xufVxuXG5mdW5jdGlvbiB0cmllU3RlcChtLCBrZXkpIHtcbiAgaWYgKGlzX2VtcHR5VHJpZShtKSkgcmV0dXJuIGVtcHR5VHJpZTtcbiAgaWYgKG0gaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkgcmV0dXJuIChpc19rZXlDbG9zZShrZXkpID8gbS50cmllIDogbSk7XG4gIGlmIChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHJldHVybiBlbXB0eVRyaWU7XG4gIHJldHVybiBybG9va3VwV2lsZChtLCBrZXkpO1xufVxuXG5mdW5jdGlvbiByZWxhYmVsKG0sIGYpIHtcbiAgcmV0dXJuIHdhbGsobSk7XG5cbiAgZnVuY3Rpb24gd2FsayhtKSB7XG4gICAgaWYgKGlzX2VtcHR5VHJpZShtKSkgcmV0dXJuIGVtcHR5VHJpZTtcbiAgICBpZiAobSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSByZXR1cm4gcndpbGRzZXEod2FsayhtLnRyaWUpKTtcbiAgICBpZiAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSByZXR1cm4gcnN1Y2Nlc3MoZihtLnZhbHVlKSk7XG5cbiAgICB2YXIgdGFyZ2V0ID0gZW1wdHlUcmllO1xuICAgIG0uZm9yRWFjaChmdW5jdGlvbiAoaywga2V5KSB7XG4gICAgICB0YXJnZXQgPSBydXBkYXRlKHRhcmdldCwga2V5LCB3YWxrKGspKTtcbiAgICB9KTtcbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbXBpbGVQcm9qZWN0aW9uKC8qIHByb2plY3Rpb24sIHByb2plY3Rpb24sIC4uLiAqLykge1xuICB2YXIgbmFtZXMgPSBbXTtcbiAgdmFyIGFjYyA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHdhbGsoYXJndW1lbnRzW2ldKTtcbiAgfVxuICBhY2MucHVzaChFT0EpO1xuICByZXR1cm4ge25hbWVzOiBuYW1lcywgc3BlYzogYWNjfTtcblxuICBmdW5jdGlvbiB3YWxrKHApIHtcbiAgICBpZiAoaXNDYXB0dXJlKHApKSB7XG4gICAgICBuYW1lcy5wdXNoKGNhcHR1cmVOYW1lKHApKTtcbiAgICAgIGFjYy5wdXNoKFNPQyk7XG4gICAgICB3YWxrKGNhcHR1cmVQYXR0ZXJuKHApKTtcbiAgICAgIGFjYy5wdXNoKEVPQyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkocCkpIHtcbiAgICAgIGFjYy5wdXNoKFNPQSk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHAubGVuZ3RoOyBpKyspIHtcblx0d2FsayhwW2ldKTtcbiAgICAgIH1cbiAgICAgIGFjYy5wdXNoKEVPQSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGlzU3RydWN0dXJlKHApKSB7XG4gICAgICBhY2MucHVzaChTT0EpO1xuICAgICAgYWNjLnB1c2gocC4kU3luZGljYXRlTWV0YSQubGFiZWwpO1xuICAgICAgdmFyIGFyZ3MgPSBwLiRTeW5kaWNhdGVNZXRhJC5hcmd1bWVudHM7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgd2FsayhwW2FyZ3NbaV1dKTtcbiAgICAgIH1cbiAgICAgIGFjYy5wdXNoKEVPQSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHAgaW5zdGFuY2VvZiAkRW1iZWRkZWQpIHtcbiAgICAgIGRpZShcIkNhbm5vdCBlbWJlZCB0cmllIGluIHByb2plY3Rpb25cIik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFjYy5wdXNoKHApO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9qZWN0aW9uVG9QYXR0ZXJuKHApIHtcbiAgcmV0dXJuIHdhbGsocCk7XG5cbiAgZnVuY3Rpb24gd2FsayhwKSB7XG4gICAgaWYgKGlzQ2FwdHVyZShwKSkgcmV0dXJuIHdhbGsoY2FwdHVyZVBhdHRlcm4ocCkpO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkocCkpIHtcbiAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuXHRyZXN1bHQucHVzaCh3YWxrKHBbaV0pKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgaWYgKGlzU3RydWN0dXJlKHApKSB7XG4gICAgICB2YXIgcmVzdWx0ID0ge1wiJFN5bmRpY2F0ZU1ldGEkXCI6IHAuJFN5bmRpY2F0ZU1ldGEkfTtcbiAgICAgIHZhciBhcmdzID0gcC4kU3luZGljYXRlTWV0YSQuYXJndW1lbnRzO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJlc3VsdFthcmdzW2ldXSA9IHdhbGsocFthcmdzW2ldXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIGlmIChwIGluc3RhbmNlb2YgJEVtYmVkZGVkKSB7XG4gICAgICByZXR1cm4gcC50cmllO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcDtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJvamVjdChtLCBjb21waWxlZFByb2plY3Rpb24pIHtcbiAgdmFyIHNwZWMgPSBjb21waWxlZFByb2plY3Rpb24uc3BlYztcbiAgcmV0dXJuIHdhbGsoZmFsc2UsIG0sIDApO1xuXG4gIGZ1bmN0aW9uIHdhbGsoaXNDYXB0dXJpbmcsIG0sIHNwZWNJbmRleCkge1xuICAgIGlmIChzcGVjSW5kZXggPj0gc3BlYy5sZW5ndGgpIHtcbiAgICAgIGlmIChpc0NhcHR1cmluZykgZGllKFwiQmFkIHNwZWNpZmljYXRpb246IHVuY2xvc2VkIGNhcHR1cmVcIik7XG4gICAgICBpZiAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSB7XG5cdHJldHVybiByc2VxKEVPQSwgcnN1Y2Nlc3MocHJvamVjdFN1Y2Nlc3MobS52YWx1ZSkpKTtcbiAgICAgIH0gZWxzZSB7XG5cdHJldHVybiBlbXB0eVRyaWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzX2VtcHR5VHJpZShtKSkgcmV0dXJuIGVtcHR5VHJpZTtcblxuICAgIHZhciBpdGVtID0gc3BlY1tzcGVjSW5kZXhdO1xuICAgIHZhciBuZXh0SW5kZXggPSBzcGVjSW5kZXggKyAxO1xuXG4gICAgaWYgKGl0ZW0gPT09IEVPQykge1xuICAgICAgaWYgKCFpc0NhcHR1cmluZykgZGllKFwiQmFkIHNwZWNpZmljYXRpb246IHVuZXhwZWN0ZWQgRU9DXCIpO1xuICAgICAgcmV0dXJuIHdhbGsoZmFsc2UsIG0sIG5leHRJbmRleCk7XG4gICAgfVxuXG4gICAgaWYgKGl0ZW0gPT09IFNPQykge1xuICAgICAgaWYgKGlzQ2FwdHVyaW5nKSBkaWUoXCJCYWQgc3BlY2lmaWNhdGlvbjogbmVzdGVkIGNhcHR1cmVcIik7XG4gICAgICByZXR1cm4gd2Fsayh0cnVlLCBtLCBuZXh0SW5kZXgpO1xuICAgIH1cblxuICAgIGlmIChpdGVtID09PSBfXykge1xuICAgICAgaWYgKG0gaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHRpZiAoaXNDYXB0dXJpbmcpIHtcblx0ICByZXR1cm4gcndpbGQod2Fsayhpc0NhcHR1cmluZywgbSwgbmV4dEluZGV4KSk7XG5cdH0gZWxzZSB7XG5cdCAgcmV0dXJuIHdhbGsoaXNDYXB0dXJpbmcsIG0sIG5leHRJbmRleCk7XG5cdH1cbiAgICAgIH1cblxuICAgICAgaWYgKG0gaW5zdGFuY2VvZiAkU3VjY2Vzcykge1xuXHRyZXR1cm4gZW1wdHlUcmllO1xuICAgICAgfVxuXG4gICAgICB2YXIgdGFyZ2V0O1xuICAgICAgaWYgKGlzQ2FwdHVyaW5nKSB7XG5cdHRhcmdldCA9IGVtcHR5VHJpZTtcblx0dGFyZ2V0ID0gcnVwZGF0ZSh0YXJnZXQsIF9fLCB3YWxrKGlzQ2FwdHVyaW5nLCBybG9va3VwKG0sIF9fKSwgbmV4dEluZGV4KSk7XG5cdG0uZm9yRWFjaChmdW5jdGlvbiAobWssIGtleSkge1xuXHQgIGlmIChrZXkgIT09IF9fKSB7XG5cdCAgICBpZiAoaXNfa2V5T3BlbihrZXkpKSB7XG5cdCAgICAgIHRhcmdldCA9IHJ1cGRhdGUodGFyZ2V0LCBrZXksIGNhcHR1cmVOZXN0ZWQobWssIGZ1bmN0aW9uIChtazIpIHtcblx0XHRyZXR1cm4gd2Fsayhpc0NhcHR1cmluZywgbWsyLCBuZXh0SW5kZXgpO1xuXHQgICAgICB9KSk7XG5cdCAgICB9IGVsc2UgaWYgKGlzX2tleUNsb3NlKGtleSkpIHtcblx0ICAgICAgLy8gZG8gbm90aGluZ1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgdGFyZ2V0ID0gcnVwZGF0ZSh0YXJnZXQsIGtleSwgd2Fsayhpc0NhcHR1cmluZywgbWssIG5leHRJbmRleCkpO1xuXHQgICAgfVxuXHQgIH1cblx0fSk7XG4gICAgICB9IGVsc2Uge1xuXHR0YXJnZXQgPSB3YWxrKGlzQ2FwdHVyaW5nLCBybG9va3VwKG0sIF9fKSwgbmV4dEluZGV4KTtcblx0bS5mb3JFYWNoKGZ1bmN0aW9uIChtaywga2V5KSB7XG5cdCAgaWYgKGtleSAhPT0gX18pIHtcblx0ICAgIGlmIChpc19rZXlPcGVuKGtleSkpIHtcblx0ICAgICAgdGFyZ2V0ID0gdW5pb24odGFyZ2V0LCBza2lwTmVzdGVkKG1rLCBmdW5jdGlvbiAobWsyKSB7XG5cdFx0cmV0dXJuIHdhbGsoaXNDYXB0dXJpbmcsIG1rMiwgbmV4dEluZGV4KTtcblx0ICAgICAgfSkpO1xuXHQgICAgfSBlbHNlIGlmIChpc19rZXlDbG9zZShrZXkpKSB7XG5cdCAgICAgIC8vIGRvIG5vdGhpbmdcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIHRhcmdldCA9IHVuaW9uKHRhcmdldCwgd2Fsayhpc0NhcHR1cmluZywgbWssIG5leHRJbmRleCkpO1xuXHQgICAgfVxuXHQgIH1cblx0fSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cblxuICAgIHZhciByZXN1bHQ7XG4gICAgaWYgKG0gaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuICAgICAgaWYgKGlzX2tleU9wZW4oaXRlbSkpIHtcblx0cmVzdWx0ID0gd2Fsayhpc0NhcHR1cmluZywgcndpbGRzZXEobSksIG5leHRJbmRleCk7XG4gICAgICB9IGVsc2UgaWYgKGlzX2tleUNsb3NlKGl0ZW0pKSB7XG5cdHJlc3VsdCA9IHdhbGsoaXNDYXB0dXJpbmcsIG0udHJpZSwgbmV4dEluZGV4KTtcbiAgICAgIH0gZWxzZSB7XG5cdHJlc3VsdCA9IHdhbGsoaXNDYXB0dXJpbmcsIG0sIG5leHRJbmRleCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcbiAgICAgIHJlc3VsdCA9IGVtcHR5VHJpZTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGlzX2tleU9wZW4oaXRlbSkpIHtcblx0cmVzdWx0ID0gd2Fsayhpc0NhcHR1cmluZywgcndpbGRzZXEocmxvb2t1cChtLCBfXykpLCBuZXh0SW5kZXgpO1xuICAgICAgfSBlbHNlIGlmIChpc19rZXlDbG9zZShpdGVtKSkge1xuXHRyZXN1bHQgPSBlbXB0eVRyaWU7XG4gICAgICB9IGVsc2Uge1xuXHRyZXN1bHQgPSB3YWxrKGlzQ2FwdHVyaW5nLCBybG9va3VwKG0sIF9fKSwgbmV4dEluZGV4KTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdCA9IHVuaW9uKHJlc3VsdCwgd2Fsayhpc0NhcHR1cmluZywgcmxvb2t1cChtLCBpdGVtKSwgbmV4dEluZGV4KSk7XG4gICAgfVxuICAgIGlmIChpc0NhcHR1cmluZykge1xuICAgICAgcmVzdWx0ID0gcnNlcShpdGVtLCByZXN1bHQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gY2FwdHVyZU5lc3RlZChtLCBjb250KSB7XG4gICAgaWYgKG0gaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuICAgICAgcmV0dXJuIHJ3aWxkc2VxKGNvbnQobS50cmllKSk7XG4gICAgfVxuXG4gICAgaWYgKGlzX2VtcHR5VHJpZShtKSB8fCAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSkge1xuICAgICAgcmV0dXJuIGVtcHR5VHJpZTtcbiAgICB9XG5cbiAgICB2YXIgdGFyZ2V0ID0gZW1wdHlUcmllO1xuICAgIHRhcmdldCA9IHJ1cGRhdGUodGFyZ2V0LCBfXywgY2FwdHVyZU5lc3RlZChybG9va3VwKG0sIF9fKSwgY29udCkpO1xuICAgIG0uZm9yRWFjaChmdW5jdGlvbiAobWssIGtleSkge1xuICAgICAgaWYgKGtleSAhPT0gX18pIHtcblx0aWYgKGlzX2tleU9wZW4oa2V5KSkge1xuXHQgIHRhcmdldCA9IHJ1cGRhdGUodGFyZ2V0LCBrZXksIGNhcHR1cmVOZXN0ZWQobWssIGZ1bmN0aW9uIChtazIpIHtcblx0ICAgIHJldHVybiBjYXB0dXJlTmVzdGVkKG1rMiwgY29udCk7XG5cdCAgfSkpO1xuXHR9IGVsc2UgaWYgKGlzX2tleUNsb3NlKGtleSkpIHtcblx0ICB0YXJnZXQgPSBydXBkYXRlKHRhcmdldCwga2V5LCBjb250KG1rKSk7XG5cdH0gZWxzZSB7XG5cdCAgdGFyZ2V0ID0gcnVwZGF0ZSh0YXJnZXQsIGtleSwgY2FwdHVyZU5lc3RlZChtaywgY29udCkpO1xuXHR9XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNraXBOZXN0ZWQobSwgY29udCkge1xuICAgIGlmIChtIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcbiAgICAgIHJldHVybiBjb250KG0udHJpZSk7XG4gICAgfVxuXG4gICAgaWYgKGlzX2VtcHR5VHJpZShtKSB8fCAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSkge1xuICAgICAgcmV0dXJuIGVtcHR5VHJpZTtcbiAgICB9XG5cbiAgICB2YXIgdGFyZ2V0ID0gc2tpcE5lc3RlZChybG9va3VwKG0sIF9fKSwgY29udCk7XG4gICAgbS5mb3JFYWNoKGZ1bmN0aW9uIChtaywga2V5KSB7XG4gICAgICBpZiAoa2V5ICE9PSBfXykge1xuXHRpZiAoaXNfa2V5T3BlbihrZXkpKSB7XG5cdCAgdGFyZ2V0ID0gdW5pb24odGFyZ2V0LCBza2lwTmVzdGVkKG1rLCBmdW5jdGlvbiAobWsyKSB7XG5cdCAgICByZXR1cm4gc2tpcE5lc3RlZChtazIsIGNvbnQpXG5cdCAgfSkpO1xuXHR9IGVsc2UgaWYgKGlzX2tleUNsb3NlKGtleSkpIHtcblx0ICB0YXJnZXQgPSB1bmlvbih0YXJnZXQsIGNvbnQobWspKTtcblx0fSBlbHNlIHtcblx0ICB0YXJnZXQgPSB1bmlvbih0YXJnZXQsIHNraXBOZXN0ZWQobWssIGNvbnQpKTtcblx0fVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB0YXJnZXQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gdHJpZUtleXMobSkge1xuICBpZiAoaXNfZW1wdHlUcmllKG0pKSByZXR1cm4gSW1tdXRhYmxlLlNldCgpO1xuICB2YXIgcmVzdWx0ID0gd2Fsa1NlcShtLCBmdW5jdGlvbiAodnNzLCB2c2spIHsgcmV0dXJuIHZzczsgfSk7XG4gIGlmIChyZXN1bHQgPT09IG51bGwpIHJldHVybiBudWxsO1xuICByZXR1cm4gSW1tdXRhYmxlLlNldChyZXN1bHQpO1xuXG4gIGZ1bmN0aW9uIHdhbGsobSwgaykge1xuICAgIGlmIChtIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHJldHVybiBudWxsO1xuICAgIGlmIChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHJldHVybiBbXTtcbiAgICBpZiAobS5oYXMoX18pKSByZXR1cm4gbnVsbDtcbiAgICB2YXIgYWNjID0gW107XG4gICAgbS5mb3JFYWNoKGZ1bmN0aW9uIChtaywga2V5KSB7XG4gICAgICB2YXIgcGllY2U7XG4gICAgICBpZiAoaXNfa2V5T3BlbihrZXkpKSB7XG5cdHBpZWNlID0gd2Fsa1NlcShtaywgZnVuY3Rpb24gKHZzcywgdnNrKSB7XG5cdCAgdmFyIGFjYyA9IFtdO1xuXHQgIGZvciAodmFyIGkgPSAwOyBpIDwgdnNzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICB2YXIgdnMgPSB2c3NbaV07XG5cdCAgICBhY2MgPSBhY2MuY29uY2F0KGsodHJhbnNmb3JtU2Vxcyh2cywga2V5KSwgdnNrKSk7XG5cdCAgfVxuXHQgIHJldHVybiBhY2M7XG5cdH0pO1xuICAgICAgfSBlbHNlIGlmIChpc19rZXlDbG9zZShrZXkpKSB7XG5cdGRpZShcInRyaWVLZXlzOiBpbnRlcm5hbCBlcnJvcjogdW5leHBlY3RlZCBrZXktY2xvc2VcIik7XG4gICAgICB9IGVsc2Uge1xuXHRwaWVjZSA9IGsoa2V5LCBtayk7XG4gICAgICB9XG4gICAgICBpZiAocGllY2UgPT09IG51bGwpIHJldHVybiBudWxsO1xuICAgICAgYWNjID0gYWNjLmNvbmNhdChwaWVjZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjYztcbiAgfVxuXG4gIGZ1bmN0aW9uIHdhbGtTZXEobSwgaykge1xuICAgIGlmIChtIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHJldHVybiBudWxsO1xuICAgIGlmIChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHJldHVybiBrKFtdLCBlbXB0eVRyaWUpOyAvLyBUT0RPOiA/P1xuICAgIGlmIChtLmhhcyhfXykpIHJldHVybiBudWxsO1xuICAgIHZhciBhY2MgPSBbXTtcbiAgICBtLmZvckVhY2goZnVuY3Rpb24gKG1rLCBrZXkpIHtcbiAgICAgIHZhciBwaWVjZTtcbiAgICAgIGlmIChpc19rZXlDbG9zZShrZXkpKSB7XG5cdHBpZWNlID0gayhbSW1tdXRhYmxlLkxpc3QoKV0sIG1rKTtcbiAgICAgIH0gZWxzZSB7XG5cdHBpZWNlID0gd2Fsayhyc2VxKGtleSwgbWspLCBmdW5jdGlvbiAodiwgdmspIHtcblx0ICByZXR1cm4gd2Fsa1NlcSh2aywgZnVuY3Rpb24gKHZzcywgdnNrKSB7XG5cdCAgICB2YXIgYWNjID0gW107XG5cdCAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZzcy5sZW5ndGg7IGkrKykge1xuXHQgICAgICBhY2MucHVzaCh2c3NbaV0udW5zaGlmdCh2KSk7XG5cdCAgICB9XG5cdCAgICByZXR1cm4gayhhY2MsIHZzayk7XG5cdCAgfSk7XG5cdH0pO1xuICAgICAgfVxuICAgICAgaWYgKHBpZWNlID09PSBudWxsKSByZXR1cm4gbnVsbDtcbiAgICAgIGFjYyA9IGFjYy5jb25jYXQocGllY2UpO1xuICAgIH0pO1xuICAgIHJldHVybiBhY2M7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFuc2Zvcm1TZXFzKHZzLCBvcGVuZXIpIHtcbiAgICBpZiAob3BlbmVyID09PSBTT0EpIHJldHVybiB2cztcbiAgICBkaWUoXCJJbnRlcm5hbCBlcnJvcjogdW5rbm93biBvcGVuZXIgXCIgKyBvcGVuZXIpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNhcHR1cmVUb09iamVjdChjYXB0dXJlcywgY29tcGlsZWRQcm9qZWN0aW9uKSB7XG4gIHZhciBkID0ge307XG4gIGNhcHR1cmVzLmZvckVhY2goZnVuY3Rpb24gKGtleSwgaW5kZXgpIHtcbiAgICBkW2NvbXBpbGVkUHJvamVjdGlvbi5uYW1lc1tpbmRleF0gfHwgKCckJyArIGluZGV4KV0gPSBrZXk7XG4gIH0pO1xuICByZXR1cm4gZDtcbn1cblxuZnVuY3Rpb24gdHJpZUtleXNUb09iamVjdHModHJpZUtleXNSZXN1bHQsIGNvbXBpbGVkUHJvamVjdGlvbikge1xuICBpZiAodHJpZUtleXNSZXN1bHQgPT09IG51bGwpIHJldHVybiBudWxsO1xuICByZXR1cm4gdHJpZUtleXNSZXN1bHQudG9MaXN0KCkubWFwKGZ1bmN0aW9uIChlKSB7IHJldHVybiBjYXB0dXJlVG9PYmplY3QoZSwgY29tcGlsZWRQcm9qZWN0aW9uKTsgfSk7XG59XG5cbmZ1bmN0aW9uIHByb2plY3RPYmplY3RzKG0sIGNvbXBpbGVkUHJvamVjdGlvbikge1xuICByZXR1cm4gdHJpZUtleXNUb09iamVjdHModHJpZUtleXMocHJvamVjdChtLCBjb21waWxlZFByb2plY3Rpb24pKSwgY29tcGlsZWRQcm9qZWN0aW9uKTtcbn1cblxuZnVuY3Rpb24gcHJldHR5VHJpZShtLCBpbml0aWFsSW5kZW50KSB7XG4gIHZhciBhY2MgPSBbXTtcbiAgd2Fsayhpbml0aWFsSW5kZW50IHx8IDAsIG0pO1xuICByZXR1cm4gYWNjLmpvaW4oJycpO1xuXG4gIGZ1bmN0aW9uIHdhbGsoaSwgbSkge1xuICAgIGlmIChtIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcbiAgICAgIGFjYy5wdXNoKFwiLi4uPlwiKTtcbiAgICAgIHdhbGsoaSArIDQsIG0udHJpZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcbiAgICAgIHZhciB2ID0gbS52YWx1ZTtcbiAgICAgIGlmIChJbW11dGFibGUuU2V0LmlzU2V0KHYpKSB7IHYgPSB2LnRvQXJyYXkoKTsgfVxuICAgICAgYWNjLnB1c2goXCJ7XCIgKyBKU09OLnN0cmluZ2lmeSh2KSArIFwifVwiKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAobS5zaXplID09PSAwKSB7XG4gICAgICBhY2MucHVzaChcIjo6OiBub3RoaW5nXCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBuZWVkU2VwID0gZmFsc2U7XG4gICAgbS50b09yZGVyZWRNYXAoKVxuICAgICAgLnNvcnRCeShmdW5jdGlvbiAoaywga2V5KSB7IHJldHVybiBrZXkgfSlcbiAgICAgIC5mb3JFYWNoKGZ1bmN0aW9uIChrLCBrZXkpIHtcblx0aWYgKG5lZWRTZXApIHtcblx0ICBhY2MucHVzaChcIlxcblwiKTtcblx0ICBhY2MucHVzaChpbmRlbnRTdHIoaSkpO1xuXHR9IGVsc2Uge1xuXHQgIG5lZWRTZXAgPSB0cnVlO1xuXHR9XG5cdGFjYy5wdXNoKFwiIFwiKTtcblx0aWYgKGtleSA9PT0gX18pIGtleSA9ICfimIUnO1xuXHRlbHNlIGlmIChrZXkgPT09IFNPQSkga2V5ID0gJzwnO1xuXHRlbHNlIGlmIChrZXkgPT09IEVPQSkga2V5ID0gJz4nO1xuXHRlbHNlIGlmIChrZXkgaW5zdGFuY2VvZiAkU3BlY2lhbCkga2V5ID0ga2V5Lm5hbWU7XG5cdGVsc2Uga2V5ID0gSlNPTi5zdHJpbmdpZnkoa2V5KTtcblx0YWNjLnB1c2goa2V5KTtcblx0d2FsayhpICsga2V5Lmxlbmd0aCArIDEsIGspO1xuICAgICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBpbmRlbnRTdHIoaSkge1xuICAgIHJldHVybiBuZXcgQXJyYXkoaSArIDEpLmpvaW4oJyAnKTsgLy8gZXd3XG4gIH1cbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbm1vZHVsZS5leHBvcnRzLl9fID0gX187XG5tb2R1bGUuZXhwb3J0cy5TT0EgPSBTT0E7XG5tb2R1bGUuZXhwb3J0cy5FT0EgPSBFT0E7XG5tb2R1bGUuZXhwb3J0cy4kQ2FwdHVyZSA9ICRDYXB0dXJlO1xubW9kdWxlLmV4cG9ydHMuJFNwZWNpYWwgPSAkU3BlY2lhbDtcbm1vZHVsZS5leHBvcnRzLm1ha2VTdHJ1Y3R1cmVDb25zdHJ1Y3RvciA9IG1ha2VTdHJ1Y3R1cmVDb25zdHJ1Y3Rvcjtcbm1vZHVsZS5leHBvcnRzLl8kID0gXyQ7XG5tb2R1bGUuZXhwb3J0cy5pc19lbXB0eVRyaWUgPSBpc19lbXB0eVRyaWU7XG5tb2R1bGUuZXhwb3J0cy5lbXB0eVRyaWUgPSBlbXB0eVRyaWU7XG5tb2R1bGUuZXhwb3J0cy5lbWJlZGRlZFRyaWUgPSBlbWJlZGRlZFRyaWU7XG5tb2R1bGUuZXhwb3J0cy5jb21waWxlUGF0dGVybiA9IGNvbXBpbGVQYXR0ZXJuO1xubW9kdWxlLmV4cG9ydHMubWF0Y2hQYXR0ZXJuID0gbWF0Y2hQYXR0ZXJuO1xubW9kdWxlLmV4cG9ydHMuX3VuaW9uID0gdW5pb247XG5tb2R1bGUuZXhwb3J0cy51bmlvbiA9IHVuaW9uTjtcbm1vZHVsZS5leHBvcnRzLmludGVyc2VjdCA9IGludGVyc2VjdDtcbm1vZHVsZS5leHBvcnRzLnN1YnRyYWN0ID0gc3VidHJhY3Q7XG5tb2R1bGUuZXhwb3J0cy5tYXRjaFZhbHVlID0gbWF0Y2hWYWx1ZTtcbm1vZHVsZS5leHBvcnRzLm1hdGNoVHJpZSA9IG1hdGNoVHJpZTtcbm1vZHVsZS5leHBvcnRzLmFwcGVuZFRyaWUgPSBhcHBlbmRUcmllO1xubW9kdWxlLmV4cG9ydHMudHJpZVBydW5lQnJhbmNoID0gdHJpZVBydW5lQnJhbmNoO1xubW9kdWxlLmV4cG9ydHMudHJpZVN0ZXAgPSB0cmllU3RlcDtcbm1vZHVsZS5leHBvcnRzLnJlbGFiZWwgPSByZWxhYmVsO1xubW9kdWxlLmV4cG9ydHMuY29tcGlsZVByb2plY3Rpb24gPSBjb21waWxlUHJvamVjdGlvbjtcbm1vZHVsZS5leHBvcnRzLnByb2plY3Rpb25Ub1BhdHRlcm4gPSBwcm9qZWN0aW9uVG9QYXR0ZXJuO1xubW9kdWxlLmV4cG9ydHMucHJvamVjdCA9IHByb2plY3Q7XG5tb2R1bGUuZXhwb3J0cy50cmllS2V5cyA9IHRyaWVLZXlzO1xubW9kdWxlLmV4cG9ydHMuY2FwdHVyZVRvT2JqZWN0ID0gY2FwdHVyZVRvT2JqZWN0O1xubW9kdWxlLmV4cG9ydHMudHJpZUtleXNUb09iamVjdHMgPSB0cmllS2V5c1RvT2JqZWN0cztcbm1vZHVsZS5leHBvcnRzLnByb2plY3RPYmplY3RzID0gcHJvamVjdE9iamVjdHM7XG5tb2R1bGUuZXhwb3J0cy5wcmV0dHlUcmllID0gcHJldHR5VHJpZTtcblxuLy8gRm9yIHRlc3Rpbmdcbm1vZHVsZS5leHBvcnRzLl90ZXN0aW5nID0ge1xuICByc3VjY2VzczogcnN1Y2Nlc3MsXG4gIHJzZXE6IHJzZXEsXG4gIHJ3aWxkOiByd2lsZCxcbiAgcndpbGRzZXE6IHJ3aWxkc2VxXG59O1xuIiwidmFyIEltbXV0YWJsZSA9IHJlcXVpcmUoJ2ltbXV0YWJsZScpO1xuXG5mdW5jdGlvbiBTZWFsKGNvbnRlbnRzKSB7XG4gIHRoaXMuc2VhbENvbnRlbnRzID0gY29udGVudHM7XG4gIE9iamVjdC5mcmVlemUodGhpcyk7XG59XG5cblNlYWwucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChvdGhlcikge1xuICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFNlYWwpKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiBJbW11dGFibGUuaXModGhpcy5zZWFsQ29udGVudHMsIG90aGVyLnNlYWxDb250ZW50cyk7XG59O1xuXG5mdW5jdGlvbiBzZWFsKGNvbnRlbnRzKSB7XG4gIHJldHVybiBuZXcgU2VhbChjb250ZW50cyk7XG59XG5cbm1vZHVsZS5leHBvcnRzLlNlYWwgPSBTZWFsO1xubW9kdWxlLmV4cG9ydHMuc2VhbCA9IHNlYWw7XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIFJlZmxlY3QgPSByZXF1aXJlKFwiLi9yZWZsZWN0LmpzXCIpO1xuXG5tb2R1bGUuZXhwb3J0cy5leHRlbmQgPSBmdW5jdGlvbiAod2hhdCwgX3dpdGgpIHtcbiAgZm9yICh2YXIgcHJvcCBpbiBfd2l0aCkge1xuICAgIGlmIChfd2l0aC5oYXNPd25Qcm9wZXJ0eShwcm9wKSkge1xuICAgICAgd2hhdFtwcm9wXSA9IF93aXRoW3Byb3BdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gd2hhdDtcbn07XG5cbm1vZHVsZS5leHBvcnRzLmt3QXBwbHkgPSBmdW5jdGlvbiAoZiwgdGhpc0FyZywgYXJncykge1xuICB2YXIgZm9ybWFscyA9IFJlZmxlY3QuZm9ybWFsUGFyYW1ldGVycyhmKTtcbiAgdmFyIGFjdHVhbHMgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGZvcm1hbHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZm9ybWFsID0gZm9ybWFsc1tpXTtcbiAgICBpZiAoIShmb3JtYWwgaW4gYXJncykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkZ1bmN0aW9uIHBhcmFtZXRlciAnXCIrZm9ybWFsK1wiJyBub3QgcHJlc2VudCBpbiBhcmdzXCIpO1xuICAgIH1cbiAgICBhY3R1YWxzLnB1c2goYXJnc1tmb3JtYWxdKTtcbiAgfVxuICByZXR1cm4gZi5hcHBseSh0aGlzQXJnLCBhY3R1YWxzKTtcbn07XG4iXX0=